summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitattributes2
-rw-r--r--.gitignore2
-rw-r--r--.travis.yml31
-rw-r--r--EXTENSIONS4
-rw-r--r--INSTALL4
-rw-r--r--LICENSE2
-rw-r--r--Makefile.frag4
-rw-r--r--Makefile.gcov30
-rw-r--r--Makefile.global17
-rw-r--r--NEWS827
-rw-r--r--README.PARAMETER_PARSING_API21
-rw-r--r--README.md39
-rw-r--r--TSRM/tsrm_config.w32.h9
-rwxr-xr-xUPGRADING1204
-rw-r--r--UPGRADING.INTERNALS279
-rw-r--r--Zend/Makefile.am7
-rw-r--r--Zend/Zend.dsp4
-rw-r--r--Zend/ZendTS.dsp4
-rw-r--r--Zend/acinclude.m42
-rw-r--r--Zend/tests/bug18556.phpt37
-rw-r--r--Zend/tests/bug39018.phpt2
-rw-r--r--Zend/tests/bug41421.phpt2
-rw-r--r--Zend/tests/bug43450.phpt2
-rw-r--r--Zend/tests/bug51394.phpt8
-rw-r--r--Zend/tests/bug52041.phpt12
-rw-r--r--Zend/tests/bug55156.phpt3
-rw-r--r--Zend/tests/bug60536_001.phpt8
-rw-r--r--Zend/tests/bug60738.phpt22
-rw-r--r--Zend/tests/bug60738_variation.phpt23
-rw-r--r--Zend/tests/bug60833.phpt40
-rw-r--r--Zend/tests/bug61025.phpt27
-rw-r--r--Zend/tests/bug61681.phpt11
-rw-r--r--Zend/tests/bug61767.phpt12
-rw-r--r--Zend/tests/bug62005.phpt2
-rw-r--r--Zend/tests/bug62991.phpt50
-rw-r--r--Zend/tests/bug63741.phpt50
-rw-r--r--Zend/tests/bug64135.phpt17
-rw-r--r--Zend/tests/bug64555.phpt42
-rw-r--r--Zend/tests/bug64677.phpt21
-rw-r--r--Zend/tests/bug64979.phpt30
-rw-r--r--Zend/tests/bug65051.phpt23
-rw-r--r--Zend/tests/bug65784.phpt62
-rw-r--r--Zend/tests/catch_finally_001.phpt32
-rw-r--r--Zend/tests/catch_finally_002.phpt21
-rw-r--r--Zend/tests/catch_finally_003.phpt40
-rw-r--r--Zend/tests/catch_finally_004.phpt41
-rw-r--r--Zend/tests/catch_finally_005.phpt21
-rw-r--r--Zend/tests/catch_finally_006.phpt28
-rw-r--r--Zend/tests/class_name_as_scalar.phpt77
-rw-r--r--Zend/tests/class_name_as_scalar_error_001.phpt13
-rw-r--r--Zend/tests/class_name_as_scalar_error_002.phpt13
-rw-r--r--Zend/tests/class_name_as_scalar_error_003.phpt13
-rw-r--r--Zend/tests/class_name_as_scalar_error_004.phpt13
-rw-r--r--Zend/tests/class_name_as_scalar_error_005.phpt10
-rw-r--r--Zend/tests/class_name_as_scalar_error_006.phpt10
-rw-r--r--Zend/tests/closure_047.phpt26
-rw-r--r--Zend/tests/closure_048.phpt26
-rw-r--r--Zend/tests/const_dereference_001.phpt21
-rw-r--r--Zend/tests/const_dereference_002.phpt18
-rw-r--r--Zend/tests/const_dereference_003.phpt21
-rw-r--r--Zend/tests/dval_to_lval_32.phpt32
-rw-r--r--Zend/tests/dval_to_lval_64.phpt29
-rw-r--r--Zend/tests/empty_with_expr.phpt32
-rw-r--r--Zend/tests/errmsg_043.phpt12
-rw-r--r--Zend/tests/exception_before_fatal.phpt64
-rw-r--r--Zend/tests/foreach_list_001.phpt43
-rw-r--r--Zend/tests/foreach_list_002.phpt26
-rw-r--r--Zend/tests/foreach_list_003.phpt13
-rw-r--r--Zend/tests/foreach_list_004.phpt13
-rw-r--r--Zend/tests/foreach_temp_array_expr_with_refs.phpt18
-rw-r--r--Zend/tests/generators/auto_incrementing_keys.phpt22
-rw-r--r--Zend/tests/generators/backtrace.phpt27
-rw-r--r--Zend/tests/generators/bug63066.phpt16
-rw-r--r--Zend/tests/generators/bug65035.phpt20
-rw-r--r--Zend/tests/generators/bug65161.phpt20
-rw-r--r--Zend/tests/generators/bug66041.phpt17
-rw-r--r--Zend/tests/generators/clone.phpt15
-rw-r--r--Zend/tests/generators/dynamic_call.phpt19
-rw-r--r--Zend/tests/generators/errors/generator_cannot_return_before_yield_error.phpt13
-rw-r--r--Zend/tests/generators/errors/generator_cannot_return_error.phpt13
-rw-r--r--Zend/tests/generators/errors/generator_extend_error.phpt10
-rw-r--r--Zend/tests/generators/errors/generator_instantiate_error.phpt10
-rw-r--r--Zend/tests/generators/errors/non_ref_generator_iterated_by_ref_error.phpt18
-rw-r--r--Zend/tests/generators/errors/resume_running_generator_error.phpt17
-rw-r--r--Zend/tests/generators/errors/serialize_unserialize_error.phpt44
-rw-r--r--Zend/tests/generators/errors/yield_const_by_ref_error.phpt16
-rw-r--r--Zend/tests/generators/errors/yield_in_force_closed_finally_error.phpt29
-rw-r--r--Zend/tests/generators/errors/yield_non_ref_function_call_by_ref_error.phpt20
-rw-r--r--Zend/tests/generators/errors/yield_outside_function_error.phpt10
-rw-r--r--Zend/tests/generators/fibonacci.phpt36
-rw-r--r--Zend/tests/generators/finally/finally_ran_on_close.phpt30
-rw-r--r--Zend/tests/generators/finally/return_return.phpt33
-rw-r--r--Zend/tests/generators/finally/return_yield.phpt18
-rw-r--r--Zend/tests/generators/finally/run_on_dtor.phpt22
-rw-r--r--Zend/tests/generators/finally/throw_yield.phpt24
-rw-r--r--Zend/tests/generators/finally/yield_return.phpt18
-rw-r--r--Zend/tests/generators/finally/yield_throw.phpt24
-rw-r--r--Zend/tests/generators/finally/yield_yield.phpt22
-rw-r--r--Zend/tests/generators/func_get_args.phpt21
-rw-r--r--Zend/tests/generators/generator_closure.phpt20
-rw-r--r--Zend/tests/generators/generator_closure_with_this.phpt20
-rw-r--r--Zend/tests/generators/generator_in_multipleiterator.phpt37
-rw-r--r--Zend/tests/generators/generator_method.phpt29
-rw-r--r--Zend/tests/generators/generator_method_by_ref.phpt44
-rw-r--r--Zend/tests/generators/generator_returns_generator.phpt18
-rw-r--r--Zend/tests/generators/generator_rewind.phpt62
-rw-r--r--Zend/tests/generators/generator_send.phpt22
-rw-r--r--Zend/tests/generators/generator_static_method.phpt29
-rw-r--r--Zend/tests/generators/generator_throwing_during_function_call.phpt32
-rw-r--r--Zend/tests/generators/generator_throwing_exception.phpt28
-rw-r--r--Zend/tests/generators/generator_throwing_in_foreach.phpt20
-rw-r--r--Zend/tests/generators/generator_with_keys.phpt26
-rw-r--r--Zend/tests/generators/generator_with_nonscalar_keys.phpt52
-rw-r--r--Zend/tests/generators/ignored_send_leak.phpt17
-rw-r--r--Zend/tests/generators/nested_calls_with_die.phpt30
-rw-r--r--Zend/tests/generators/nested_method_calls.phpt36
-rw-r--r--Zend/tests/generators/no_foreach_var_leaks.phpt19
-rw-r--r--Zend/tests/generators/send_after_close.phpt14
-rw-r--r--Zend/tests/generators/send_returns_current.phpt20
-rw-r--r--Zend/tests/generators/throw_already_closed.phpt23
-rw-r--r--Zend/tests/generators/throw_caught.phpt27
-rw-r--r--Zend/tests/generators/throw_not_an_exception.phpt15
-rw-r--r--Zend/tests/generators/throw_rethrow.phpt34
-rw-r--r--Zend/tests/generators/throw_uncaught.phpt19
-rw-r--r--Zend/tests/generators/unused_return_value.phpt13
-rw-r--r--Zend/tests/generators/xrange.phpt23
-rw-r--r--Zend/tests/generators/yield_array_key.phpt18
-rw-r--r--Zend/tests/generators/yield_array_offset_by_ref.phpt26
-rw-r--r--Zend/tests/generators/yield_by_reference.phpt42
-rw-r--r--Zend/tests/generators/yield_closure.phpt17
-rw-r--r--Zend/tests/generators/yield_during_function_call.phpt15
-rw-r--r--Zend/tests/generators/yield_during_method_call.phpt27
-rw-r--r--Zend/tests/generators/yield_in_finally.phpt29
-rw-r--r--Zend/tests/generators/yield_in_parenthesis.phpt23
-rw-r--r--Zend/tests/generators/yield_ref_function_call_by_reference.phpt24
-rw-r--r--Zend/tests/generators/yield_without_value.phpt27
-rw-r--r--Zend/tests/isset_expr_error.phpt8
-rw-r--r--Zend/tests/isset_func_error.phpt8
-rw-r--r--Zend/tests/ns_026.phpt2
-rw-r--r--Zend/tests/offset_assign.phpt4
-rw-r--r--Zend/tests/offset_string.phpt2
-rw-r--r--Zend/tests/try_catch_finally_001.phpt36
-rw-r--r--Zend/tests/try_catch_finally_002.phpt42
-rw-r--r--Zend/tests/try_catch_finally_003.phpt36
-rw-r--r--Zend/tests/try_catch_finally_004.phpt30
-rw-r--r--Zend/tests/try_catch_finally_005.phpt52
-rw-r--r--Zend/tests/try_catch_finally_006.phpt39
-rw-r--r--Zend/tests/try_catch_finally_007.phpt46
-rw-r--r--Zend/tests/try_finally_001.phpt22
-rw-r--r--Zend/tests/try_finally_002.phpt23
-rw-r--r--Zend/tests/try_finally_003.phpt27
-rw-r--r--Zend/tests/try_finally_004.phpt14
-rw-r--r--Zend/tests/try_finally_005.phpt17
-rw-r--r--Zend/tests/try_finally_006.phpt26
-rw-r--r--Zend/tests/try_finally_007.phpt22
-rw-r--r--Zend/tests/try_finally_008.phpt21
-rw-r--r--Zend/tests/try_finally_009.phpt23
-rw-r--r--Zend/tests/try_finally_010.phpt30
-rw-r--r--Zend/zend.c9
-rw-r--r--Zend/zend.h30
-rw-r--r--Zend/zend_API.c91
-rw-r--r--Zend/zend_API.h4
-rw-r--r--Zend/zend_alloc.c60
-rw-r--r--Zend/zend_alloc.h6
-rw-r--r--Zend/zend_builtin_functions.c55
-rw-r--r--Zend/zend_closures.c17
-rw-r--r--Zend/zend_closures.h2
-rw-r--r--Zend/zend_compile.c540
-rw-r--r--Zend/zend_compile.h52
-rw-r--r--Zend/zend_config.w32.h9
-rw-r--r--Zend/zend_default_classes.c2
-rw-r--r--Zend/zend_dtrace.c8
-rw-r--r--Zend/zend_dtrace.h6
-rw-r--r--Zend/zend_exceptions.c8
-rw-r--r--Zend/zend_exceptions.h8
-rw-r--r--Zend/zend_execute.c354
-rw-r--r--Zend/zend_execute.h133
-rw-r--r--Zend/zend_execute_API.c104
-rw-r--r--Zend/zend_extensions.h2
-rw-r--r--Zend/zend_float.h6
-rw-r--r--Zend/zend_generators.c759
-rw-r--r--Zend/zend_generators.h79
-rw-r--r--Zend/zend_globals.h6
-rw-r--r--Zend/zend_hash.c28
-rw-r--r--Zend/zend_hash.h9
-rw-r--r--Zend/zend_highlight.c3
-rw-r--r--Zend/zend_ini_parser.y6
-rw-r--r--Zend/zend_ini_scanner.c713
-rw-r--r--Zend/zend_ini_scanner.l8
-rw-r--r--Zend/zend_ini_scanner_defs.h2
-rw-r--r--Zend/zend_interfaces.c38
-rw-r--r--Zend/zend_interfaces.h2
-rw-r--r--Zend/zend_iterators.h7
-rw-r--r--Zend/zend_language_parser.y172
-rw-r--r--Zend/zend_language_scanner.c5372
-rw-r--r--Zend/zend_language_scanner.h5
-rw-r--r--Zend/zend_language_scanner.l84
-rw-r--r--Zend/zend_language_scanner_defs.h2
-rw-r--r--Zend/zend_llist.c4
-rw-r--r--Zend/zend_modules.h2
-rw-r--r--Zend/zend_multiply.h45
-rw-r--r--Zend/zend_object_handlers.c11
-rw-r--r--Zend/zend_object_handlers.h2
-rw-r--r--Zend/zend_opcode.c188
-rw-r--r--Zend/zend_operators.c114
-rw-r--r--Zend/zend_operators.h131
-rw-r--r--Zend/zend_ptr_stack.c1
-rw-r--r--Zend/zend_ptr_stack.h5
-rw-r--r--Zend/zend_qsort.c12
-rw-r--r--Zend/zend_qsort.h2
-rw-r--r--Zend/zend_signal.c4
-rw-r--r--Zend/zend_types.h1
-rw-r--r--Zend/zend_vm_def.h1294
-rw-r--r--Zend/zend_vm_execute.h9363
-rw-r--r--Zend/zend_vm_execute.skl64
-rw-r--r--Zend/zend_vm_gen.php235
-rw-r--r--Zend/zend_vm_opcodes.c7
-rw-r--r--Zend/zend_vm_opcodes.h5
-rw-r--r--acinclude.m46
-rw-r--r--build/libtool.m415
-rwxr-xr-xbuild/shtool9
-rw-r--r--config.guess505
-rw-r--r--config.sub295
-rw-r--r--configure.in18
-rw-r--r--ext/bcmath/libbcmath/src/recmul.c3
-rw-r--r--ext/bz2/bz2_filter.c2
-rw-r--r--ext/bz2/config.m42
-rw-r--r--ext/calendar/calendar.c23
-rw-r--r--ext/calendar/jewish.c64
-rw-r--r--ext/calendar/sdncal.h3
-rw-r--r--ext/calendar/tests/bug54254.phpt59
-rw-r--r--ext/calendar/tests/cal_info.phpt8
-rw-r--r--ext/calendar/tests/jdmonthname.phpt8
-rw-r--r--ext/calendar/tests/jdtojewish.phpt8
-rw-r--r--ext/com_dotnet/com_iterator.c9
-rw-r--r--ext/com_dotnet/com_saproxy.c9
-rw-r--r--ext/com_dotnet/com_variant.c2
-rw-r--r--ext/com_dotnet/com_wrapper.c6
-rw-r--r--ext/curl/config.m419
-rw-r--r--ext/curl/config.w324
-rw-r--r--ext/curl/curl.dsp4
-rw-r--r--ext/curl/curl_file.c177
-rw-r--r--ext/curl/interface.c2143
-rw-r--r--ext/curl/multi.c92
-rw-r--r--ext/curl/package.xml1
-rw-r--r--ext/curl/php_curl.h116
-rw-r--r--ext/curl/share.c136
-rw-r--r--ext/curl/streams.c542
-rw-r--r--ext/curl/tests/bug27023.phpt2
-rw-r--r--ext/curl/tests/bug54995.phpt30
-rw-r--r--ext/curl/tests/check_win_config.phpt48
-rw-r--r--ext/curl/tests/curl_basic_022.phpt25
-rw-r--r--ext/curl/tests/curl_escape.phptbin0 -> 688 bytes
-rw-r--r--ext/curl/tests/curl_file_serialize.phpt21
-rw-r--r--ext/curl/tests/curl_file_upload.phpt85
-rw-r--r--ext/curl/tests/curl_multi_setopt_basic001.phpt25
-rw-r--r--ext/curl/tests/curl_multi_strerror_001.phpt22
-rw-r--r--ext/curl/tests/curl_reset.phpt40
-rw-r--r--ext/curl/tests/curl_setopt_basic003.phpt2
-rw-r--r--ext/curl/tests/curl_setopt_error.phpt4
-rw-r--r--ext/curl/tests/curl_share_setopt_basic001.phpt23
-rw-r--r--ext/curl/tests/curl_strerror_001.phpt24
-rw-r--r--ext/date/TODO1
-rw-r--r--ext/date/lib/parse_date.c234
-rw-r--r--ext/date/lib/parse_date.re38
-rw-r--r--ext/date/lib/parse_iso_intervals.c71
-rw-r--r--ext/date/lib/parse_iso_intervals.re35
-rw-r--r--ext/date/lib/timelib.c34
-rw-r--r--ext/date/lib/timelib.h2
-rw-r--r--ext/date/lib/tm2unixtime.c75
-rw-r--r--ext/date/php_date.c729
-rw-r--r--ext/date/php_date.h17
-rw-r--r--ext/date/tests/014.phpt6
-rw-r--r--ext/date/tests/DatePeriod_wrong_constructor.phpt4
-rw-r--r--ext/date/tests/DateTimeZone_clone_basic1.phpt12
-rw-r--r--ext/date/tests/DateTimeZone_clone_basic2.phpt24
-rw-r--r--ext/date/tests/DateTimeZone_clone_basic3.phpt30
-rw-r--r--ext/date/tests/DateTimeZone_construct_basic.phpt18
-rw-r--r--ext/date/tests/DateTimeZone_serialize_type_1.phpt35
-rw-r--r--ext/date/tests/DateTimeZone_serialize_type_2.phpt35
-rw-r--r--ext/date/tests/DateTimeZone_serialize_type_3.phpt (renamed from ext/date/tests/DateTimeZone_serialize.phpt)20
-rw-r--r--ext/date/tests/DateTimeZone_verify.phpt28
-rw-r--r--ext/date/tests/bug60774.phpt44
-rw-r--r--ext/date/tests/bug61642.phpt62
-rw-r--r--ext/date/tests/bug65184.phpt28
-rw-r--r--ext/date/tests/bug65502.phpt12
-rw-r--r--ext/date/tests/bug65548.phpt34
-rw-r--r--ext/date/tests/date_format_error.phpt6
-rw-r--r--ext/date/tests/date_format_variation1.phpt60
-rw-r--r--ext/date/tests/date_offset_get_error.phpt10
-rw-r--r--ext/date/tests/date_offset_get_variation1.phpt60
-rw-r--r--ext/date/tests/date_period-immutable.phpt56
-rw-r--r--ext/date/tests/date_time_immutable-inherited.phpt25
-rw-r--r--ext/date/tests/date_time_immutable.phpt167
-rw-r--r--ext/date/tests/date_timestamp_get.phpt2
-rw-r--r--ext/date/tests/date_timezone_get_error.phpt12
-rw-r--r--ext/date/tests/date_timezone_get_variation1.phpt62
-rw-r--r--ext/date/tests/timezone_open_basic1.phpt18
-rw-r--r--ext/dba/config.m44
-rw-r--r--ext/dba/dba_flatfile.c19
-rw-r--r--ext/dba/dba_gdbm.c17
-rw-r--r--ext/dba/dba_inifile.c1
-rw-r--r--ext/dba/dba_qdbm.c10
-rw-r--r--ext/dba/libinifile/inifile.c14
-rw-r--r--ext/dba/tests/dba_db1.phpt4
-rw-r--r--ext/dba/tests/dba_db2.phpt4
-rw-r--r--ext/dba/tests/dba_db3.phpt4
-rw-r--r--ext/dba/tests/dba_db4_000.phpt4
-rw-r--r--ext/dba/tests/dba_dbm.phpt4
-rw-r--r--ext/dba/tests/dba_flatfile.phpt4
-rw-r--r--ext/dba/tests/dba_gdbm.phpt2
-rw-r--r--ext/dba/tests/dba_handler.inc12
-rw-r--r--ext/dba/tests/dba_inifile.phpt4
-rw-r--r--ext/dba/tests/dba_ndbm.phpt4
-rw-r--r--ext/dba/tests/dba_qdbm.phpt2
-rw-r--r--ext/dba/tests/dba_tcadb.phpt4
-rw-r--r--ext/dom/document.c16
-rw-r--r--ext/dom/dom_iterators.c27
-rw-r--r--ext/dom/php_dom.c70
-rw-r--r--ext/dom/tests/DOMDocument_loadXML_basic.phpt21
-rw-r--r--ext/dom/tests/DOMDocument_loadXML_error1.phpt26
-rw-r--r--ext/dom/tests/DOMDocument_loadXML_error2.phpt30
-rw-r--r--ext/dom/tests/DOMDocument_loadXML_error3.phpt22
-rw-r--r--ext/dom/tests/DOMDocument_loadXML_error4.phpt22
-rw-r--r--ext/dom/tests/DOMDocument_loadXML_error5.phpt22
-rw-r--r--ext/dom/tests/DOMDocument_loadXML_variation1.phpt21
-rw-r--r--ext/dom/tests/DOMDocument_loadXML_variation2.phpt22
-rw-r--r--ext/dom/tests/DOMDocument_loadXML_variation3.phpt22
-rw-r--r--ext/dom/tests/DOMDocument_loadXML_variation4.phpt32
-rw-r--r--ext/dom/tests/DOMDocument_load_basic.phpt21
-rw-r--r--ext/dom/tests/DOMDocument_load_error1.phpt26
-rw-r--r--ext/dom/tests/DOMDocument_load_error2.phpt30
-rw-r--r--ext/dom/tests/DOMDocument_load_error3.phpt22
-rw-r--r--ext/dom/tests/DOMDocument_load_error4.phpt22
-rw-r--r--ext/dom/tests/DOMDocument_load_error5.phpt22
-rw-r--r--ext/dom/tests/DOMDocument_load_variation1.phpt21
-rw-r--r--ext/dom/tests/DOMDocument_load_variation2.phpt22
-rw-r--r--ext/dom/tests/DOMDocument_load_variation3.phpt22
-rw-r--r--ext/dom/tests/DOMDocument_load_variation4.phpt25
-rw-r--r--ext/dom/tests/DOMDocument_schemaValidateSource_addAttrs.phpt25
-rw-r--r--ext/dom/tests/DOMDocument_schemaValidateSource_error4.phpt2
-rw-r--r--ext/dom/tests/DOMDocument_schemaValidateSource_missingAttrs.phpt25
-rw-r--r--ext/dom/tests/DOMDocument_schemaValidate_addAttrs.phpt23
-rw-r--r--ext/dom/tests/DOMDocument_schemaValidate_error4.phpt2
-rw-r--r--ext/dom/tests/DOMDocument_schemaValidate_missingAttrs.phpt23
-rw-r--r--ext/dom/tests/book-attr.xml11
-rwxr-xr-xext/dom/tests/book.xsd1
-rw-r--r--ext/dom/tests/book_with_dtd.xml16
-rw-r--r--ext/dom/tests/book_with_dtd2.xml23
-rw-r--r--ext/dom/tests/books.dtd7
-rw-r--r--ext/dom/tests/domdocumentload_test_method.php12
-rw-r--r--ext/dom/tests/domdocumentload_test_method_savexml.php14
-rw-r--r--ext/dom/tests/domdocumentload_utilities.php16
-rw-r--r--ext/dom/tests/domdocumentloadxml_test_method.php12
-rw-r--r--ext/dom/tests/domdocumentloadxml_test_method_savexml.php14
-rw-r--r--ext/dom/tests/not_well_formed.xml12
-rw-r--r--ext/dom/tests/not_well_formed2.xml12
-rw-r--r--ext/dom/tests/not_well_formed3.xml12
-rw-r--r--ext/dom/tests/not_well_formed4.xml12
-rw-r--r--ext/dom/tests/not_well_formed5.xml10
-rw-r--r--ext/dom/tests/wrong_book_with_dtd.xml13
-rw-r--r--ext/dom/tests/wrong_book_with_dtd2.xml20
-rwxr-xr-xext/enchant/config.m42
-rw-r--r--ext/ereg/config0.m42
-rw-r--r--ext/ereg/regex.patch72
-rw-r--r--ext/ereg/tests/split_variation_004.phpt6
-rw-r--r--ext/ereg/tests/spliti_variation_004.phpt6
-rw-r--r--ext/fileinfo/libmagic/print.c1
-rw-r--r--ext/fileinfo/php_fileinfo.h2
-rw-r--r--ext/filter/config.m42
-rw-r--r--ext/filter/filter.c2
-rw-r--r--ext/filter/filter_private.h3
-rw-r--r--ext/filter/logical_filters.c61
-rw-r--r--ext/filter/php_filter.h1
-rw-r--r--ext/filter/tests/008.phpt26
-rw-r--r--ext/filter/tests/033.phpt39
-rw-r--r--ext/filter/tests/033_run.inc6
-rw-r--r--ext/filter/tests/055.phpt48
-rw-r--r--ext/ftp/ftp.c5
-rw-r--r--ext/gd/config.m4163
-rw-r--r--ext/gd/config.w3224
-rw-r--r--ext/gd/gd.c1205
-rw-r--r--ext/gd/gd_compat.c63
-rw-r--r--ext/gd/gd_compat.h14
-rw-r--r--ext/gd/gd_ctx.c4
-rw-r--r--ext/gd/gdcache.c7
-rw-r--r--ext/gd/libgd/gd.c86
-rw-r--r--ext/gd/libgd/gd.h208
-rw-r--r--ext/gd/libgd/gd_compat.c35
-rw-r--r--ext/gd/libgd/gd_compat.h66
-rw-r--r--ext/gd/libgd/gd_crop.c369
-rw-r--r--ext/gd/libgd/gd_interpolation.c2550
-rw-r--r--ext/gd/libgd/gd_jpeg.c25
-rw-r--r--ext/gd/libgd/gd_matrix.c334
-rw-r--r--ext/gd/libgd/gd_png.c2
-rw-r--r--ext/gd/libgd/gd_transform.c73
-rw-r--r--ext/gd/libgd/gd_webp.c33
-rw-r--r--ext/gd/php_gd.h23
-rw-r--r--ext/gd/tests/bug43073.phpt8
-rw-r--r--ext/gd/tests/bug48801.phpt4
-rw-r--r--ext/gd/tests/bug66356.phpt40
-rw-r--r--ext/gd/tests/imagecrop_auto.phpt84
-rw-r--r--ext/gd/tests/imageflip.phpt30
-rw-r--r--ext/gd/tests/imageloadfont_invalid.phpt1
-rw-r--r--ext/gd/tests/logo_noise.pngbin0 -> 25182 bytes
-rw-r--r--ext/gettext/config.m42
-rw-r--r--ext/gmp/config.m42
-rw-r--r--ext/hash/config.m42
-rw-r--r--ext/hash/hash.c217
-rw-r--r--ext/hash/php_hash.h1
-rw-r--r--ext/hash/tests/bug64745.phpt17
-rw-r--r--ext/hash/tests/hash_pbkdf2_basic.phpt37
-rw-r--r--ext/hash/tests/hash_pbkdf2_error.phpt78
-rw-r--r--ext/iconv/config.m42
-rw-r--r--ext/imap/config.m42
-rw-r--r--ext/interbase/config.m42
-rw-r--r--ext/interbase/tests/skipif.inc3
-rw-r--r--ext/intl/ERROR.CONVENTIONS115
-rw-r--r--ext/intl/breakiterator/breakiterator_class.cpp397
-rw-r--r--ext/intl/breakiterator/breakiterator_class.h71
-rw-r--r--ext/intl/breakiterator/breakiterator_iterators.cpp342
-rw-r--r--ext/intl/breakiterator/breakiterator_iterators.h42
-rw-r--r--ext/intl/breakiterator/breakiterator_methods.cpp452
-rw-r--r--ext/intl/breakiterator/breakiterator_methods.h64
-rw-r--r--ext/intl/breakiterator/codepointiterator_internal.cpp291
-rw-r--r--ext/intl/breakiterator/codepointiterator_internal.h98
-rw-r--r--ext/intl/breakiterator/codepointiterator_methods.cpp44
-rw-r--r--ext/intl/breakiterator/codepointiterator_methods.h24
-rw-r--r--ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp221
-rw-r--r--ext/intl/breakiterator/rulebasedbreakiterator_methods.h32
-rw-r--r--ext/intl/calendar/calendar_class.cpp555
-rw-r--r--ext/intl/calendar/calendar_class.h70
-rw-r--r--ext/intl/calendar/calendar_methods.cpp1353
-rw-r--r--ext/intl/calendar/calendar_methods.h114
-rw-r--r--ext/intl/calendar/gregoriancalendar_methods.cpp255
-rw-r--r--ext/intl/calendar/gregoriancalendar_methods.h32
-rw-r--r--ext/intl/collator/collator_convert.c4
-rw-r--r--ext/intl/collator/collator_create.c4
-rw-r--r--ext/intl/collator/collator_sort.c1
-rw-r--r--ext/intl/common/common_date.cpp250
-rw-r--r--ext/intl/common/common_date.h40
-rw-r--r--ext/intl/common/common_enum.cpp342
-rw-r--r--ext/intl/common/common_enum.h77
-rw-r--r--ext/intl/common/common_error.c2
-rw-r--r--ext/intl/config.m425
-rw-r--r--ext/intl/config.w3233
-rw-r--r--ext/intl/converter/converter.c1173
-rw-r--r--ext/intl/converter/converter.h28
-rw-r--r--ext/intl/dateformat/dateformat.c154
-rw-r--r--ext/intl/dateformat/dateformat_attr.c164
-rw-r--r--ext/intl/dateformat/dateformat_attr.h4
-rw-r--r--ext/intl/dateformat/dateformat_attrcpp.cpp261
-rw-r--r--ext/intl/dateformat/dateformat_attrcpp.h35
-rw-r--r--ext/intl/dateformat/dateformat_class.c28
-rw-r--r--ext/intl/dateformat/dateformat_class.h12
-rw-r--r--ext/intl/dateformat/dateformat_create.cpp193
-rw-r--r--ext/intl/dateformat/dateformat_create.h25
-rw-r--r--ext/intl/dateformat/dateformat_format.c179
-rw-r--r--ext/intl/dateformat/dateformat_format_object.cpp230
-rw-r--r--ext/intl/dateformat/dateformat_format_object.h19
-rw-r--r--ext/intl/dateformat/dateformat_helpers.cpp106
-rw-r--r--ext/intl/dateformat/dateformat_helpers.h39
-rw-r--r--ext/intl/dateformat/dateformat_parse.c6
-rw-r--r--ext/intl/formatter/formatter_main.c4
-rw-r--r--ext/intl/grapheme/grapheme.h1
-rw-r--r--ext/intl/intl_convertcpp.cpp89
-rw-r--r--ext/intl/intl_convertcpp.h32
-rw-r--r--ext/intl/intl_cppshims.h34
-rw-r--r--ext/intl/intl_error.c101
-rw-r--r--ext/intl/intl_error.h8
-rw-r--r--ext/intl/locale/locale_methods.c67
-rw-r--r--ext/intl/msgformat/msgformat.c4
-rw-r--r--ext/intl/msgformat/msgformat_attr.c6
-rw-r--r--ext/intl/msgformat/msgformat_data.c24
-rw-r--r--ext/intl/msgformat/msgformat_data.h2
-rw-r--r--ext/intl/msgformat/msgformat_format.c51
-rw-r--r--ext/intl/msgformat/msgformat_helpers.cpp632
-rw-r--r--ext/intl/msgformat/msgformat_helpers.h6
-rw-r--r--ext/intl/msgformat/msgformat_parse.c4
-rw-r--r--ext/intl/php_intl.c364
-rw-r--r--ext/intl/php_intl.h10
-rw-r--r--ext/intl/resourcebundle/resourcebundle_class.c17
-rw-r--r--ext/intl/resourcebundle/resourcebundle_iterator.c13
-rw-r--r--ext/intl/tests/badargs.phpt5
-rw-r--r--ext/intl/tests/breakiter___construct.phpt14
-rw-r--r--ext/intl/tests/breakiter___construct_error.phpt38
-rw-r--r--ext/intl/tests/breakiter_clone_basic.phpt27
-rw-r--r--ext/intl/tests/breakiter_createCodePointInstance_basic.phpt43
-rw-r--r--ext/intl/tests/breakiter_createCodePointInstance_error.phpt18
-rw-r--r--ext/intl/tests/breakiter_current_basic.phpt28
-rw-r--r--ext/intl/tests/breakiter_factories_basic.phpt46
-rw-r--r--ext/intl/tests/breakiter_factories_error.phpt43
-rw-r--r--ext/intl/tests/breakiter_first_basic.phpt22
-rw-r--r--ext/intl/tests/breakiter_first_last_previous_current_error.phpt39
-rw-r--r--ext/intl/tests/breakiter_following_basic.phpt24
-rw-r--r--ext/intl/tests/breakiter_following_preceding_isBoundary_error.phpt51
-rw-r--r--ext/intl/tests/breakiter_getLocale_basic.phpt21
-rw-r--r--ext/intl/tests/breakiter_getLocale_error.phpt33
-rw-r--r--ext/intl/tests/breakiter_getPartsIterator_basic.phpt37
-rw-r--r--ext/intl/tests/breakiter_getPartsIterator_error.phpt33
-rw-r--r--ext/intl/tests/breakiter_getPartsIterator_var1.phpt60
-rw-r--r--ext/intl/tests/breakiter_getText_basic.phpt17
-rw-r--r--ext/intl/tests/breakiter_getText_error.phpt19
-rw-r--r--ext/intl/tests/breakiter_isBoundary_basic.phpt28
-rw-r--r--ext/intl/tests/breakiter_last_basic.phpt20
-rw-r--r--ext/intl/tests/breakiter_next_basic.phpt30
-rw-r--r--ext/intl/tests/breakiter_next_error.phpt27
-rw-r--r--ext/intl/tests/breakiter_preceding_basic.phpt24
-rw-r--r--ext/intl/tests/breakiter_previous_basic.phpt22
-rw-r--r--ext/intl/tests/breakiter_setText_basic.phpt36
-rw-r--r--ext/intl/tests/breakiter_setText_error.phpt44
-rw-r--r--ext/intl/tests/bug50590.phpt2
-rw-r--r--ext/intl/tests/bug58756_MessageFormatter.phpt37
-rw-r--r--ext/intl/tests/bug58756_MessageFormatter_variant2.phpt37
-rw-r--r--ext/intl/tests/bug62017.phpt2
-rw-r--r--ext/intl/tests/bug62081.phpt6
-rw-r--r--ext/intl/tests/bug62915.phpt24
-rw-r--r--ext/intl/tests/calendar_add_basic.phpt33
-rw-r--r--ext/intl/tests/calendar_add_error.phpt41
-rw-r--r--ext/intl/tests/calendar_before_after_error.phpt57
-rw-r--r--ext/intl/tests/calendar_clear_basic.phpt40
-rw-r--r--ext/intl/tests/calendar_clear_error.phpt31
-rw-r--r--ext/intl/tests/calendar_clear_variation1.phpt33
-rw-r--r--ext/intl/tests/calendar_const_field_field_count.phpt13
-rw-r--r--ext/intl/tests/calendar_createInstance_basic.phpt42
-rw-r--r--ext/intl/tests/calendar_createInstance_error.phpt38
-rw-r--r--ext/intl/tests/calendar_createInstance_variation1.phpt84
-rw-r--r--ext/intl/tests/calendar_equals_before_after_basic.phpt59
-rw-r--r--ext/intl/tests/calendar_equals_error.phpt46
-rw-r--r--ext/intl/tests/calendar_fieldDifference_basic.phpt35
-rw-r--r--ext/intl/tests/calendar_fieldDifference_error.phpt42
-rw-r--r--ext/intl/tests/calendar_fromDateTime_basic.phpt52
-rw-r--r--ext/intl/tests/calendar_fromDateTime_error.phpt59
-rw-r--r--ext/intl/tests/calendar_getAvailableLocales_basic.phpt23
-rw-r--r--ext/intl/tests/calendar_getAvailableLocales_error.phpt24
-rw-r--r--ext/intl/tests/calendar_getDayOfWeekType_basic.phpt34
-rw-r--r--ext/intl/tests/calendar_getDayOfWeekType_error.phpt44
-rw-r--r--ext/intl/tests/calendar_getErrorCode_error.phpt26
-rw-r--r--ext/intl/tests/calendar_getErrorCode_getErrorMessage_basic.phpt43
-rw-r--r--ext/intl/tests/calendar_getErrorMessage_error.phpt26
-rw-r--r--ext/intl/tests/calendar_getFirstDayOfWeek_basic.phpt20
-rw-r--r--ext/intl/tests/calendar_getFirstDayOfWeek_error.phpt32
-rw-r--r--ext/intl/tests/calendar_getKeywordValuesForLocale_basic.phpt36
-rw-r--r--ext/intl/tests/calendar_getKeywordValuesForLocale_error.phpt26
-rw-r--r--ext/intl/tests/calendar_getLocale_basic.phpt22
-rw-r--r--ext/intl/tests/calendar_getLocale_error.phpt42
-rw-r--r--ext/intl/tests/calendar_getMinimalDaysInFirstWeek_basic.phpt22
-rw-r--r--ext/intl/tests/calendar_getMinimalDaysInFirstWeek_error.phpt32
-rw-r--r--ext/intl/tests/calendar_getNow_basic.phpt23
-rw-r--r--ext/intl/tests/calendar_getNow_error.phpt24
-rw-r--r--ext/intl/tests/calendar_getSkipped_RepeatedWallTimeOption_error.phpt47
-rw-r--r--ext/intl/tests/calendar_getTimeZone_basic.phpt34
-rw-r--r--ext/intl/tests/calendar_getTimeZone_error.phpt32
-rw-r--r--ext/intl/tests/calendar_getTime_basic.phpt29
-rw-r--r--ext/intl/tests/calendar_getTime_error.phpt31
-rw-r--r--ext/intl/tests/calendar_getType_basic.phpt23
-rw-r--r--ext/intl/tests/calendar_getType_error.phpt32
-rw-r--r--ext/intl/tests/calendar_getWeekendTransition_basic.phpt24
-rw-r--r--ext/intl/tests/calendar_getWeekendTransition_error.phpt44
-rw-r--r--ext/intl/tests/calendar_getXMaximum_basic.phpt34
-rw-r--r--ext/intl/tests/calendar_getXMinimum_basic.phpt34
-rw-r--r--ext/intl/tests/calendar_get_Least_Greatest_Minimum_Maximum_error.phpt100
-rw-r--r--ext/intl/tests/calendar_get_basic.phpt23
-rw-r--r--ext/intl/tests/calendar_get_getActualMaximum_Minumum_error.phpt84
-rw-r--r--ext/intl/tests/calendar_get_getActualMaximum_Minumum_error2.phpt71
-rw-r--r--ext/intl/tests/calendar_get_setRepeatedWallTimeOption_basic.phpt49
-rw-r--r--ext/intl/tests/calendar_get_setSkippedWallTimeOption_basic.phpt67
-rw-r--r--ext/intl/tests/calendar_inDaylightTime_basic.phpt24
-rw-r--r--ext/intl/tests/calendar_inDaylightTime_error.phpt32
-rw-r--r--ext/intl/tests/calendar_isEquivalentTo_basic.phpt40
-rw-r--r--ext/intl/tests/calendar_isEquivalentTo_error.phpt50
-rw-r--r--ext/intl/tests/calendar_isLenient_error.phpt32
-rw-r--r--ext/intl/tests/calendar_isSet_basic.phpt24
-rw-r--r--ext/intl/tests/calendar_isSet_error.phpt42
-rw-r--r--ext/intl/tests/calendar_isWeekend_basic.phpt26
-rw-r--r--ext/intl/tests/calendar_isWeekend_error.phpt38
-rw-r--r--ext/intl/tests/calendar_is_set_lenient_basic.phpt28
-rw-r--r--ext/intl/tests/calendar_roll_basic.phpt34
-rw-r--r--ext/intl/tests/calendar_roll_error.phpt37
-rw-r--r--ext/intl/tests/calendar_roll_variation1.phpt32
-rw-r--r--ext/intl/tests/calendar_setFirstDayOfWeek_basic.phpt28
-rw-r--r--ext/intl/tests/calendar_setFirstDayOfWeek_error.phpt40
-rw-r--r--ext/intl/tests/calendar_setLenient_error.phpt44
-rw-r--r--ext/intl/tests/calendar_setMinimalDaysInFirstWeek_basic.phpt26
-rw-r--r--ext/intl/tests/calendar_setMinimalDaysInFirstWeek_error.phpt40
-rw-r--r--ext/intl/tests/calendar_setSkipped_RepeatedWallTimeOption_error.phpt82
-rw-r--r--ext/intl/tests/calendar_setTimeZone_basic.phpt39
-rw-r--r--ext/intl/tests/calendar_setTimeZone_error.phpt41
-rw-r--r--ext/intl/tests/calendar_setTimeZone_error2.phpt29
-rw-r--r--ext/intl/tests/calendar_setTimeZone_variation1.phpt30
-rw-r--r--ext/intl/tests/calendar_setTimeZone_variation2.phpt30
-rw-r--r--ext/intl/tests/calendar_setTime_basic.phpt33
-rw-r--r--ext/intl/tests/calendar_setTime_error.phpt37
-rw-r--r--ext/intl/tests/calendar_set_basic.phpt27
-rw-r--r--ext/intl/tests/calendar_set_error.phpt41
-rw-r--r--ext/intl/tests/calendar_set_variation1.phpt41
-rw-r--r--ext/intl/tests/calendar_toDateTime_basic.phpt23
-rw-r--r--ext/intl/tests/calendar_toDateTime_error.phpt41
-rw-r--r--ext/intl/tests/collator_asort.phpt1
-rw-r--r--ext/intl/tests/collator_asort_variant2.phpt243
-rw-r--r--ext/intl/tests/collator_compare.phpt1
-rw-r--r--ext/intl/tests/collator_compare_variant2.phpt135
-rw-r--r--ext/intl/tests/collator_get_sort_key.phpt4
-rw-r--r--ext/intl/tests/collator_get_sort_key_variant2.phpt98
-rw-r--r--ext/intl/tests/collator_sort.phpt1
-rw-r--r--ext/intl/tests/collator_sort_variant2.phpt248
-rw-r--r--ext/intl/tests/collator_sort_with_sort_keys.phpt1
-rw-r--r--ext/intl/tests/collator_sort_with_sort_keys_variant2.phpt190
-rw-r--r--ext/intl/tests/cpbi_clone_equality.phpt33
-rw-r--r--ext/intl/tests/cpbi_getLastCodePoint_basic.phpt82
-rw-r--r--ext/intl/tests/cpbi_getLastCodePoint_error.phpt19
-rw-r--r--ext/intl/tests/cpbi_parts_iterator.phpt40
-rw-r--r--ext/intl/tests/dateformat___construct_bad_tz_cal.phpt32
-rw-r--r--ext/intl/tests/dateformat_calendars.phpt6
-rw-r--r--ext/intl/tests/dateformat_calendars_variant2.phpt45
-rw-r--r--ext/intl/tests/dateformat_create_cal_arg.phpt53
-rw-r--r--ext/intl/tests/dateformat_create_cal_arg_variant2.phpt53
-rw-r--r--ext/intl/tests/dateformat_format.phpt15
-rw-r--r--ext/intl/tests/dateformat_formatObject_calendar.phpt41
-rw-r--r--ext/intl/tests/dateformat_formatObject_calendar_variant2.phpt40
-rw-r--r--ext/intl/tests/dateformat_formatObject_datetime.phpt34
-rw-r--r--ext/intl/tests/dateformat_formatObject_datetime_variant2.phpt33
-rw-r--r--ext/intl/tests/dateformat_formatObject_error.phpt74
-rw-r--r--ext/intl/tests/dateformat_format_parse.phpt3
-rw-r--r--ext/intl/tests/dateformat_format_parse_version2.phpt295
-rw-r--r--ext/intl/tests/dateformat_format_variant2.phpt423
-rw-r--r--ext/intl/tests/dateformat_getCalendarObject_error.phpt43
-rw-r--r--ext/intl/tests/dateformat_getTimeZone_error.phpt43
-rw-r--r--ext/intl/tests/dateformat_get_set_calendar.phpt95
-rw-r--r--ext/intl/tests/dateformat_get_set_calendar_variant2.phpt55
-rw-r--r--ext/intl/tests/dateformat_get_set_timezone.phpt62
-rw-r--r--ext/intl/tests/dateformat_get_set_timezone_variant2.phpt62
-rw-r--r--ext/intl/tests/dateformat_get_timezone_id.phpt15
-rw-r--r--ext/intl/tests/dateformat_setTimeZoneID_deprecation.phpt22
-rw-r--r--ext/intl/tests/dateformat_setTimeZone_error.phpt53
-rw-r--r--ext/intl/tests/dateformat_set_timezone_id2.phpt23
-rw-r--r--ext/intl/tests/dateformat_set_timezone_id3.phpt85
-rw-r--r--ext/intl/tests/dateformat_timezone_arg_variations.phpt45
-rw-r--r--ext/intl/tests/dateformat_timezone_arg_variations2.phpt45
-rw-r--r--ext/intl/tests/formatter_get_locale.phpt1
-rw-r--r--ext/intl/tests/formatter_get_locale_variant2.phpt50
-rw-r--r--ext/intl/tests/gregoriancalendar___construct_basic.phpt51
-rw-r--r--ext/intl/tests/gregoriancalendar___construct_error.phpt35
-rw-r--r--ext/intl/tests/gregoriancalendar___construct_variant1.phpt30
-rw-r--r--ext/intl/tests/gregoriancalendar_getGregorianChange_error.phpt30
-rw-r--r--ext/intl/tests/gregoriancalendar_get_setGregorianChange_basic.phpt32
-rw-r--r--ext/intl/tests/gregoriancalendar_isLeapYear_basic.phpt28
-rw-r--r--ext/intl/tests/gregoriancalendar_isLeapYear_error.phpt48
-rw-r--r--ext/intl/tests/gregoriancalendar_setGregorianChange_error.phpt42
-rw-r--r--ext/intl/tests/ini_use_exceptions_basic.phpt21
-rw-r--r--ext/intl/tests/locale_filter_matches2.phpt3
-rw-r--r--ext/intl/tests/locale_filter_matches3.phpt366
-rw-r--r--ext/intl/tests/locale_get_display_name2.phpt3
-rw-r--r--ext/intl/tests/locale_get_display_name3.phpt342
-rw-r--r--ext/intl/tests/locale_get_display_region2.phpt3
-rw-r--r--ext/intl/tests/locale_get_display_region3.phpt275
-rw-r--r--ext/intl/tests/locale_lookup.phpt1
-rw-r--r--ext/intl/tests/locale_lookup_variant2.phpt100
-rw-r--r--ext/intl/tests/msgfmt_format_datetime.phpt28
-rw-r--r--ext/intl/tests/msgfmt_format_error1.phpt19
-rw-r--r--ext/intl/tests/msgfmt_format_error2.phpt23
-rw-r--r--ext/intl/tests/msgfmt_format_error3.phpt23
-rw-r--r--ext/intl/tests/msgfmt_format_error4.phpt28
-rw-r--r--ext/intl/tests/msgfmt_format_error5.phpt26
-rw-r--r--ext/intl/tests/msgfmt_format_error6.phpt23
-rw-r--r--ext/intl/tests/msgfmt_format_intlcalendar.phpt30
-rw-r--r--ext/intl/tests/msgfmt_format_intlcalendar_variant2.phpt30
-rw-r--r--ext/intl/tests/msgfmt_format_mixed_params.phpt25
-rw-r--r--ext/intl/tests/msgfmt_format_simple_types_numeric_strings.phpt58
-rw-r--r--ext/intl/tests/msgfmt_format_subpatterns.phpt75
-rw-r--r--ext/intl/tests/msgfmt_format_subpatterns_named.phpt75
-rw-r--r--ext/intl/tests/msgfmt_get_error.phpt29
-rw-r--r--ext/intl/tests/msgfmt_millisecond_dates.phpt29
-rw-r--r--ext/intl/tests/msgfmt_setPattern_cache.phpt26
-rw-r--r--ext/intl/tests/rbbiter___construct_basic.phpt31
-rw-r--r--ext/intl/tests/rbbiter_getBinaryRules_basic.phpt39
-rw-r--r--ext/intl/tests/rbbiter_getRuleStatusVec_basic.phpt59
-rw-r--r--ext/intl/tests/rbbiter_getRuleStatus_basic.phpt46
-rw-r--r--ext/intl/tests/rbbiter_getRules_basic.phpt32
-rw-r--r--ext/intl/tests/resourcebundle_null_mandatory_args.phpt8
-rw-r--r--ext/intl/tests/resourcebundle_null_mandatory_args_variant2.phpt26
-rw-r--r--ext/intl/tests/timezone_clone_basic.phpt51
-rw-r--r--ext/intl/tests/timezone_clone_error.phpt32
-rw-r--r--ext/intl/tests/timezone_countEquivalentIDs_basic.phpt20
-rw-r--r--ext/intl/tests/timezone_countEquivalentIDs_error.phpt35
-rw-r--r--ext/intl/tests/timezone_createDefault_basic.phpt31
-rw-r--r--ext/intl/tests/timezone_createDefault_error.phpt19
-rw-r--r--ext/intl/tests/timezone_createEnumeration_basic.phpt26
-rw-r--r--ext/intl/tests/timezone_createEnumeration_error.phpt23
-rw-r--r--ext/intl/tests/timezone_createEnumeration_variation1.phpt24
-rw-r--r--ext/intl/tests/timezone_createEnumeration_variation2.phpt24
-rw-r--r--ext/intl/tests/timezone_createTimeZoneIDEnumeration_basic.phpt34
-rw-r--r--ext/intl/tests/timezone_createTimeZoneIDEnumeration_error.phpt42
-rw-r--r--ext/intl/tests/timezone_createTimeZoneIDEnumeration_variant1.phpt32
-rw-r--r--ext/intl/tests/timezone_createTimeZoneIDEnumeration_variant2.phpt52
-rw-r--r--ext/intl/tests/timezone_createTimeZone_basic.phpt33
-rw-r--r--ext/intl/tests/timezone_createTimeZone_error.phpt34
-rw-r--r--ext/intl/tests/timezone_equals_basic.phpt33
-rw-r--r--ext/intl/tests/timezone_equals_error.phpt43
-rw-r--r--ext/intl/tests/timezone_fromDateTimeZone_basic.phpt41
-rw-r--r--ext/intl/tests/timezone_fromDateTimeZone_error.phpt50
-rw-r--r--ext/intl/tests/timezone_getCanonicalID_basic.phpt19
-rw-r--r--ext/intl/tests/timezone_getCanonicalID_error.phpt32
-rw-r--r--ext/intl/tests/timezone_getCanonicalID_variant1.phpt24
-rw-r--r--ext/intl/tests/timezone_getDSTSavings_basic.phpt21
-rw-r--r--ext/intl/tests/timezone_getDSTSavings_error.phpt23
-rw-r--r--ext/intl/tests/timezone_getDisplayName_basic.phpt24
-rw-r--r--ext/intl/tests/timezone_getDisplayName_error.phpt45
-rw-r--r--ext/intl/tests/timezone_getDisplayName_variant1.phpt26
-rw-r--r--ext/intl/tests/timezone_getDisplayName_variant2-49+.phpt36
-rw-r--r--ext/intl/tests/timezone_getDisplayName_variant2.phpt40
-rw-r--r--ext/intl/tests/timezone_getDisplayName_variant3-49+.phpt28
-rw-r--r--ext/intl/tests/timezone_getDisplayName_variant3.phpt28
-rw-r--r--ext/intl/tests/timezone_getDisplayName_variant4.phpt35
-rw-r--r--ext/intl/tests/timezone_getEquivalentID_basic.phpt19
-rw-r--r--ext/intl/tests/timezone_getEquivalentID_error.phpt34
-rw-r--r--ext/intl/tests/timezone_getErrorCodeMessage_basic.phpt31
-rw-r--r--ext/intl/tests/timezone_getErrorCode_error.phpt23
-rw-r--r--ext/intl/tests/timezone_getErrorMessage_error.phpt23
-rw-r--r--ext/intl/tests/timezone_getGMT_basic.phpt31
-rw-r--r--ext/intl/tests/timezone_getGMT_error.phpt19
-rw-r--r--ext/intl/tests/timezone_getID_error.phpt23
-rw-r--r--ext/intl/tests/timezone_getOffset_basic.phpt33
-rw-r--r--ext/intl/tests/timezone_getOffset_error.phpt33
-rw-r--r--ext/intl/tests/timezone_getRawOffset_basic.phpt21
-rw-r--r--ext/intl/tests/timezone_getRawOffset_error.phpt23
-rw-r--r--ext/intl/tests/timezone_getRegion_basic.phpt21
-rw-r--r--ext/intl/tests/timezone_getRegion_error.phpt42
-rw-r--r--ext/intl/tests/timezone_getTZDataVersion_error.phpt18
-rw-r--r--ext/intl/tests/timezone_getTZData_basic.phpt19
-rw-r--r--ext/intl/tests/timezone_getUnknown_basic.phpt35
-rw-r--r--ext/intl/tests/timezone_getUnknown_error.phpt29
-rw-r--r--ext/intl/tests/timezone_hasSameRules_basic.phpt35
-rw-r--r--ext/intl/tests/timezone_hasSameRules_error.phpt37
-rw-r--r--ext/intl/tests/timezone_toDateTimeZone_basic.phpt38
-rw-r--r--ext/intl/tests/timezone_toDateTimeZone_error.phpt38
-rw-r--r--ext/intl/tests/timezone_useDaylightTime_basic.phpt25
-rw-r--r--ext/intl/tests/timezone_useDaylightTime_error.phpt22
-rw-r--r--ext/intl/tests/uconverter___construct_error.phpt14
-rw-r--r--ext/intl/tests/uconverter_enum.phpt21
-rw-r--r--ext/intl/tests/uconverter_func_basic.phpt17
-rw-r--r--ext/intl/tests/uconverter_func_subst.phpt31
-rw-r--r--ext/intl/tests/uconverter_oop_algo.phpt18
-rw-r--r--ext/intl/tests/uconverter_oop_basic.phpt21
-rw-r--r--ext/intl/tests/uconverter_oop_callback.phpt52
-rw-r--r--ext/intl/tests/uconverter_oop_callback_return.phpt40
-rw-r--r--ext/intl/tests/uconverter_oop_subst.phpt24
-rw-r--r--ext/intl/timezone/timezone_class.cpp540
-rw-r--r--ext/intl/timezone/timezone_class.h72
-rw-r--r--ext/intl/timezone/timezone_methods.cpp659
-rw-r--r--ext/intl/timezone/timezone_methods.h68
-rw-r--r--ext/intl/transliterator/transliterator.c79
-rw-r--r--ext/intl/transliterator/transliterator_class.c10
-rw-r--r--ext/intl/transliterator/transliterator_methods.c2
-rw-r--r--ext/json/JSON_parser.h5
-rw-r--r--ext/json/json.c80
-rw-r--r--ext/json/php_json.h2
-rw-r--r--ext/json/tests/003.phpt17
-rw-r--r--ext/json/tests/004.phpt16
-rw-r--r--ext/json/tests/007.phpt16
-rw-r--r--ext/json/tests/bug43941.phpt7
-rw-r--r--ext/json/tests/bug53946.phpt6
-rw-r--r--ext/json/tests/bug54058.phpt13
-rw-r--r--ext/json/tests/bug61537.phpt39
-rw-r--r--ext/json/tests/bug61978.phpt10
-rw-r--r--ext/json/tests/bug62369.phpt34
-rw-r--r--ext/json/tests/inf_nan_error.phpt45
-rw-r--r--ext/json/tests/json_encode_basic.phpt6
-rw-r--r--ext/json/tests/json_encode_error.phpt4
-rw-r--r--ext/json/tests/pass001.1.phpt4
-rw-r--r--ext/json/tests/pass001.1_64bit.phpt4
-rw-r--r--ext/json/tests/pass001.phpt4
-rw-r--r--ext/json/tests/unsupported_type_error.phpt26
-rw-r--r--ext/ldap/config.m441
-rw-r--r--ext/ldap/ldap.c40
-rw-r--r--ext/libxml/libxml.c6
-rw-r--r--ext/mbstring/config.m48
-rw-r--r--ext/mbstring/config.w322
-rw-r--r--ext/mbstring/libmbfl/filters/mbfilter_sjis_mac.c2
-rw-r--r--ext/mbstring/libmbfl/filters/mbfilter_utf8_mobile.h2
-rw-r--r--ext/mbstring/mbstring.c14
-rw-r--r--ext/mbstring/oniguruma/COPYING6
-rw-r--r--ext/mbstring/oniguruma/HISTORY318
-rw-r--r--ext/mbstring/oniguruma/README42
-rw-r--r--ext/mbstring/oniguruma/README.ja41
-rw-r--r--ext/mbstring/oniguruma/doc/API67
-rw-r--r--ext/mbstring/oniguruma/doc/API.ja72
-rw-r--r--ext/mbstring/oniguruma/doc/FAQ4
-rw-r--r--ext/mbstring/oniguruma/doc/FAQ.ja18
-rw-r--r--ext/mbstring/oniguruma/doc/RE153
-rw-r--r--ext/mbstring/oniguruma/doc/RE.ja162
-rw-r--r--ext/mbstring/oniguruma/enc/ascii.c19
-rw-r--r--ext/mbstring/oniguruma/enc/big5.c36
-rw-r--r--ext/mbstring/oniguruma/enc/cp1251.c200
-rw-r--r--ext/mbstring/oniguruma/enc/euc_jp.c199
-rw-r--r--ext/mbstring/oniguruma/enc/euc_kr.c53
-rw-r--r--ext/mbstring/oniguruma/enc/euc_tw.c39
-rw-r--r--ext/mbstring/oniguruma/enc/gb18030.c36
-rw-r--r--ext/mbstring/oniguruma/enc/iso8859_1.c269
-rw-r--r--ext/mbstring/oniguruma/enc/iso8859_10.c305
-rw-r--r--ext/mbstring/oniguruma/enc/iso8859_11.c81
-rw-r--r--ext/mbstring/oniguruma/enc/iso8859_13.c254
-rw-r--r--ext/mbstring/oniguruma/enc/iso8859_14.c297
-rw-r--r--ext/mbstring/oniguruma/enc/iso8859_15.c272
-rw-r--r--ext/mbstring/oniguruma/enc/iso8859_16.c287
-rw-r--r--ext/mbstring/oniguruma/enc/iso8859_2.c291
-rw-r--r--ext/mbstring/oniguruma/enc/iso8859_3.c282
-rw-r--r--ext/mbstring/oniguruma/enc/iso8859_4.c291
-rw-r--r--ext/mbstring/oniguruma/enc/iso8859_5.c292
-rw-r--r--ext/mbstring/oniguruma/enc/iso8859_6.c71
-rw-r--r--ext/mbstring/oniguruma/enc/iso8859_7.c264
-rw-r--r--ext/mbstring/oniguruma/enc/iso8859_8.c67
-rw-r--r--ext/mbstring/oniguruma/enc/iso8859_9.c262
-rw-r--r--ext/mbstring/oniguruma/enc/koi8.c260
-rw-r--r--ext/mbstring/oniguruma/enc/koi8_r.c240
-rw-r--r--ext/mbstring/oniguruma/enc/mktable.c127
-rw-r--r--ext/mbstring/oniguruma/enc/sjis.c188
-rw-r--r--ext/mbstring/oniguruma/enc/unicode.c9755
-rw-r--r--ext/mbstring/oniguruma/enc/utf16_be.c125
-rw-r--r--ext/mbstring/oniguruma/enc/utf16_le.c122
-rw-r--r--ext/mbstring/oniguruma/enc/utf32_be.c125
-rw-r--r--ext/mbstring/oniguruma/enc/utf32_le.c123
-rw-r--r--ext/mbstring/oniguruma/enc/utf8.c3563
-rwxr-xr-xext/mbstring/oniguruma/index.html18
-rw-r--r--ext/mbstring/oniguruma/index_ja.html190
-rw-r--r--ext/mbstring/oniguruma/onigposix.h2
-rw-r--r--ext/mbstring/oniguruma/oniguruma.h266
-rw-r--r--ext/mbstring/oniguruma/regcomp.c2070
-rw-r--r--ext/mbstring/oniguruma/regenc.c690
-rw-r--r--ext/mbstring/oniguruma/regenc.h120
-rw-r--r--ext/mbstring/oniguruma/regerror.c50
-rw-r--r--ext/mbstring/oniguruma/regexec.c998
-rw-r--r--ext/mbstring/oniguruma/regext.c27
-rw-r--r--ext/mbstring/oniguruma/reggnu.c28
-rw-r--r--ext/mbstring/oniguruma/regint.h418
-rw-r--r--ext/mbstring/oniguruma/regparse.c1824
-rw-r--r--ext/mbstring/oniguruma/regparse.h307
-rw-r--r--ext/mbstring/oniguruma/regposerr.c14
-rw-r--r--ext/mbstring/oniguruma/regposix.c12
-rw-r--r--ext/mbstring/oniguruma/regsyntax.c87
-rw-r--r--ext/mbstring/oniguruma/regversion.c5
-rw-r--r--ext/mbstring/oniguruma/st.c21
-rw-r--r--ext/mbstring/oniguruma/st.h5
-rw-r--r--ext/mbstring/oniguruma/testc.c863
-rw-r--r--ext/mbstring/oniguruma/testu.c911
-rw-r--r--ext/mbstring/oniguruma/win32/Makefile200
-rw-r--r--ext/mbstring/oniguruma/win32/testc.c863
-rw-r--r--ext/mbstring/php_mbregex.h2
-rw-r--r--ext/mcrypt/config.m42
-rw-r--r--ext/mcrypt/mcrypt.c10
-rw-r--r--ext/mcrypt/tests/mcrypt_cbc.phpt6
-rw-r--r--ext/mcrypt/tests/mcrypt_cbc_3des_decrypt.phpt14
-rw-r--r--ext/mcrypt/tests/mcrypt_cbc_3des_encrypt.phpt14
-rw-r--r--ext/mcrypt/tests/mcrypt_cbc_error.phpt4
-rw-r--r--ext/mcrypt/tests/mcrypt_cbc_variation1.phpt26
-rw-r--r--ext/mcrypt/tests/mcrypt_cbc_variation2.phpt27
-rw-r--r--ext/mcrypt/tests/mcrypt_cbc_variation3.phpt27
-rw-r--r--ext/mcrypt/tests/mcrypt_cbc_variation4.phpt28
-rw-r--r--ext/mcrypt/tests/mcrypt_cbc_variation5.phpt26
-rw-r--r--ext/mcrypt/tests/mcrypt_cfb.phpt6
-rw-r--r--ext/mcrypt/tests/mcrypt_ecb.phpt6
-rw-r--r--ext/mcrypt/tests/mcrypt_ecb_3des_decrypt.phpt4
-rw-r--r--ext/mcrypt/tests/mcrypt_ecb_3des_encrypt.phpt2
-rw-r--r--ext/mcrypt/tests/mcrypt_ecb_error.phpt2
-rw-r--r--ext/mcrypt/tests/mcrypt_ecb_variation1.phpt4
-rw-r--r--ext/mcrypt/tests/mcrypt_ecb_variation2.phpt4
-rw-r--r--ext/mcrypt/tests/mcrypt_ecb_variation3.phpt4
-rw-r--r--ext/mcrypt/tests/mcrypt_ecb_variation4.phpt4
-rw-r--r--ext/mcrypt/tests/mcrypt_ecb_variation5.phpt4
-rw-r--r--ext/mcrypt/tests/mcrypt_ofb.phpt10
-rw-r--r--ext/mcrypt/tests/mcrypt_rijndael128_128BitKey.phpt20
-rw-r--r--ext/mssql/config.m42
-rw-r--r--ext/mssql/php_mssql.c13
-rw-r--r--ext/mssql/php_mssql.h2
-rw-r--r--ext/mysql/CREDITS2
-rw-r--r--ext/mysql/config.m47
-rw-r--r--ext/mysql/php_mysql.c44
-rw-r--r--ext/mysql/tests/001.phpt3
-rw-r--r--ext/mysql/tests/002.phpt1
-rw-r--r--ext/mysql/tests/003.phpt1
-rw-r--r--ext/mysql/tests/bug47438.phpt3
-rw-r--r--ext/mysql/tests/bug48754.phpt8
-rw-r--r--ext/mysql/tests/bug51242.phpt1
-rw-r--r--ext/mysql/tests/bug53649.phpt5
-rw-r--r--ext/mysql/tests/bug55473.phpt25
-rw-r--r--ext/mysql/tests/mysql_affected_rows.phpt1
-rw-r--r--ext/mysql/tests/mysql_client_encoding.phpt1
-rw-r--r--ext/mysql/tests/mysql_close.phpt1
-rw-r--r--ext/mysql/tests/mysql_connect.phpt20
-rw-r--r--ext/mysql/tests/mysql_constants.phpt3
-rw-r--r--ext/mysql/tests/mysql_create_db.phpt3
-rw-r--r--ext/mysql/tests/mysql_data_seek.phpt2
-rw-r--r--ext/mysql/tests/mysql_db_name.phpt2
-rw-r--r--ext/mysql/tests/mysql_db_query.phpt1
-rw-r--r--ext/mysql/tests/mysql_deprecated_api.phpt3
-rw-r--r--ext/mysql/tests/mysql_drop_db.phpt3
-rw-r--r--ext/mysql/tests/mysql_errno.phpt1
-rw-r--r--ext/mysql/tests/mysql_error.phpt2
-rw-r--r--ext/mysql/tests/mysql_fetch_array.phpt1
-rw-r--r--ext/mysql/tests/mysql_fetch_assoc.phpt3
-rw-r--r--ext/mysql/tests/mysql_fetch_field.phpt1
-rw-r--r--ext/mysql/tests/mysql_fetch_lengths.phpt1
-rw-r--r--ext/mysql/tests/mysql_fetch_object.phpt1
-rw-r--r--ext/mysql/tests/mysql_fetch_row.phpt3
-rw-r--r--ext/mysql/tests/mysql_field_flags.phpt8
-rw-r--r--ext/mysql/tests/mysql_field_len.phpt2
-rw-r--r--ext/mysql/tests/mysql_field_name.phpt2
-rw-r--r--ext/mysql/tests/mysql_field_seek.phpt2
-rw-r--r--ext/mysql/tests/mysql_field_table.phpt2
-rw-r--r--ext/mysql/tests/mysql_field_type.phpt2
-rw-r--r--ext/mysql/tests/mysql_free_result.phpt1
-rw-r--r--ext/mysql/tests/mysql_get_host_info.phpt1
-rw-r--r--ext/mysql/tests/mysql_get_proto_info.phpt1
-rw-r--r--ext/mysql/tests/mysql_get_server_info.phpt1
-rw-r--r--ext/mysql/tests/mysql_info.phpt3
-rw-r--r--ext/mysql/tests/mysql_insert_id.phpt2
-rw-r--r--ext/mysql/tests/mysql_list_dbs.phpt3
-rw-r--r--ext/mysql/tests/mysql_list_fields.phpt3
-rw-r--r--ext/mysql/tests/mysql_list_processes.phpt3
-rw-r--r--ext/mysql/tests/mysql_list_tables.phpt1
-rw-r--r--ext/mysql/tests/mysql_max_links.phpt12
-rw-r--r--ext/mysql/tests/mysql_max_persistent.phpt8
-rw-r--r--ext/mysql/tests/mysql_mysqlnd_read_timeout_long.phpt3
-rw-r--r--ext/mysql/tests/mysql_num_fields.phpt2
-rw-r--r--ext/mysql/tests/mysql_num_rows.phpt2
-rw-r--r--ext/mysql/tests/mysql_pconn_disable.phpt9
-rw-r--r--ext/mysql/tests/mysql_pconn_kill.phpt7
-rw-r--r--ext/mysql/tests/mysql_pconn_max_links.phpt5
-rw-r--r--ext/mysql/tests/mysql_pconn_reuse.phpt11
-rw-r--r--ext/mysql/tests/mysql_pconnect.phpt12
-rw-r--r--ext/mysql/tests/mysql_ping.phpt1
-rw-r--r--ext/mysql/tests/mysql_query.phpt1
-rw-r--r--ext/mysql/tests/mysql_query_load_data_openbasedir.phpt3
-rw-r--r--ext/mysql/tests/mysql_real_escape_string.phpt1
-rw-r--r--ext/mysql/tests/mysql_reflection_extension.phpt105
-rw-r--r--ext/mysql/tests/mysql_reflection_functions.phpt387
-rw-r--r--ext/mysql/tests/mysql_result.phpt2
-rw-r--r--ext/mysql/tests/mysql_select_db.phpt1
-rw-r--r--ext/mysql/tests/mysql_set_charset.phpt1
-rw-r--r--ext/mysql/tests/mysql_stat.phpt2
-rw-r--r--ext/mysql/tests/mysql_tablename.phpt2
-rw-r--r--ext/mysql/tests/mysql_thread_id.phpt4
-rw-r--r--ext/mysql/tests/mysql_trace_mode.phpt1
-rw-r--r--ext/mysql/tests/mysql_unbuffered_query.phpt1
-rw-r--r--ext/mysqli/config.m47
-rw-r--r--ext/mysqli/mysqli.c228
-rw-r--r--ext/mysqli/mysqli_api.c203
-rw-r--r--ext/mysqli/mysqli_fe.c82
-rw-r--r--ext/mysqli/mysqli_fe.h4
-rw-r--r--ext/mysqli/mysqli_libmysql.h12
-rw-r--r--ext/mysqli/mysqli_nonapi.c167
-rw-r--r--ext/mysqli/mysqli_priv.h1
-rw-r--r--ext/mysqli/mysqli_prop.c4
-rw-r--r--ext/mysqli/mysqli_report.h64
-rw-r--r--ext/mysqli/mysqli_result_iterator.c5
-rw-r--r--ext/mysqli/package.xml1
-rw-r--r--ext/mysqli/php_mysqli_structs.h12
-rw-r--r--ext/mysqli/tests/057.phpt4
-rw-r--r--ext/mysqli/tests/connect.inc93
-rw-r--r--ext/mysqli/tests/mysqli_class_mysqli_interface.phpt49
-rw-r--r--ext/mysqli/tests/mysqli_class_mysqli_reflection.phpt110
-rw-r--r--ext/mysqli/tests/mysqli_commit_oo.phpt6
-rw-r--r--ext/mysqli/tests/mysqli_constants.phpt19
-rw-r--r--ext/mysqli/tests/mysqli_expire_password.phpt8
-rw-r--r--ext/mysqli/tests/mysqli_fetch_field.phpt22
-rw-r--r--ext/mysqli/tests/mysqli_fetch_field_oo.phpt21
-rw-r--r--ext/mysqli/tests/mysqli_fetch_fields.phpt20
-rw-r--r--ext/mysqli/tests/mysqli_field_seek.phpt22
-rw-r--r--ext/mysqli/tests/mysqli_info.phpt8
-rw-r--r--ext/mysqli/tests/mysqli_pam_sha256.phpt113
-rw-r--r--ext/mysqli/tests/mysqli_pam_sha256_public_key_ini.phpt129
-rw-r--r--ext/mysqli/tests/mysqli_pam_sha256_public_key_option.phpt132
-rw-r--r--ext/mysqli/tests/mysqli_pam_sha256_public_key_option_invalid.phpt188
-rw-r--r--ext/mysqli/tests/mysqli_query_local_infile_large.phpt103
-rw-r--r--ext/mysqli/tests/mysqli_set_local_infile_default.phpt132
-rw-r--r--ext/mysqli/tests/mysqli_set_local_infile_handler.phpt196
-rw-r--r--ext/mysqli/tests/mysqli_set_local_infile_handler_bad_character.phpt82
-rw-r--r--ext/mysqli/tests/mysqli_set_local_infile_handler_buffer_overflow.phpt60
-rw-r--r--ext/mysqli/tests/mysqli_set_local_infile_handler_close_link.phpt61
-rw-r--r--ext/mysqli/tests/mysqli_set_local_infile_handler_closefile.phpt70
-rw-r--r--ext/mysqli/tests/mysqli_set_local_infile_handler_closures.phpt62
-rw-r--r--ext/mysqli/tests/mysqli_set_local_infile_handler_kill_link.phpt61
-rw-r--r--ext/mysqli/tests/mysqli_set_local_infile_handler_negative_len.phpt58
-rw-r--r--ext/mysqli/tests/mysqli_set_local_infile_handler_nested_call.phpt107
-rw-r--r--ext/mysqli/tests/mysqli_set_local_infile_handler_new_query.phpt71
-rw-r--r--ext/mysqli/tests/mysqli_set_local_infile_handler_nofileop.phpt70
-rw-r--r--ext/mysqli/tests/mysqli_set_local_infile_handler_openbasedir.phpt115
-rw-r--r--ext/mysqli/tests/mysqli_set_local_infile_handler_replace_buffer.phpt78
-rw-r--r--ext/mysqli/tests/mysqli_set_local_infile_handler_short_len.phpt101
-rw-r--r--ext/mysqli/tests/mysqli_set_local_infile_handler_unregister.phpt64
-rw-r--r--ext/mysqli/tests/mysqli_stmt_get_result_metadata_fetch_field.phpt21
-rw-r--r--ext/mysqlnd/CREDITS2
-rw-r--r--ext/mysqlnd/config9.m416
-rw-r--r--ext/mysqlnd/mysqlnd.c1062
-rw-r--r--ext/mysqlnd/mysqlnd.h21
-rw-r--r--ext/mysqlnd/mysqlnd_alloc.c194
-rw-r--r--ext/mysqlnd/mysqlnd_alloc.h4
-rw-r--r--ext/mysqlnd/mysqlnd_auth.c209
-rw-r--r--ext/mysqlnd/mysqlnd_bt.c256
-rw-r--r--ext/mysqlnd/mysqlnd_charset.c20
-rw-r--r--ext/mysqlnd/mysqlnd_debug.c29
-rw-r--r--ext/mysqlnd/mysqlnd_debug.h91
-rw-r--r--ext/mysqlnd/mysqlnd_driver.c33
-rw-r--r--ext/mysqlnd/mysqlnd_enum_n_def.h23
-rw-r--r--ext/mysqlnd/mysqlnd_ext_plugin.c1
-rw-r--r--ext/mysqlnd/mysqlnd_libmysql_compat.h7
-rw-r--r--ext/mysqlnd/mysqlnd_loaddata.c8
-rw-r--r--ext/mysqlnd/mysqlnd_net.c400
-rw-r--r--ext/mysqlnd/mysqlnd_plugin.c4
-rw-r--r--ext/mysqlnd/mysqlnd_priv.h37
-rw-r--r--ext/mysqlnd/mysqlnd_ps.c21
-rw-r--r--ext/mysqlnd/mysqlnd_ps_codec.c173
-rw-r--r--ext/mysqlnd/mysqlnd_result.c31
-rw-r--r--ext/mysqlnd/mysqlnd_result_meta.c82
-rw-r--r--ext/mysqlnd/mysqlnd_reverse_api.h1
-rw-r--r--ext/mysqlnd/mysqlnd_statistics.c12
-rw-r--r--ext/mysqlnd/mysqlnd_structs.h114
-rw-r--r--ext/mysqlnd/mysqlnd_wireprotocol.c293
-rw-r--r--ext/mysqlnd/mysqlnd_wireprotocol.h24
-rw-r--r--ext/mysqlnd/php_mysqlnd.c62
-rw-r--r--ext/oci8/config.m42
-rw-r--r--ext/oci8/package.xml27
-rw-r--r--ext/oci8/php_oci8.h2
-rw-r--r--ext/oci8/php_oci8_int.h2
-rw-r--r--ext/odbc/config.m433
-rw-r--r--ext/opcache/Optimizer/block_pass.c2091
-rw-r--r--ext/opcache/Optimizer/nop_removal.c126
-rw-r--r--ext/opcache/Optimizer/optimize_temp_vars_5.c222
-rw-r--r--ext/opcache/Optimizer/pass10.c3
-rw-r--r--ext/opcache/Optimizer/pass1_5.c338
-rw-r--r--ext/opcache/Optimizer/pass2.c211
-rw-r--r--ext/opcache/Optimizer/pass3.c442
-rw-r--r--ext/opcache/Optimizer/pass5.c3
-rw-r--r--ext/opcache/Optimizer/pass9.c8
-rw-r--r--ext/opcache/Optimizer/zend_optimizer.c351
-rw-r--r--ext/opcache/Optimizer/zend_optimizer.h49
-rw-r--r--ext/opcache/Optimizer/zend_optimizer_internal.h86
-rw-r--r--ext/opcache/README220
-rw-r--r--ext/opcache/ZendAccelerator.c2832
-rw-r--r--ext/opcache/ZendAccelerator.h398
-rw-r--r--ext/opcache/config.m4383
-rw-r--r--ext/opcache/config.w3227
-rw-r--r--ext/opcache/shared_alloc_mmap.c78
-rw-r--r--ext/opcache/shared_alloc_posix.c98
-rw-r--r--ext/opcache/shared_alloc_shm.c145
-rw-r--r--ext/opcache/shared_alloc_win32.c344
-rw-r--r--ext/opcache/tests/001_cli.phpt19
-rw-r--r--ext/opcache/tests/blacklist-win32.phpt34
-rw-r--r--ext/opcache/tests/blacklist.inc3
-rw-r--r--ext/opcache/tests/blacklist.phpt34
-rw-r--r--ext/opcache/tests/bug64353.phpt29
-rw-r--r--ext/opcache/tests/bug64482.inc2
-rw-r--r--ext/opcache/tests/bug64482.phpt17
-rw-r--r--ext/opcache/tests/bug65510.phpt20
-rw-r--r--ext/opcache/tests/bug65559.phpt22
-rw-r--r--ext/opcache/tests/bug65665.phpt118
-rw-r--r--ext/opcache/tests/bug65845.phpt14
-rw-r--r--ext/opcache/tests/bug65915.phpt26
-rw-r--r--ext/opcache/tests/bug66176.phpt19
-rw-r--r--ext/opcache/tests/bug66461.phpt15
-rw-r--r--ext/opcache/tests/bug66474.phpt18
-rw-r--r--ext/opcache/tests/issue0057.phpt38
-rw-r--r--ext/opcache/tests/issue0079.phpt34
-rw-r--r--ext/opcache/tests/issue0115.phpt48
-rw-r--r--ext/opcache/tests/issue0128.phpt16
-rw-r--r--ext/opcache/tests/issue0140.phpt43
-rw-r--r--ext/opcache/tests/issue0149.phpt35
-rw-r--r--ext/opcache/tests/opcache-1.blacklist5
-rw-r--r--ext/opcache/tests/opcache-2.blacklist6
-rw-r--r--ext/opcache/tests/php_cli_server.inc47
-rw-r--r--ext/opcache/tests/revalidate_path_01.phpt61
-rw-r--r--ext/opcache/tests/skipif.inc3
-rw-r--r--ext/opcache/zend_accelerator_blacklist.c381
-rw-r--r--ext/opcache/zend_accelerator_blacklist.h49
-rw-r--r--ext/opcache/zend_accelerator_debug.c99
-rw-r--r--ext/opcache/zend_accelerator_debug.h33
-rw-r--r--ext/opcache/zend_accelerator_hash.c224
-rw-r--r--ext/opcache/zend_accelerator_hash.h98
-rw-r--r--ext/opcache/zend_accelerator_module.c761
-rw-r--r--ext/opcache/zend_accelerator_module.h28
-rw-r--r--ext/opcache/zend_accelerator_util_funcs.c1077
-rw-r--r--ext/opcache/zend_accelerator_util_funcs.h50
-rw-r--r--ext/opcache/zend_persist.c684
-rw-r--r--ext/opcache/zend_persist.h29
-rw-r--r--ext/opcache/zend_persist_calc.c345
-rw-r--r--ext/opcache/zend_shared_alloc.c494
-rw-r--r--ext/opcache/zend_shared_alloc.h182
-rw-r--r--ext/openssl/CREDITS2
-rw-r--r--ext/openssl/config0.m42
-rw-r--r--ext/openssl/openssl.c321
-rw-r--r--ext/openssl/php_openssl.h2
-rw-r--r--ext/openssl/tests/openssl_pbkdf2.phpt26
-rw-r--r--ext/openssl/xp_ssl.c8
-rw-r--r--ext/pcntl/pcntl.c4
-rw-r--r--ext/pcntl/php_signal.c3
-rw-r--r--ext/pcre/php_pcre.c4
-rw-r--r--ext/pcre/tests/002.phpt2
-rw-r--r--ext/pcre/tests/004.phpt4
-rw-r--r--ext/pdo/Makefile.frag2
-rw-r--r--ext/pdo/pdo_sql_parser.c2
-rw-r--r--ext/pdo/pdo_stmt.c10
-rw-r--r--ext/pdo/php_pdo_int.h2
-rw-r--r--ext/pdo/tests/pdo_036.phpt8
-rw-r--r--ext/pdo_firebird/config.m42
-rwxr-xr-xext/pdo_mysql/config.m46
-rw-r--r--ext/pdo_mysql/mysql_driver.c14
-rw-r--r--ext/pdo_mysql/pdo_mysql.c4
-rw-r--r--ext/pdo_mysql/php_pdo_mysql_int.h5
-rw-r--r--ext/pdo_mysql/tests/bug_39858.phpt2
-rw-r--r--ext/pdo_mysql/tests/bug_41997.phpt2
-rw-r--r--ext/pdo_mysql/tests/bug_44454.phpt2
-rw-r--r--ext/pdo_mysql/tests/pdo_mysql___construct.phpt11
-rw-r--r--ext/pdo_mysql/tests/pdo_mysql_class_constants.phpt18
-rw-r--r--ext/pdo_mysql/tests/pdo_mysql_pconnect.phpt4
-rw-r--r--ext/pdo_mysql/tests/pdo_mysql_stmt_nextrowset.phpt4
-rw-r--r--ext/pdo_mysql/tests/pdo_mysql_stmt_variable_columncount.phpt4
-rwxr-xr-xext/pdo_oci/config.m48
-rwxr-xr-xext/pdo_odbc/config.m432
-rw-r--r--ext/pdo_pgsql/config.m42
-rw-r--r--ext/pdo_sqlite/config.m44
-rw-r--r--ext/pgsql/config.m42
-rw-r--r--ext/pgsql/pgsql.c9
-rw-r--r--ext/pgsql/tests/09notice.phpt5
-rw-r--r--ext/pgsql/tests/80_bug32223.phpt6
-rw-r--r--ext/pgsql/tests/80_bug32223b.phpt6
-rw-r--r--ext/pgsql/tests/bug46408.phpt26
-rw-r--r--ext/phar/Makefile.frag2
-rw-r--r--ext/phar/config.m42
-rw-r--r--ext/phar/dirstream.c10
-rw-r--r--ext/phar/phar.c98
-rw-r--r--ext/phar/phar_internal.h59
-rw-r--r--ext/phar/phar_object.c128
-rw-r--r--ext/phar/phar_path_check.c2
-rw-r--r--ext/phar/php_phar.h6
-rw-r--r--ext/phar/stream.c20
-rw-r--r--ext/phar/tests/create_new_and_modify.phpt8
-rw-r--r--ext/phar/tests/delete_in_phar.phpt9
-rw-r--r--ext/phar/tests/delete_in_phar_confirm.phpt9
-rw-r--r--ext/phar/tests/phar_commitwrite.phpt2
-rw-r--r--ext/phar/tests/phar_create_in_cwd.phpt2
-rw-r--r--ext/phar/tests/phar_gobyebye.phpt2
-rw-r--r--ext/phar/tests/phar_mount.phpt2
-rw-r--r--ext/phar/tests/phpinfo_001.phpt4
-rw-r--r--ext/phar/tests/phpinfo_002.phpt2
-rw-r--r--ext/phar/tests/phpinfo_004.phpt4
-rw-r--r--ext/phar/tests/tar/create_new_and_modify.phpt8
-rw-r--r--ext/phar/tests/tar/delete_in_phar.phpt8
-rw-r--r--ext/phar/tests/tar/delete_in_phar_confirm.phpt8
-rw-r--r--ext/phar/tests/zip/create_new_and_modify.phpt8
-rw-r--r--ext/phar/tests/zip/delete_in_phar.phpt8
-rw-r--r--ext/phar/tests/zip/delete_in_phar_confirm.phpt8
-rw-r--r--ext/phar/util.c313
-rw-r--r--ext/phar/zip.c10
-rw-r--r--ext/posix/tests/posix_getgrnam.phpt19
-rw-r--r--ext/posix/tests/posix_getgrnam_basic.phpt23
-rw-r--r--ext/posix/tests/posix_getpwnam.phpt19
-rw-r--r--ext/posix/tests/posix_getpwnam_basic.phpt23
-rw-r--r--ext/pspell/config.m42
-rw-r--r--ext/readline/config.m44
-rw-r--r--ext/readline/readline.c5
-rw-r--r--ext/recode/config.m42
-rw-r--r--ext/reflection/php_reflection.c63
-rw-r--r--ext/reflection/tests/005.phpt3
-rw-r--r--ext/reflection/tests/009.phpt3
-rw-r--r--ext/reflection/tests/025.phpt3
-rw-r--r--ext/reflection/tests/ReflectionClass_getDocComment_001.phpt3
-rw-r--r--ext/reflection/tests/ReflectionFunction_getDocComment.001.phpt3
-rw-r--r--ext/reflection/tests/ReflectionFunction_isGenerator_basic.phpt52
-rw-r--r--ext/reflection/tests/ReflectionMethod_getDocComment_basic.phpt3
-rw-r--r--ext/reflection/tests/ReflectionProperty_basic2.phpt3
-rw-r--r--ext/reflection/tests/ReflectionProperty_getDocComment_basic.phpt3
-rw-r--r--ext/reflection/tests/bug36308.phpt3
-rw-r--r--ext/reflection/tests/bug64007.phpt19
-rw-r--r--ext/session/mod_files.c99
-rw-r--r--ext/session/mod_files.h2
-rw-r--r--ext/session/mod_mm.c62
-rw-r--r--ext/session/mod_user.c34
-rw-r--r--ext/session/mod_user.h2
-rw-r--r--ext/session/mod_user_class.c16
-rw-r--r--ext/session/php_session.h19
-rw-r--r--ext/session/session.c254
-rw-r--r--ext/session/tests/003.phpt1
-rw-r--r--ext/session/tests/004.phpt1
-rw-r--r--ext/session/tests/005.phpt1
-rw-r--r--ext/session/tests/006.phpt1
-rw-r--r--ext/session/tests/009.phpt1
-rw-r--r--ext/session/tests/012.phpt1
-rw-r--r--ext/session/tests/013.phpt1
-rw-r--r--ext/session/tests/014.phpt1
-rw-r--r--ext/session/tests/015.phpt1
-rw-r--r--ext/session/tests/016.phpt7
-rw-r--r--ext/session/tests/018.phpt1
-rw-r--r--ext/session/tests/019.phpt1
-rw-r--r--ext/session/tests/020.phpt1
-rw-r--r--ext/session/tests/021.phpt1
-rw-r--r--ext/session/tests/023.phpt1
-rw-r--r--ext/session/tests/024.phpt1
-rw-r--r--ext/session/tests/025.phpt1
-rw-r--r--ext/session/tests/026.phpt1
-rw-r--r--ext/session/tests/027.phpt1
-rw-r--r--ext/session/tests/030.phpt1
-rw-r--r--ext/session/tests/bug41600.phpt1
-rw-r--r--ext/session/tests/bug60634.phpt3
-rw-r--r--ext/session/tests/bug60634_error_1.phpt3
-rw-r--r--ext/session/tests/bug60634_error_2.phpt7
-rw-r--r--ext/session/tests/bug60634_error_3.phpt3
-rw-r--r--ext/session/tests/bug60634_error_4.phpt7
-rw-r--r--ext/session/tests/bug65475.phpt34
-rw-r--r--ext/session/tests/rfc1867.phpt1
-rw-r--r--ext/session/tests/rfc1867_cleanup.phpt1
-rw-r--r--ext/session/tests/rfc1867_disabled.phpt1
-rw-r--r--ext/session/tests/rfc1867_disabled_2.phpt1
-rw-r--r--ext/session/tests/rfc1867_inter.phpt1
-rw-r--r--ext/session/tests/rfc1867_no_name.phpt1
-rw-r--r--ext/session/tests/rfc1867_sid_cookie.phpt1
-rw-r--r--ext/session/tests/rfc1867_sid_get.phpt1
-rw-r--r--ext/session/tests/rfc1867_sid_get_2.phpt1
-rw-r--r--ext/session/tests/rfc1867_sid_invalid.phpt10
-rw-r--r--ext/session/tests/rfc1867_sid_only_cookie.phpt1
-rw-r--r--ext/session/tests/rfc1867_sid_post.phpt1
-rw-r--r--ext/session/tests/session_commit_variation4.phpt2
-rw-r--r--ext/session/tests/session_decode_basic_serialize.phpt274
-rw-r--r--ext/session/tests/session_encode_serialize.phpt24
-rw-r--r--ext/session/tests/session_id_basic.phpt2
-rw-r--r--ext/session/tests/session_name_error.phpt2
-rw-r--r--ext/session/tests/session_save_path_variation2.phpt2
-rw-r--r--ext/session/tests/session_save_path_variation5.phpt3
-rw-r--r--ext/session/tests/session_set_save_handler_class_016.phpt90
-rw-r--r--ext/session/tests/session_set_save_handler_class_017.phpt90
-rw-r--r--ext/session/tests/session_set_save_handler_error2.phpt2
-rw-r--r--ext/session/tests/session_set_save_handler_error3.phpt1
-rw-r--r--ext/session/tests/session_set_save_handler_error4.phpt1
-rw-r--r--ext/session/tests/session_set_save_handler_iface_003.phpt90
-rw-r--r--ext/session/tests/session_set_save_handler_sid_001.phpt85
-rw-r--r--ext/session/tests/session_set_save_handler_sid_002.phpt77
-rw-r--r--ext/session/tests/session_write_close_variation4.phpt2
-rw-r--r--ext/simplexml/config.m42
-rw-r--r--ext/simplexml/simplexml.c29
-rw-r--r--ext/snmp/config.m42
-rw-r--r--ext/snmp/snmp.c6
-rw-r--r--ext/soap/config.m42
-rw-r--r--ext/soap/php_encoding.c19
-rw-r--r--ext/soap/php_http.c66
-rw-r--r--ext/soap/php_soap.h7
-rw-r--r--ext/soap/soap.c237
-rw-r--r--ext/soap/tests/bugs/bug34657.phpt7
-rw-r--r--ext/soap/tests/bugs/bug47273.phpt3
-rw-r--r--ext/soap/tests/bugs/bug66112.phpt36
-rw-r--r--ext/soap/tests/bugs/bug66112.wsdl42
-rw-r--r--ext/sockets/config.m423
-rw-r--r--ext/sockets/config.w322
-rw-r--r--ext/sockets/conversions.c1561
-rw-r--r--ext/sockets/conversions.h84
-rw-r--r--ext/sockets/multicast.c385
-rw-r--r--ext/sockets/multicast.h40
-rw-r--r--ext/sockets/php_sockets.h36
-rw-r--r--ext/sockets/sendrecvmsg.c454
-rw-r--r--ext/sockets/sendrecvmsg.h36
-rw-r--r--ext/sockets/sockaddr_conv.c142
-rw-r--r--ext/sockets/sockaddr_conv.h31
-rw-r--r--ext/sockets/sockets.c719
-rw-r--r--ext/sockets/tests/mcast_ipv6_send.phpt4
-rw-r--r--ext/sockets/tests/socket_abstract_path.phpt44
-rw-r--r--ext/sockets/tests/socket_abstract_path_sendmsg.phpt40
-rw-r--r--ext/sockets/tests/socket_cmsg_credentials.phpt89
-rw-r--r--ext/sockets/tests/socket_cmsg_rights.phpt101
-rw-r--r--ext/sockets/tests/socket_recvmsg.phpt92
-rw-r--r--ext/sockets/tests/socket_sendrecvmsg_multi_msg-win32.phpt110
-rw-r--r--ext/sockets/tests/socket_sendrecvmsg_multi_msg.phpt113
-rw-r--r--ext/sockets/tests/socket_sentto_recvfrom_ipv4_udp.phpt6
-rw-r--r--ext/sockets/tests/socket_sentto_recvfrom_ipv6_udp.phpt4
-rw-r--r--ext/sockets/tests/socket_sentto_recvfrom_unix.phpt5
-rw-r--r--ext/sockets/tests/socket_set_option_error_socket_option.phpt5
-rw-r--r--ext/sockets/tests/socket_set_option_in6_pktinfo.phpt38
-rw-r--r--ext/sockets/windows_common.h120
-rwxr-xr-xext/spl/doxygen.cfg4
-rw-r--r--ext/spl/php_spl.c15
-rw-r--r--ext/spl/spl_array.c110
-rw-r--r--ext/spl/spl_directory.c22
-rw-r--r--ext/spl/spl_dllist.c71
-rw-r--r--ext/spl/spl_fixedarray.c8
-rw-r--r--ext/spl/spl_heap.c5
-rw-r--r--ext/spl/spl_iterators.c197
-rw-r--r--ext/spl/spl_iterators.h5
-rw-r--r--ext/spl/tests/SplDoublyLinkedList_add_invalid_offset.phpt13
-rw-r--r--ext/spl/tests/SplDoublyLinkedList_add_missing_parameter1.phpt11
-rw-r--r--ext/spl/tests/SplDoublyLinkedList_add_missing_parameter2.phpt11
-rw-r--r--ext/spl/tests/SplDoublyLinkedList_add_null_offset.phpt13
-rw-r--r--ext/spl/tests/bug61697.phpt24
-rw-r--r--ext/spl/tests/bug64782.phpt21
-rw-r--r--ext/spl/tests/dllist_013.phpt45
-rw-r--r--ext/spl/tests/iterator_to_array_nonscalar_keys.phpt31
-rw-r--r--ext/spl/tests/multiple_iterator_001.phpt20
-rw-r--r--ext/spl/tests/recursive_tree_iterator_setpostfix.phpt88
-rw-r--r--ext/sqlite3/config0.m42
-rw-r--r--ext/sqlite3/libsqlite/sqlite3.c2
-rw-r--r--ext/sqlite3/php_sqlite3.h2
-rw-r--r--ext/sqlite3/tests/bug53463.phpt2
-rw-r--r--ext/standard/Makefile.frag4
-rw-r--r--ext/standard/array.c207
-rw-r--r--ext/standard/basic_functions.c186
-rw-r--r--ext/standard/config.m423
-rw-r--r--ext/standard/config.w322
-rw-r--r--ext/standard/credits.c2
-rw-r--r--ext/standard/credits_ext.h6
-rw-r--r--ext/standard/crypt.c185
-rw-r--r--ext/standard/dl.c9
-rw-r--r--ext/standard/file.c43
-rw-r--r--ext/standard/file.h3
-rw-r--r--ext/standard/filestat.c2
-rw-r--r--ext/standard/head.c19
-rw-r--r--ext/standard/http.c7
-rw-r--r--ext/standard/incomplete_class.c18
-rw-r--r--ext/standard/info.c131
-rw-r--r--ext/standard/info.h12
-rw-r--r--ext/standard/mail.c14
-rw-r--r--ext/standard/math.c2
-rw-r--r--ext/standard/pack.c72
-rw-r--r--ext/standard/password.c460
-rw-r--r--ext/standard/php_array.h1
-rw-r--r--ext/standard/php_crypt.h1
-rw-r--r--ext/standard/php_password.h48
-rw-r--r--ext/standard/php_standard.h1
-rw-r--r--ext/standard/php_type.h1
-rw-r--r--ext/standard/proc_open.c25
-rw-r--r--ext/standard/streamsfuncs.c4
-rw-r--r--ext/standard/string.c69
-rw-r--r--ext/standard/tests/array/array_column_basic.phpt327
-rw-r--r--ext/standard/tests/array/array_column_error.phpt82
-rw-r--r--ext/standard/tests/array/array_column_object_cast.phpt52
-rw-r--r--ext/standard/tests/array/array_column_variant.phpt85
-rw-r--r--ext/standard/tests/array/compact.phpt3
-rw-r--r--ext/standard/tests/array/each.phptbin9570 -> 9574 bytes
-rw-r--r--ext/standard/tests/array/locale_sort.phpt3
-rw-r--r--ext/standard/tests/array/uasort_variation9.phpt2
-rw-r--r--ext/standard/tests/bug64370_var1.phpt5
-rw-r--r--ext/standard/tests/dir/dir_variation1-win32.phpt170
-rw-r--r--ext/standard/tests/dir/dir_variation5-win32.phpt37
-rw-r--r--ext/standard/tests/dir/dir_variation6-win32.phpt61
-rw-r--r--ext/standard/tests/dir/dir_variation8-win32.phpt68
-rw-r--r--ext/standard/tests/dir/dir_variation9-win32.phpt125
-rw-r--r--ext/standard/tests/dir/opendir_error2-win32.phpt47
-rw-r--r--ext/standard/tests/dir/opendir_variation1-win32.phpt248
-rw-r--r--ext/standard/tests/dir/scandir_error2-win32.phpt51
-rw-r--r--ext/standard/tests/dir/scandir_variation1-win32.phpt289
-rw-r--r--ext/standard/tests/dir/scandir_variation6-win32.phpt84
-rw-r--r--ext/standard/tests/file/007_error.phpt4
-rw-r--r--ext/standard/tests/file/bug22414.phpt2
-rw-r--r--ext/standard/tests/file/disk_free_space_basic.phpt2
-rw-r--r--ext/standard/tests/file/fgetss_error.phpt2
-rw-r--r--ext/standard/tests/file/fputcsv_error.phpt2
-rwxr-xr-xext/standard/tests/file/fputcsv_variation15.phpt107
-rw-r--r--ext/standard/tests/file/ftruncate_error.phpt2
-rw-r--r--ext/standard/tests/file/parse_ini_file.phpt36
-rw-r--r--ext/standard/tests/general_functions/boolval.phpt29
-rw-r--r--ext/standard/tests/general_functions/floatval.phpt8
-rw-r--r--ext/standard/tests/general_functions/gettype_settype_basic.phpt32
-rw-r--r--ext/standard/tests/general_functions/parse_ini_string_001.phpt36
-rw-r--r--ext/standard/tests/general_functions/print_r.phpt12
-rw-r--r--ext/standard/tests/general_functions/strval.phpt4
-rw-r--r--ext/standard/tests/general_functions/type.phpt8
-rw-r--r--ext/standard/tests/general_functions/var_dump.phpt8
-rw-r--r--ext/standard/tests/mail/bug51604.phpt4
-rw-r--r--ext/standard/tests/mail/mail_basic.phpt6
-rw-r--r--ext/standard/tests/mail/mail_basic2.phpt4
-rw-r--r--ext/standard/tests/mail/mail_basic3.phpt2
-rw-r--r--ext/standard/tests/mail/mail_basic4.phpt2
-rw-r--r--ext/standard/tests/mail/mail_basic5.phpt2
-rw-r--r--ext/standard/tests/mail/mail_basic_alt1-win32.phpt2
-rw-r--r--ext/standard/tests/mail/mail_basic_alt2-win32.phpt2
-rw-r--r--ext/standard/tests/mail/mail_basic_alt3-win32.phpt2
-rw-r--r--ext/standard/tests/mail/mail_basic_alt4-win32.phpt2
-rw-r--r--ext/standard/tests/mail/mail_log.phpt48
-rw-r--r--ext/standard/tests/mail/mail_variation1.phpt2
-rw-r--r--ext/standard/tests/mail/mail_variation2.phpt4
-rw-r--r--ext/standard/tests/mail/mail_variation_alt1-win32.phpt2
-rw-r--r--ext/standard/tests/mail/mail_variation_alt2-win32.phpt2
-rw-r--r--ext/standard/tests/network/ip2long_variation1.phpt7
-rw-r--r--ext/standard/tests/network/ip2long_variation2.phpt39
-rw-r--r--ext/standard/tests/network/ip2long_variation2_x64.phpt47
-rw-r--r--ext/standard/tests/network/setcookie.phpt70
-rw-r--r--ext/standard/tests/password/password_bcrypt_errors.phpt39
-rw-r--r--ext/standard/tests/password/password_get_info.phpt58
-rw-r--r--ext/standard/tests/password/password_get_info_error.phpt17
-rw-r--r--ext/standard/tests/password/password_hash.phpt25
-rw-r--r--ext/standard/tests/password/password_hash_error.phpt48
-rw-r--r--ext/standard/tests/password/password_needs_rehash.phpt45
-rw-r--r--ext/standard/tests/password/password_needs_rehash_error.phpt33
-rw-r--r--ext/standard/tests/password/password_verify.phpt21
-rw-r--r--ext/standard/tests/password/password_verify_error.phpt18
-rw-r--r--ext/standard/tests/php_ini_loaded_file.phpt4
-rw-r--r--ext/standard/tests/php_logo_guid.phpt13
-rw-r--r--ext/standard/tests/php_real_logo_guid.phpt12
-rw-r--r--ext/standard/tests/strings/bug61038.phpt26
-rw-r--r--ext/standard/tests/strings/bug63874.phpt16
-rw-r--r--ext/standard/tests/strings/implode1.phptbin5875 -> 5877 bytes
-rw-r--r--ext/standard/tests/strings/pack_A.phpt25
-rw-r--r--ext/standard/tests/strings/pack_Z.phpt50
-rw-r--r--ext/standard/tests/strings/parse_str_basic3.phptbin5141 -> 5140 bytes
-rw-r--r--ext/standard/tests/strings/unpack_error.phpt4
-rw-r--r--ext/standard/tests/strings/vprintf_variation15_64bit.phpt4
-rw-r--r--ext/standard/tests/strings/vsprintf_variation15_64bit.phpt2
-rw-r--r--ext/standard/tests/time/strptime_basic.phpt4
-rw-r--r--ext/standard/tests/zend_logo_guid.phpt12
-rw-r--r--ext/standard/type.c14
-rw-r--r--ext/standard/url_scanner_ex.c223
-rw-r--r--ext/standard/user_filters.c2
-rw-r--r--ext/standard/var.c4
-rw-r--r--ext/standard/var_unserializer.c2
-rw-r--r--ext/sybase_ct/config.m42
-rw-r--r--ext/sybase_ct/config.w327
-rw-r--r--ext/tidy/config.m42
-rw-r--r--ext/tokenizer/tests/bug60097.phpt121
-rw-r--r--ext/tokenizer/tests/token_get_all_variation11.phpt4
-rw-r--r--ext/tokenizer/tests/token_get_all_variation13.phpt2
-rw-r--r--ext/tokenizer/tests/token_get_all_variation17.phpt2
-rw-r--r--ext/tokenizer/tests/token_get_all_variation4.phpt4
-rw-r--r--ext/tokenizer/tests/token_get_all_variation5.phpt22
-rw-r--r--ext/tokenizer/tests/token_get_all_variation6.phpt4
-rw-r--r--ext/tokenizer/tests/token_get_all_variation8.phpt2
-rw-r--r--ext/tokenizer/tokenizer.c5
-rw-r--r--ext/tokenizer/tokenizer_data.c6
-rw-r--r--ext/wddx/config.m44
-rw-r--r--ext/wddx/wddx.c8
-rw-r--r--ext/xml/compat.c40
-rw-r--r--ext/xml/config.m44
-rw-r--r--ext/xml/expat_compat.h5
-rw-r--r--ext/xmlreader/config.m42
-rw-r--r--ext/xmlreader/php_xmlreader.c44
-rw-r--r--ext/xmlrpc/config.m48
-rw-r--r--ext/xmlrpc/xmlrpc-epi-php.c4
-rw-r--r--ext/xmlwriter/config.m42
-rw-r--r--ext/xsl/config.m42
-rw-r--r--ext/xsl/php_xsl.c2
-rw-r--r--ext/zip/config.m42
-rw-r--r--ext/zip/php_zip.c78
-rw-r--r--ext/zlib/config0.m42
-rw-r--r--ext/zlib/tests/001.phpt2
-rw-r--r--ext/zlib/tests/bug_52944-win.phpt24
-rw-r--r--ext/zlib/tests/bug_52944.phpt7
-rw-r--r--ext/zlib/tests/data.inc2
-rw-r--r--ext/zlib/zlib_filter.c12
-rw-r--r--main/fopen_wrappers.h2
-rw-r--r--main/logos.h1080
-rw-r--r--main/main.c36
-rw-r--r--main/network.c5
-rw-r--r--main/output.c2
-rw-r--r--main/php.h3
-rw-r--r--main/php_globals.h1
-rw-r--r--main/php_ini.c19
-rw-r--r--main/php_logos.c99
-rw-r--r--main/php_network.h2
-rw-r--r--main/php_open_temporary_file.c23
-rw-r--r--main/php_open_temporary_file.h2
-rw-r--r--main/php_streams.h4
-rw-r--r--main/php_variables.c17
-rw-r--r--main/php_version.h8
-rw-r--r--main/rfc1867.c8
-rw-r--r--main/streams/php_stream_context.h8
-rw-r--r--main/streams/plain_wrapper.c97
-rw-r--r--main/streams/streams.c69
-rw-r--r--main/streams/xp_socket.c2
-rw-r--r--main/win32_internal_function_disabled.h6
-rwxr-xr-xmakedist13
-rw-r--r--php.ini-development120
-rw-r--r--php.ini-production120
-rwxr-xr-xrun-tests.php31
-rw-r--r--sapi/apache/config.m46
-rw-r--r--sapi/apache2handler/config.m42
-rw-r--r--sapi/apache_hooks/config.m42
-rw-r--r--sapi/caudium/config.m42
-rw-r--r--sapi/cgi/cgi_main.c11
-rw-r--r--sapi/cli/config.m419
-rw-r--r--sapi/cli/config.w324
-rw-r--r--sapi/cli/php_cli.c18
-rw-r--r--sapi/cli/php_cli_process_title.c80
-rw-r--r--sapi/cli/php_cli_process_title.h (renamed from main/php_logos.h)31
-rw-r--r--sapi/cli/php_cli_server.c188
-rw-r--r--sapi/cli/php_cli_server.h1
-rw-r--r--sapi/cli/ps_title.c437
-rw-r--r--sapi/cli/ps_title.h42
-rw-r--r--sapi/cli/tests/bug64544.phpt20
-rw-r--r--sapi/cli/tests/cli_process_title_unix.phpt49
-rw-r--r--sapi/cli/tests/cli_process_title_windows.phpt83
-rw-r--r--sapi/cli/tests/php_cli_server_011.phpt41
-rw-r--r--sapi/cli/tests/php_cli_server_013.phpt6
-rw-r--r--sapi/cli/tests/php_cli_server_014.phpt2
-rw-r--r--sapi/cli/tests/php_cli_server_019.phpt68
-rw-r--r--sapi/embed/config.m42
-rw-r--r--sapi/fpm/config.m412
-rw-r--r--sapi/fpm/fpm/fastcgi.c2
-rw-r--r--sapi/fpm/fpm/fpm_sockets.h2
-rw-r--r--sapi/fpm/php-fpm.conf.in4
-rw-r--r--sapi/isapi/config.m42
-rw-r--r--sapi/litespeed/lsapi_main.c1297
-rw-r--r--sapi/litespeed/lsapilib.c47
-rw-r--r--sapi/litespeed/lsapilib.h5
-rw-r--r--sapi/milter/config.m42
-rw-r--r--sapi/pi3web/config.m42
-rw-r--r--sapi/roxen/config.m42
-rwxr-xr-xserver-tests.php111
-rw-r--r--tests/basic/php_egg_logo_guid.phpt13
-rw-r--r--tests/basic/php_logo_guid.phpt10
-rw-r--r--tests/basic/php_real_logo_guid.phpt12
-rw-r--r--tests/basic/req60524-win.phpt13
-rw-r--r--tests/basic/req60524.phpt14
-rw-r--r--tests/basic/zend_logo_guid.phpt13
-rw-r--r--tests/classes/bug65768.phpt36
-rw-r--r--tests/classes/implicit_instantiation_001.phpt16
-rw-r--r--tests/func/011.phpt10
-rw-r--r--tests/func/bug64523.phpt10
-rw-r--r--tests/lang/bug24403.phpt3
-rw-r--r--tests/lang/foreachLoop.007.phpt11
-rw-r--r--tests/lang/foreachLoop.008.phpt10
-rw-r--r--tests/output/ob_017.phpt2
-rw-r--r--tests/output/ob_start_basic_004.phpt2
-rw-r--r--tests/strings/001.phpt19
-rwxr-xr-xtravis/compile.sh38
-rwxr-xr-xtravis/ext/curl/setup.sh5
-rwxr-xr-xtravis/ext/mysql/setup.sh2
-rwxr-xr-xtravis/ext/mysqli/setup.sh2
-rwxr-xr-xtravis/ext/pdo_mysql/setup.sh2
-rwxr-xr-xtravis/ext/pdo_pgsql/setup.sh2
-rwxr-xr-xtravis/ext/pgsql/setup.sh4
-rw-r--r--win32/build/Makefile4
-rw-r--r--win32/build/config.w3215
-rw-r--r--win32/build/config.w32.h.in4
-rw-r--r--win32/build/config.w32.phpize.in2
-rw-r--r--win32/build/confutils.js2
-rw-r--r--win32/build/libs_version.txt18
-rw-r--r--win32/build/mkdist.php4
-rw-r--r--win32/inet.c77
-rw-r--r--win32/inet.h10
-rw-r--r--win32/install.txt21
-rw-r--r--win32/php5dll.dsp8
-rw-r--r--win32/php5dllts.dsp8
-rw-r--r--win32/pws-php5cgi.reg6
-rw-r--r--win32/pws-php5isapi.reg5
-rw-r--r--win32/select.c6
-rw-r--r--win32/sendmail.c1
-rw-r--r--win32/syslog.reg2
1541 files changed, 98394 insertions, 33267 deletions
diff --git a/.gitattributes b/.gitattributes
index 9ed6e5f4b9..79b218fcba 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -23,6 +23,8 @@ sapi/continuity/capi.c ident
Zend/RFCs/002.txt ident
Zend/RFCs/003.txt ident
NEWS merge=NEWS
+UPGRADING merge=NEWS
+UPGRADING.INTERNALS merge=NEWS
/ext/bz2/tests/with_strings.phpt -crlf
/ext/dom/tests/bug40836.phpt -crlf
/ext/dom/tests/domelement.phpt -crlf
diff --git a/.gitignore b/.gitignore
index 6f291dc917..cf615c6e92 100644
--- a/.gitignore
+++ b/.gitignore
@@ -96,6 +96,8 @@ stamp-h.in
scan_makefile_in.awk
TSRM/tsrm_config.h
Zend/zend_config.h
+Zend/zend_dtrace_gen.h
+Zend/zend_dtrace_gen.hbak
Zend/zend_ini_parser.c
Zend/zend_ini_parser.h
Zend/zend_ini_parser.output
diff --git a/.travis.yml b/.travis.yml
index f1a333adcb..07653040dd 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,9 +1,32 @@
language: php
-branches:
- except:
- - /^PHP-5\.3.*/
- - /^PHP-5\.4.*/
+php:
+ # We only specify one version so we only get one worker
+ - 5.4
notifications:
email: false
+
+env:
+ global:
+ - MYSQL_TEST_HOST=127.0.0.1
+ - MYSQL_TEST_USER=travis
+ - PDO_MYSQL_TEST_DSN="mysql:host=127.0.0.1;dbname=test"
+ - PDO_MYSQL_TEST_USER=travis
+ - PDO_MYSQL_TEST_PASS=
+ - PDO_MYSQL_TEST_HOST=127.0.0.1
+ matrix:
+ - REPORT_EXIT_STATUS=1
+
+before_script:
+ # Compile PHP
+ - ./travis/compile.sh
+ # Setup Extensions
+ - . ./travis/ext/mysql/setup.sh
+ - . ./travis/ext/mysqli/setup.sh
+ - . ./travis/ext/pdo_mysql/setup.sh
+ - . ./travis/ext/pgsql/setup.sh
+ - . ./travis/ext/pdo_pgsql/setup.sh
+
+# Run PHPs run-tests.php
+script: ./sapi/cli/php run-tests.php -p `pwd`/sapi/cli/php -g "FAIL,XFAIL,BORK,WARN,LEAK,SKIP" --show-diff --set-timeout 120
diff --git a/EXTENSIONS b/EXTENSIONS
index 5308582023..61a1688b3c 100644
--- a/EXTENSIONS
+++ b/EXTENSIONS
@@ -147,7 +147,7 @@ STATUS: Working
COMMENT: Tested on phpts and isapi versions
-------------------------------------------------------------------------------
EXTENSION: mysql
-PRIMARY MAINTAINER: Zak Greant <zak@mysql.com>, Georg Richter <georg@php.net>, Johannes Schlter <johannes@php.net>, Ulf Wendel <uw@php.net>
+PRIMARY MAINTAINER: Zak Greant <zak@mysql.com>, Georg Richter <georg@php.net>, Andrey Hristov <andrey@php.net>, Johannes Schlter <johannes@php.net>, Ulf Wendel <uw@php.net>
MAINTENANCE: Maintained
STATUS: Working
-------------------------------------------------------------------------------
@@ -158,7 +158,7 @@ STATUS: Working
SINCE: 5.0
-------------------------------------------------------------------------------
EXTENSION: mysqlnd
-PRIMARY MAINTAINER: Georg Richter <georg@php.net>, Andrey Hristov <andrey@php.net>, Johannes Schlter <johannes@php.net>, Ulf Wendel <uw@php.net>
+PRIMARY MAINTAINER: Andrey Hristov <andrey@php.net>, Johannes Schlter <johannes@php.net>, Ulf Wendel <uw@php.net>
MAINTENANCE: Maintained
STATUS: Working
SINCE: 5.3
diff --git a/INSTALL b/INSTALL
index c0cbe5f2c1..141e4f8312 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1819,7 +1819,7 @@ Installation
set of HTTP headers. The headers it did return are:
10. Windows: I've followed all the instructions, but still can't get
PHP and IIS to work together!
- 11. When running PHP as CGI with IIS, PWS, OmniHTTPD or Xitami, I get
+ 11. When running PHP as CGI with IIS, OmniHTTPD or Xitami, I get
the following error: Security Alert! PHP CGI cannot be accessed
directly..
12. How do I know if my php.ini is being found and read? It seems like
@@ -2007,7 +2007,7 @@ cgi error:
And for IIS4 you need to tell it that PHP is a script engine.
Also, you will want to read this faq.
- When running PHP as CGI with IIS, PWS, OmniHTTPD or Xitami, I get the
+ When running PHP as CGI with IIS, OmniHTTPD or Xitami, I get the
following error: Security Alert! PHP CGI cannot be accessed
directly..
You must set the cgi.force_redirect directive to 0. It defaults
diff --git a/LICENSE b/LICENSE
index 3cc8b777b7..42536af320 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
--------------------------------------------------------------------
The PHP License, version 3.01
-Copyright (c) 1999 - 2010 The PHP Group. All rights reserved.
+Copyright (c) 1999 - 2012 The PHP Group. All rights reserved.
--------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
diff --git a/Makefile.frag b/Makefile.frag
index c8b3cb2d80..12646c20ad 100644
--- a/Makefile.frag
+++ b/Makefile.frag
@@ -7,7 +7,7 @@ $(builddir)/zend_language_scanner.lo: $(srcdir)/zend_language_parser.h
$(builddir)/zend_ini_scanner.lo: $(srcdir)/zend_ini_parser.h
$(srcdir)/zend_language_scanner.c: $(srcdir)/zend_language_scanner.l
- @(cd $(top_srcdir); $(RE2C) $(RE2C_FLAGS) --case-inverted -cbdFt Zend/zend_language_scanner_defs.h -oZend/zend_language_scanner.c Zend/zend_language_scanner.l)
+ @(cd $(top_srcdir); $(RE2C) $(RE2C_FLAGS) --no-generation-date --case-inverted -cbdFt Zend/zend_language_scanner_defs.h -oZend/zend_language_scanner.c Zend/zend_language_scanner.l)
$(srcdir)/zend_language_parser.h: $(srcdir)/zend_language_parser.c
$(srcdir)/zend_language_parser.c: $(srcdir)/zend_language_parser.y
@@ -18,6 +18,6 @@ $(srcdir)/zend_ini_parser.c: $(srcdir)/zend_ini_parser.y
@$(YACC) -p ini_ -v -d $(srcdir)/zend_ini_parser.y -o $@
$(srcdir)/zend_ini_scanner.c: $(srcdir)/zend_ini_scanner.l
- @(cd $(top_srcdir); $(RE2C) $(RE2C_FLAGS) --case-inverted -cbdFt Zend/zend_ini_scanner_defs.h -oZend/zend_ini_scanner.c Zend/zend_ini_scanner.l)
+ @(cd $(top_srcdir); $(RE2C) $(RE2C_FLAGS) --no-generation-date --case-inverted -cbdFt Zend/zend_ini_scanner_defs.h -oZend/zend_ini_scanner.c Zend/zend_ini_scanner.l)
$(builddir)/zend_indent.lo $(builddir)/zend_highlight.lo $(builddir)/zend_compile.lo: $(srcdir)/zend_language_parser.h
diff --git a/Makefile.gcov b/Makefile.gcov
index 946f539d10..37c1b4b44c 100644
--- a/Makefile.gcov
+++ b/Makefile.gcov
@@ -3,6 +3,8 @@
# LCOV
#
+LCOV_INCLUDE="."
+
lcov: lcov-html
lcov-test: lcov-clean-data test
@@ -12,7 +14,7 @@ php_lcov.info: lcov-test
@rm -rf lcov_data/
@$(mkinstalldirs) lcov_data/
@echo
- -@files=`find . -name \*.gcda -o -name \*.gcno -o -name \*.da -o -name \*.h | sed -e 's/^\.\///' | sed -e 's/\.gcda//g' -e 's/\.gcno//g' -e 's/\.da//g' | uniq` ;\
+ -@files=`find . -name \*.gcda -o -name \*.gcno -o -name \*.da -o -name \*.c -o -name \*.h | sed -e 's/^\.\///' | sed -e 's/\.gcda//g' -e 's/\.gcno//g' -e 's/\.da//g' | $(EGREP) $(LCOV_INCLUDE) | uniq` ;\
for x in $$files; do \
echo -n . ;\
y=`echo $$x | sed -e 's!\.libs/!!'`; \
@@ -39,14 +41,26 @@ php_lcov.info: lcov-test
if test -f "$(top_builddir)/$$y.c"; then \
ln -f -s $(top_builddir)/$$y.c lcov_data/$$y.c; \
fi; \
- test -f "$$x.gcno" && cp $$x.gcno lcov_data/$$y.gcno ; \
- test -f "$$x.gcda" && cp $$x.gcda lcov_data/$$y.gcda ; \
- test -f "$$x.da" && cp $$x.da lcov_data/$$y.da ; \
- test -f "$$x.bb" && cp $$x.bb lcov_data/$$y.bb ; \
- test -f "$$x.bbg" && cp $$x.bbg lcov_data/$$y.bbg ; \
- done
+ if test -f "$$x.gcno"; then \
+ cp $$x.gcno lcov_data/$$y.gcno ; \
+ fi; \
+ if test -f "$$x.gcda"; then \
+ cp $$x.gcda lcov_data/$$y.gcda ; \
+ fi; \
+ if test -f "$$x.da"; then \
+ cp $$x.da lcov_data/$$y.da ; \
+ fi; \
+ if test -f "$$x.bb"; then \
+ cp $$x.bb lcov_data/$$y.bb ; \
+ fi; \
+ if test -f "$$x.bbg"; then \
+ cp $$x.bbg lcov_data/$$y.bbg ; \
+ fi; \
+ done; \
for dir in ext/bcmath/libbcmath ext/fileinfo/libmagic ext/gd/libgd ext/mbstring/libmbfl ext/mbstring/oniguruma ext/pcre/pcrelib ext/pdo_sqlite/libsqlite ext/sqlite/libsqlite ext/sqlite3/libsqlite ext/xmlrpc/libxmlrpc ext/zip/lib; do \
- test -d lcov_data/$$dir && rm -rf lcov_data/$$dir ; \
+ if test -d lcov_data/$$dir; then \
+ rm -rf lcov_data/$$dir ; \
+ fi; \
done
@echo
@echo "Generating $@"
diff --git a/Makefile.global b/Makefile.global
index 6b79ad7aa4..05c5d151b7 100644
--- a/Makefile.global
+++ b/Makefile.global
@@ -86,7 +86,7 @@ PHP_TEST_SHARED_EXTENSIONS = ` \
PHP_DEPRECATED_DIRECTIVES_REGEX = '^(magic_quotes_(gpc|runtime|sybase)?|(zend_)?extension(_debug)?(_ts)?)[\t\ ]*='
test: all
- -@if test ! -z "$(PHP_EXECUTABLE)" && test -x "$(PHP_EXECUTABLE)"; then \
+ @if test ! -z "$(PHP_EXECUTABLE)" && test -x "$(PHP_EXECUTABLE)"; then \
INI_FILE=`$(PHP_EXECUTABLE) -d 'display_errors=stderr' -r 'echo php_ini_loaded_file();' 2> /dev/null`; \
if test "$$INI_FILE"; then \
$(EGREP) -h -v $(PHP_DEPRECATED_DIRECTIVES_REGEX) "$$INI_FILE" > $(top_builddir)/tmp-php.ini; \
@@ -102,7 +102,9 @@ test: all
TEST_PHP_SRCDIR=$(top_srcdir) \
CC="$(CC)" \
$(PHP_EXECUTABLE) -n -c $(top_builddir)/tmp-php.ini $(PHP_TEST_SETTINGS) $(top_srcdir)/run-tests.php -n -c $(top_builddir)/tmp-php.ini -d extension_dir=$(top_builddir)/modules/ $(PHP_TEST_SHARED_EXTENSIONS) $(TESTS); \
+ TEST_RESULT_EXIT_CODE=$$?; \
rm $(top_builddir)/tmp-php.ini; \
+ exit $$TEST_RESULT_EXIT_CODE; \
else \
echo "ERROR: Cannot run tests without CLI sapi."; \
fi
@@ -113,10 +115,19 @@ clean:
find . -name \*.la -o -name \*.a | xargs rm -f
find . -name \*.so | xargs rm -f
find . -name .libs -a -type d|xargs rm -rf
- rm -f libphp$(PHP_MAJOR_VERSION).la $(SAPI_CLI_PATH) $(OVERALL_TARGET) modules/* libs/*
+ rm -f libphp$(PHP_MAJOR_VERSION).la $(SAPI_CLI_PATH) $(SAPI_CGI_PATH) $(SAPI_MILTER_PATH) $(SAPI_LITESPEED_PATH) $(SAPI_FPM_PATH) $(OVERALL_TARGET) modules/* libs/*
distclean: clean
- 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 Zend/zend_dtrace_gen.h Zend/zend_dtrace_gen.h.bak
+ rm -f Makefile config.cache config.log config.status Makefile.objects Makefile.fragments libtool main/php_config.h main/internal_functions_cli.c main/internal_functions.c stamp-h sapi/apache/libphp$(PHP_MAJOR_VERSION).module sapi/apache_hooks/libphp$(PHP_MAJOR_VERSION).module buildmk.stamp Zend/zend_dtrace_gen.h Zend/zend_dtrace_gen.h.bak Zend/zend_config.h TSRM/tsrm_config.h
+ rm -f php5.spec main/build-defs.h scripts/phpize
+ rm -f ext/date/lib/timelib_config.h ext/mbstring/oniguruma/config.h ext/mbstring/libmbfl/config.h ext/mysqlnd/php_mysqlnd_config.h
+ rm -f scripts/man1/phpize.1 scripts/php-config scripts/man1/php-config.1 sapi/cli/php.1 sapi/cgi/php-cgi.1 ext/phar/phar.1 ext/phar/phar.phar.1
+ rm -f sapi/fpm/php-fpm.conf sapi/fpm/init.d.php-fpm sapi/fpm/php-fpm.service sapi/fpm/php-fpm.8 sapi/fpm/status.html
+ rm -f ext/iconv/php_have_bsd_iconv.h ext/iconv/php_have_glibc_iconv.h ext/iconv/php_have_ibm_iconv.h ext/iconv/php_have_iconv.h ext/iconv/php_have_libiconv.h ext/iconv/php_iconv_aliased_libiconv.h ext/iconv/php_iconv_supports_errno.h ext/iconv/php_php_iconv_h_path.h ext/iconv/php_php_iconv_impl.h
+ rm -f ext/phar/phar.phar ext/phar/phar.php
+ if test "$(srcdir)" != "$(builddir)"; then \
+ rm -f ext/phar/phar/phar.inc; \
+ fi
$(EGREP) define'.*include/php' $(top_srcdir)/configure | $(SED) 's/.*>//'|xargs rm -f
.PHONY: all clean install distclean test
diff --git a/NEWS b/NEWS
index 00a0a940ad..ce2d100799 100644
--- a/NEWS
+++ b/NEWS
@@ -1,28 +1,56 @@
PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
-?? ??? 2013, PHP 5.4.25
+?? ??? 2014, PHP 5.5.9
- Core:
- . Fixed bug #66286 (Incorrect object comparison with inheritance). (Nikita)
. Fixed bug #66509 (copy() arginfo has changed starting from 5.4). (willfitch)
-- Session:
- . Fixed bug #66481 (Calls to session_name() segfault when session.name is
- null). (Laruence)
+- GD:
+ . Fixed bug #66356 (Heap Overflow Vulnerability in imagecrop()).
+ (Laruence, Remi)
+
+- OPCache:
+ . Fixed bug #66474 (Optimizer bug in constant string to boolean conversion).
+ (Dmitry)
+ . Fixed bug #66461 (PHP crashes if opcache.interned_strings_buffer=0).
+ (Dmitry)
+ . Fixed bug #66298 (ext/opcache/Optimizer/zend_optimizer.c has dos-style
+ ^M as lineend). (Laruence)
+
+- Session
+ . Fixed bug #66469 (Session module is sending multiple set-cookie headers when
+ session.use_strict_mode=1) (Yasuo)
+ . Fixed bug #66481 (Segfaults on session_name()).
+ (cmcdermottroe at engineyard dot com, Yasuo)
+
+- Standard
+ . Fixed bug #66395 (basename function doesn't remove drive letter). (Anatol)
+
+- Sockets:
+ . Fixed bug #66381 (__ss_family was changed on AIX 5.3). (Felipe)
+
+- Zend Engine
+ . Fixed bug #66009 (Failed compilation of PHP extension with C++ std
+ library using VS 2012). (Anatol)
-?? ??? 2013, PHP 5.4.24
+09 Jan 2014, PHP 5.5.8
- Core:
+ . Disallowed JMP into a finally block. (Laruence)
. Added validation of class names in the autoload process. (Dmitry)
. Fixed invalid C code in zend_strtod.c. (Lior Kaplan)
+ . Fixed ZEND_MM_MEM_TYPE=mmap_zero. (Dmitry, Tony)
+ . Fixed bug #66041 (list() fails to unpack yielded ArrayAccess object).
+ (Nikita)
+ . Fixed bug #65764 (generators/throw_rethrow FAIL with
+ ZEND_COMPILE_EXTENDED_INFO). (Nikita)
. Fixed bug #61645 (fopen and O_NONBLOCK). (Mike)
+ . Fixed bug #66218 (zend_register_functions breaks reflection). (Remi)
- Date:
. Fixed bug #66060 (Heap buffer over-read in DateInterval). (Remi)
- . Fixed bug #63391 (Incorrect/inconsistent day of week prior to the year
- 1600). (Derick, T. Carter)
- . Fixed bug #61599 (Wrong Day of Week). (Derick, T. Carter)
-
+ . Fixed bug #65768 (DateTimeImmutable::diff does not work). (Nikita Nefedov)
+
- DOM:
. Fixed bug #65196 (Passing DOMDocumentFragment to DOMDocument::saveHTML()
Produces invalid Markup). (Mike)
@@ -41,9 +69,25 @@ PHP NEWS
. Fixed bug #66311 (Stack smashing protection kills PDO/ODBC queries).
(michael at orlitzky dot com)
+- MySQLi:
+ . Fixed bug #65486 (mysqli_poll() is broken on win x64). (Anatol)
+
+- OPCache:
+ . Fixed revalidate_path=1 behavior to avoid caching of symlinks values.
+ (Dmitry)
+ . Fixed Issue #140: "opcache.enable_file_override" doesn't respect
+ "opcache.revalidate_freq". (Dmitry).
+
- SNMP:
. Fixed SNMP_ERR_TOOBIG handling for bulk walk operations. (Boris Lytochkin)
+- SOAP
+ . Fixed bug #66112 (Use after free condition in SOAP extension).
+ (martin dot koegler at brz dot gv dot at)
+
+- Sockets:
+ . Fixed bug #65923 (ext/socket assumes AI_V4MAPPED is defined). (Felipe)
+
- XSL
. Fixed bug #49634 (Segfault throwing an exception in a XSL registered
function). (Mike)
@@ -51,85 +95,97 @@ PHP NEWS
- ZIP:
. Fixed Bug #66321 (ZipArchive::open() ze_obj->filename_len not real). (Remi)
-12 Dec 2013, PHP 5.4.23
+12 Dec 2013, PHP 5.5.7
+
+- CLI server:
+ . Added some MIME types to the CLI web server (Chris Jones)
+ . Implemented FR #65917 (getallheaders() is not supported by the built-in web
+ server) - also implements apache_response_headers() (Andrea Faulds)
- Core:
. Fixed bug #66094 (unregister_tick_function tries to cast a Closure to a
string). (Laruence)
. Fixed bug #65969 (Chain assignment with T_LIST failure). (Dmitry)
- . Fixed bug #65947 (basename is no more working after fgetcsv in certain
- situation). (Laruence)
-
-- JSON
- . Fixed whitespace part of bug #64874 ("json_decode handles whitespace and
- case-sensitivity incorrectly"). (Andrea Faulds)
-- MySQLi:
- . Fixed bug #66043 (Segfault calling bind_param() on mysqli). (Laruence)
+- OPCache
+ . Fixed bug #66176 (Invalid constant substitution). (Dmitry)
+ . Fixed bug #65915 (Inconsistent results with require return value). (Dmitry)
+ . Fixed bug #65559 (Opcache: cache not cleared if changes occur while
+ running). (Dmitry)
-- mysqlnd:
- . Fixed bug #66124 (mysqli under mysqlnd loses precision when bind_param
- with 'i'). (Andrey)
- . Fixed bug #66141 (mysqlnd quote function is wrong with NO_BACKSLASH_ESCAPES
- after failed query). (Andrey)
+- readline
+ . Fixed Bug #65714 (PHP cli forces the tty to cooked mode). (Remi)
- Openssl:
. Fixed memory corruption in openssl_x509_parse() (CVE-2013-6420).
(Stefan Esser).
-- PDO
- . Fixed bug 65946 (sql_parser permanently converts values bound to strings)
-
-14 Nov 2013, PHP 5.4.22
+14 Nov 2013, PHP 5.5.6
- Core:
+ . Fixed bug #65947 (basename is no more working after fgetcsv in certain
+ situation). (Laruence)
+ . Improved performance of array_merge() and func_get_args() by eliminating
+ useless copying. (Dmitry)
+ . Fixed bug #65939 (Space before ";" breaks php.ini parsing).
+ (brainstorm at nopcode dot org)
. Fixed bug #65911 (scope resolution operator - strange behavior with $this).
(Bob Weinand)
+ . Fixed bug #65936 (dangling context pointer causes crash). (Tony)
-- CLI server:
- . Fixed bug #65818 (Segfault with built-in webserver and chunked transfer
- encoding). (Felipe)
+- FPM:
+ . Changed default listen() backlog to 65535. (Tony)
-- Exif:
- . Fixed crash on unknown encoding. (Draal)
+- JSON
+ . Fixed whitespace part of bug #64874 ("json_decode handles whitespace and
+ case-sensitivity incorrectly"). (Andrea Faulds)
-- FTP:
- . Fixed bug #65667 (ftp_nb_continue produces segfault). (Philip Hofstetter)
+- MySQLi:
+ . Fixed bug #66043 (Segfault calling bind_param() on mysqli). (Laruence)
+
+- OPcache
+ . Increased limit for opcache.max_accelerated_files to 1,000,000. (Chris)
+ . Fixed issue #115 (path issue when using phar). (Dmitry)
+ . Fixed issue #149 (Phar mount points not working with OPcache enabled).
+ (Dmitry)
-- ODBC:
- . Fixed bug #65950 (Field name truncation if the field name is bigger than
+- ODBC
+ . Fixed bug #65950 (Field name truncation if the field name is bigger than
32 characters). (patch submitted by: michael dot y at zend dot com, Yasuo)
- PDO:
. Fixed bug #66033 (Segmentation Fault when constructor of PDO statement
throws an exception). (Laruence)
-
-- Sockets:
- . Fixed bug #65808 (the socket_connect() won't work with IPv6 address).
- (Mike)
+ . Fixed bug 65946 (sql_parser permanently converts values bound to strings)
- Standard:
. Fixed bug #64760 (var_export() does not use full precision for floating-point
numbers) (Yasuo)
- . Fixed bug #66395 (basename function doesn't remove drive letter). (Anatol)
-- XMLReader:
- . Fixed bug #51936 (Crash with clone XMLReader). (Mike)
- . Fixed bug #64230 (XMLReader does not suppress errors). (Mike)
-
-17 Oct 2013, PHP 5.4.21
+17 Oct 2013, PHP 5.5.5
- Core:
+ . Fixed bug #64979 (Wrong behavior of static variables in closure generators).
+ (Nikita)
. Fixed bug #65322 (compile time errors won't trigger auto loading). (Nikita)
+ . Fixed bug #65821 (By-ref foreach on property access of string offset
+ segfaults). (Nikita)
- CLI server:
. Fixed bug #65633 (built-in server treat some http headers as
case-sensitive). (Adam)
+ . Fixed bug #65818 (Segfault with built-in webserver and chunked transfer
+ encoding). (Felipe)
+ . Added application/pdf to PHP CLI Web Server mime types (Chris Jones)
- Datetime:
. Fixed bug #64157 (DateTime::createFromFormat() reports confusing error
message). (Boro Sitnikovski)
+ . Fixed bug #65502 (DateTimeImmutable::createFromFormat returns DateTime).
+ (Boro Sitnikovski)
+ . Fixed bug #65548 (Comparison for DateTimeImmutable doesn't work).
+ (Boro Sitnikovski)
- DBA extension:
. Fixed bug #65708 (dba functions cast $key param to string in-place,
@@ -140,263 +196,693 @@ PHP NEWS
. Fixed bug #64441 (FILTER_VALIDATE_URL rejects fully qualified domain names).
(Syra)
+- FTP:
+ . Fixed bug #65667 (ftp_nb_continue produces segfault). (Philip Hofstetter)
+
+- GD
+ . Ensure that the defined interpolation method is used with the generic
+ scaling methods. (Pierre)
+
- IMAP:
. Fixed bug #65721 (configure script broken in 5.5.4 and 5.4.20 when enabling
imap). (ryotakatsuki at gmail dot com)
+- OPcache:
+ . Added support for GNU Hurd. (Svante Signell)
+ . Added function opcache_compile_file() to load PHP scripts into cache
+ without execution. (Julien)
+ . Fixed bug #65845 (Error when Zend Opcache Optimizer is fully enabled).
+ (Dmitry)
+ . Fixed bug #65665 (Exception not properly caught when opcache enabled).
+ (Laruence)
+ . Fixed bug #65510 (5.5.2 crashes in _get_zval_ptr_ptr_var). (Dmitry)
+ . Fixed issue #135 (segfault in interned strings if initial memory is too
+ low). (Julien)
+
+- Sockets:
+ . Fixed bug #65808 (the socket_connect() won't work with IPv6 address).
+ (Mike)
+
+- SPL:
+ . Fix bug #64782 (SplFileObject constructor make $context optional / give it
+ a default value). (Nikita)
+
- Standard:
. Fixed bug #61548 (content-type must appear at the end of headers for 201
Location to work in http). (Mike)
+- XMLReader:
+ . Fixed bug #51936 (Crash with clone XMLReader). (Mike)
+ . Fixed bug #64230 (XMLReader does not suppress errors). (Mike)
+
- Build system:
+ . Fixed bug #51076 (race condition in shtool's mkdir -p implementation).
+ (Mike, Raphael Geissert)
. Fixed bug #62396 ('make test' crashes starting with 5.3.14 (missing
gzencode())). (Mike)
-19 Sep 2013, PHP 5.4.20
+19 Sep 2013, PHP 5.5.4
- Core:
. Fixed bug #60598 (cli/apache sapi segfault on objects manipulation).
(Laruence)
- . Fixed bug #65579 (Using traits with get_class_methods causes segfault).
- (Adam)
+ . Improved fputcsv() to allow specifying escape character.
. Fixed bug #65490 (Duplicate calls to get lineno & filename for
DTRACE_FUNCTION_*). (Chris Jones)
. Fixed bug #65483 (quoted-printable encode stream filter incorrectly encoding
spaces). (Michael M Slusarz)
. Fixed bug #65481 (shutdown segfault due to serialize) (Mike)
- . Fixed bug #65470 (Segmentation fault in zend_error() with
+ . Fixed bug #65470 (Segmentation fault in zend_error() with
--enable-dtrace). (Chris Jones, Kris Van Hees)
- . Fixed bug #65372 (Segfault in gc_zval_possible_root when return reference
- fails). (Laruence)
- . Fixed bug #65304 (Use of max int in array_sum). (Laruence)
- . Fixed bug #65291 (get_defined_constants() causes PHP to crash in a very
- limited case). (Arpad)
. Fixed bug #65225 (PHP_BINARY incorrectly set). (Patrick Allaert)
- . Improved fix for bug #63186 (compile failure on netbsd). (Matteo)
. Fixed bug #62692 (PHP fails to build with DTrace). (Chris Jones, Kris Van Hees)
. Fixed bug #61759 (class_alias() should accept classes with leading
backslashes). (Julien)
- . Fixed bug #61345 (CGI mode - make install don't work). (Michael Heimpold)
- . Cherry-picked some DTrace build commits (allowing builds on Linux,
- bug #62691, and bug #63706) from PHP 5.5 branch
- . Fixed bug #61268 (--enable-dtrace leads make to clobber
- Zend/zend_dtrace.d) (Chris Jones)
+ . Fixed bug #46311 (Pointer aliasing issue results in miscompile on gcc4.4).
+ (Nikita Popov)
- cURL:
. Fixed bug #65458 (curl memory leak). (Adam)
- Datetime:
- . Fixed bug #65554 (createFromFormat broken when weekday name is followed
+ . Fixed bug #65554 (createFromFormat broken when weekday name is followed
by some delimiters). (Valentin Logvinskiy, Stas).
. Fixed bug #65564 (stack-buffer-overflow in DateTimeZone stuff caught
by AddressSanitizer). (Remi).
+- OPCache:
+ . Fixed bug #65561 (Zend Opcache on Solaris 11 x86 needs ZEND_MM_ALIGNMENT=4).
+ (Terry Ellison)
+
- Openssl:
- . Fixed bug #64802 (openssl_x509_parse fails to parse subject properly in
+ . Fixed bug #64802 (openssl_x509_parse fails to parse subject properly in
some cases). (Mark Jones)
-- Session:
- . Fixed bug #62129 (rfc1867 crashes php even though turned off). (gxd305 at
- gmail dot com)
- . Fixed bug #50308 (session id not appended properly for empty anchor tags).
- (Arpad)
- . Fixed possible buffer overflow under Windows. Note: Not a security fix.
- (Yasuo)
- . Changed session.auto_start to PHP_INI_PERDIR. (Yasuo)
-
-- SOAP:
- . Fixed bug #65018 (SoapHeader problems with SoapServer). (Dmitry)
-
-- SPL:
- . Fixed bug #65328 (Segfault when getting SplStack object Value). (Laruence)
-
- PDO:
. Fixed bug #64953 (Postgres prepared statement positional parameter
casting). (Mike)
-- Phar:
- . Fixed bug #65028 (Phar::buildFromDirectory creates corrupt archives for
- some specific contents). (Stas)
+- Session:
+ . Fixed bug #65475 (Session ID is not initialized properly when strict session
+ is enabled). (Yasuo)
+ . Fixed bug #51127/#65359 Request #25630/#43980/#54383 (Added php_serialize
+ session serialize handler that uses plain serialize()). (Yasuo)
-- Pgsql:
- . Fixed bug #65336 (pg_escape_literal/identifier() silently returns false).
- (Yasuo)
- . Fixed bug #62978 (Disallow possible SQL injections with pg_select()/pg_update()
- /pg_delete()/pg_insert()). (Yasuo)
+- Standard:
+ . Fix issue with return types of password API helper functions. Found via
+ static analysis by cjones. (Anthony Ferrara)
- Zlib:
. Fixed bug #65391 (Unable to send vary header user-agent when
ob_start('ob_gzhandler') is called) (Mike)
-22 Aug 2013, PHP 5.4.19
-
-- Core:
- . Fixed bug #64503 (Compilation fails with error: conflicting types for
- 'zendparse'). (Laruence)
+22 Aug 2013, PHP 5.5.3
- Openssl:
. Fixed UMR in fix for CVE-2013-4248.
-15 Aug 2013, PHP 5.4.18
+15 Aug 2013, PHP 5.5.2
- Core:
+ . Fixed bug #65372 (Segfault in gc_zval_possible_root when return reference
+ fails). (Laruence)
. Fixed value of FILTER_SANITIZE_FULL_SPECIAL_CHARS constant (previously was
- erroneously set to FILTER_SANITIZE_SPECIAL_CHARS value). (Andrey
+ erroneously set to FILTER_SANITIZE_SPECIAL_CHARS value). (Andrey
avp200681 gmail com).
+ . Fixed bug #65304 (Use of max int in array_sum). (Laruence)
+ . Fixed bug #65291 (get_defined_constants() causes PHP to crash in a very
+ limited case). (Arpad)
+ . Fixed bug #62691 (solaris sed has no -i switch). (Chris Jones)
+ . Fixed bug #61345 (CGI mode - make install don't work). (Michael Heimpold)
+ . Fixed bug #61268 (--enable-dtrace leads make to clobber
+ Zend/zend_dtrace.d) (Chris Jones)
+
+- DOM:
+ . Added flags option to DOMDocument::schemaValidate() and
+ DOMDocument::schemaValidateSource(). Added LIBXML_SCHEMA_CREATE flag.
+ (Chris Wright)
+
+- OPcache:
+ . Added opcache.restrict_api configuration directive that may limit
+ usage of OPcache API functions only to particular script(s). (Dmitry)
+ . Added support for glob symbols in blacklist entries (?, *, **).
+ (Terry Elison, Dmitry)
+ . Fixed bug #65338 (Enabling both php_opcache and php_wincache AVs on
+ shutdown). (Dmitry)
+
+- Openssl:
+ . Fixed handling null bytes in subjectAltName (CVE-2013-4248).
+ (Christian Heimes)
+
+- PDO_mysql:
+ . Fixed bug #65299 (pdo mysql parsing errors). (Johannes)
+
+- Pgsql:
+ . Fixed bug #62978 (Disallow possible SQL injections with pg_select()/pg_update()
+ /pg_delete()/pg_insert()). (Yasuo)
+
+- Phar:
+ . Fixed bug #65028 (Phar::buildFromDirectory creates corrupt archives for
+ some specific contents). (Stas)
+
+- Sessions:
+ . Implemented strict sessions RFC (https://wiki.php.net/rfc/strict_sessions)
+ which protects against session fixation attacks and session collisions.
+ (CVE-2011-4718). (Yasuo Ohgaki)
+ . Fixed possible buffer overflow under Windows. Note: Not a security fix.
+ (Yasuo)
+ . Changed session.auto_start to PHP_INI_PERDIR. (Yasuo)
+
+- SOAP:
+ . Fixed bug #65018 (SoapHeader problems with SoapServer). (Dmitry)
+
+- SPL:
+ . Fixed bug #65328 (Segfault when getting SplStack object Value). (Laruence)
+ . Added RecursiveTreeIterator setPostfix and getPostifx methods. (Joshua
+ Thijssen)
+ . Fixed bug #61697 (spl_autoload_functions returns lambda functions
+ incorrectly). (Laruence)
+
+- Streams:
+ . Fixed bug #65268 (select() implementation uses outdated tick API). (Anatol)
+
+- Pgsql:
+ . Fixed bug #65336 (pg_escape_literal/identifier() scilently returns false).
+ (Yasuo)
+
+18 Jul 2013, PHP 5.5.1
+
+- Core:
. Fixed bug #65254 (Exception not catchable when exception thrown in autoload
with a namespace). (Laruence)
- . Fixed bug #65108 (is_callable() triggers Fatal Error).
- (David Soria Parra, Laruence)
. Fixed bug #65088 (Generated configure script is malformed on OpenBSD).
(Adam)
- . Fixed bug #62964 (Possible XSS on "Registered stream filters" info).
- (david at nnucomputerwhiz dot com)
- . Fixed bug #62672 (Error on serialize of ArrayObject). (Lior Kaplan)
- . Fixed bug #62475 (variant_* functions causes crash when null given as an
- argument). (Felipe)
- . Fixed bug #60732 (php_error_docref links to invalid pages). (Jakub Vrana)
+ . Fixed bug #65108 (is_callable() triggers Fatal Error).
+ (David Soria Parra, Laruence)
+ . Fixed bug #65035 (yield / exit segfault). (Nikita)
+ . Fixed bug #65161 (Generator + autoload + syntax error = segfault). (Nikita)
+ . hex2bin() raises E_WARNING for invalid hex string. (Yasuo)
. Fixed bug #65226 (chroot() does not get enabled). (Anatol)
+- OPcache
+ . Fixed bug #64827 (Segfault in zval_mark_grey (zend_gc.c)). (Laruence)
+ . OPcache must be compatible with LiteSpeed SAPI (Dmitry)
+
- CGI:
. Fixed Bug #65143 (Missing php-cgi man page). (Remi)
- CLI server:
. Fixed bug #65066 (Cli server not responsive when responding with 422 http
status code). (Adam)
-
-- CURL:
- . Fixed bug #62665 (curl.cainfo doesn't appear in php.ini). (Lior Kaplan)
-- FPM:
- . Fixed bug #63983 (enabling FPM borks compile on FreeBSD).
- (chibisuke at web dot de, Felipe)
-
-- FTP:
- . Fixed bug #65228 (FTPs memory leak with SSL).
- (marco dot beierer at mbsecurity dot ch)
-
-- GMP:
- . Fixed bug #65227 (Memory leak in gmp_cmp second parameter). (Felipe)
+- DateTime
+ . Fixed fug #65184 (strftime() returns insufficient-length string under
+ multibyte locales). (Anatol)
-- Imap:
- . Fixed bug #64467 (Segmentation fault after imap_reopen failure).
- (askalski at gmail dot com)
+- GD
+ . Fixed #65070 (bgcolor does not use the same format as the input image with
+ imagerotate). (Pierre)
+ . Fixed Bug #65060 (imagecreatefrom... crashes with user streams). (Remi)
+ . Fixed Bug #65084 (imagecreatefromjpeg fails with URL). (Remi)
+ . Fix gdImageCreateFromWebpCtx and use same logic to load WebP image
+ that other formats. (Remi)
-- Intl:
+- Intl:
+ . Add IntlCalendar::setMinimalDaysInFirstWeek()/
+ intlcal_set_minimal_days_in_first_week().
+ . Fixed trailing space in name of constant IntlCalendar::FIELD_FIELD_COUNT.
. Fixed bug #62759 (Buggy grapheme_substr() on edge case). (Stas)
. Fixed bug #61860 (Offsets may be wrong for grapheme_stri* functions).
(Stas)
-- mysqlnd:
- . Fixed segfault in mysqlnd when doing long prepare. (Andrey)
-
-- ODBC:
- . Fixed bug #61387 (NULL valued anonymous column causes segfault in
- odbc_fetch_array). (Brandon Kirsch)
-
-- Openssl:
- . Fixed handling null bytes in subjectAltName (CVE-2013-4248).
- (Christian Heimes)
+- OCI8:
+ . Bump PECL package info version check to allow PECL installs with PHP 5.5+
- PDO:
. Allowed PDO_OCI to compile with Oracle Database 12c client libraries.
(Chris Jones)
-- PDO_dblib:
- . Fixed bug #65219 (PDO/dblib not working anymore ("use dbName" not sent)).
- (Stanley Sufficool)
-
-- PDO_pgsql:
- . Fixed meta data retrieve when OID is larger than 2^31. (Yasuo)
+- Pgsql
+ . pg_unescape_bytea() raises E_WARNING for invalid inputs. (Yasuo)
- Phar:
. Fixed Bug #65142 (Missing phar man page). (Remi)
-- Session
- . Fixed bug #62535 ($_SESSION[$key]["cancel_upload"] doesn't work as
- documented). (Arpad)
- . Fixed bug #35703 (when session_name("123") consist only digits,
- should warning). (Yasuo)
- . Fixed bug #49175 (mod_files.sh does not support hash bits). Patch by
- oorza2k5 at gmail dot com (Yasuo)
+- Session:
+ . Added optional create_sid() argument to session_set_save_handler(),
+ SessionHandler and new SessionIdInterface. (Leigh, Arpad)
- Sockets:
- . Implemented FR #63472 (Setting SO_BINDTODEVICE with socket_set_option).
+ . Implemented FR #63472 (Setting SO_BINDTODEVICE with socket_set_option).
(Damjan Cvetko)
+ . Allowed specifying paths in the abstract namespace for the functions
+ socket_bind(), socket_connect() and socket_sendmsg(). (Gustavo)
+ . Fixed bug #65260 (sendmsg() ancillary data construction for SCM_RIGHTS is
+ faulty). (Gustavo)
- SPL:
. Fixed bug #65136 (RecursiveDirectoryIterator segfault). (Laruence)
. Fixed bug #61828 (Memleak when calling Directory(Recursive)Iterator
/Spl(Temp)FileObject ctor twice). (Laruence)
- . Fixed bug #60560 (SplFixedArray un-/serialize, getSize(), count() return 0,
- keys are strings). (Adam)
-- XML:
- . Fixed bug #65236 (heap corruption in xml parser, CVE-2013-4113). (Rob)
+- CGI/FastCGI SAPI:
+ . Added PHP_FCGI_BACKLOG, overrides the default listen backlog. (Arnaud Le
+ Blanc)
-04 Jul 2013, PHP 5.4.17
+20 Jun 2013, PHP 5.5.0
- Core:
+ . Added Zend Opcache extension and enable building it by default.
+ More details here: https://wiki.php.net/rfc/optimizerplus. (Dmitry)
+ . Added generators and coroutines (https://wiki.php.net/rfc/generators).
+ (Nikita Popov)
+ . Added "finally" keyword (https://wiki.php.net/rfc/finally). (Laruence)
+ . Added simplified password hashing API
+ (https://wiki.php.net/rfc/password_hash). (Anthony Ferrara)
+ . Added support for constant array/string dereferencing. (Laruence)
+ . Added array_column function which returns a column in a multidimensional
+ array. https://wiki.php.net/rfc/array_column. (Ben Ramsey)
+ . Added boolval(). (Jille Timmermans)
+ . Added "Z" option to pack/unpack. (Gustavo)
+ . Added Generator::throw() method. (Nikita Popov)
+ . Added Class Name Resolution As Scalar Via "class" Keyword.
+ (Ralph Schindler, Nikita Popov, Lars)
+ . Added optional second argument for assert() to specify custom message. Patch
+ by Lonny Kapelushnik (lonny@lonnylot.com). (Lars)
+ . Added support for using empty() on the result of function calls and
+ other expressions (https://wiki.php.net/rfc/empty_isset_exprs).
+ (Nikita Popov)
+ . Added support for non-scalar Iterator keys in foreach
+ (https://wiki.php.net/rfc/foreach-non-scalar-keys). (Nikita Popov)
+ . Added support for list in foreach (https://wiki.php.net/rfc/foreachlist).
+ (Laruence)
+ . Added support for changing the process's title in CLI/CLI-Server SAPIs.
+ The implementation is more robust that the proctitle PECL module. More
+ details here: https://wiki.php.net/rfc/cli_process_title. (Keyur)
+ . Added ARMv7/v8 versions of various Zend arithmetic functions that are
+ implemented using inline assembler (Ard Biesheuvel)
+ . Added systemtap support by enabling systemtap compatible dtrace probes on
+ linux. (David Soria Parra)
+ . Optimized access to temporary and compiled VM variables. 8% less memory
+ reads. (Dmitry)
+ . The VM stacks for passing function arguments and syntaticaly nested calls
+ were merged into a single stack. The stack size needed for op_array
+ execution is calculated at compile time and preallocated at once. As result
+ all the stack push operatins don't require checks for stack overflow
+ any more. (Dmitry)
+ . Improve set_exception_handler while doing reset. (Laruence)
+ . Return previous handler when passing NULL to set_error_handler and
+ set_exception_handler. (Nikita Popov)
+ . Remove php_logo_guid(), php_egg_logo_guid(), php_real_logo_guid(),
+ zend_logo_guid(). (Adnrew Faulds)
+ . Drop Windows XP and 2003 support. (Pierre)
+ . Implemented FR #64175 (Added HTTP codes as of RFC 6585). (Jonh Wendell)
+ . Implemented FR #60738 (Allow 'set_error_handler' to handle NULL).
+ (Laruence, Nikita Popov)
+ . Implemented FR #60524 (specify temp dir by php.ini). (ALeX Kazik).
+ . Implemented FR #46487 (Dereferencing process-handles no longer waits on
+ those processes). (Jille Timmermans)
+ . Fixed bug #65051 (count() off by one inside unset()). (Nikita)
. Fixed bug #64988 (Class loading order affects E_STRICT warning). (Laruence)
. Fixed bug #64966 (segfault in zend_do_fcall_common_helper_SPEC). (Laruence)
. Fixed bug #64960 (Segfault in gc_zval_possible_root). (Laruence)
. Fixed bug #64936 (doc comments picked up from previous scanner run). (Stas,
Jonathan Oddy)
. Fixed bug #64934 (Apache2 TS crash with get_browser()). (Anatol)
- . Fixed bug #64166 (quoted-printable-encode stream filter incorrectly
+ . Fixed bug #64879 (Heap based buffer overflow in quoted_printable_encode,
+ CVE 2013-2110). (Stas)
+ . Fixed bug #64853 (Use of no longer available ini directives causes crash
+ on TS build). (Anatol)
+ . Fixed bug #64821 (Custom Exceptions crash when internal properties overridden).
+ (Anatol)
+ . Fixed bug #64720 (SegFault on zend_deactivate). (Dmitry)
+ . Fixed bug #64677 (execution operator `` stealing surrounding arguments).
+ . Fixed bug #64660 (Segfault on memory exhaustion within function definition).
+ (Stas, reported by Juha Kylmänen)
+ . Fixed bug #64578 (debug_backtrace in set_error_handler corrupts zend heap:
+ segfault). (Laruence)
+ . Fixed bug #64565 (copy doesn't report failure on partial copy). (Remi)
+ . Fixed bug #64555 (foreach no longer copies keys if they are interned).
+ (Nikita Popov)
+ . Fixed bugs #47675 and #64577 (fd leak on Solaris)
+ . Fixed bug #64544 (Valgrind warnings after using putenv). (Laruence)
+ . Fixed bug #64515 (Memoryleak when using the same variablename 2times in
+ function declaration). (Laruence)
+ . Fixed bug #64503 (Compilation fails with error: conflicting types for
+ 'zendparse'). (Laruence)
+ . Fixed bug #64239 (Debug backtrace changed behavior since 5.4.10 or 5.4.11).
+ (Dmitry, Laruence)
+ . Fixed bug #64523, allow XOR in php.ini. (Dejan Marjanovic, Lars)
+ . Fixed bug #64354 (Unserialize array of objects whose class can't
+ be autoloaded fail). (Laruence)
+ . Fixed bug #64370 (microtime(true) less than $_SERVER['REQUEST_TIME_FLOAT']).
+ (Anatol)
+ . Fixed bug #64166 (quoted-printable-encode stream filter incorrectly
discarding whitespace). (Michael M Slusarz)
+ (Laruence)
+ . Fixed bug #64142 (dval to lval different behavior on ppc64). (Remi)
+ . Fixed bug #64135 (Exceptions from set_error_handler are not always
+ propagated). (Laruence)
+ . Fixed bug #63980 (object members get trimmed by zero bytes). (Laruence)
+ . Fixed bug #63874 (Segfault if php_strip_whitespace has heredoc). (Pierrick)
+ . Fixed bug #63830 (Segfault on undefined function call in nested generator).
+ (Nikita Popov)
+ . Fixed bug #63822 (Crash when using closures with ArrayAccess).
+ (Nikita Popov)
+ . Fixed bug #61681 (Malformed grammar). (Nikita Popov, Etienne, Laruence)
+ . Fixed bug #61038 (unpack("a5", "str\0\0") does not work as expected).
+ (srgoogleguy, Gustavo)
+ . Fixed bug #61025 (__invoke() visibility not honored). (Laruence)
+ . Fixed bug #60833 (self, parent, static behave inconsistently
+ case-sensitive). (Stas, mario at include-once dot org)
+ . Fixed Bug #52126: timestamp for mail.log (Martin Jansen, Lars)
+ . Fixed bug #49348 (Uninitialized ++$foo->bar; does not cause a notice).
+ (Stas)
+ . Fixed Bug #23955: allow specifying Max-Age attribute in setcookie() (narfbg, Lars)
+ . Fixed bug #18556 (Engine uses locale rules to handle class names). (Stas)
+ . Fix undefined behavior when converting double variables to integers.
+ The double is now always rounded towards zero, the remainder of its division
+ by 2^32 or 2^64 (depending on sizeof(long)) is calculated and it's made
+ signed assuming a two's complement representation. (Gustavo)
+ . Drop support for bison < 2.4 when building PHP from GIT source.
+ (Laruence)
-- DateTime:
+- Apache2 Handler SAPI:
+ . Enabled Apache 2.4 configure option for Windows (Pierre, Anatoliy)
+
+- Calendar:
+ . Fixed bug #64895 (Integer overflow in SndToJewish). (Remi)
+ . Fixed bug #54254 (cal_from_jd returns month = 6 when there is only one Adar)
+ (Stas, Eitan Mosenkis)
+
+- CLI server:
+ . Fixed bug #64128 (buit-in web server is broken on ppc64). (Remi)
+
+- CURL:
+ . Remove curl stream wrappers. (Pierrick)
+ . Implemented FR #46439 - added CURLFile for safer file uploads.
+ (Stas)
+ . Added support for CURLOPT_FTP_RESPONSE_TIMEOUT, CURLOPT_APPEND,
+ CURLOPT_DIRLISTONLY, CURLOPT_NEW_DIRECTORY_PERMS, CURLOPT_NEW_FILE_PERMS,
+ CURLOPT_NETRC_FILE, CURLOPT_PREQUOTE, CURLOPT_KRBLEVEL, CURLOPT_MAXFILESIZE,
+ CURLOPT_FTP_ACCOUNT, CURLOPT_COOKIELIST, CURLOPT_IGNORE_CONTENT_LENGTH,
+ CURLOPT_CONNECT_ONLY, CURLOPT_LOCALPORT, CURLOPT_LOCALPORTRANGE,
+ CURLOPT_FTP_ALTERNATIVE_TO_USER, CURLOPT_SSL_SESSIONID_CACHE,
+ CURLOPT_FTP_SSL_CCC, CURLOPT_HTTP_CONTENT_DECODING,
+ CURLOPT_HTTP_TRANSFER_DECODING, CURLOPT_PROXY_TRANSFER_MODE,
+ CURLOPT_ADDRESS_SCOPE, CURLOPT_CRLFILE, CURLOPT_ISSUERCERT,
+ CURLOPT_USERNAME, CURLOPT_PASSWORD, CURLOPT_PROXYUSERNAME,
+ CURLOPT_PROXYPASSWORD, CURLOPT_NOPROXY, CURLOPT_SOCKS5_GSSAPI_NEC,
+ CURLOPT_SOCKS5_GSSAPI_SERVICE, CURLOPT_TFTP_BLKSIZE,
+ CURLOPT_SSH_KNOWNHOSTS, CURLOPT_FTP_USE_PRET, CURLOPT_MAIL_FROM,
+ CURLOPT_MAIL_RCPT, CURLOPT_RTSP_CLIENT_CSEQ, CURLOPT_RTSP_SERVER_CSEQ,
+ CURLOPT_RTSP_SESSION_ID, CURLOPT_RTSP_STREAM_URI, CURLOPT_RTSP_TRANSPORT,
+ CURLOPT_RTSP_REQUEST, CURLOPT_RESOLVE, CURLOPT_ACCEPT_ENCODING,
+ CURLOPT_TRANSFER_ENCODING, CURLOPT_DNS_SERVERS and CURLOPT_USE_SSL.
+ (Pierrick)
+ . Fixed bug #55635 (CURLOPT_BINARYTRANSFER no longer used. The constant
+ still exists for backward compatibility but is doing nothing). (Pierrick)
+ . Fixed bug #54995 (Missing CURLINFO_RESPONSE_CODE support). (Pierrick)
+
+- DateTime
+ . Added DateTimeImmutable - a variant of DateTime that only returns the
+ modified state instead of changing itself. (Derick)
+ . Added new functions curl_escape, curl_multi_setopt, curl_multi_strerror
+ curl_pause, curl_reset, curl_share_close, curl_share_init,
+ curl_share_setopt curl_strerror and curl_unescape. (Pierrick)
+ . Addes new curl options CURLOPT_TELNETOPTIONS, CURLOPT_GSSAPI_DELEGATION,
+ CURLOPT_ACCEPTTIMEOUT_MS, CURLOPT_SSL_OPTIONS, CURLOPT_TCP_KEEPALIVE,
+ CURLOPT_TCP_KEEPIDLE and CURLOPT_TCP_KEEPINTVL. (Pierrick)
+ . Fixed bug #64825 (Invalid free when unserializing DateTimeZone).
+ (Anatol)
+ . Fixed bug #64359 (strftime crash with VS2012). (Anatol)
+ . Fixed bug #62852 (Unserialize Invalid Date causes crash). (Anatol)
+ . Fixed bug #61642 (modify("+5 weekdays") returns Sunday).
+ (Dmitri Iouchtchenko)
+ . Fixed bug #60774 (DateInterval::format("%a") is always zero when an
+ interval is created using the createFromDateString method) (Lonny
+ Kapelushnik, Derick)
+ . Fixed bug #54567 (DateTimeZone serialize/unserialize) (Lonny
+ Kapelushnik, Derick)
. Fixed bug #53437 (Crash when using unserialized DatePeriod instance).
(Gustavo, Derick, Anatol)
+- dba:
+ . Bug #62489: dba_insert not working as expected.
+ (marc-bennewitz at arcor dot de, Lars)
+
+- Filter:
+ . Implemented FR #49180 - added MAC address validation. (Martin)
+
+- Fileinfo:
+ . Upgraded libmagic to 5.14. (Anatol)
+ . Fixed bug #64830 (mimetype detection segfaults on mp3 file). (Anatol)
+ . Fixed bug #63590 (Different results in TS and NTS under Windows).
+ (Anatoliy)
+ . Fixed bug #63248 (Load multiple magic files from a directory under Windows).
+ (Anatoliy)
+
- FPM:
- . Fixed Bug #64915 (error_log ignored when daemonize=0). (Remi)
+ . Add --with-fpm-systemd option to report health to systemd, and
+ systemd_interval option to configure this. The service can now use
+ Type=notify in the systemd unit file. (Remi)
+ . Ignore QUERY_STRING when sent in SCRIPT_FILENAME. (Remi)
+ . Log a warning when a syscall fails. (Remi)
. Implemented FR #64764 (add support for FPM init.d script). (Lior Kaplan)
+ . Fixed Bug #64915 (error_log ignored when daemonize=0). (Remi)
+ . Fixed bug #63999 (php with fpm fails to build on Solaris 10 or 11). (Adam)
+ . Fixed some possible memory or resource leaks and possible null dereference
+ detected by code coverity scan. (Remi)
+
+- GD:
+ . Fixed Bug #64962 (imagerotate produces corrupted image). (Remi)
+ . Fixed Bug #64961 (segfault in imagesetinterpolation). (Remi)
+ . Fix build with system libgd >= 2.1 which is now the minimal
+ version required (as build with previous version is broken).
+ No change when bundled libgd is used. (Ondrej Sury, Remi)
+
+- Hash:
+ . Added support for PBKDF2 via hash_pbkdf2(). (Anthony Ferrara)
+ . Fixed Bug #64745 (hash_pbkdf2() truncates data when using default length
+ and hex output). (Anthony Ferrara)
+
+- Intl:
+ . Added UConverter wrapper.
+ . The intl extension now requires ICU 4.0+.
+ . Added intl.use_exceptions INI directive, which controls what happens when
+ global errors are set together with intl.error_level. (Gustavo)
+ . MessageFormatter::format() and related functions now accepted named
+ arguments and mixed numeric/named arguments in ICU 4.8+. (Gustavo)
+ . MessageFormatter::format() and related functions now don't error out when
+ an insufficient argument count is provided. Instead, the placeholders will
+ remain unsubstituted. (Gustavo)
+ . MessageFormatter::parse() and MessageFormat::format() (and their static
+ equivalents) don't throw away better than second precision in the arguments.
+ (Gustavo)
+ . IntlDateFormatter::__construct and datefmt_create() now accept for the
+ $timezone argument time zone identifiers, IntlTimeZone objects, DateTimeZone
+ objects and NULL. (Gustavo)
+ . IntlDateFormatter::__construct and datefmt_create() no longer accept invalid
+ timezone identifiers or empty strings. (Gustavo)
+ . The default time zone used in IntlDateFormatter::__construct and
+ datefmt_create() (when the corresponding argument is not passed or NULL is
+ passed) is now the one given by date_default_timezone_get(), not the
+ default ICU time zone. (Gustavo)
+ . The time zone passed to the IntlDateFormatter is ignored if it is NULL and
+ if the calendar passed is an IntlCalendar object -- in this case, the
+ IntlCalendar's time zone will be used instead. Otherwise, the time zone
+ specified in the $timezone argument is used instead. This does not affect
+ old code, as IntlCalendar was introduced in this version. (Gustavo)
+ . IntlDateFormatter::__construct and datefmt_create() now accept for the
+ $calendar argument also IntlCalendar objects. (Gustavo)
+ . IntlDateFormatter::getCalendar() and datefmt_get_calendar() return false
+ if the IntlDateFormatter was set up with an IntlCalendar instead of the
+ constants IntlDateFormatter::GREGORIAN/TRADITIONAL. IntlCalendar did not
+ exist before this version. (Gustavo)
+ . IntlDateFormatter::setCalendar() and datefmt_set_calendar() now also accept
+ an IntlCalendar object, in which case its time zone is taken. Passing a
+ constant is still allowed, and still keeps the time zone. (Gustavo)
+ . IntlDateFormatter::setTimeZoneID() and datefmt_set_timezone_id() are
+ deprecated. Use IntlDateFormatter::setTimeZone() or datefmt_set_timezone()
+ instead. (Gustavo)
+ . IntlDateFormatter::format() and datefmt_format() now also accept an
+ IntlCalendar object for formatting. (Gustavo)
+ . Added the classes: IntlCalendar, IntlGregorianCalendar, IntlTimeZone,
+ IntlBreakIterator, IntlRuleBasedBreakIterator and
+ IntlCodePointBreakIterator. (Gustavo)
+ . Added the functions: intlcal_get_keyword_values_for_locale(),
+ intlcal_get_now(), intlcal_get_available_locales(), intlcal_get(),
+ intlcal_get_time(), intlcal_set_time(), intlcal_add(),
+ intlcal_set_time_zone(), intlcal_after(), intlcal_before(), intlcal_set(),
+ intlcal_roll(), intlcal_clear(), intlcal_field_difference(),
+ intlcal_get_actual_maximum(), intlcal_get_actual_minimum(),
+ intlcal_get_day_of_week_type(), intlcal_get_first_day_of_week(),
+ intlcal_get_greatest_minimum(), intlcal_get_least_maximum(),
+ intlcal_get_locale(), intlcal_get_maximum(),
+ intlcal_get_minimal_days_in_first_week(), intlcal_get_minimum(),
+ intlcal_get_time_zone(), intlcal_get_type(),
+ intlcal_get_weekend_transition(), intlcal_in_daylight_time(),
+ intlcal_is_equivalent_to(), intlcal_is_lenient(), intlcal_is_set(),
+ intlcal_is_weekend(), intlcal_set_first_day_of_week(),
+ intlcal_set_lenient(), intlcal_equals(),
+ intlcal_get_repeated_wall_time_option(),
+ intlcal_get_skipped_wall_time_option(),
+ intlcal_set_repeated_wall_time_option(),
+ intlcal_set_skipped_wall_time_option(), intlcal_from_date_time(),
+ intlcal_to_date_time(), intlcal_get_error_code(),
+ intlcal_get_error_message(), intlgregcal_create_instance(),
+ intlgregcal_set_gregorian_change(), intlgregcal_get_gregorian_change() and
+ intlgregcal_is_leap_year(). (Gustavo)
+ . Added the functions: intltz_create_time_zone(), intltz_create_default(),
+ intltz_get_id(), intltz_get_gmt(), intltz_get_unknown(),
+ intltz_create_enumeration(), intltz_count_equivalent_ids(),
+ intltz_create_time_zone_id_enumeration(), intltz_get_canonical_id(),
+ intltz_get_region(), intltz_get_tz_data_version(),
+ intltz_get_equivalent_id(), intltz_use_daylight_time(), intltz_get_offset(),
+ intltz_get_raw_offset(), intltz_has_same_rules(), intltz_get_display_name(),
+ intltz_get_dst_savings(), intltz_from_date_time_zone(),
+ intltz_to_date_time_zone(), intltz_get_error_code(),
+ intltz_get_error_message(). (Gustavo)
+ . Added the methods: IntlDateFormatter::formatObject(),
+ IntlDateFormatter::getCalendarObject(), IntlDateFormatter::getTimeZone(),
+ IntlDateFormatter::setTimeZone(). (Gustavo)
+ . Added the functions: datefmt_format_object(), datefmt_get_calendar_object(),
+ datefmt_get_timezone(), datefmt_set_timezone(),
+ datefmt_get_calendar_object(), intlcal_create_instance(). (Gustavo)
+
+- mbstring:
+ . Fixed bug #64769 (mbstring PHPTs crash on Windows x64). (Anatol)
+
+- MCrypt
+ . mcrypt_ecb(), mcrypt_cbc(), mcrypt_cfb() and mcrypt_ofb() now throw
+ E_DEPRECATED. (GoogleGuy)
+
+- mysql
+ . This extension is now deprecated, and deprecation warnings will be generated
+ when connections are established to databases via mysql_connect(),
+ mysql_pconnect(), or through implicit connection: use MySQLi or PDO_MySQL
+ instead (https://wiki.php.net/rfc/mysql_deprecation). (Adam)
+ . Dropped support for LOAD DATA LOCAL INFILE handlers when using libmysql.
+ Known for stability problems. (Andrey)
+ . Added support for SHA256 authentication available with MySQL 5.6.6+.
+ (Andrey)
+
+- mysqli:
+ . Added mysqli_begin_transaction()/mysqli::begin_transaction(). Implemented
+ all options, per MySQL 5.6, which can be used with START TRANSACTION, COMMIT
+ and ROLLBACK through options to mysqli_commit()/mysqli_rollback() and their
+ respective OO counterparts. They work in libmysql and mysqlnd mode. (Andrey)
+ . Added mysqli_savepoint(), mysqli_release_savepoint(). (Andrey)
+ . Fixed bug #64726 (Segfault when calling fetch_object on a use_result and DB
+ pointer has closed). (Laruence)
+ . Fixed bug #64394 (MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS undeclared when
+ using Connector/C). (Andrey)
+
+- mysqlnd
+ . Add new begin_transaction() call to the connection object. Implemented all
+ options, per MySQL 5.6, which can be used with START TRANSACTION, COMMIT
+ and ROLLBACK. (Andrey)
+ . Added mysqlnd_savepoint(), mysqlnd_release_savepoint(). (Andrey)
+ . Fixed bug #63530 (mysqlnd_stmt::bind_one_parameter crashes, uses wrong alloc
+ for stmt->param_bind). (Andrey)
+ . Fixed return value of mysqli_stmt_affected_rows() in the time after
+ prepare() and before execute(). (Andrey)
+
+- PCRE:
+ . Merged PCRE 8.32. (Anatol)
+ . Deprecated the /e modifier
+ (https://wiki.php.net/rfc/remove_preg_replace_eval_modifier). (Nikita Popov)
+ . Fixed bug #63284 (Upgrade PCRE to 8.31). (Anatoliy)
- PDO:
. Fixed bug #63176 (Segmentation fault when instantiate 2 persistent PDO to
the same db server). (Laruence)
- PDO_DBlib:
- . Fixed bug #63638 (Cannot connect to SQL Server 2008 with PDO dblib).
+ . Fixed bug #63638 (Cannot connect to SQL Server 2008 with PDO dblib).
(Stanley Sufficool)
- . Fixed bug #64338 (pdo_dblib can't connect to Azure SQL). (Stanley
+ . Fixed bug #64338 (pdo_dblib can't connect to Azure SQL). (Stanley
Sufficool)
- . Fixed bug #64808 (FreeTDS PDO getColumnMeta on a prepared but not executed
+ . Fixed bug #64808 (FreeTDS PDO getColumnMeta on a prepared but not executed
statement crashes). (Stanley Sufficool)
-- PDO_firebird:
- . Fixed bug #64037 (Firebird return wrong value for numeric field).
- (Matheus Degiovani, Matteo)
- . Fixed bug #62024 (Cannot insert second row with null using parametrized
- query). (patch by james@kenjim.com, Matheus Degiovani, Matteo)
+- PDO_pgsql:
+ . Fixed Bug #64949 (Buffer overflow in _pdo_pgsql_error). (Remi)
- PDO_mysql:
- . Fixed bug #48724 (getColumnMeta() doesn't return native_type for BIT,
+ . Fixed bug #48724 (getColumnMeta() doesn't return native_type for BIT,
TINYINT and YEAR). (Antony, Daniel Beardsley)
-- PDO_pgsql:
- . Fixed Bug #64949 (Buffer overflow in _pdo_pgsql_error). (Remi)
-
- pgsql:
- . Fixed bug #64609 (pg_convert enum type support). (Matteo)
- . Fixed bug #65015 (pg_send_query does not flush send buffer)
- patch submitted by: adam at vektah dot net (Yasuo)
+ . Added pg_escape_literal() and pg_escape_identifier() (Yasuo)
+ . Bug #46408: Locale number format settings can cause pg_query_params to
+ break with numerics. (asmecher, Lars)
+
+- Phar:
+ . Fixed timestamp update on Phar contents modification. (Dmitry)
- Readline:
- . Implement FR #55694 (Expose additional readline variable to prevent
+ . Implement FR #55694 (Expose additional readline variable to prevent
default filename completion). (Hartmel)
+- Reflection:
+ . Fixed bug #64007 (There is an ability to create instance of Generator by
+ hand). (Laruence)
+
+- Sockets:
+ . Added recvmsg() and sendmsg() wrappers. (Gustavo)
+ See https://wiki.php.net/rfc/sendrecvmsg
+ . Fixed bug #64508 (Fails to build with --disable-ipv6). (Gustavo)
+ . Fixed bug #64287 (sendmsg/recvmsg shutdown handler causes segfault).
+ (Gustavo)
+
- SPL:
. Fixed bug #64997 (Segfault while using RecursiveIteratorIterator on
64-bits systems). (Laruence)
+ . Fixed bug #64264 (SPLFixedArray toArray problem). (Laruence)
+ . Fixed bug #64228 (RecursiveDirectoryIterator always assumes SKIP_DOTS).
+ (patch by kriss@krizalys.com, Laruence)
+ . Fixed bug #64106 (Segfault on SplFixedArray[][x] = y when extended).
+ (Nikita Popov)
+ . Fix bug #60560 (SplFixedArray un-/serialize, getSize(), count() return 0,
+ keys are strings). (Adam)
+ . Fixed bug #52861 (unset fails with ArrayObject and deep arrays).
+ (Mike Willbanks)
+ . Implement FR #48358 (Add SplDoublyLinkedList::add() to insert an element
+ at a given offset). (Mark Baker, David Soria Parra)
+
+- SNMP:
+ . Fixed bug #64765 (Some IPv6 addresses get interpreted wrong).
+ (Boris Lytochkin)
+ . Fixed bug #64159 (Truncated snmpget). (Boris Lytochkin)
+ . Fixed bug #64124 (IPv6 malformed). (Boris Lytochkin)
+ . Fixed bug #61981 (OO API, walk: $suffix_as_key is not working correctly).
+ (Boris Lytochkin)
+
+- SOAP:
+ . Added SoapClient constructor option 'ssl_method' to specify ssl method.
+ (Eric Iversen)
+
+- Streams:
+ . Fixed bug #64770 (stream_select() fails with pipes returned by proc_open()
+ on Windows x64). (Anatol)
+ . Fixed Windows x64 version of stream_socket_pair() and improved error
+ handling. (Anatol Belski)
+
+- Tokenizer:
+ . Fixed bug #60097 (token_get_all fails to lex nested heredoc). (Nikita Popov)
+
+- Zip:
+ . Upgraded libzip to 0.10.1 (Anatoliy)
+ . Bug #64452 (Zip crash intermittently). (Anatol)
+ . Fixed bug #64342 (ZipArchive::addFile() has to check for file existence).
+ (Anatol)
06 Jun 2013, PHP 5.4.16
- Core:
- . Fixed bug #64879 (Heap based buffer overflow in quoted_printable_encode,
+ . Fixed bug #64879 (Heap based buffer overflow in quoted_printable_encode,
CVE 2013-2110). (Stas)
. Fixed bug #64853 (Use of no longer available ini directives causes crash on
TS build). (Anatol)
@@ -421,7 +907,7 @@ PHP NEWS
Type=notify in the systemd unit file. (Remi)
- MySQLi
- . Fixed bug #64726 (Segfault when calling fetch_object on a use_result and DB
+ . Fixed bug #64726 (Segfault when calling fetch_object on a use_result and DB
pointer has closed). (Laruence)
- Phar
@@ -538,6 +1024,9 @@ PHP NEWS
. Disabled external entities loading (CVE-2013-1643, CVE-2013-1824).
(Dmitry)
+- Phar:
+ . Fixed timestamp update on Phar contents modification. (Dmitry)
+
- SPL:
. Fixed bug #64264 (SPLFixedArray toArray problem). (Laruence)
. Fixed bug #64228 (RecursiveDirectoryIterator always assumes SKIP_DOTS).
diff --git a/README.PARAMETER_PARSING_API b/README.PARAMETER_PARSING_API
index 4579340e5e..25a41096cf 100644
--- a/README.PARAMETER_PARSING_API
+++ b/README.PARAMETER_PARSING_API
@@ -28,6 +28,17 @@ Both functions return SUCCESS or FAILURE depending on the result.
The auto-conversions are performed as necessary. Arrays, objects, and
resources cannot be auto-converted.
+PHP 5.5 includes a new function:
+
+int zend_parse_parameter(int flags, int arg_num TSRMLS_DC, zval **arg, const char *spec, ...);
+
+This function behaves like zend_parse_parameters_ex() except that instead of
+reading the arguments from the stack, it receives a single zval to convert
+(passed with double indirection). The passed zval may be changed in place as
+part of the conversion process.
+
+See also https://wiki.php.net/rfc/zpp_improv#expose_zend_parse_arg_as_zend_parse_parameter
+
Type specifiers
---------------
@@ -65,9 +76,13 @@ Type specifiers
will not be touched by the parsing function if they are not
passed to it.
/ - use SEPARATE_ZVAL_IF_NOT_REF() on the parameter it follows
- ! - the parameter it follows can be of specified type or NULL (applies
- to all specifiers except for 'b', 'l', and 'd'). If NULL is passed, the
- results pointer is set to NULL as well.
+ ! - the parameter it follows can be of specified type or NULL. If NULL is
+ passed and the output for such type is a pointer, then the output
+ pointer is set to a native NULL pointer.
+ For 'b', 'l' and 'd', an extra argument of type zend_bool* must be
+ passed after the corresponding bool*, long* or double* arguments,
+ respectively. A non-zero value will be written to the zend_bool iif a
+ PHP NULL is passed.
Note on 64bit compatibility
diff --git a/README.md b/README.md
new file mode 100644
index 0000000000..09e70e6a39
--- /dev/null
+++ b/README.md
@@ -0,0 +1,39 @@
+The PHP Interpreter
+===================
+
+This is the github mirror of the official PHP repository located at
+http://git.php.net.
+
+[![Build Status](https://secure.travis-ci.org/php/php-src.png?branch=master)](http://travis-ci.org/php/php-src)
+
+Pull Requests
+=============
+PHP accepts pull requests via github. Discussions are done on github, but
+depending on the topic can also be relayed to the official PHP developer
+mailinglist internals@lists.php.net.
+
+New features require an RFC and must be accepted by the developers.
+See https://wiki.php.net/rfc and https://wiki.php.net/rfc/voting for more
+information on the process.
+
+Bug fixes **do not** require an RFC, but require a bugtracker ticket. Always
+open a ticket at https://bugs.php.net and reference the bug id using #NNNNNN.
+
+ Fix #55371: get_magic_quotes_gpc() throws deprecation warning
+
+ After removing magic quotes, the get_magic_quotes_gpc function caused
+ a deprecate warning. get_magic_quotes_gpc can be used to detected
+ the magic_quotes behavior and therefore should not raise a warning at any
+ time. The patch removes this warning
+
+We do not merge pull requests directly on github. All PRs will be
+pulled and pushed through http://git.php.net.
+
+
+Guidelines for contributors
+===========================
+- [CODING_STANDARDS](/CODING_STANDARDS)
+- [README.GIT-RULES](/README.GIT-RULES)
+- [README.MAILINGLIST_RULES](/README.MAILINGLIST_RULES)
+- [README.RELEASE_PROCESS](/README.RELEASE_PROCESS)
+
diff --git a/TSRM/tsrm_config.w32.h b/TSRM/tsrm_config.w32.h
index 14c6443a03..1443e7cca9 100644
--- a/TSRM/tsrm_config.w32.h
+++ b/TSRM/tsrm_config.w32.h
@@ -2,6 +2,7 @@
#define TSRM_CONFIG_W32_H
#include <../main/config.w32.h>
+#include "Zend/zend_config.w32.h"
#define HAVE_UTIME 1
#define HAVE_ALLOCA 1
@@ -11,12 +12,4 @@
#include <stdlib.h>
#include <crtdbg.h>
-#undef inline
-#ifdef ZEND_WIN32_FORCE_INLINE
-# define inline __forceinline
-#else
-# define inline
-#endif
-
-
#endif
diff --git a/UPGRADING b/UPGRADING
index e6f582a4a8..43e4118b21 100755
--- a/UPGRADING
+++ b/UPGRADING
@@ -1,820 +1,486 @@
$Id$
-PHP 5.4 UPGRADE NOTES
-
-===========
-0. Contents
-===========
-
-1. Changes to INI directives
-2. Changes to reserved words and classes
-3. Changes to engine behavior
-4. Changes to existing functions
-5. Changes to existing classes
-6. Changes to existing methods
-7. Deprecated Functionality
-8. Removed Functionality
- a. Removed features
- b. Removed functions
- c. Removed syntax
- d. Removed hash algorithms
-9. Extension Changes:
- a. Extensions no longer maintained
- b. Extensions with changed behavior
-10. Changes in SAPI support
-11. Windows support
-12. New in PHP 5.4:
- a. New features
- b. Syntax additions
- c. New functions
- d. New global constants
- e. New classes
- f. New methods
- g. New hash algorithms
-
-=============================
-1. Changes to INI directives
-=============================
-
-- PHP 5.4 now checks at compile time if /dev/urandom or /dev/arandom
- are present. If either is available, session.entropy_file now
- defaults to that file and session.entropy_length defaults to 32.
- This provides non-blocking entropy to session id generation. If you
- do not want extra entropy for your session ids, add:
-
- session.entropy_file=
- session.entropy_length=0
-
- to your php.ini to preserve pre-PHP 5.4 behavior.
-
-- Deprecated php.ini directives will now throw an E_CORE_WARNING's
- instead of the previous E_WARNING's.
-
-- The following php.ini directives are no longer available in PHP 5.4
- and will now throw an E_CORE_ERROR upon startup:
- - allow_call_time_pass_reference
- - define_syslog_variables
- - highlight.bg
- - magic_quotes_gpc
- - magic_quotes_runtime
- - magic_quotes_sybase
- - register_globals
- - register_long_arrays
- - safe_mode
- - safe_mode_gid
- - safe_mode_include_dir
- - safe_mode_exec_dir
- - safe_mode_allowed_env_vars
- - safe_mode_protected_env_vars
- - session.bug_compat_42
- - session.bug_compat_warn
- - y2k_compliance
- - zend.ze1_compatibility_mode
-
-- the following new php.ini directives were added:
- - max_input_vars - specifies how many GET/POST/COOKIE input
- variables may be accepted. The default value is 1000.
-
-- E_ALL now includes E_STRICT.
-
-- The recommended production value for error_reporting changed to E_ALL &
- ~E_DEPRECATED & ~E_STRICT.
-
-- Added new session support directives:
- session.upload_progress.enabled
- session.upload_progress.cleanup
- session.upload_progress.prefix
- session.upload_progress.name
- session.upload_progress.freq
- session.upload_progress.min_freq
-
-- Added a zend.multibyte directive as a replacement of the PHP compile time
- configuration option --enable-zend-multibyte. Now the Zend Engine always
- contains code for multibyte support, which can be enabled or disabled at
- runtime. Note: It doesn't make a lot of sense to enable this option if
- ext/mbstring is not enabled, because most functionality is implemented by
- mbstrings callbacks.
-
-- Added zend.script_encoding. This value will be used unless a
- "declare(encoding=...)" directive appears at the top of the script.
-
-- Added zend.signal_check to check for replaced signal handlers on shutdown
-
-- Added enable_post_data_reading, which is enabled by default. When it's
- disabled, the POST data is not read (or processed); the behavior is similar
- to that of other request methods with body, like PUT. This allows reading
- the raw POST data in multipart requests and reading/processing the POST data
- in a stream fashion (through php://input) without having it copied in memory
- multiple times.
-
-- Added windows_show_crt_warning. This directive shows the CRT warnings when
- enabled. These warnings were displayed by default until now. It is disabled
- by default.
-
-- Added cli.pager to set a pager for CLI interactive shell output.
-
-- Added cli.prompt to configure the CLI interactive shell prompt.
-
-- Added cli_server.color to enable the CLI web server to use ANSI color coding
- in terminal output.
+PHP 5.5 UPGRADE NOTES
+
+1. Backward Incompatible Changes
+2. New Features
+2. Changes in SAPI modules
+3. Deprecated Functionality
+4. Changed Functions
+5. New Functions
+6. New Classes and Interfaces
+7. Removed Extensions
+8. Other Changes to Extensions
+9. New Global Constants
+10. Changes to INI File Handling
+11. Windows Support
+12. Other Changes
+
========================================
-2. Changes to reserved words and classes
+1. Backward Incompatible Changes
========================================
-- "callable", "insteadof" and "trait" are now reserved words.
-
-=============================
-3. Changes to engine behavior
-=============================
-
-- The __construct arguments of an extended abstract constructor must
- now match:
-
- abstract class Base
- {
- abstract public function __construct();
- }
- class Foo extends Base
- {
- public function __construct($bar) {}
- }
-
- This now emits a Fatal error due the incompatible declaration.
-
-- In previous versions, superglobal names could be used for parameter
- names, thereby shadowing the corresponding superglobal. In PHP 5.4
- this now causes a fatal error such as "Cannot re-assign auto-global
- variable GLOBALS".
-
-- Turning null, false or an empty string into an object by adding a
- property will now emit a warning instead of an E_STRICT error.
-
- $test = null;
- $test->baz = 1;
-
- To create a generic object you can use StdClass:
-
- $test = new StdClass;
- $test->baz = 1;
-
-- Converting an array to a string now will cause an E_NOTICE warning.
-
-- Non-numeric string offsets, e.g. $a['foo'] where $a is a string, now
- return false on isset() and true on empty(), and produce warning if
- trying to use them. Offsets of types double, bool and null produce
- notice. Numeric strings ($a['2']) still work as before.
-
- Note that offsets like '12.3' and '5 and a half' are considered
- non-numeric and produce warning, but are converted to 12 and 5
- respectively for backwards compatibility reasons.
-
-- Long numeric strings that do not fit in integer or double (such as
- "92233720368547758070") are compared using string comparison if
- they could otherwise result in precision loss - since 5.4.4.
-
-- Closures now support scopes and $this and can be rebound to
- objects using Closure::bind() and Closure::bindTo().
-
-- <?= is now always available regardless of the short_open_tag
- setting.
-
-- Parse error messages are changed to contain more information about
- the error.
-
-- __clone and __destruct since 5.4.4 follow the same scoping rules as
- the rest of the methods (see bug #61782 for details).
-
-================================
-4. Changes to existing functions
-================================
-
-- array_combine now returns array() instead of FALSE when two empty arrays are
- provided as parameters.
-
-- dns_get_record() has an extra parameter which allows requesting DNS records
- by numeric type and makes the result include only the raw data of the
- response.
-
-- call_user_func_array() no longer allows call-time pass by reference.
-
-- the default character set for htmlspecialchars() and htmlentities() is
- now UTF-8. In previous versions it was ISO-8859-1. Note that changing
- your output charset via the php.ini default_charset directive does not
- affect htmlspecialchars/htmlentities unless you are passing "" (an
- empty string) as the encoding parameter to your htmlspecialchars/htmlentities
- calls.
-
-- htmlentities() and htmlspecialchars() are stricter in the code units they
- accept for the asian encodings. For Big5-HKSCS, the octets 0x80 and 0xFF are
- rejected. For GB2312/EUC-CN, the octets 0x8E, 0x8F, 0xA0 and 0xFF are
- rejected. For SJIS, the octets 0x80, 0xA0, 0xFD, 0xFE and 0xFF are rejected,
- except maybe after a valid starting byte. For EUC-JP, the octets 0xA0 and
- 0xFF are rejected.
-
-- htmlentities() now emits an E_STRICT warning when used with asian characters,
- as in that case htmlentities has (and already had before this version) the
- same functionality as htmlspecialchars.
-
-- htmlentities() no longer numerically encodes high characters for single-byte
- encodings (except when there's actually a corresponding named entity). This
- behavior was not documented and was inconsistent with that for "UTF-8".
-
-- html_entity_decode() and htmlspecialchars_decode() behave more consistently,
- now decoding entities in malformed strings such as "&&amp;" or "&#&amp;".
-
-- htmlentities(), htmlspecialchars(), html_entity_decode(), and
- htmlspecialchars_decode: Added the flags ENT_HTML401, ENT_XML1, ENT_XHTML,
- and ENT_HTML5. The behavior of these functions including, but not limited to,
- the characters that are encoded and the entities that are decoded depend on
- the document type that is specified by those flags.
-
-- htmlentities() and htmlspecialchars() with !$double_encode do more strict
- checks on the validity of the entities. Numerical entities are checked for a
- valid range (0 to 0x10FFFF); if the flag ENT_DISALLOWED is given, the
- validity of such numerical entity in the target document type is also
- checked. Named entities are checked for necessary existence in the target
- document type instead of only checking whether they were constituted by
- alphanumeric characters.
-
-- The flag ENT_DISALLOWED was added. In addition to the behavior described in
- the item before, it also makes htmlentities() and htmlspecialchars()
- substitute characters that appear literally in the argument string and which
- are not allowed in the target document type with U+FFFD (UTF-8) or &#xFFFD;.
-
-- The flag ENT_SUBSTITUTE was added. This flag makes invalid multibyte
- sequences be replaced by U+FFFD (UTF-8) or &#FFFD; by htmlspecialchars() and
- htmlentities(). It is an alternative to the default behavior, which just
- returns an empty string and to ENT_IGNORE, which is a security risk. The
- behavior follows the recommendations of Unicode Technical Report #36.
-
-- htmlspecialchars_decode() and html_entity_decode() now decode &apos; if the
- document type is ENT_XML1, ENT_XHTML, or ENT_HTML5.
-
-- Charset detection with $charset == '' no longer turns to mbstring's
- internal encoding defined through mb_internal_encoding(). Only the encoding
- defined through the php.ini setting mbstring.internal_encoding is considered.
-
-- number_format() no longer truncates multibyte decimal points and thousand
- separators to the first byte.
-
-- The third parameter ($matches) to preg_match_all() is now optional. If
- omitted, the function will simply return the number of times the pattern was
- matched in the subject and will have no other side effects.
-
-- The second argument of scandir() now accepts SCANDIR_SORT_NONE (2) as a
- possible value. This value results in scandir() performing no sorting: on
- local filesystems, this allows files to be returned in native filesystem
- order.
-
-- stream_select() now preserves the keys of the passed array, be they numeric or
- strings. This breaks code that iterated the resulting stream array using a
- numeric index, but makes easier to identify which of the passed streams are
- present in the result.
-
-- stream_set_write_buffer() no longer disables the read buffer of a plain
- stream when 0 is given as the second argument.
+- Dropped Windows XP and 2003 support. (Pierre)
-- stream_set_write_buffer() no longer changes the chunk size in socket streams.
+- All internal case insensitivity handling for class, function and constant
+ names is done according to ASCII rules. Current locale settings are ignored.
-- fclose() closes streams with resource refcount > 1; it doesn't merely
- decrement the resource refcount.
+- self, parent & static keywords now are always case-insensitive (see bug
+ #60833).
-- socket_set_options() and socket_get_options() now support multicast options.
+- Removed Logo GUIDs: php_logo_guid(), php_egg_logo_guid(),
+ php_real_logo_guid() and zend_logo_guid()
-- The raw data parameter in openssl_encrypt() and openssl_decrypt() is now an
- options integer rather than a boolean. A value of true produces the same
- behavior.
-
-- Write operations within XSLT (for example with the extension sax:output) are
- disabled by default. You can define what is forbidden with the method
- XsltProcess::setSecurityPrefs($options).
-
-- Added AES support to OpenSSL.
-
-- openssl_csr_new() expects the textual data to be in UTF-8.
-
-- Added no-padding option to openssl_encrypt() and openssl_decrypt().
-
-- Added a "no_ticket" SSL context option to disable the SessionTicket TLS
- extension.
-
-- Added new json_encode() options: JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES,
- JSON_NUMERIC_CHECK, JSON_BIGINT_AS_STRING, JSON_UNESCAPED_UNICODE.
-
-- Added Tokyo Cabinet and Berkley DB 5 support to DBA extension.
-
-- Added support for CURLOPT_MAX_SEND_SPEED_LARGE and CURLOPT_MAX_RECV_SPEED_LARGE
- to cURL.
-
-- Added optional argument to debug_backtrace() and debug_print_backtrace()
- to limit the amount of stack frames returned.
-
-- Fixed crypt_blowfish handling of 8-bit characters. crypt() in Blowfish mode
- now supports hashes marked $2a$, $2x$, $2y$ and $2z$.
-
-- mbstring now supports following encodings: Shift_JIS/UTF-8 Emoji,
- JIS X0213:2004 (Shift_JIS-2004, EUC-JP-2004, ISO-2022-JP-2004),
- MacJapanese (Shift_JIS), gb18030.
-
-- Added encode and decode in hex format to mb_encode_numericentity() and
- mb_decode_numericentity().
-
-- Added support for SORT_NATURAL and SORT_FLAG_CASE in array sort functions:
- sort(), rsort(), ksort(), krsort(), asort(), arsort() and array_multisort().
+========================================
+2. New Features
+========================================
-- is_a() and is_subclass_of() now have third boolean parameter, which specifies
- if the first argument can be a string class name. Default if false for is_a
- and true for is_subclass_of() for BC reasons.
+- Support list in foreach. (Laruence)
+ (http://php.net/foreach#control-structures.foreach.list,
+ http://wiki.php.net/rfc/foreachlist)
-- ob_start() will now treat a chunk size of 1 as meaning 1 byte, rather than
- the previous special case behavior of treating it as 4096 bytes.
+- Support "finally" keyword. (Laruence)
+ (http://php.net/exceptions, http://wiki.php.net/rfc/finally)
-- idn_to_ascii() and idn_to_utf8() now take two extra parameters, one indicating
- the variant (IDNA 2003 or UTS #46) and another, passed by reference, to return
- details about the operation in case UTS #46 is chosen.
+- Support constant array/string dereferencing. (Laruence)
+ (http://php.net/manual/en/language.types.array.php,
+ https://wiki.php.net/rfc/constdereference)
-- gzencode() used with FORCE_DEFLATE now generates RFC1950 compliant data.
+- Add support for using empty() on the result of function calls and
+ other expressions. Thus it is now possible to write empty(getArray()),
+ for example. (http://php.net/manual/en/function.empty.php,
+ https://wiki.php.net/rfc/empty_isset_exprs)
-- ob_start() no longer starts multiple output buffers when passed
- array("callback1", "callback2", "callback3", ...).
+- Added generators.
+ (http://php.net/generators, https://wiki.php.net/rfc/generators)
-- Since 5.4.4, "php://fd" stream syntax is available only in CLI build.
+- ClassName::class syntax returning full class name for a class as a
+ string constant. (http://php.net/oop5.basic,
+ https://wiki.php.net/rfc/class_name_scalars)
-- Since 5.4.5, resourcebundle_create() accepts null for the first two arguments.
+- Added support for non-scalar Iterator keys in foreach.
+ (http://php.net/manual/en/control-structures.foreach.php,
+ https://wiki.php.net/rfc/foreach-non-scalar-keys).
-- Since 5.4.6, SimpleXMLElement::getDocNamespaces() has and extra parameter which
- allows for toggling if the list of namespaces starts from the document root
- or from the node you call the method on
+- Bundled Zend OPcache extension to improve performance
+ (http://php.net/manual/en/book.opcache.php,
+ https://wiki.php.net/rfc/optimizerplus)
-- Since 5.4.7, ctor is always called when new user stream wrapper object is created.
- Before, it was called only when stream_open was called.
+- Added a simplified password hashing API
+ (http://php.net/password, https://wiki.php.net/rfc/password_hash)
-==============================
-5. Changes to existing classes
-==============================
+========================================
+2. Changes in SAPI modules
+========================================
-- Classes that implement stream wrappers can define a method called
- stream_truncate that will respond to truncation, e.g. through ftruncate.
- Strictly speaking, this is an addition to the user-space stream wrapper
- template, not a change to an actual class.
+- Support for changing the process's title in CLI/CLI-Server
+ SAPIs. (Keyur)
+ (http://php.net/manual/en/function.cli-set-process-title.php,
+ http://php.net/manual/en/function.cli-get-process-title.php,
+ https://wiki.php.net/rfc/cli_process_title)
-- Classes that implement stream wrappers can define a method called
- stream_metadata that will be called on touch(), chmod(), chgrp(), chown().
+- Support for systemd in php-fpm: Add --with-fpm-systemd option to
+ report health to systemd, and add systemd_interval option to
+ configure this. The service can now use Type=notify in the systemd
+ unit file. (Remi)
-- Arrays cast from SimpleXMLElement now always contain all nodes instead of
- just the first matching node.
+========================================
+3. Deprecated Functionality
+========================================
-- All SimpleXMLElement children are now always printed when using var_dump(),
- var_export(), and print_r().
+- The original MySQL extension is now deprecated and will generate
+ deprecation warnings when connecting to a database through
+ mysql_connect(), mysql_pconnect() or by establishing an implicit
+ connection. Use MySQLi or PDO instead.
-- Added iterator support in MySQLi. mysqli_result implements Traversable.
+- The preg_replace /e modifier is now deprecated. Use
+ preg_replace_callback instead.
+ (https://wiki.php.net/rfc/remove_preg_replace_eval_modifier)
-==============================
-6. Changes to existing methods
-==============================
+- IntlDateFormatter::setTimeZoneID() and datefmt_set_timezone_id() are
+ deprecated. Use IntlDateFormatter::setTimeZone() or
+ datefmt_set_timezone() instead.
-- DateTime::parseFromFormat() now has a "+" modifier to allow trailing text in
- the string to parse without throwing an error.
+- mcrypt_ecb(), mcrypt_cbc(), mcrypt_cfb() and mcrypt_ofb() now throw
+ E_DEPRECATED. Their use was already previously discouraged in the
+ documentation, but that predated the existence of E_DEPRECATED.
-- Added the ability to pass options to DOMDocument::loadHTML().
+========================================
+4. Changed Functions
+========================================
-- FilesystemIterator, GlobIterator and (Recursive)DirectoryIterator now use
- the default stream context.
+- pack()/unpack() had the following changes, which bring it more in
+ line with Perl's behavior: - Implemented format character "Z": NULL
+ padded string, with trailing NULL bytes removed. - Changed format
+ character "a": this no longer removes trailing NULL bytes. -
+ Changed format character "A": all trailing ASCII whitespace is now
+ removed (defined as spaces, tabs, \r, \n and NULL).
+
+- MessageFormatter::format() and related functions now accepted named
+ arguments and mixed numeric/named arguments in ICU 4.8+.
+
+- MessageFormatter::format() and related functions now don't error out
+ when an insufficient argument count is provided. Instead, the
+ placeholders will remain unsubstituted.
+
+- MessageFormatter::parse() and MessageFormat::format() (and their
+ static equivalents) now don't throw away better than second
+ precision in the arguments.
+
+- IntlDateFormatter::__construct and datefmt_create() now accept for
+ the $timezone argument time zone identifiers, IntlTimeZone objects,
+ DateTimeZone objects and NULL. It used to accept only time zone
+ identifiers and NULL. Invalid time zone identifiers are no longer
+ accepted. Empty strings are no longer accepted.
+
+- The default time zone used in IntlDateFormatter::__construct and
+ datefmt_create() (when the corresponding argument is not passed or
+ NULL is passed) is now the one given by date_default_timezone_get(),
+ not the default ICU time zone.
+
+- The time zone passed to the IntlDateFormatter is ignored if it is
+ NULL and if the calendar passed is an IntlCalendar object -- in this
+ case, the IntlCalendar's time zone will be used instead. Otherwise,
+ the time zone specified in the $timezone argument is used
+ instead. This does not affect old code, as IntlCalendar was
+ introduced in this version.
+
+- IntlDateFormatter::__construct and datefmt_create() now accept for
+ the $calendar argument also IntlCalendar objects.
+
+- IntlDateFormatter::getCalendar() and datefmt_get_calendar() return
+ false if the IntlDateFormatter was set up with an IntlCalendar
+ instead of the constants
+ IntlDateFormatter::GREGORIAN/TRADITIONAL. IntlCalendar did not exist
+ before this version.
+
+- IntlDateFormatter::setCalendar() and datefmt_set_calendar() now also
+ accept an IntlCalendar object, in which case its time zone is
+ taken. Passing a constant is still allowed, and still keeps the time
+ zone.
+
+- IntlDateFormatter::format() and datefmt_format() now also accept an
+ IntlCalendar object for formatting.
+
+- set_error_handler(NULL) can now be used to reset the error handler.
+ Furthermore both set_error_handler(NULL) and
+ set_exception_handler(NULL) will now return the previously defined
+ error/exception handler. Previously bool(true) was returned.
+
+- setcookie(), setrawcookie() and ext/session now send Max-Age headers
+ alongside Expires headers. (see
+ https://wiki.php.net/rfc/cookie_max-age)
+
+- curl_setopt now accepts new option CURLOPT_SAFE_UPLOAD and CURLFile
+ object for safer file uploads (see
+ https://wiki.php.net/rfc/curl-file-upload)
+
+- Functions in the socket extension now do not emit warnings when the
+ errno is EAGAIN, EWOULDBLOCK or EINPROGRESS.
+
+- Since 5.5.2, spl_autoload_functions() returns different names for
+ different lambda functions registered via spl_autoload_register().
+
+- Since 5.5.3, DOMDocument::schemaValidateSource() and
+ DOMDocument::schemaValidate() accept flag parameter. Only flag
+ available now is LIBXML_SCHEMA_CREATE. Default is 0.
+
+- Since 5.5.4, fputcsv() has fifth parameter escape_char, allowing to
+ specify escape char.
-- Since 5.4.5, the constructor of ResourceBundle accepts NULL for the first two
- arguments.
+========================================
+5. New Functions
+========================================
-===========================
-7. Deprecated Functionality
-===========================
+- Core:
+ - array_column()
+ - boolval()
+ - password_get_info()
+ - password_hash()
+ - password_needs_rehash()
+ - password_verify()
+
+- cURL:
+ - curl_file_create
+
+- GD
+ - imageflip
+ - imagecrop
+ - imagecropauto
+ - imagesetinterpolation
+ - imageaffine
+ - imageaffinematrixget
+ - imageaffinematrixconcat
+ - imagescale
+
+- Hash:
+ - hash_pbkdf2()
+
+- Intl:
+ - datefmt_format_object()
+ - datefmt_get_calendar_object()
+ - datefmt_get_timezone()
+ - datefmt_set_timezone()
+ - datefmt_get_calendar_object()
+ - intlcal_create_instance()
+ - intlcal_get_keyword_values_for_locale()
+ - intlcal_get_now()
+ - intlcal_get_available_locales()
+ - intlcal_get()
+ - intlcal_get_time()
+ - intlcal_set_time()
+ - intlcal_add()
+ - intlcal_set_time_zone()
+ - intlcal_after()
+ - intlcal_before()
+ - intlcal_set()
+ - intlcal_roll()
+ - intlcal_clear()
+ - intlcal_field_difference()
+ - intlcal_get_actual_maximum()
+ - intlcal_get_actual_minimum()
+ - intlcal_get_day_of_week_type()
+ - intlcal_get_first_day_of_week()
+ - intlcal_get_greatest_minimum()
+ - intlcal_get_least_maximum()
+ - intlcal_get_locale()
+ - intlcal_get_maximum()
+ - intlcal_get_minimal_days_in_first_week()
+ - intlcal_get_minimum()
+ - intlcal_get_time_zone()
+ - intlcal_get_type()
+ - intlcal_get_weekend_transition()
+ - intlcal_in_daylight_time()
+ - intlcal_is_equivalent_to()
+ - intlcal_is_lenient()
+ - intlcal_is_set()
+ - intlcal_is_weekend()
+ - intlcal_set_first_day_of_week()
+ - intlcal_set_lenient()
+ - intlcal_equals()
+ - intlcal_get_repeated_wall_time_option()
+ - intlcal_get_skipped_wall_time_option()
+ - intlcal_set_repeated_wall_time_option()
+ - intlcal_set_skipped_wall_time_option()
+ - intlcal_from_date_time()
+ - intlcal_to_date_time()
+ - intlcal_get_error_code()
+ - intlcal_get_error_message()
+ - intlgregcal_create_instance()
+ - intlgregcal_set_gregorian_change()
+ - intlgregcal_get_gregorian_change()
+ - intlgregcal_is_leap_year()
+ - intltz_create_time_zone()
+ - intltz_create_default()
+ - intltz_get_id()
+ - intltz_get_gmt()
+ - intltz_get_unknown()
+ - intltz_create_enumeration()
+ - intltz_count_equivalent_ids()
+ - intltz_create_time_zone_id_enumeration()
+ - intltz_get_canonical_id()
+ - intltz_get_region()
+ - intltz_get_tz_data_version()
+ - intltz_get_equivalent_id()
+ - intltz_use_daylight_time()
+ - intltz_get_offset()
+ - intltz_get_raw_offset()
+ - intltz_has_same_rules()
+ - intltz_get_display_name()
+ - intltz_get_dst_savings()
+ - intltz_from_date_time_zone()
+ - intltz_to_date_time_zone()
+ - intltz_get_error_code()
+ - intltz_get_error_message()
+
+ - IntlDateFormatter::formatObject()
+ - IntlDateFormatter::getCalendarObject()
+ - IntlDateFormatter::getTimeZone()
+ - IntlDateFormatter::setTimeZone()
+
+- Sockets:
+ - socket_sendmsg()
+ - socket_recvmsg()
+ - socket_cmsg_space()
+
+- SPL:
+ - SplFixedArray::__wakeup()
+ - SplDoublyLinkedList::add()
+ - RecursiveTreeIterator::getPostfix() (5.5.2)
+ - RecursiveTreeIterator::setPostfix() (5.5.2)
+
+- Zend OPcache:
+ - opcache_get_configuration()
+ - opcache_get_status()
+ - opcache_reset()
-- The following functions are deprecated in PHP 5.4:
- - mcrypt_generic_end(): use mcrypt_generic_deinit() instead
- - mysql_list_dbs()
+========================================
+6. New Classes and Interfaces
+========================================
-========================
-8. Removed Functionality
-========================
+- Intl:
+ - IntlCalendar
+ - IntlGregorianCalendar
+ - IntlTimeZone
+ - IntlBreakIterator
+ - IntlRuleBasedBreakIterator
+ - IntlCodePointBreakIterator
+ - UConverter
-a. Removed features
+- cURL:
+ - CURLFile
- The following features have been removed from PHP 5.4:
+========================================
+7. Removed Extensions
+========================================
- - Magic quotes
- - Register globals
- - Safe mode
- - Session extension bug compatibility mode
- - Y2K compliance mode
+None
-b. Removed functions
+========================================
+8. Other Changes to Extensions
+========================================
- The following functions are no longer available in PHP 5.4:
+- Intl:
+ - This extension now requires ICU 4.0+.
+- Phar:
+ - Added ability of resolving alias created by Phar::map
- - define_syslog_variables()
- - import_request_variables()
- - session_is_registered()
- - session_register()
- - session_unregister()
- - set_magic_quotes_runtime()
- - mysqli_bind_param() (alias of mysqli_stmt_bind_param())
- - mysqli_bind_result() (alias of mysqli_stmt_bind_result())
- - mysqli_client_encoding() (alias of mysqli_character_set_name())
- - mysqli_fetch() (alias of mysqli_stmt_fetch())
- - mysqli_param_count() (alias of mysqli_stmt_param_count())
- - mysqli_get_metadata() (alias of mysqli_stmt_result_metadata())
- - mysqli_send_long_data() (alias of mysqli_stmt_send_long_data())
- - mysqli::client_encoding() (alias of mysqli::character_set_name)
- - mysqli_stmt::stmt() (never worked/always throws, undocumented)
+========================================
+9. New Global Constants
+========================================
-c. Removed syntax
+- mysqli:
+ - Added MYSQLI_SERVER_PUBLIC_KEY constant to be used with mysqli_options()
+
+- cURL:
+ - Added CURLOPT_SAFE_UPLOAD to be used with curl_setopt().
+ - Added CURL_WRAPPERS_ENABLED to reflect --with-curlwrappers.
+
+- GD
+ - Added constants for imageflip:
+ . IMG_FLIP_HORIZONTAL
+ . IMG_FLIP_VERTICAL
+ . IMG_FLIP_BOTH
+ - Added constants for imagecrop
+ . IMG_CROP_DEFAULT
+ . IMG_CROP_TRANSPARENT
+ . IMG_CROP_BLACK
+ . IMG_CROP_WHITE
+ . IMG_CROP_SIDES
+ . IMG_CROP_THRESHOLD
+ - Added constants for imagesetinterpolation, used by imagescale
+ imagerotate and imageaffine:
+ . IMG_BELL
+ . IMG_BESSEL
+ . IMG_BILINEAR_FIXED
+ . IMG_BICUBIC
+ . IMG_BICUBIC_FIXED
+ . IMG_BLACKMAN
+ . IMG_BOX
+ . IMG_BSPLINE
+ . IMG_CATMULLROM
+ . IMG_GAUSSIAN
+ . IMG_GENERALIZED_CUBIC
+ . IMG_HERMITE
+ . IMG_HAMMING
+ . IMG_HANNING
+ . IMG_MITCHELL
+ . IMG_POWER
+ . IMG_QUADRATIC
+ . IMG_SINC
+ . IMG_NEAREST_NEIGHBOUR
+ . IMG_WEIGHTED4
+ . IMG_TRIANGLE
+ - Added constants for imageaffinematrixget
+ . IMG_AFFINE_TRANSLATE
+ . IMG_AFFINE_SCALE
+ . IMG_AFFINE_ROTATE
+ . IMG_AFFINE_SHEAR_HORIZONTAL
+ . IMG_AFFINE_SHEAR_VERTICAL
- - break $var;
- - continue $var;
+========================================
+10. Changes to INI File Handling
+========================================
-d. Removed hash algorithms
+- Core:
+ - Added sys_temp_dir INI directive, for specifying temporary
+ directory.
+
+- Intl:
+ - Added intl.use_exceptions INI directive, which controls what
+ happens when global errors are set together with intl.error_level.
+
+- MSSQL:
+ - mssql.compatability_mode renamed to mssql.compatibility_mode in 5.5.2,
+ old directive still supported for BC reasons.
+
+- mysqlnd:
+ - Added mysqlnd.sha256_server_public_key INI PERDIR setting that
+ affects all APIs which use(are built) for mysqlnd. This allows
+ ext/mysqli to be used with the new auth protocol, although at
+ coarser level.
+
+- Sessions:
+ - Added session.use_strict_mode in 5.5.3, which prevents session
+ fixation attacks and session collisions.
+ See also https://wiki.php.net/rfc/strict_sessions
+
+- Zend OPcache (See http://php.net/manual/en/book.opcache.php)
+ - Added the following directives:
+ - opcache.enable (default "1")
+ - opcache.memory_consumption (default "64")
+ - opcache.interned_strings_buffer (default "4")
+ - opcache.max_accelerated_files (default "2000")
+ - opcache.max_wasted_percentage (default "5")
+ - opcache.use_cwd (default "1")
+ - opcache.validate_timestamps (default "1")
+ - opcache.revalidate_freq (default "2")
+ - opcache.revalidate_path (default "0")
+ - opcache.save_comments (default "1")
+ - opcache.load_comments (default "1")
+ - opcache.fast_shutdown (default "0")
+ - opcache.enable_file_override (default "0")
+ - opcache.optimization_level (default "0xffffffff")
+ - opcache.inherited_hack (default "1")
+ - opcache.blacklist_filename (default "")
+ - opcache.max_file_size (default "0")
+ - opcache.consistency_checks (default "0")
+ - opcache.force_restart_timeout (default "180")
+ - opcache.error_log (default "" which means stderr)
+ - opcache.log_verbosity_level (default "1")
+ - opcache.preferred_memory_model (default "")
+ - opcache.protect_memory (default "0")
+ - opcache.mmap_base (Windows-only)
- - Salsa10 and Salsa20, which are actually stream ciphers
+========================================
+11. Windows Support
+========================================
-====================
-9. Extension Changes
-====================
+- The Apache 2.4 handler is supported as of PHP 5.5.0
-a. Extensions no longer maintained
+- OPcache: Errors like 'unable to reattach to base address' could
+ happen in many common setups. It is due to some technical and
+ design restriction in the engine and could not be fixed easily
+ before 5.5.0 was released.
- - ext/sqlite is no longer part of the base distribution and has been moved
- to PECL. Use sqlite3 or PDO_SQLITE instead.
+ A possible fix is to tweak the opcache.mmap_base INI setting by
+ forcing the first address to be tried.
-b. Extensions with changed behavior
+ For x86 version, the following addreses can be tried:
+ . 0x20000000, 0x21000000, 0x30000000, 0x31000000, 0x50000000
+ and for x64 (still experimental):
+ . 0x0000100000000000, 0x0000200000000000, 0x0000300000000000, 0x0000700000000000
- - The MySQL extensions (ext/mysql, mysqli and PDO_MYSQL) use mysqlnd
- as the default library now. It is still possible to use libmysql by
- specifying a path to the configure options.
+========================================
+12. Other Changes
+========================================
- - PDO_MYSQL: Support for linking with MySQL client libraries older
- than 4.1 is removed.
+- If the APC or WinCache user cache APIs were used before, consider
+ these alternatives for PHP 5.5:
- - The session extension now can hook into the file upload feature
- in order to provide upload progress information through session
- variables.
+ - APCu
+ - all supported OSes: http://pecl.php.net/package/APCu
+ - Windows: http://windows.php.net/downloads/pecl/releases/apcu/
- - SNMP extension
- - Functions in SNMP extension now returns FALSE on every error
- condition including SNMP-related (no such instance, end of MIB,
- etc). Thus, in patricular, breaks previous behavior of get/walk
- functions returning an empty string on SNMP-related errors.
- - Multi OID get/getnext/set queries are now supported.
- - New constants added for use in snmp_set_oid_output_format()
- function.
- - Function snmp_set_valueretrieval() changed it's behavior:
- SNMP_VALUE_OBJECT can be combined with one of
- SNMP_VALUE_PLAIN or SNMP_VALUE_LIBRARY resulting OID value
- changes. When no SNMP_VALUE_PLAIN or SNMP_VALUE_LIBRARY
- is supplied with SNMP_VALUE_OBJECT, SNMP_VALUE_LIBRARY is used.
- Prior to 5.4.0 when no SNMP_VALUE_PLAIN or SNMP_VALUE_LIBRARY
- was supplied with SNMP_VALUE_OBJECT, SNMP_VALUE_PLAIN was used.
- - Added feature-rich OO API (SNMP class)
- - Dropped UCD-SNMP compatibility code. Consider upgrading to
- net-snmp v5.3+. Net-SNMP v5.4+ is required for Windows version.
- - In sake of adding support for IPv6 DNS name resolution of
- remote SNMP agent (peer) is done by extension now, not by Net-SNMP
- library anymore.
-
- - Date extension
- - Setting the timezone with the TZ environment variable is no longer
- supported, instead date.timezone and/or date_default_timezone_set()
- have to be used.
- - The extension will no longer guess the default timezone if none
- is set with date.timezone and/or date_default_timezone_set().
- Instead it will always fall back to "UTC".
-
- - Hash extension
- - the output of the tiger hash family has been corrected, see
- https://bugs.php.net/61307
-
-===========================
-10. Changes in SAPI support
-===========================
-
-- A REQUEST_TIME_FLOAT value returns a floating point number indicating the
- time with microsecond precision. All SAPIs providing this value should be
- returning float and not time_t.
-
-- apache_child_terminate(), getallheaders(), apache_request_headers()
- and apache_response_headers() are now supported on FastCGI.
-
-- The interactive shell allows a shortcut #inisetting=value to change php.ini
- settings at run-time.
-
-- The interactive shell now works with the shared readline extension.
-
-- The interactive shell no longer terminates on fatal errors.
-
-- A new PHP CLI command line option --rz <name> shows information about the
- named Zend extension.
-
-===================
-11. Windows support
-===================
-
-- is_link now works properly for symbolic links on Windows Vista
- or later. Earlier systems do not support symbolic links.
-
-- As of PHP 5.4.5 and above the COM extension isn't compiled statically in PHP
- anymore but shared. It'll still be delivered with the standard PHP release but
- must be activated manually with the "extension = php_com_dotnet.dll" directive
- in php.ini.
-
-- Apache 2.4 handler is supported as of PHP 5.4.9
-
-==================
-12. New in PHP 5.4
-==================
-
-a. New Features
-
- - A built-in CLI web server for testing purposes is now available:
- $ php -S 127.0.0.1:8888
-
- - File Upload Progress support is implemented in the Session extension.
-
-b. Syntax additions
-
- - Traits:
- trait HelloWorld {
- public function sayHello() {
- echo 'Hello World!';
- }
- }
-
- class CanIGetHello {
- use HelloWorld;
- }
-
- $hello = new CanIGetHello();
- $hello->sayHello();
-
- - Function call result array access, e.g.:
- foo()[0]
- $foo->bar()[0]
-
- - Callable typehint indicating argument must be callable:
- function foo(callable $do) {
- }
- foo("strcmp");
- foo(function() {});
- $o = new ArrayObject();
- foo(array($o, "count"));
-
- - Short array syntax:
- $a = [1, 2, 3, 4];
- $a = ['one' => 1, 'two' => 2, 'three' => 3, 'four' => 4];
- $a = ['one' => 1, 2, 'three' => 3, 4];
-
- - Binary number format:
- 0b00100 0b010101
-
- - Chained string array offsets now work.
- $a = "abc";
- echo $a[0][0];
-
- - Anonymous functions now support using $this and class scope.
- Anonymous function can be declared as "static" to ignore the scope.
-
- - Class::{expr}() syntax is now supported:
- class A {
- static function foo() {
- echo "Hello world!\n";
- }
- }
- $x = "f";
- $y = "o";
- A::{$x.$y.$y}();
-
- - Class member access on instantiation:
- (new foo)->method()
- (new foo)->property
- (new foo)[0]
-
-
-c. New functions
-
- - Core:
- - get_declared_traits()
- - getimagesizefromstring()
- - hex2bin()
- - header_register_callback()
- - http_response_code()
- - stream_set_chunk_size()
- - socket_import_stream()
- - trait_exists()
-
- - Intl:
- - transliterator_create()
- - transliterator_create_from_rules()
- - transliterator_create_inverse()
- - transliterator_get_error_code()
- - transliterator_get_error_message()
- - transliterator_list_ids()
- - transliterator_transliterate()
-
- - LDAP:
- - ldap_control_paged_result()
- - ldap_control_paged_result_response()
-
- - libxml:
- - libxml_set_external_entity_loader()
-
- - mysqli:
- - mysqli_error_list()
- - mysqli_stmt_error_list()
-
- - pgsql
- - pg_escape_identifier() (5.4.4)
- - pg_escape_literal() (5.4.4)
-
- - Session:
- - session_register_shutdown()
- - session_status()
-
- - SPL
- - class_uses()
-
- - SplFixedArray
- - SplFixedArray::__wakeup() (5.4.18)
-
-d. New global constants
-
- - CURLOPT_MAX_RECV_SPEED_LARGE
- - CURLOPT_MAX_SEND_SPEED_LARGE
- - ENT_DISALLOWED
- - ENT_HTML401
- - ENT_HTML5
- - ENT_SUBSTITUTE
- - ENT_XHTML
- - ENT_XML1
- - IPPROTO_IP
- - IPPROTO_IPV6
- - IPV6_MULTICAST_HOPS
- - IPV6_MULTICAST_IF
- - IPV6_MULTICAST_LOOP
- - IP_MULTICAST_IF
- - IP_MULTICAST_LOOP
- - IP_MULTICAST_TTL
- - JSON_BIGINT_AS_STRING
- - JSON_OBJECT_AS_ARRAY
- - JSON_PRETTY_PRINT
- - JSON_UNESCAPED_SLASHES
- - JSON_UNESCAPED_UNICODE
- - LIBXML_HTML_NODEFDTD
- - LIBXML_HTML_NOIMPLIED
- - LIBXML_PEDANTIC
- - MCAST_JOIN_GROUP
- - MCAST_LEAVE_GROUP
- - MCAST_BLOCK_SOURCE
- - MCAST_UNBLOCK_SOURCE
- - MCAST_JOIN_SOURCE_GROUP
- - MCAST_LEAVE_SOURCE_GROUP
- - OPENSSL_CIPHER_AES_128_CBC
- - OPENSSL_CIPHER_AES_192_CBC
- - OPENSSL_CIPHER_AES_256_CBC
- - OPENSSL_RAW_DATA
- - OPENSSL_ZERO_PADDING
- - PHP_OUTPUT_HANDLER_CLEAN
- - PHP_OUTPUT_HANDLER_CLEANABLE
- - PHP_OUTPUT_HANDLER_DISABLED
- - PHP_OUTPUT_HANDLER_FINAL
- - PHP_OUTPUT_HANDLER_FLUSH
- - PHP_OUTPUT_HANDLER_FLUSHABLE
- - PHP_OUTPUT_HANDLER_REMOVABLE
- - PHP_OUTPUT_HANDLER_STARTED
- - PHP_OUTPUT_HANDLER_STDFLAGS
- - PHP_OUTPUT_HANDLER_WRITE
- - PHP_QUERY_RFC1738
- - PHP_QUERY_RFC3986
- - PHP_SESSION_ACTIVE
- - PHP_SESSION_DISABLED
- - PHP_SESSION_NONE
- - SCANDIR_SORT_ASCENDING
- - SCANDIR_SORT_DESCENDING
- - SCANDIR_SORT_NONE
- - SORT_FLAG_CASE
- - SORT_NATURAL
- - STREAM_META_ACCESS
- - STREAM_META_GROUP
- - STREAM_META_GROUP_NAME
- - STREAM_META_OWNER
- - STREAM_META_OWNER_NAME
- - STREAM_META_TOUCH
- - T_CALLABLE
- - T_INSTEADOF
- - T_TRAIT
- - T_TRAIT_C
- - ZLIB_ENCODING_DEFLATE
- - ZLIB_ENCODING_GZIP
- - ZLIB_ENCODING_RAW
- - U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR
- - IDNA_CHECK_BIDI
- - IDNA_CHECK_CONTEXTJ
- - IDNA_NONTRANSITIONAL_TO_ASCII
- - IDNA_NONTRANSITIONAL_TO_UNICODE
- - INTL_IDNA_VARIANT_2003
- - INTL_IDNA_VARIANT_UTS46
- - IDNA_ERROR_EMPTY_LABEL
- - IDNA_ERROR_LABEL_TOO_LONG
- - IDNA_ERROR_DOMAIN_NAME_TOO_LONG
- - IDNA_ERROR_LEADING_HYPHEN
- - IDNA_ERROR_TRAILING_HYPHEN
- - IDNA_ERROR_HYPHEN_3_4
- - IDNA_ERROR_LEADING_COMBINING_MARK
- - IDNA_ERROR_DISALLOWED
- - IDNA_ERROR_PUNYCODE
- - IDNA_ERROR_LABEL_HAS_DOT
- - IDNA_ERROR_INVALID_ACE_LABEL
- - IDNA_ERROR_BIDI
- - IDNA_ERROR_CONTEXTJ
-
-e. New classes
-
- - Reflection:
- - ReflectionZendExtension
-
- - Intl:
- - Transliterator
- - Spoofchecker
-
- - JSON:
- - JsonSerializable
-
- - Session:
- - SessionHandler
-
- - SNMP:
- - SNMP
-
- - SPL:
- - CallbackFilterIterator
- - RecursiveCallbackFilterIterator
-
-f. New methods
-
- - Closure:
- - Closure::bind()
- - Closure::bindTo()
-
- - Reflection:
- - ReflectionClass::getTraitAliases()
- - ReflectionClass::getTraitNames()
- - ReflectionClass::getTraits()
- - ReflectionClass::isCloneable()
- - ReflectionClass::isTrait()
- - ReflectionClass::newInstanceWithoutConstructor()
- - ReflectionExtension::isPersistent()
- - ReflectionExtension::isTemporary()
- - ReflectionFunction::getClosure()
- - ReflectionFunction::getClosureScopeClass()
- - ReflectionFunction::getClosureThis()
- - ReflectionFunctionAbstract::getClosureScopeClass()
- - ReflectionFunctionAbstract::getClosureThis()
- - ReflectionMethod::getClosure()
- - ReflectionMethod::getClosureScopeClass()
- - ReflectionMethod::getClosureThis()
- - ReflectionObject::getTraitAliases()
- - ReflectionObject::getTraitNames()
- - ReflectionObject::getTraits()
- - ReflectionObject::isCloneable()
- - ReflectionObject::isTrait()
- - ReflectionObject::newInstanceWithoutConstructor()
- - ReflectionParameter::canBePassedByValue()
- - ReflectionParameter::isCallable()
-
- - PDO_DBLIB:
- - PDO::newRowset()
-
- - SPL:
- - DirectoryIterator::getExtension()
- - RegexIterator::getRegex()
- - SplDoublyLinkedList::serialize()
- - SplDoublyLinkedList::unserialize()
- - SplFileInfo::getExtension()
- - SplFileObject::fputcsv()
- - SplObjectStorage::getHash()
- - SplQueue::serialize
- - SplQueue::unserialize
- - SplStack::serialize
- - SplStack::unserialize
- - SplTempFileObject::fputcsv
-
- - XSLT:
- - XsltProcessor::setSecurityPrefs()
- - XsltProcessor::getSecurityPrefs()
-
- - Zlib:
- - zlib_decode()
- - zlib_encode()
-
-g. New Hash algorithms
-
- - fnv132
- - fnv164
- - joaat
+ - WinCache, Windows only: http://pecl.php.net/package/WinCache
diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS
index e9d0adf554..bdc2a43ab9 100644
--- a/UPGRADING.INTERNALS
+++ b/UPGRADING.INTERNALS
@@ -3,15 +3,11 @@ $Id$
UPGRADE NOTES - PHP X.Y
1. Internal API changes
- a. virtual_file_ex
- b. stat/lstat support
- c. readlink support
- d. layout of some core ZE structures (zend_op_array, zend_class_entry, ...)
- e. Zend\zend_fast_cache.h has been removed
- f. streams that enclose private streams
- g. leak_variable
- h. API Signature changes
- i. new TSRM function expand_filepath_with_mode
+ a. Executor changes
+ b. Streams pooling API
+ c. Lowercasing and locales
+ d. zend_qsort_r
+ e. get_current_key
2. Build system changes
a. Unix build system changes
@@ -22,186 +18,103 @@ UPGRADE NOTES - PHP X.Y
1. Internal API changes
========================
- a. virtual_file_ex
-
-virtual_file_ex takes now a TSRM context as last parameter:
-CWD_API int virtual_file_ex(cwd_state *state, const char *path,
- verify_path_func verify_path, int use_realpath TSRLS_DC);
-
-
- b. stat/lstat support
-
-lstat is now available on all platforms. On unix-like platform
-php_sys_lstat is an alias to lstat (when avaible). On Windows it is now
-available using php_sys_lstat. php_sys_stat and php_sys_lstat usage is recommended
-instead of calling lstat directly, to ensure portability.
-
-
- c. readlink support
-
-readlink is now available on all platforms. On unix-like platform
-php_sys_readlink is an alias to readlink (when avaible). On Windows it is now
-available using php_sys_readlink. php_sys_readlink usage is recommended
-instead of calling readlink directly, to ensure portability.
-
-
- d. layout of some core ZE structures (zend_op_array, zend_class_entry, ...)
-
-. zend_function.pass_rest_by_reference is replaced by
- ZEND_ACC_PASS_REST_BY_REFERENCE in zend_function.fn_flags
-. zend_function.return_reference is replaced by ZEND_ACC_RETURN_REFERENCE
- in zend_function.fn_flags
-. zend_arg_info.required_num_args removed. it was needed only for internal
- functions. Now the first arg_info for internal function (which has special
- meaning) is represented by zend_internal_function_info structure.
-. zend_op_array.size, size_var, size_literal, current_brk_cont,
- backpatch_count moved into CG(context), because they are used only during
- compilation.
-. zend_op_array.start_op is moved into EG(start_op), because it's used
- only for 'interactive' execution of single top-level op-array.
-. zend_op_array.done_pass_two is replaced by ZEND_ACC_DONE_PASS_TWO in
- zend_op_array.fn_flags.
-. op_array.vars array is trimmed (reallocated) during pass_two.
-. zend_class_entry.constants_updated is replaced by
- ZEND_ACC_CONSTANTS_UPDATED in zend_class_entry.ce_flags
-. the size of zend_class_entry is reduced by sharing the same memory space
- by different information for internal and user classes.
- See zend_class_inttry.info union.
-
-
- e. Zend\zend_fast_cache.h
-
-It should not have been used anymore since php5, but now this header has
-been removed. The following macros are not available anymore:
-
-ZEND_FAST_ALLOC(p, type, fc_type)
-ZEND_FAST_FREE(p, fc_type)
-ZEND_FAST_ALLOC_REL(p, type, fc_type)
-ZEND_FAST_FREE_REL(p, fc_type)
-
-Use emalloc, emalloc_rel, efree or efree_rel instead.
-
-
- f. Streams that enclose private streams
-
-Some streams, like the temp:// stream, may enclose private streams. If the
-outer stream leaks due to a programming error or is not exposed through a
-zval (and therefore is not deleted when all the zvals are gone), it will
-be destroyed on shutdown.
-The problem is that the outer usually wants itself to close the inner stream,
-so that it may do any other shutdown action that requires the inner stream to
-be live (e.g. commit data to it). If the outer stream is exposed through a
-zval and the inner one isn't, this is not a problem because the outer stream
-will be freed when the zval is destroyed, which happens before the resources
-are destroyed on shutdown.
-On resource list shutdown, the cleanup happens in reverse order of resource
-creation, so if the inner stream was created in the opener of the outer stream,
-it will be destroyed first.
-The following functions were added to the streams API to force a predictable
-destruction order:
-
-PHPAPI php_stream *php_stream_encloses(php_stream *enclosing, php_stream *enclosed);
-#define php_stream_free_enclosed(stream_enclosed, close_options)
-PHPAPI int _php_stream_free_enclosed(php_stream *stream_enclosed, int close_options TSRMLS_DC);
-
-Additionally, the following member was added to php_stream:
-
- struct _php_stream *enclosing_stream;
-
-and the following macro was added:
-
-#define PHP_STREAM_FREE_IGNORE_ENCLOSING 32
-
-The function php_stream_encloses declares the first stream encloses the second.
-This has the effect that, when the inner stream is closed from a resource
-destructor it will abort and try to free its enclosing stream instead.
-To prevent this from happening when the inner stream is freed from the outer
-stream, the macro php_stream_free_enclosed should be used instead of
-php_stream_free/php_stream_close/php_stream_pclose, or the flag
-PHP_STREAM_FREE_IGNORE_ENCLOSING should be directly passed to php_stream_free.
-The outer stream cannot abstain, in its close callback, from closing the inner
-stream or clear the enclosing_stream pointer in its enclosed stream by calling
-php_stream_encloses with the 2nd argument NULL. If this is not done, there will
-be problems, so observe this requirement when using php_stream_encloses.
-
-
- g. leak_variable
-
-The function leak_variable(variable [, leak_data]) was added. It is only
-available on debug builds. It increments the refcount of a zval or, if the
-second argument is true and the variable is either an object or a resource
-it increments the refcounts of those objects instead.
-
-
- h. API Signature changes
-
-. zend_list_insert
- ZEND_API int zend_list_insert(void *ptr, int type TSRMLS_DC);
- call: zend_list_insert(a, SOMETYPE TSRMLS_CC);
- NB: If zend_list_insert is used to register a resource,
- ZEND_REGISTER_RESOURCE could be used instead.
-
-. php_le_stream_context(TSRMLS_C)
- PHPAPI php_stream_context *php_stream_context_alloc(TSRMLS_D)
- call: context = php_stream_context_alloc(TSRMLS_C);
-
-. php_stream_context_alloc
- PHPAPI php_stream_context *php_stream_context_alloc(TSRMLS_D);
- call: context = php_stream_context_alloc(TSRMLS_C);
-
-. sapi_get_request_time(TSRMLS_D);
- SAPI_API double sapi_get_request_time(TSRMLS_D);
-
-. sapi_register_default_post_reader
- SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(TSRMLS_D) TSRMLS_DC);
-
-. sapi_register_treat_data
- SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray TSRMLS_DC) TSRMLS_DC);
-
-. sapi_register_input_filter
- SAPI_API int sapi_register_input_filter(unsigned int (*input_filter)(int arg, char *var, char **val, unsigned int val_len, unsigned int *new_val_len TSRMLS_DC), unsigned int (*input_filter_init)(TSRMLS_D) TSRMLS_DC);
-
-. tsrm_win32_access
- TSRM_API int tsrm_win32_access(const char *pathname, int mode TSRMLS_DC);
-
-. popen_ex (win32)
- TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd, char *env TSRMLS_DC);
-
-. php_get_current_user
- PHPAPI php_get_current_user(TSRMLS_D)
- Call: char *user = php_get_current_user(TSRMLS_C);
-
-. php_idate
- PHPAPI php_idate(char format, time_t ts, int localtime TSRMLS_DC)
- Call: int ret = php_idate(format, ts, localtime TSRMLS_CC)
-
-. php_escape_html_entities
- (size_t parameters were ints, previous "quote_style" (now flags) has expanded meaning)
- PHPAPI char *php_escape_html_entities(unsigned char *old, size_t oldlen, size_t *newlen, int all, int flags, char *hint_charset TSRMLS_DC);
-
-. php_escape_html_entities_ex
- PHPAPI char *php_escape_html_entities_ex(unsigned char *old, size_t oldlen, size_t *newlen, int all, int flags, char *hint_charset, zend_bool double_encode TSRMLS_DC);
-
-. php_unescape_html_entities
- PHPAPI char *php_unescape_html_entities(unsigned char *old, size_t oldlen, size_t *newlen, int all, int flags, char *hint_charset TSRMLS_DC);
-
- i.
- PHPAPI char *expand_filepath_with_mode(const char *filepath, char *real_path, const char *relative_to, size_t relative_to_len, int realpath_mode TSRMLS_DC);
- expand_filepath_with_mode lets define how realpath will behave, using one of the existing mode: CWD_EXPAND , CWD_FILEPATH or CWD_REALPATH.
+ a. Executor changes
+
+ * extensions can't override zend_execute() any more, they should override
+ zend_execute_ex() instead. The EG(current_execute_data) is already
+ initialized in zend_execute_ex(), so for compatibility extensions
+ may need to use EG(current_execute_data)->prev_execute_data instead.
+ * removed EG(arg_types_stack), EX(fbc), EX(called_scope), EX(current_object)
+ * added op_array->nested_calls. It's calculated at compile time.
+ * added EX(call_slots). It is an array to store information about syntaticaly
+ nested calls (e.g. foo(bar())). It's preallocated together with execute_data.
+ * added EX(call) - pointer to a current calling function. Actually an
+ element of EX(call_slots)
+ * opcodes INIT_METHOD_CALL, ZEND_INIT_STATIC_METHOD_CALL,
+ ZEND_INIT_FCALL_BY_NAME, ZEND_INIT_NS_FCALL_BY_NAME use result.num as
+ an index in EX(call_slots)
+ * opcode ZEND_NEW uses extended_vallue as an index in EX(call_slots)
+ * opcoes ZEND_DO_FCALL and ZEND_DO_FCALL_BY_NAME use op2.num as
+ an index in EX(call_slots)
+ * added op_array->used_stack. It's calculated at compile time and the
+ corresponding stack space is preallocated together with execute_data.
+ ZEND_SEND* and ZEND_DO_FCALL* don't need to check for stack overflow
+ anymore.
+ * Removed execute_data->Ts field. The VM temporary variables always allocated
+ immediately before execute_data structure. Now they are accessed by offset
+ from the execute_data base pointer (instead of execute_data->Ts). Compiler
+ stores new offsets in op_array->opcodes[*].op?.num. You can use macros
+ EX_TMP_VAR() and EX_TMP_VAR_NUM() to access temp_variable by offset or
+ number. You can convert number to offset using EX_TMP_VAR_NUM(0, num) or
+ offset to number (EX_TMP_VAR_NUM(0,0)-EX_TMP_VAR(0,offset)).
+ * Removed execute_data->CVs field. The VM compiled variables always allocated
+ immediately after execute_data structure. Now they are accessed by offset
+ from the execute_data base pointer (instead of execute_data->CVs). You can
+ use macros EX_CV_NUM() to access compiled variables by number.
+
+ b. Streams pooling API
+
+The streams pooling API has been removed. The following functions no longer
+exist:
+
+PHPAPI int php_stream_context_get_link(php_stream_context *context,
+ const char *hostent, php_stream **stream);
+PHPAPI int php_stream_context_set_link(php_stream_context *context,
+ const char *hostent, php_stream *stream);
+PHPAPI int php_stream_context_del_link(php_stream_context *context,
+ php_stream *stream);
+
+ c. Lowercasing and locales
+
+The lowercasing functions in zend_operators.c were split into those that do
+lowercasing according to locale rules and those that do ASCII lowercasing.
+ASCII:
+
+ zend_str_tolower_copy
+ zend_str_tolower_dup
+ zend_str_tolower
+ zend_binary_strcasecmp
+ zend_binary_strncasecmp
+
+Locale-based:
+ zend_binary_strncasecmp_l
+ zend_binary_strcasecmp_l
+ zend_binary_zval_strcasecmp
+ zend_binary_zval_strncasecmp
+ string_compare_function_ex
+ string_case_compare_function
+
+Internal engine lowercasing will be using ASCII-only rules. User-facing functions,
+such as strcasecmp, will be using locale rules.
+
+Two new functions - zend_binary_strncasecmp_l and zend_binary_strcasecmp_l - added as
+locale-based counterparts to zend_binary_strcasecmp and zend_binary_strncasecmp.
+
+ d. zend_qsort_r
+
+Added the function zend_qsort_r():
+
+typedef int (*compare_r_func_t)(const void *, const void * TSRMLS_DC, void *);
+void zend_qsort_r(void *base, size_t nmemb, size_t siz, compare_r_func_t compare, void *arg TSRMLS_DC);
+
+The extra argument it has (relatively to zend_qsort()) is passed to the
+comparison function.
+
+ e. get_current_key
+
+The signature of the get_current_key iteration handler has been changed to:
+
+void (*get_current_key)(zend_object_iterator *iter, zval *key TSRMLS_DC);
+
+The key should be written into the zval* using the ZVAL_* macros.
========================
2. Build system changes
========================
a. Unix build system changes
-
- - Changes in SAPI module build:
- . When adding new binary SAPI (executable, like CLI/CGI/FPM) use CLI config.m4 and Makefile.frag files as templates and replace CLI/cli with your SAPI name.
-
- - New macros:
- . PHP_INIT_DTRACE(providerdesc, header-file, sources [, module])
-
+ -
b. Windows build system changes
- -
+ - Drop Windows XP and 2003 support.
diff --git a/Zend/Makefile.am b/Zend/Makefile.am
index 7955badf6e..cea5c17fa2 100644
--- a/Zend/Makefile.am
+++ b/Zend/Makefile.am
@@ -17,7 +17,8 @@ libZend_la_SOURCES=\
zend_objects_API.c zend_ts_hash.c zend_stream.c \
zend_default_classes.c \
zend_iterators.c zend_interfaces.c zend_exceptions.c \
- zend_strtod.c zend_closures.c zend_float.c zend_string.c zend_signal.c
+ zend_strtod.c zend_closures.c zend_float.c zend_string.c zend_signal.c \
+ zend_generators.c
libZend_la_LDFLAGS =
libZend_la_LIBADD = @ZEND_EXTRA_LIBS@
@@ -31,7 +32,7 @@ zend_ini_scanner.lo: zend_ini_parser.h
# Language parser/scanner rules
zend_language_scanner.c: $(srcdir)/zend_language_scanner.l
- $(RE2C) $(RE2C_FLAGS) --case-inverted -cbdFt $(srcdir)/zend_language_scanner_defs.h -o$@ $(srcdir)/zend_language_scanner.l
+ $(RE2C) $(RE2C_FLAGS) --no-generation-date --case-inverted -cbdFt $(srcdir)/zend_language_scanner_defs.h -o$@ $(srcdir)/zend_language_scanner.l
zend_language_parser.h: zend_language_parser.c
zend_language_parser.c: $(srcdir)/zend_language_parser.y
@@ -43,7 +44,7 @@ zend_ini_parser.c: $(srcdir)/zend_ini_parser.y
$(YACC) -p ini_ -v -d $(srcdir)/zend_ini_parser.y -o zend_ini_parser.c
zend_ini_scanner.c: $(srcdir)/zend_ini_scanner.l
- $(RE2C) $(RE2C_FLAGS) --case-inverted -cbdFt $(srcdir)/zend_ini_scanner_defs.h -o$@ $(srcdir)/zend_ini_scanner.l
+ $(RE2C) $(RE2C_FLAGS) --no-generation-date --case-inverted -cbdFt $(srcdir)/zend_ini_scanner_defs.h -o$@ $(srcdir)/zend_ini_scanner.l
zend_ini_parser.h: zend_ini_parser.c
diff --git a/Zend/Zend.dsp b/Zend/Zend.dsp
index 5e95b61d8d..61bdab0875 100644
--- a/Zend/Zend.dsp
+++ b/Zend/Zend.dsp
@@ -159,6 +159,10 @@ SOURCE=.\zend_float.c
# End Source File
# Begin Source File
+SOURCE=.\zend_generators.c
+# End Source File
+# Begin Source File
+
SOURCE=.\zend_hash.c
# End Source File
# Begin Source File
diff --git a/Zend/ZendTS.dsp b/Zend/ZendTS.dsp
index bab134623a..0292fda667 100644
--- a/Zend/ZendTS.dsp
+++ b/Zend/ZendTS.dsp
@@ -185,6 +185,10 @@ SOURCE=.\zend_extensions.c
# End Source File
# Begin Source File
+SOURCE=.\zend_generators.c
+# End Source File
+# Begin Source File
+
SOURCE=.\zend_hash.c
# End Source File
# Begin Source File
diff --git a/Zend/acinclude.m4 b/Zend/acinclude.m4
index 95b5bf2061..5a521dc98c 100644
--- a/Zend/acinclude.m4
+++ b/Zend/acinclude.m4
@@ -4,7 +4,7 @@ dnl This file contains local autoconf functions.
AC_DEFUN([LIBZEND_BISON_CHECK],[
# we only support certain bison versions
- bison_version_list="1.28 1.35 1.75 1.875 2.0 2.1 2.2 2.3 2.4 2.4.1 2.4.2 2.4.3 2.5 2.5.1 2.6 2.6.1 2.6.2 2.6.4"
+ bison_version_list="2.4 2.4.1 2.4.2 2.4.3 2.5 2.5.1 2.6 2.6.1 2.6.2 2.6.3 2.6.4 2.6.5 2.7"
# for standalone build of Zend Engine
test -z "$SED" && SED=sed
diff --git a/Zend/tests/bug18556.phpt b/Zend/tests/bug18556.phpt
new file mode 100644
index 0000000000..036abb2ada
--- /dev/null
+++ b/Zend/tests/bug18556.phpt
@@ -0,0 +1,37 @@
+--TEST--
+Bug #18556 (Setting locale to 'tr_TR' lowercases class names)
+--FILE--
+<?php
+$g_lang = 'tr_TR';
+putenv("LANG=$g_lang");
+setlocale(LC_ALL, $g_lang);
+
+class InfoBlob {
+ var $foo;
+ function InfoBlob() {
+ $this->foo = "Foo";
+ }
+}
+
+echo "Instantiating an infoBlob with a lowercase i\n";
+$foobar = new infoBlob();
+echo $foobar->foo;
+echo "\nInstantiating an InfoBlob with an uppercase I\n";
+$foobar = new InfoBlob();
+echo $foobar->foo;
+echo "\n";
+setlocale(LC_ALL, "tr_TR.utf8");
+foreach(get_declared_classes() as $class)
+{
+ if(!class_exists($class))
+ echo "$class No Longer Exists!\n";
+
+}
+echo "Done.\n";
+?>
+--EXPECT--
+Instantiating an infoBlob with a lowercase i
+Foo
+Instantiating an InfoBlob with an uppercase I
+Foo
+Done.
diff --git a/Zend/tests/bug39018.phpt b/Zend/tests/bug39018.phpt
index 32566ba864..a00e1fb819 100644
--- a/Zend/tests/bug39018.phpt
+++ b/Zend/tests/bug39018.phpt
@@ -64,6 +64,8 @@ print "\nDone\n";
--EXPECTF--
Notice: String offset cast occurred in %s on line %d
+Notice: Uninitialized string offset: %s in %s on line 6
+
Notice: Uninitialized string offset: 0 in %s on line %d
Notice: Uninitialized string offset: 0 in %s on line %d
diff --git a/Zend/tests/bug41421.phpt b/Zend/tests/bug41421.phpt
index f10db10980..f39fb15dda 100644
--- a/Zend/tests/bug41421.phpt
+++ b/Zend/tests/bug41421.phpt
@@ -24,6 +24,6 @@ Warning: feof(): wrapper::stream_eof is not implemented! Assuming EOF in %s on l
Fatal error: Uncaught exception 'Exception' in %s:%d
Stack trace:
#0 [internal function]: wrapper->stream_eof()
-#1 %s(%d): feof(Resource id #6)
+#1 %s(%d): feof(Resource id #%d)
#2 {main}
thrown in %s on line %d
diff --git a/Zend/tests/bug43450.phpt b/Zend/tests/bug43450.phpt
index 926e146f4e..a94eba312e 100644
--- a/Zend/tests/bug43450.phpt
+++ b/Zend/tests/bug43450.phpt
@@ -2,6 +2,8 @@
Bug #43450 (Memory leak on some functions with implicit object __toString() call)
--SKIPIF--
<?php if (!function_exists('memory_get_usage')) die('memory_get_usage() not installed'); ?>
+--INI--
+opcache.enable_cli=0
--FILE--
<?php
error_reporting(E_ALL|E_STRICT);
diff --git a/Zend/tests/bug51394.phpt b/Zend/tests/bug51394.phpt
index 406de13a9b..b0dddffaf8 100644
--- a/Zend/tests/bug51394.phpt
+++ b/Zend/tests/bug51394.phpt
@@ -13,10 +13,8 @@ function eh()
set_error_handler("eh");
$a = $empty($b);
--EXPECTF--
-Warning: Uncaught exception 'Exception' with message 'error!' in %sbug51394.php:4
+Fatal error: Uncaught exception 'Exception' with message 'error!' in %sbug51394.php:%d
Stack trace:
-#0 %sbug51394.php(9): eh(8, 'Undefined varia...', '%s', 9, Array)
+#0 %sbug51394.php(%d): eh(8, 'Undefined varia%s', '%s', %d, Array)
#1 {main}
- thrown in %sbug51394.php on line 4
-
-Fatal error: Function name must be a string in %sbug51394.php on line 9 \ No newline at end of file
+ thrown in %sbug51394.php on line %d
diff --git a/Zend/tests/bug52041.phpt b/Zend/tests/bug52041.phpt
index c4b9f97ee5..7e1f3423a6 100644
--- a/Zend/tests/bug52041.phpt
+++ b/Zend/tests/bug52041.phpt
@@ -35,18 +35,30 @@ Notice: Undefined variable: x in %sbug52041.php on line 3
Warning: Creating default object from empty value in %sbug52041.php on line 8
+Notice: Undefined property: stdClass::$a in %sbug52041.php on line 8
+
Notice: Undefined variable: x in %sbug52041.php on line 3
+Notice: Undefined property: stdClass::$a in %sbug52041.php on line 9
+
Warning: Creating default object from empty value in %sbug52041.php on line 9
+Notice: Undefined property: stdClass::$b in %sbug52041.php on line 9
+
Notice: Undefined variable: x in %sbug52041.php on line 3
Warning: Creating default object from empty value in %sbug52041.php on line 10
+Notice: Undefined property: stdClass::$a in %sbug52041.php on line 10
+
Notice: Undefined variable: x in %sbug52041.php on line 3
+Notice: Undefined property: stdClass::$a in %sbug52041.php on line 11
+
Warning: Creating default object from empty value in %sbug52041.php on line 11
+Notice: Undefined property: stdClass::$b in %sbug52041.php on line 11
+
Notice: Undefined variable: x in %sbug52041.php on line 3
Notice: Undefined variable: x in %sbug52041.php on line 3
diff --git a/Zend/tests/bug55156.phpt b/Zend/tests/bug55156.phpt
index 6c0ff768d1..7d75ce3e94 100644
--- a/Zend/tests/bug55156.phpt
+++ b/Zend/tests/bug55156.phpt
@@ -1,5 +1,8 @@
--TEST--
Bug #55156 (ReflectionClass::getDocComment() returns comment even though the class has none)
+--INI--
+opcache.save_comments=1
+opcache.load_comments=1
--FILE--
<?php
diff --git a/Zend/tests/bug60536_001.phpt b/Zend/tests/bug60536_001.phpt
index 916646727d..a94e21ecee 100644
--- a/Zend/tests/bug60536_001.phpt
+++ b/Zend/tests/bug60536_001.phpt
@@ -3,18 +3,18 @@ Bug #60536 (Traits Segfault)
--FILE--
<?php
trait T { private $x = 0; }
-class X {
+class X {
use T;
}
class Y extends X {
use T;
function x() {
- return ++$this->x;
+ return ++$this->x;
}
}
class Z extends Y {
function z() {
- return ++$this->x;
+ return ++$this->x;
}
}
$a = new Z();
@@ -22,4 +22,6 @@ $a->x();
echo "DONE";
?>
--EXPECTF--
+
+Notice: Undefined property: Z::$x in %s on line 14
DONE
diff --git a/Zend/tests/bug60738.phpt b/Zend/tests/bug60738.phpt
new file mode 100644
index 0000000000..e4080715ec
--- /dev/null
+++ b/Zend/tests/bug60738.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Bug #60738 Allow 'set_error_handler' to handle NULL
+--FILE--
+<?php
+
+var_dump(set_error_handler(
+ function() { echo 'Intercepted error!', "\n"; }
+));
+
+trigger_error('Error!');
+
+var_dump(set_error_handler(null));
+
+trigger_error('Error!');
+?>
+--EXPECTF--
+NULL
+Intercepted error!
+object(Closure)#1 (0) {
+}
+
+Notice: Error! in %s on line %d
diff --git a/Zend/tests/bug60738_variation.phpt b/Zend/tests/bug60738_variation.phpt
new file mode 100644
index 0000000000..d7cf00ecdb
--- /dev/null
+++ b/Zend/tests/bug60738_variation.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Bug #60738 Allow 'set_error_handler' to handle NULL
+--FILE--
+<?php
+
+var_dump(set_exception_handler(
+ function() { echo 'Intercepted exception!', "\n"; }
+));
+
+var_dump(set_exception_handler(null));
+
+throw new Exception('Exception!');
+?>
+--EXPECTF--
+NULL
+object(Closure)#1 (0) {
+}
+
+Fatal error: Uncaught exception 'Exception' with message 'Exception!' in %s:%d
+Stack trace:
+#0 {main}
+ thrown in %s on line %d
+
diff --git a/Zend/tests/bug60833.phpt b/Zend/tests/bug60833.phpt
new file mode 100644
index 0000000000..deb6c0f691
--- /dev/null
+++ b/Zend/tests/bug60833.phpt
@@ -0,0 +1,40 @@
+--TEST--
+Bug #60833 (self, parent, static behave inconsistently case-sensitive)
+--FILE--
+<?php
+class A {
+ static $x = "A";
+ function testit() {
+ $this->v1 = new sELF;
+ $this->v2 = new SELF;
+ }
+}
+
+class B extends A {
+ static $x = "B";
+ function testit() {
+ PARENT::testit();
+ $this->v3 = new sELF;
+ $this->v4 = new PARENT;
+ $this->v4 = STATIC::$x;
+ }
+}
+$t = new B();
+$t->testit();
+var_dump($t);
+?>
+--EXPECTF--
+object(B)#%d (4) {
+ ["v1"]=>
+ object(A)#%d (0) {
+ }
+ ["v2"]=>
+ object(A)#%d (0) {
+ }
+ ["v3"]=>
+ object(B)#%d (0) {
+ }
+ ["v4"]=>
+ string(1) "B"
+}
+
diff --git a/Zend/tests/bug61025.phpt b/Zend/tests/bug61025.phpt
new file mode 100644
index 0000000000..0709c28fbc
--- /dev/null
+++ b/Zend/tests/bug61025.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Bug #61025 (__invoke() visibility not honored)
+--FILE--
+<?php
+
+Interface InvokeAble {
+ static function __invoke();
+}
+
+class Bar {
+ private function __invoke() {
+ return __CLASS__;
+ }
+}
+
+$b = new Bar;
+echo $b();
+
+echo $b->__invoke();
+
+?>
+--EXPECTF--
+Warning: The magic method __invoke() must have public visibility and cannot be static in %sbug61025.php on line %d
+
+Warning: The magic method __invoke() must have public visibility and cannot be static in %sbug61025.php on line %d
+Bar
+Fatal error: Call to private method Bar::__invoke() from context '' in %sbug61025.php on line %d
diff --git a/Zend/tests/bug61681.phpt b/Zend/tests/bug61681.phpt
new file mode 100644
index 0000000000..acc0275398
--- /dev/null
+++ b/Zend/tests/bug61681.phpt
@@ -0,0 +1,11 @@
+--TEST--
+Bug #61681: Malformed grammar
+--FILE--
+<?php
+$la = "ooxx";
+
+echo "${substr('laruence', 0, 2)}";
+
+?>
+--EXPECT--
+ooxx
diff --git a/Zend/tests/bug61767.phpt b/Zend/tests/bug61767.phpt
index 5270872e5d..9bd9c907bd 100644
--- a/Zend/tests/bug61767.phpt
+++ b/Zend/tests/bug61767.phpt
@@ -17,18 +17,16 @@ $undefined->foo();
--EXPECTF--
Error handler called (Undefined variable: undefined)
-Warning: Uncaught exception 'ErrorException' with message 'Undefined variable: undefined' in %sbug61767.php:13
+Fatal error: Uncaught exception 'ErrorException' with message 'Undefined variable: undefined' in %sbug61767.php:%d
Stack trace:
-#0 %sbug61767.php(13): {closure}(8, 'Undefined varia...', '%s', 13, Array)
+#0 %sbug61767.php(%d): {closure}(%s, 'Undefined varia...', '%s', %d, Array)
#1 {main}
- thrown in %sbug61767.php on line 13
-
-Fatal error: Call to a member function foo() on a non-object in %sbug61767.php on line 13
+ thrown in %sbug61767.php on line %d
Shutting down
Array
(
[type] => 1
- [message] => Call to a member function foo() on a non-object
+ [message] => %a
[file] => %sbug61767.php
- [line] => 13
+ [line] => %d
)
diff --git a/Zend/tests/bug62005.phpt b/Zend/tests/bug62005.phpt
index c99b28726f..83158d5cc2 100644
--- a/Zend/tests/bug62005.phpt
+++ b/Zend/tests/bug62005.phpt
@@ -9,6 +9,8 @@ function add_points($player, $points) {
add_points(NULL, 2);
--EXPECTF--
Warning: Creating default object from empty value in %sbug62005.php on line %d
+
+Notice: Undefined property: stdClass::$energy in %sbug62005.php on line 3
stdClass Object
(
[energy] => 2
diff --git a/Zend/tests/bug62991.phpt b/Zend/tests/bug62991.phpt
new file mode 100644
index 0000000000..cb4ff93359
--- /dev/null
+++ b/Zend/tests/bug62991.phpt
@@ -0,0 +1,50 @@
+--TEST--
+Bug #62991 (Segfault with generator and closure)
+--FILE--
+<?php
+
+function test( array $array )
+{
+ $closure = function() use ( $array ) {
+ print_r( $array );
+ yield "hi";
+ };
+ return $closure();
+}
+
+function test2( array $array )
+{
+ $closure = function() use ( $array ) {
+ print_r( $array );
+ yield "hi";
+ };
+ return $closure; // if you return the $closure and call it outside this function it works.
+}
+
+$generator = test(array( 1, 2, 3 ) );
+foreach($generator as $something) {
+}
+
+$generator = test2(array( 1, 2, 3 ) );
+foreach($generator() as $something) {
+}
+
+
+$generator = test2(array( 1, 2, 3 ) );
+
+echo "okey\n";
+?>
+--EXPECT--
+Array
+(
+ [0] => 1
+ [1] => 2
+ [2] => 3
+)
+Array
+(
+ [0] => 1
+ [1] => 2
+ [2] => 3
+)
+okey
diff --git a/Zend/tests/bug63741.phpt b/Zend/tests/bug63741.phpt
new file mode 100644
index 0000000000..fc04c9e79c
--- /dev/null
+++ b/Zend/tests/bug63741.phpt
@@ -0,0 +1,50 @@
+--TEST--
+Bug #63741 (Crash when autoloading from spl)
+--FILE--
+<?php
+file_put_contents(dirname(__FILE__)."/bug63741.tmp.php",
+<<<'EOT'
+<?php
+if (isset($autoloading))
+{
+ class ClassToLoad
+ {
+ static function func ()
+ {
+ print "OK!\n";
+ }
+ }
+ return;
+}
+else
+{
+ class autoloader
+ {
+ static function autoload($classname)
+ {
+ print "autoloading...\n";
+ $autoloading = true;
+ include __FILE__;
+ }
+ }
+
+ spl_autoload_register(["autoloader", "autoload"]);
+
+ function start()
+ {
+ ClassToLoad::func();
+ }
+
+ start();
+}
+?>
+EOT
+);
+
+include dirname(__FILE__)."/bug63741.tmp.php";
+?>
+--CLEAN--
+<?php unlink(dirname(__FILE__)."/bug63741.tmp.php"); ?>
+--EXPECT--
+autoloading...
+OK!
diff --git a/Zend/tests/bug64135.phpt b/Zend/tests/bug64135.phpt
new file mode 100644
index 0000000000..1c7b1500a2
--- /dev/null
+++ b/Zend/tests/bug64135.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Bug #64135 (Exceptions from set_error_handler are not always propagated)
+--FILE--
+<?php
+
+function exception_error_handler() {
+ throw new Exception();
+}
+
+set_error_handler("exception_error_handler");
+try {
+ $undefined->undefined();
+} catch(Exception $e) {
+ echo "Exception is thrown";
+}
+--EXPECT--
+Exception is thrown
diff --git a/Zend/tests/bug64555.phpt b/Zend/tests/bug64555.phpt
new file mode 100644
index 0000000000..d5226af7a9
--- /dev/null
+++ b/Zend/tests/bug64555.phpt
@@ -0,0 +1,42 @@
+--TEST--
+Bug #64555: Array key within interned string gets wrong hash value
+--FILE--
+<?php
+
+class Foo {
+ protected $unsetme = 1;
+ protected $keepme = 2;
+
+ public function test() {
+ $a = get_object_vars($this);
+
+ foreach ($a as $k => $v) {
+ if ($k == 'unsetme') {
+ echo "Unsetting: $k\n";
+ unset($a[$k]);
+ } else if ($k == 'keepme') {
+ echo "Changing: $k\n";
+ $a[$k] = 42;
+ $a['keepme'] = 43;
+ }
+ }
+
+ var_dump($a, array_keys($a));
+ }
+}
+
+$f = new Foo;
+$f->test();
+
+?>
+--EXPECT--
+Unsetting: unsetme
+Changing: keepme
+array(1) {
+ ["keepme"]=>
+ int(43)
+}
+array(1) {
+ [0]=>
+ string(6) "keepme"
+}
diff --git a/Zend/tests/bug64677.phpt b/Zend/tests/bug64677.phpt
new file mode 100644
index 0000000000..44a7c5fc6f
--- /dev/null
+++ b/Zend/tests/bug64677.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Bug #64677 (execution operator `` stealing surrounding arguments)
+--FILE--
+<?PHP
+class cat {
+ public function show_output($prepend, $output = '') {
+ }
+}
+$cat = new cat();
+$cat->show_output('Files: ', trim(`cd .`)); // this gives invalid args to shell_exec
+$cat->show_output('Files: ', `cd .`); // this causes a segmentation fault
+$cat->show_output(`cd .`); // this causes a segmentation fault
+
+function show_outputa($prepend, $output) {
+ echo "Okey";
+}
+show_outputa('Files: ', `cd .`); // this works as expected
+
+?>
+--EXPECT--
+Okey
diff --git a/Zend/tests/bug64979.phpt b/Zend/tests/bug64979.phpt
new file mode 100644
index 0000000000..5bc8e5a6ab
--- /dev/null
+++ b/Zend/tests/bug64979.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Bug #64979 (Wrong behavior of static variables in closure generators)
+--FILE--
+<?php
+
+function new_closure_gen() {
+ return function() {
+ static $foo = 0;
+ yield ++$foo;
+ };
+}
+
+$closure1 = new_closure_gen();
+$closure2 = new_closure_gen();
+
+$gen1 = $closure1();
+$gen2 = $closure1();
+$gen3 = $closure2();
+
+foreach (array($gen1, $gen2, $gen3) as $gen) {
+ foreach ($gen as $val) {
+ var_dump($val);
+ }
+}
+
+?>
+--EXPECT--
+int(1)
+int(2)
+int(1)
diff --git a/Zend/tests/bug65051.phpt b/Zend/tests/bug65051.phpt
new file mode 100644
index 0000000000..42febf5b92
--- /dev/null
+++ b/Zend/tests/bug65051.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Bug #65051: count() off by one inside unset()
+--FILE--
+<?php
+
+class Foo {
+ public $array;
+
+ public function __destruct() {
+ var_dump(count($this->array[0]));
+ var_dump($this->array[0]);
+ }
+}
+
+$array = [[new Foo]];
+$array[0][0]->array =& $array;
+unset($array[0][0]);
+
+?>
+--EXPECT--
+int(0)
+array(0) {
+}
diff --git a/Zend/tests/bug65784.phpt b/Zend/tests/bug65784.phpt
new file mode 100644
index 0000000000..adc34113a5
--- /dev/null
+++ b/Zend/tests/bug65784.phpt
@@ -0,0 +1,62 @@
+--TEST--
+Fixed Bug #65784 (Segfault with finally)
+--XFAIL--
+This bug is not fixed in 5.5 due to ABI BC
+--FILE--
+<?php
+function foo1() {
+ try {
+ throw new Exception("not catch");
+ return true;
+ } finally {
+ try {
+ throw new Exception("catched");
+ } catch (Exception $e) {
+ }
+ }
+}
+try {
+ $foo = foo1();
+ var_dump($foo);
+} catch (Exception $e) {
+ do {
+ var_dump($e->getMessage());
+ } while ($e = $e->getPrevious());
+}
+
+function foo2() {
+ try {
+ try {
+ throw new Exception("catched");
+ return true;
+ } finally {
+ try {
+ throw new Exception("catched");
+ } catch (Exception $e) {
+ }
+ }
+ } catch (Exception $e) {
+ }
+}
+
+$foo = foo2();
+var_dump($foo);
+
+function foo3() {
+ try {
+ throw new Exception("not catched");
+ return true;
+ } finally {
+ try {
+ throw new NotExists();
+ } catch (Exception $e) {
+ }
+ }
+}
+
+$bar = foo3();
+--EXPECTF--
+string(9) "not catch"
+NULL
+
+Fatal error: Class 'NotExists' not found in %sbug65784.php on line %d
diff --git a/Zend/tests/catch_finally_001.phpt b/Zend/tests/catch_finally_001.phpt
new file mode 100644
index 0000000000..0c3f597a0a
--- /dev/null
+++ b/Zend/tests/catch_finally_001.phpt
@@ -0,0 +1,32 @@
+--TEST--
+Try catch finally (basic test)
+--FILE--
+<?php
+function foo ($throw = FALSE) {
+ try {
+ echo "try\n";
+ if ($throw) {
+ throw new Exception("ex");
+ }
+ } catch (Exception $e) {
+ echo "catch\n";
+ } finally {
+ echo "finally\n";
+ }
+
+ echo "end\n";
+}
+
+foo();
+echo "\n";
+foo(true);
+?>
+--EXPECTF--
+try
+finally
+end
+
+try
+catch
+finally
+end
diff --git a/Zend/tests/catch_finally_002.phpt b/Zend/tests/catch_finally_002.phpt
new file mode 100644
index 0000000000..c54477ff8c
--- /dev/null
+++ b/Zend/tests/catch_finally_002.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Try catch finally (basic test with return)
+--FILE--
+<?php
+function foo () {
+ try {
+ echo "try\n";
+ return 1;
+ } catch (Exception $e) {
+ } finally {
+ echo "finally\n";
+ }
+ return 2;
+}
+
+var_dump(foo());
+?>
+--EXPECTF--
+try
+finally
+int(1)
diff --git a/Zend/tests/catch_finally_003.phpt b/Zend/tests/catch_finally_003.phpt
new file mode 100644
index 0000000000..24e468d335
--- /dev/null
+++ b/Zend/tests/catch_finally_003.phpt
@@ -0,0 +1,40 @@
+--TEST--
+Try catch finally (with multi-returns)
+--FILE--
+<?php
+function dummy($msg) {
+ var_dump($msg);
+}
+
+function foo ($a) {
+ try {
+ dummy("try");
+ return $a;
+ } catch (Exception $e) {
+ throw $e;
+ } finally {
+ dummy("finally");
+ return "finally";
+ }
+ return "end";
+}
+
+function &bar($a) {
+ try {
+ echo "try\n";
+ throw new Exception("ex");
+ } catch (Exception $e) {
+ } finally {
+ return $a;
+ }
+ return ($c = "end");
+}
+var_dump(foo("para"));
+var_dump(bar("para"));
+?>
+--EXPECTF--
+string(3) "try"
+string(7) "finally"
+string(7) "finally"
+try
+string(4) "para"
diff --git a/Zend/tests/catch_finally_004.phpt b/Zend/tests/catch_finally_004.phpt
new file mode 100644
index 0000000000..a2c22beab1
--- /dev/null
+++ b/Zend/tests/catch_finally_004.phpt
@@ -0,0 +1,41 @@
+--TEST--
+Try catch finally (nesting try-catch-finally)
+--FILE--
+<?php
+
+function throw_exception($msg) {
+ throw new Exception($msg);
+}
+
+function foo (&$ex) {
+ try {
+ echo "1";
+ try {
+ echo "2";
+ throw_exception("try");
+ } catch (Exception $e) {
+ echo "3";
+ throw_exception("catch");
+ } finally {
+ echo "4";
+ throw_exception("finally");
+ }
+ } catch (Exception $e) {
+ $ex = $e;
+ echo "3";
+ } finally {
+ echo "2";
+ }
+ return 1;
+}
+
+var_dump(foo($ex));
+
+do {
+ var_dump($ex->getMessage());
+} while ($ex = $ex->getPrevious());
+?>
+--EXPECT--
+123432int(1)
+string(7) "finally"
+string(5) "catch"
diff --git a/Zend/tests/catch_finally_005.phpt b/Zend/tests/catch_finally_005.phpt
new file mode 100644
index 0000000000..c2fd55df27
--- /dev/null
+++ b/Zend/tests/catch_finally_005.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Try catch finally (with multi-returns and exception)
+--FILE--
+<?php
+function foo ($a) {
+ try {
+ throw new Exception("ex");
+ } catch (PdoException $e) {
+ die("error");
+ } catch (Exception $e) {
+ return 2;
+ } finally {
+ return 3;
+ }
+ return 1;
+}
+
+var_dump(foo("para"));
+?>
+--EXPECTF--
+int(3)
diff --git a/Zend/tests/catch_finally_006.phpt b/Zend/tests/catch_finally_006.phpt
new file mode 100644
index 0000000000..216219b6a5
--- /dev/null
+++ b/Zend/tests/catch_finally_006.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Try catch finally (re-throw exception in catch block)
+--FILE--
+<?php
+function foo ($a) {
+ try {
+ throw new Exception("ex");
+ } catch (Exception $e) {
+ var_dump($a);
+ throw $e;
+ } finally {
+ var_dump("finally");
+ return "return";
+ }
+ return 1;
+}
+
+try {
+ var_dump(foo("para"));
+} catch (Exception $e) {
+ "caught exception" . PHP_EOL;
+ var_dump($e->getMessage());
+}
+?>
+--EXPECT--
+string(4) "para"
+string(7) "finally"
+string(6) "return"
diff --git a/Zend/tests/class_name_as_scalar.phpt b/Zend/tests/class_name_as_scalar.phpt
new file mode 100644
index 0000000000..38e55b16d5
--- /dev/null
+++ b/Zend/tests/class_name_as_scalar.phpt
@@ -0,0 +1,77 @@
+--TEST--
+class name as scalar from ::class keyword
+--FILE--
+<?php
+
+namespace Foo\Bar {
+ class One {
+ // compile time constants
+ const A = self::class;
+ const B = Two::class;
+ }
+ class Two extends One {
+ public static function run() {
+ var_dump(self::class); // self compile time lookup
+ var_dump(static::class); // runtime lookup
+ var_dump(parent::class); // runtime lookup
+ var_dump(Baz::class); // default compile time lookup
+ }
+ }
+ class Three extends Two {
+ // compile time static lookups
+ public static function checkCompileTime(
+ $one = self::class,
+ $two = Baz::class,
+ $three = One::A,
+ $four = self::B
+ ) {
+ var_dump($one, $two, $three, $four);
+ }
+ }
+ echo "In NS\n";
+ var_dump(Moo::CLASS); // resolve in namespace
+}
+
+namespace {
+ use Bee\Bop as Moo,
+ Foo\Bar\One;
+ echo "Top\n";
+ var_dump(One::class); // resolve from use
+ var_dump(Boo::class); // resolve in global namespace
+ var_dump(Moo::CLASS); // resolve from use as
+ var_dump(\Moo::Class); // resolve fully qualified
+ $class = One::class; // assign class as scalar to var
+ $x = new $class; // create new class from original scalar assignment
+ var_dump($x);
+ Foo\Bar\Two::run(); // resolve runtime lookups
+ echo "Parent\n";
+ Foo\Bar\Three::run(); // resolve runtime lookups with inheritance
+ echo "Compile Check\n";
+ Foo\Bar\Three::checkCompileTime();
+}
+
+?>
+--EXPECTF--
+In NS
+string(11) "Foo\Bar\Moo"
+Top
+string(11) "Foo\Bar\One"
+string(3) "Boo"
+string(7) "Bee\Bop"
+string(3) "Moo"
+object(Foo\Bar\One)#1 (0) {
+}
+string(11) "Foo\Bar\Two"
+string(11) "Foo\Bar\Two"
+string(11) "Foo\Bar\One"
+string(11) "Foo\Bar\Baz"
+Parent
+string(11) "Foo\Bar\Two"
+string(13) "Foo\Bar\Three"
+string(11) "Foo\Bar\One"
+string(11) "Foo\Bar\Baz"
+Compile Check
+string(13) "Foo\Bar\Three"
+string(11) "Foo\Bar\Baz"
+string(11) "Foo\Bar\One"
+string(11) "Foo\Bar\Two"
diff --git a/Zend/tests/class_name_as_scalar_error_001.phpt b/Zend/tests/class_name_as_scalar_error_001.phpt
new file mode 100644
index 0000000000..1c7aa7ea84
--- /dev/null
+++ b/Zend/tests/class_name_as_scalar_error_001.phpt
@@ -0,0 +1,13 @@
+--TEST--
+class name as scalar from ::class keyword error using static in class constant
+--FILE--
+<?php
+
+namespace Foo\Bar {
+ class One {
+ const Baz = static::class;
+ }
+}
+?>
+--EXPECTF--
+Fatal error: static::class cannot be used for compile-time class name resolution in %s on line %d
diff --git a/Zend/tests/class_name_as_scalar_error_002.phpt b/Zend/tests/class_name_as_scalar_error_002.phpt
new file mode 100644
index 0000000000..59b7a2edc9
--- /dev/null
+++ b/Zend/tests/class_name_as_scalar_error_002.phpt
@@ -0,0 +1,13 @@
+--TEST--
+class name as scalar from ::class keyword error using parent in class constant
+--FILE--
+<?php
+
+namespace Foo\Bar {
+ class One {
+ const Baz = parent::class;
+ }
+}
+?>
+--EXPECTF--
+Fatal error: parent::class cannot be used for compile-time class name resolution in %s on line %d
diff --git a/Zend/tests/class_name_as_scalar_error_003.phpt b/Zend/tests/class_name_as_scalar_error_003.phpt
new file mode 100644
index 0000000000..9299041693
--- /dev/null
+++ b/Zend/tests/class_name_as_scalar_error_003.phpt
@@ -0,0 +1,13 @@
+--TEST--
+class name as scalar from ::class keyword error using static in method signature
+--FILE--
+<?php
+
+namespace Foo\Bar {
+ class One {
+ public function baz($x = static::class) {}
+ }
+}
+?>
+--EXPECTF--
+Fatal error: static::class cannot be used for compile-time class name resolution in %s on line %d
diff --git a/Zend/tests/class_name_as_scalar_error_004.phpt b/Zend/tests/class_name_as_scalar_error_004.phpt
new file mode 100644
index 0000000000..c00037fca3
--- /dev/null
+++ b/Zend/tests/class_name_as_scalar_error_004.phpt
@@ -0,0 +1,13 @@
+--TEST--
+class name as scalar from ::class keyword error using parent in method signature
+--FILE--
+<?php
+
+namespace Foo\Bar {
+ class One {
+ public function baz($x = parent::class) {}
+ }
+}
+?>
+--EXPECTF--
+Fatal error: parent::class cannot be used for compile-time class name resolution in %s on line %d
diff --git a/Zend/tests/class_name_as_scalar_error_005.phpt b/Zend/tests/class_name_as_scalar_error_005.phpt
new file mode 100644
index 0000000000..39de69ffb3
--- /dev/null
+++ b/Zend/tests/class_name_as_scalar_error_005.phpt
@@ -0,0 +1,10 @@
+--TEST--
+class name as scalar from ::class keyword error using static non class context
+--FILE--
+<?php
+
+$x = static::class;
+
+?>
+--EXPECTF--
+Fatal error: Cannot access static::class when no class scope is active in %s on line %d \ No newline at end of file
diff --git a/Zend/tests/class_name_as_scalar_error_006.phpt b/Zend/tests/class_name_as_scalar_error_006.phpt
new file mode 100644
index 0000000000..a4cc9a528b
--- /dev/null
+++ b/Zend/tests/class_name_as_scalar_error_006.phpt
@@ -0,0 +1,10 @@
+--TEST--
+class name as scalar from ::class keyword error using parent in non class context
+--FILE--
+<?php
+
+$x = parent::class;
+
+?>
+--EXPECTF--
+Fatal error: Cannot access parent::class when no class scope is active in %s on line %d
diff --git a/Zend/tests/closure_047.phpt b/Zend/tests/closure_047.phpt
new file mode 100644
index 0000000000..2377bef6b7
--- /dev/null
+++ b/Zend/tests/closure_047.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Closure 047: Use in preg_replace_callback() using variables by reference
+--FILE--
+<?php
+
+function replace_variables($text, $params) {
+
+ preg_replace_callback( '/(\?)/', function($matches) use (&$params, &$text) {
+
+ $text = preg_replace( '/(\?)/', array_shift( $params ), $text, 1 );
+
+ }, $text );
+
+ return $text;
+}
+
+echo replace_variables('a=?', array('0')) . "\n";
+echo replace_variables('a=?, b=?', array('0', '1')) . "\n";
+echo replace_variables('a=?, b=?, c=?', array('0', '1', '2')) . "\n";
+echo "Done\n";
+?>
+--EXPECT--
+a=0
+a=0, b=1
+a=0, b=1, c=2
+Done
diff --git a/Zend/tests/closure_048.phpt b/Zend/tests/closure_048.phpt
new file mode 100644
index 0000000000..40f2e2fbac
--- /dev/null
+++ b/Zend/tests/closure_048.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Closure 048: Use in preg_replace_callback() using variables by reference
+--FILE--
+<?php
+
+function replace_variables($text, $params) {
+
+ $c = function($matches) use (&$params, &$text) {
+ $text = preg_replace( '/(\?)/', array_shift( $params ), $text, 1 );
+ };
+
+ preg_replace_callback( '/(\?)/', $c, $text );
+
+ return $text;
+}
+
+echo replace_variables('a=?', array('0')) . "\n";
+echo replace_variables('a=?, b=?', array('0', '1')) . "\n";
+echo replace_variables('a=?, b=?, c=?', array('0', '1', '2')) . "\n";
+echo "Done\n";
+?>
+--EXPECT--
+a=0
+a=0, b=1
+a=0, b=1, c=2
+Done
diff --git a/Zend/tests/const_dereference_001.phpt b/Zend/tests/const_dereference_001.phpt
new file mode 100644
index 0000000000..5fe6e4d433
--- /dev/null
+++ b/Zend/tests/const_dereference_001.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Const array deference
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+var_dump(array(1, 2, 3, 4,) [3]);
+var_dump(array(1, 2, 3, 4,) ['foo']);
+var_dump(array(array(1,2,3), array(4, 5, 6))[1][2]);
+
+foreach (array(array(1, 2, 3))[0] as $var) {
+ echo $var;
+}
+?>
+--EXPECTF--
+int(4)
+
+Notice: Undefined index: foo in %sconst_dereference_001.php on line %d
+NULL
+int(6)
+123
diff --git a/Zend/tests/const_dereference_002.phpt b/Zend/tests/const_dereference_002.phpt
new file mode 100644
index 0000000000..ff89519755
--- /dev/null
+++ b/Zend/tests/const_dereference_002.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Const string dereference
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+var_dump("foobar"[3]);
+var_dump("foobar"[2][0]);
+var_dump("foobar"["foo"]["bar"]);
+
+--EXPECTF--
+string(1) "b"
+string(1) "o"
+
+Warning: Illegal string offset 'foo' in %sconst_dereference_002.php on line %d
+
+Warning: Illegal string offset 'bar' in %sconst_dereference_002.php on line %d
+string(1) "f"
diff --git a/Zend/tests/const_dereference_003.phpt b/Zend/tests/const_dereference_003.phpt
new file mode 100644
index 0000000000..810ad14b8e
--- /dev/null
+++ b/Zend/tests/const_dereference_003.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Const array deference
+--FILE--
+<?php
+error_reporting(E_ALL);
+
+var_dump([1, 2, 3, 4,][3]);
+var_dump([1, 2, 3, 4]['foo']);
+var_dump([array(1,2,3), [4, 5, 6]][1][2]);
+
+foreach (array([1, 2, 3])[0] as $var) {
+ echo $var;
+}
+?>
+--EXPECTF--
+int(4)
+
+Notice: Undefined index: foo in %sconst_dereference_003.php on line %d
+NULL
+int(6)
+123
diff --git a/Zend/tests/dval_to_lval_32.phpt b/Zend/tests/dval_to_lval_32.phpt
new file mode 100644
index 0000000000..f2acc39f51
--- /dev/null
+++ b/Zend/tests/dval_to_lval_32.phpt
@@ -0,0 +1,32 @@
+--TEST--
+zend_dval_to_lval preserves low bits (32 bit long)
+--SKIPIF--
+<?php
+if (PHP_INT_SIZE != 4)
+ die("skip for machines with 32-bit longs");
+?>
+--FILE--
+<?php
+ /* test doubles around -4e21 */
+ $values = [
+ -4000000000000001048576.,
+ -4000000000000000524288.,
+ -4000000000000000000000.,
+ -3999999999999999475712.,
+ -3999999999999998951424.,
+ ];
+ /* see if we're rounding negative numbers right */
+ $values[] = -2147483649.8;
+
+ foreach ($values as $v) {
+ var_dump((int)$v);
+ }
+
+?>
+--EXPECT--
+int(-2056257536)
+int(-2055733248)
+int(-2055208960)
+int(-2054684672)
+int(-2054160384)
+int(2147483647)
diff --git a/Zend/tests/dval_to_lval_64.phpt b/Zend/tests/dval_to_lval_64.phpt
new file mode 100644
index 0000000000..da7f56d81c
--- /dev/null
+++ b/Zend/tests/dval_to_lval_64.phpt
@@ -0,0 +1,29 @@
+--TEST--
+zend_dval_to_lval preserves low bits (64 bit long)
+--SKIPIF--
+<?php
+if (PHP_INT_SIZE != 8)
+ die("skip for machines with 64-bit longs");
+?>
+--FILE--
+<?php
+ /* test doubles around -4e21 */
+ $values = [
+ -4000000000000001048576.,
+ -4000000000000000524288.,
+ -4000000000000000000000.,
+ -3999999999999999475712.,
+ -3999999999999998951424.,
+ ];
+
+ foreach ($values as $v) {
+ var_dump((int)$v);
+ }
+
+?>
+--EXPECT--
+int(2943463994971652096)
+int(2943463994972176384)
+int(2943463994972700672)
+int(2943463994973224960)
+int(2943463994973749248)
diff --git a/Zend/tests/empty_with_expr.phpt b/Zend/tests/empty_with_expr.phpt
new file mode 100644
index 0000000000..582eb3d2d0
--- /dev/null
+++ b/Zend/tests/empty_with_expr.phpt
@@ -0,0 +1,32 @@
+--TEST--
+empty() with arbitrary expressions
+--FILE--
+<?php
+
+function getEmptyArray() { return []; }
+function getNonEmptyArray() { return [1, 2, 3]; }
+
+var_dump(empty([]));
+var_dump(empty([1, 2, 3]));
+
+var_dump(empty(getEmptyArray()));
+var_dump(empty(getNonEmptyArray()));
+
+var_dump(empty([] + []));
+var_dump(empty([1, 2, 3] + []));
+
+var_dump(empty("string"));
+var_dump(empty(""));
+var_dump(empty(true));
+var_dump(empty(false));
+--EXPECT--
+bool(true)
+bool(false)
+bool(true)
+bool(false)
+bool(true)
+bool(false)
+bool(false)
+bool(true)
+bool(false)
+bool(true)
diff --git a/Zend/tests/errmsg_043.phpt b/Zend/tests/errmsg_043.phpt
deleted file mode 100644
index 3de8bc2062..0000000000
--- a/Zend/tests/errmsg_043.phpt
+++ /dev/null
@@ -1,12 +0,0 @@
---TEST--
-errmsg: cannot create references to temp array
---FILE--
-<?php
-
-foreach (array(1,2,3) as $k=>&$v) {
-}
-
-echo "Done\n";
-?>
---EXPECTF--
-Fatal error: Cannot create references to elements of a temporary array expression in %s on line %d
diff --git a/Zend/tests/exception_before_fatal.phpt b/Zend/tests/exception_before_fatal.phpt
new file mode 100644
index 0000000000..608d65094b
--- /dev/null
+++ b/Zend/tests/exception_before_fatal.phpt
@@ -0,0 +1,64 @@
+--TEST--
+Exceptions before fatal error
+--FILE--
+<?php
+function exception_error_handler($code, $msg) {
+ throw new Exception($msg);
+}
+
+set_error_handler("exception_error_handler");
+
+try {
+ $foo->a();
+} catch(Exception $e) {
+ var_dump($e->getMessage());
+}
+
+try {
+ new $foo();
+} catch(Exception $e) {
+ var_dump($e->getMessage());
+}
+
+try {
+ throw $foo;
+} catch(Exception $e) {
+ var_dump($e->getMessage());
+}
+
+try {
+ $foo();
+} catch(Exception $e) {
+ var_dump($e->getMessage());
+}
+
+try {
+ $foo::b();
+} catch(Exception $e) {
+ var_dump($e->getMessage());
+}
+
+
+try {
+ $b = clone $foo;
+} catch(Exception $e) {
+ var_dump($e->getMessage());
+}
+
+class b {
+}
+
+try {
+ b::$foo();
+} catch(Exception $e) {
+ var_dump($e->getMessage());
+}
+?>
+--EXPECT--
+string(23) "Undefined variable: foo"
+string(23) "Undefined variable: foo"
+string(23) "Undefined variable: foo"
+string(23) "Undefined variable: foo"
+string(23) "Undefined variable: foo"
+string(23) "Undefined variable: foo"
+string(23) "Undefined variable: foo"
diff --git a/Zend/tests/foreach_list_001.phpt b/Zend/tests/foreach_list_001.phpt
new file mode 100644
index 0000000000..a318f1aad9
--- /dev/null
+++ b/Zend/tests/foreach_list_001.phpt
@@ -0,0 +1,43 @@
+--TEST--
+foreach with list syntax
+--FILE--
+<?php
+
+foreach(array(array(1,2), array(3,4)) as list($a, $b)) {
+ var_dump($a . $b);
+}
+
+$array = array(
+ array('a', 'b'),
+ array('c', 'd'),
+);
+
+foreach ($array as list($a, $b)) {
+ var_dump($a . $b);
+}
+
+
+$multi = array(
+ array(array(1,2), array(3,4)),
+ array(array(5,6), array(7,8)),
+);
+
+foreach ($multi as list(list($a, $b), list($c, $d))) {
+ var_dump($a . $b . $c . $d);
+}
+
+foreach ($multi as $key => list(list($a, $b), list($c, $d))) {
+ var_dump($key . $a . $b . $c . $d);
+}
+
+
+?>
+--EXPECT--
+string(2) "12"
+string(2) "34"
+string(2) "ab"
+string(2) "cd"
+string(4) "1234"
+string(4) "5678"
+string(5) "01234"
+string(5) "15678"
diff --git a/Zend/tests/foreach_list_002.phpt b/Zend/tests/foreach_list_002.phpt
new file mode 100644
index 0000000000..251870ba09
--- /dev/null
+++ b/Zend/tests/foreach_list_002.phpt
@@ -0,0 +1,26 @@
+--TEST--
+foreach with freak lists
+--FILE--
+<?php
+
+foreach (array(array(1,2), array(3,4)) as list($a, )) {
+ var_dump($a);
+}
+
+$array = [['a', 'b'], 'c', 'd'];
+
+foreach($array as list(list(), $a)) {
+ var_dump($a);
+}
+
+?>
+--EXPECTF--
+int(1)
+int(3)
+string(1) "b"
+
+Notice: Uninitialized string offset: 1 in %sforeach_list_002.php on line %d
+string(0) ""
+
+Notice: Uninitialized string offset: 1 in %sforeach_list_002.php on line %d
+string(0) ""
diff --git a/Zend/tests/foreach_list_003.phpt b/Zend/tests/foreach_list_003.phpt
new file mode 100644
index 0000000000..8674ecd754
--- /dev/null
+++ b/Zend/tests/foreach_list_003.phpt
@@ -0,0 +1,13 @@
+--TEST--
+foreach with list key
+--FILE--
+<?php
+
+$array = [['a', 'b'], 'c', 'd'];
+
+foreach($array as list($key) => list(list(), $a)) {
+}
+
+?>
+--EXPECTF--
+Fatal error: Cannot use list as key element in %sforeach_list_003.php on line %d
diff --git a/Zend/tests/foreach_list_004.phpt b/Zend/tests/foreach_list_004.phpt
new file mode 100644
index 0000000000..fd48e8a1f3
--- /dev/null
+++ b/Zend/tests/foreach_list_004.phpt
@@ -0,0 +1,13 @@
+--TEST--
+foreach with empty list
+--FILE--
+<?php
+
+$array = [['a', 'b'], 'c', 'd'];
+
+foreach($array as $key => list()) {
+}
+
+?>
+--EXPECTF--
+Fatal error: Cannot use empty list in %sforeach_list_004.php on line %d
diff --git a/Zend/tests/foreach_temp_array_expr_with_refs.phpt b/Zend/tests/foreach_temp_array_expr_with_refs.phpt
new file mode 100644
index 0000000000..8978b7b011
--- /dev/null
+++ b/Zend/tests/foreach_temp_array_expr_with_refs.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Temporary array expressions can be iterated by reference
+--FILE--
+<?php
+
+$a = 'a';
+$b = 'b';
+
+foreach ([&$a, &$b] as &$value) {
+ $value .= '-foo';
+}
+
+var_dump($a, $b);
+
+?>
+--EXPECT--
+string(5) "a-foo"
+string(5) "b-foo"
diff --git a/Zend/tests/generators/auto_incrementing_keys.phpt b/Zend/tests/generators/auto_incrementing_keys.phpt
new file mode 100644
index 0000000000..acfb2f2ce0
--- /dev/null
+++ b/Zend/tests/generators/auto_incrementing_keys.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Generator keys are auto-incrementing by default
+--FILE--
+<?php
+
+function gen() {
+ yield 'foo';
+ yield 'bar';
+ yield 5 => 'rab';
+ yield 'oof';
+}
+
+foreach (gen() as $k => $v) {
+ echo $k, ' => ', $v, "\n";
+}
+
+?>
+--EXPECT--
+0 => foo
+1 => bar
+5 => rab
+6 => oof
diff --git a/Zend/tests/generators/backtrace.phpt b/Zend/tests/generators/backtrace.phpt
new file mode 100644
index 0000000000..5fed1d467e
--- /dev/null
+++ b/Zend/tests/generators/backtrace.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Printing the stack trace in a generator
+--FILE--
+<?php
+
+function f1() {
+ debug_print_backtrace();
+}
+
+function f2($arg1, $arg2) {
+ f1();
+ yield; // force generator
+}
+
+function f3($gen) {
+ $gen->rewind(); // trigger run
+}
+
+$gen = f2('foo', 'bar');
+f3($gen);
+
+?>
+--EXPECTF--
+#0 f1() called at [%s:%d]
+#1 f2(foo, bar)
+#2 Generator->rewind() called at [%s:%d]
+#3 f3(Generator Object ()) called at [%s:%d]
diff --git a/Zend/tests/generators/bug63066.phpt b/Zend/tests/generators/bug63066.phpt
new file mode 100644
index 0000000000..8c4c8b4a84
--- /dev/null
+++ b/Zend/tests/generators/bug63066.phpt
@@ -0,0 +1,16 @@
+--TEST--
+Bug #63066 (Calling an undefined method in a generator results in a seg fault)
+--FILE--
+<?php
+function gen($o)
+{
+ yield 'foo';
+ $o->fatalError();
+}
+
+foreach(gen(new stdClass()) as $value)
+ echo $value, "\n";
+--EXPECTF--
+foo
+
+Fatal error: Call to undefined method stdClass::fatalError() in %sbug63066.php on line 5
diff --git a/Zend/tests/generators/bug65035.phpt b/Zend/tests/generators/bug65035.phpt
new file mode 100644
index 0000000000..18276cc23a
--- /dev/null
+++ b/Zend/tests/generators/bug65035.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Bug #65035: yield / exit segfault
+--FILE--
+<?php
+
+function gen() {
+ fn();
+ yield;
+}
+
+function fn() {
+ exit('Done');
+}
+
+$gen = gen();
+$gen->current();
+
+?>
+--EXPECT--
+Done
diff --git a/Zend/tests/generators/bug65161.phpt b/Zend/tests/generators/bug65161.phpt
new file mode 100644
index 0000000000..215c1880e3
--- /dev/null
+++ b/Zend/tests/generators/bug65161.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Bug #65161: Generator + autoload + syntax error = segfault
+--FILE--
+<?php
+
+function autoload() {
+ foo();
+}
+spl_autoload_register('autoload');
+
+function testGenerator() {
+ new SyntaxError('param');
+ yield;
+}
+
+foreach (testGenerator() as $i);
+
+?>
+--EXPECTF--
+Fatal error: Call to undefined function foo() in %s on line %d
diff --git a/Zend/tests/generators/bug66041.phpt b/Zend/tests/generators/bug66041.phpt
new file mode 100644
index 0000000000..d944224134
--- /dev/null
+++ b/Zend/tests/generators/bug66041.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Bug #66041: list() fails to unpack yielded ArrayAccess object
+--FILE--
+<?php
+function dumpElement() {
+ list($value) = yield;
+ var_dump($value);
+};
+
+$fixedArray = new SplFixedArray(1);
+$fixedArray[0] = 'the element';
+
+$generator = dumpElement();
+$generator->send($fixedArray);
+?>
+--EXPECT--
+string(11) "the element"
diff --git a/Zend/tests/generators/clone.phpt b/Zend/tests/generators/clone.phpt
new file mode 100644
index 0000000000..22f4428121
--- /dev/null
+++ b/Zend/tests/generators/clone.phpt
@@ -0,0 +1,15 @@
+--TEST--
+Generators cannot be cloned
+--FILE--
+<?php
+
+function gen() {
+ yield;
+}
+
+$gen = gen();
+clone $gen;
+
+?>
+--EXPECTF--
+Fatal error: Trying to clone an uncloneable object of class Generator in %s on line %d
diff --git a/Zend/tests/generators/dynamic_call.phpt b/Zend/tests/generators/dynamic_call.phpt
new file mode 100644
index 0000000000..d564540952
--- /dev/null
+++ b/Zend/tests/generators/dynamic_call.phpt
@@ -0,0 +1,19 @@
+--TEST--
+It's possible to invoke a generator dynamically
+--FILE--
+<?php
+
+function gen($foo, $bar) {
+ yield $foo;
+ yield $bar;
+}
+
+$gen = call_user_func('gen', 'bar', 'foo');
+foreach ($gen as $value) {
+ var_dump($value);
+}
+
+?>
+--EXPECT--
+string(3) "bar"
+string(3) "foo"
diff --git a/Zend/tests/generators/errors/generator_cannot_return_before_yield_error.phpt b/Zend/tests/generators/errors/generator_cannot_return_before_yield_error.phpt
new file mode 100644
index 0000000000..ad618d20ba
--- /dev/null
+++ b/Zend/tests/generators/errors/generator_cannot_return_before_yield_error.phpt
@@ -0,0 +1,13 @@
+--TEST--
+Generators cannot return values (even before yield)
+--FILE--
+<?php
+
+function gen() {
+ return $foo;
+ yield;
+}
+
+?>
+--EXPECTF--
+Fatal error: Generators cannot return values using "return" in %s on line 4
diff --git a/Zend/tests/generators/errors/generator_cannot_return_error.phpt b/Zend/tests/generators/errors/generator_cannot_return_error.phpt
new file mode 100644
index 0000000000..51149062a7
--- /dev/null
+++ b/Zend/tests/generators/errors/generator_cannot_return_error.phpt
@@ -0,0 +1,13 @@
+--TEST--
+Generators cannot return values
+--FILE--
+<?php
+
+function gen() {
+ yield;
+ return $abc;
+}
+
+?>
+--EXPECTF--
+Fatal error: Generators cannot return values using "return" in %s on line 5
diff --git a/Zend/tests/generators/errors/generator_extend_error.phpt b/Zend/tests/generators/errors/generator_extend_error.phpt
new file mode 100644
index 0000000000..550f16ae03
--- /dev/null
+++ b/Zend/tests/generators/errors/generator_extend_error.phpt
@@ -0,0 +1,10 @@
+--TEST--
+The Generator class cannot be extended
+--FILE--
+<?php
+
+class ExtendedGenerator extends Generator { }
+
+?>
+--EXPECTF--
+Fatal error: Class ExtendedGenerator may not inherit from final class (Generator) in %s on line %d
diff --git a/Zend/tests/generators/errors/generator_instantiate_error.phpt b/Zend/tests/generators/errors/generator_instantiate_error.phpt
new file mode 100644
index 0000000000..f8941c087a
--- /dev/null
+++ b/Zend/tests/generators/errors/generator_instantiate_error.phpt
@@ -0,0 +1,10 @@
+--TEST--
+It's not possible to directly instantiate the Generator class
+--FILE--
+<?php
+
+new Generator;
+
+?>
+--EXPECTF--
+Catchable fatal error: The "Generator" class is reserved for internal use and cannot be manually instantiated in %s on line %d
diff --git a/Zend/tests/generators/errors/non_ref_generator_iterated_by_ref_error.phpt b/Zend/tests/generators/errors/non_ref_generator_iterated_by_ref_error.phpt
new file mode 100644
index 0000000000..de5b22f6ba
--- /dev/null
+++ b/Zend/tests/generators/errors/non_ref_generator_iterated_by_ref_error.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Non-ref generators cannot be iterated by-ref
+--FILE--
+<?php
+
+function gen() { yield; }
+
+$gen = gen();
+foreach ($gen as &$value) { }
+
+?>
+--EXPECTF--
+Fatal error: Uncaught exception 'Exception' with message 'You can only iterate a generator by-reference if it declared that it yields by-reference' in %s:%d
+Stack trace:
+#0 %s(%d): unknown()
+#1 {main}
+ thrown in %s on line %d
+
diff --git a/Zend/tests/generators/errors/resume_running_generator_error.phpt b/Zend/tests/generators/errors/resume_running_generator_error.phpt
new file mode 100644
index 0000000000..567d72f3f9
--- /dev/null
+++ b/Zend/tests/generators/errors/resume_running_generator_error.phpt
@@ -0,0 +1,17 @@
+--TEST--
+It is not possible to resume an already running generator
+--FILE--
+<?php
+
+function gen() {
+ $gen = yield;
+ $gen->next();
+}
+
+$gen = gen();
+$gen->send($gen);
+$gen->next();
+
+?>
+--EXPECTF--
+Fatal error: Cannot resume an already running generator in %s on line %d
diff --git a/Zend/tests/generators/errors/serialize_unserialize_error.phpt b/Zend/tests/generators/errors/serialize_unserialize_error.phpt
new file mode 100644
index 0000000000..aa2d4693f7
--- /dev/null
+++ b/Zend/tests/generators/errors/serialize_unserialize_error.phpt
@@ -0,0 +1,44 @@
+--TEST--
+Generators can't be serialized or unserialized
+--FILE--
+<?php
+
+function gen() { yield; }
+
+$gen = gen();
+
+try {
+ serialize($gen);
+} catch (Exception $e) {
+ echo $e, "\n\n";
+}
+
+try {
+ var_dump(unserialize('O:9:"Generator":0:{}'));
+} catch (Exception $e) {
+ echo $e, "\n\n";
+}
+
+try {
+ var_dump(unserialize('C:9:"Generator":0:{}'));
+} catch (Exception $e) {
+ echo $e;
+}
+
+?>
+--EXPECTF--
+exception 'Exception' with message 'Serialization of 'Generator' is not allowed' in %s:%d
+Stack trace:
+#0 %s(%d): serialize(Object(Generator))
+#1 {main}
+
+exception 'Exception' with message 'Unserialization of 'Generator' is not allowed' in %s:%d
+Stack trace:
+#0 [internal function]: Generator->__wakeup()
+#1 %s(%d): unserialize('O:9:"Generator"...')
+#2 {main}
+
+exception 'Exception' with message 'Unserialization of 'Generator' is not allowed' in %s:%d
+Stack trace:
+#0 %s(%d): unserialize('C:9:"Generator"...')
+#1 {main}
diff --git a/Zend/tests/generators/errors/yield_const_by_ref_error.phpt b/Zend/tests/generators/errors/yield_const_by_ref_error.phpt
new file mode 100644
index 0000000000..e79f83e24a
--- /dev/null
+++ b/Zend/tests/generators/errors/yield_const_by_ref_error.phpt
@@ -0,0 +1,16 @@
+--TEST--
+A notice is thrown when yielding a constant value by reference
+--FILE--
+<?php
+
+function &gen() {
+ yield "foo";
+}
+
+$gen = gen();
+var_dump($gen->current());
+
+?>
+--EXPECTF--
+Notice: Only variable references should be yielded by reference in %s on line %d
+string(3) "foo"
diff --git a/Zend/tests/generators/errors/yield_in_force_closed_finally_error.phpt b/Zend/tests/generators/errors/yield_in_force_closed_finally_error.phpt
new file mode 100644
index 0000000000..aada676a68
--- /dev/null
+++ b/Zend/tests/generators/errors/yield_in_force_closed_finally_error.phpt
@@ -0,0 +1,29 @@
+--TEST--
+yield cannot be used in a finally block when the generator is force-closed
+--FILE--
+<?php
+
+function gen() {
+ try {
+ echo "before yield\n";
+ yield;
+ echo "after yield\n";
+ } finally {
+ echo "before yield in finally\n";
+ yield;
+ echo "after yield in finally\n";
+ }
+
+ echo "after finally\n";
+}
+
+$gen = gen();
+$gen->rewind();
+unset($gen);
+
+?>
+--EXPECTF--
+before yield
+before yield in finally
+
+Fatal error: Cannot yield from finally in a force-closed generator in %s on line %d
diff --git a/Zend/tests/generators/errors/yield_non_ref_function_call_by_ref_error.phpt b/Zend/tests/generators/errors/yield_non_ref_function_call_by_ref_error.phpt
new file mode 100644
index 0000000000..4b8563331c
--- /dev/null
+++ b/Zend/tests/generators/errors/yield_non_ref_function_call_by_ref_error.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Yielding the result of a non-ref function call throw a notice
+--FILE--
+<?php
+
+function foo() {
+ return "bar";
+}
+
+function &gen() {
+ yield foo();
+}
+
+$gen = gen();
+var_dump($gen->current());
+
+?>
+--EXPECTF--
+Notice: Only variable references should be yielded by reference in %s on line %d
+string(3) "bar"
diff --git a/Zend/tests/generators/errors/yield_outside_function_error.phpt b/Zend/tests/generators/errors/yield_outside_function_error.phpt
new file mode 100644
index 0000000000..f999c1c03b
--- /dev/null
+++ b/Zend/tests/generators/errors/yield_outside_function_error.phpt
@@ -0,0 +1,10 @@
+--TEST--
+Yield cannot be used outside of functions
+--FILE--
+<?php
+
+yield "Test";
+
+?>
+--EXPECTF--
+Fatal error: The "yield" expression can only be used inside a function in %s on line %d
diff --git a/Zend/tests/generators/fibonacci.phpt b/Zend/tests/generators/fibonacci.phpt
new file mode 100644
index 0000000000..35b31352ff
--- /dev/null
+++ b/Zend/tests/generators/fibonacci.phpt
@@ -0,0 +1,36 @@
+--TEST--
+Creating an infinite fibonacci list using a generator
+--FILE--
+<?php
+
+function fib() {
+ list($a, $b) = [1, 1];
+ while (true) {
+ yield $b;
+ list($a, $b) = [$b, $a + $b];
+ }
+}
+
+foreach (fib() as $n) {
+ if ($n > 1000) break;
+
+ var_dump($n);
+}
+
+?>
+--EXPECT--
+int(1)
+int(2)
+int(3)
+int(5)
+int(8)
+int(13)
+int(21)
+int(34)
+int(55)
+int(89)
+int(144)
+int(233)
+int(377)
+int(610)
+int(987)
diff --git a/Zend/tests/generators/finally/finally_ran_on_close.phpt b/Zend/tests/generators/finally/finally_ran_on_close.phpt
new file mode 100644
index 0000000000..04a0561c87
--- /dev/null
+++ b/Zend/tests/generators/finally/finally_ran_on_close.phpt
@@ -0,0 +1,30 @@
+--TEST--
+finally is run even if a generator is closed mid-execution
+--FILE--
+<?php
+
+function gen() {
+ try {
+ try {
+ echo "before yield\n";
+ yield;
+ echo "after yield\n";
+ } finally {
+ echo "finally run\n";
+ }
+ echo "code after finally\n";
+ } finally {
+ echo "second finally run\n";
+ }
+ echo "code after second finally\n";
+}
+
+$gen = gen();
+$gen->rewind();
+unset($gen);
+
+?>
+--EXPECT--
+before yield
+finally run
+second finally run
diff --git a/Zend/tests/generators/finally/return_return.phpt b/Zend/tests/generators/finally/return_return.phpt
new file mode 100644
index 0000000000..02e2739de7
--- /dev/null
+++ b/Zend/tests/generators/finally/return_return.phpt
@@ -0,0 +1,33 @@
+--TEST--
+try { return } finally { return } in generator
+--FILE--
+<?php
+
+function gen() {
+ try {
+ try {
+ echo "before return\n";
+ return;
+ echo "after return\n";
+ } finally {
+ echo "before return in inner finally\n";
+ return;
+ echo "after return in inner finally\n";
+ }
+ } finally {
+ echo "outer finally run\n";
+ }
+
+ echo "code after finally\n";
+
+ yield; // force generator
+}
+
+$gen = gen();
+$gen->rewind(); // force run
+
+?>
+--EXPECTF--
+before return
+before return in inner finally
+outer finally run
diff --git a/Zend/tests/generators/finally/return_yield.phpt b/Zend/tests/generators/finally/return_yield.phpt
new file mode 100644
index 0000000000..c4f3485987
--- /dev/null
+++ b/Zend/tests/generators/finally/return_yield.phpt
@@ -0,0 +1,18 @@
+--TEST--
+try { return } finally { yield }
+--FILE--
+<?php
+function foo($f, $t) {
+ for ($i = $f; $i <= $t; $i++) {
+ try {
+ return;
+ } finally {
+ yield $i;
+ }
+ }
+}
+foreach (foo(1, 5) as $x) {
+ echo $x, "\n";
+}
+--EXPECT--
+1
diff --git a/Zend/tests/generators/finally/run_on_dtor.phpt b/Zend/tests/generators/finally/run_on_dtor.phpt
new file mode 100644
index 0000000000..35f8f4e0de
--- /dev/null
+++ b/Zend/tests/generators/finally/run_on_dtor.phpt
@@ -0,0 +1,22 @@
+--TEST--
+finally is run on object dtor, not free
+--FILE--
+<?php
+
+function gen() {
+ try {
+ yield;
+ } finally {
+ var_dump($_GET);
+ }
+}
+
+$gen = gen();
+$gen->rewind();
+
+set_error_handler(function() use($gen) {});
+
+?>
+--EXPECT--
+array(0) {
+}
diff --git a/Zend/tests/generators/finally/throw_yield.phpt b/Zend/tests/generators/finally/throw_yield.phpt
new file mode 100644
index 0000000000..2013c3ee14
--- /dev/null
+++ b/Zend/tests/generators/finally/throw_yield.phpt
@@ -0,0 +1,24 @@
+--TEST--
+try { throw } finally { yield }
+--FILE--
+<?php
+function foo($f, $t) {
+ for ($i = $f; $i <= $t; $i++) {
+ try {
+ throw new Exception;
+ } finally {
+ yield $i;
+ }
+ }
+}
+foreach (foo(1, 5) as $x) {
+ echo $x, "\n";
+}
+--EXPECTF--
+1
+
+Fatal error: Uncaught exception 'Exception' in %s:%d
+Stack trace:
+#0 %s(%d): foo(1, 5)
+#1 {main}
+ thrown in %s on line %d
diff --git a/Zend/tests/generators/finally/yield_return.phpt b/Zend/tests/generators/finally/yield_return.phpt
new file mode 100644
index 0000000000..e3e1bec357
--- /dev/null
+++ b/Zend/tests/generators/finally/yield_return.phpt
@@ -0,0 +1,18 @@
+--TEST--
+try { yield } finally { return }
+--FILE--
+<?php
+function foo($f, $t) {
+ for ($i = $f; $i <= $t; $i++) {
+ try {
+ yield $i;
+ } finally {
+ return;
+ }
+ }
+}
+foreach (foo(1, 5) as $x) {
+ echo $x, "\n";
+}
+--EXPECT--
+1
diff --git a/Zend/tests/generators/finally/yield_throw.phpt b/Zend/tests/generators/finally/yield_throw.phpt
new file mode 100644
index 0000000000..0ead4501af
--- /dev/null
+++ b/Zend/tests/generators/finally/yield_throw.phpt
@@ -0,0 +1,24 @@
+--TEST--
+try { yield } finally { throw }
+--FILE--
+<?php
+function foo($f, $t) {
+ for ($i = $f; $i <= $t; $i++) {
+ try {
+ yield $i;
+ } finally {
+ throw new Exception;
+ }
+ }
+}
+foreach (foo(1, 5) as $x) {
+ echo $x, "\n";
+}
+--EXPECTF--
+1
+
+Fatal error: Uncaught exception 'Exception' in %s:%d
+Stack trace:
+#0 %s(%d): foo(1, 5)
+#1 {main}
+ thrown in %s on line %d
diff --git a/Zend/tests/generators/finally/yield_yield.phpt b/Zend/tests/generators/finally/yield_yield.phpt
new file mode 100644
index 0000000000..76610ef1a4
--- /dev/null
+++ b/Zend/tests/generators/finally/yield_yield.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Try { yield } finally { yield }
+--FILE--
+<?php
+
+function foo() {
+ try {
+ echo "1";
+ yield "2";
+ echo "3";
+ } finally {
+ echo "4";
+ yield "5";
+ echo "6";
+ }
+ echo "7";
+}
+foreach (foo() as $x) {
+ echo $x;
+}
+--EXPECT--
+1234567
diff --git a/Zend/tests/generators/func_get_args.phpt b/Zend/tests/generators/func_get_args.phpt
new file mode 100644
index 0000000000..f8d3fa7c14
--- /dev/null
+++ b/Zend/tests/generators/func_get_args.phpt
@@ -0,0 +1,21 @@
+--TEST--
+func_get_args() can be used inside generator functions
+--FILE--
+<?php
+
+function gen() {
+ var_dump(func_get_args());
+ yield; // trigger generator
+}
+
+$gen = gen("foo", "bar");
+$gen->rewind();
+
+?>
+--EXPECT--
+array(2) {
+ [0]=>
+ string(3) "foo"
+ [1]=>
+ string(3) "bar"
+}
diff --git a/Zend/tests/generators/generator_closure.phpt b/Zend/tests/generators/generator_closure.phpt
new file mode 100644
index 0000000000..bf80066015
--- /dev/null
+++ b/Zend/tests/generators/generator_closure.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Closures can be generators
+--FILE--
+<?php
+
+$genFactory = function() {
+ yield 1;
+ yield 2;
+ yield 3;
+};
+
+foreach ($genFactory() as $value) {
+ var_dump($value);
+}
+
+?>
+--EXPECT--
+int(1)
+int(2)
+int(3)
diff --git a/Zend/tests/generators/generator_closure_with_this.phpt b/Zend/tests/generators/generator_closure_with_this.phpt
new file mode 100644
index 0000000000..d5a4861e80
--- /dev/null
+++ b/Zend/tests/generators/generator_closure_with_this.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Non-static closures can be generators
+--FILE--
+<?php
+
+class Test {
+ public function getGenFactory() {
+ return function() {
+ yield $this;
+ };
+ }
+}
+
+$genFactory = (new Test)->getGenFactory();
+var_dump($genFactory()->current());
+
+?>
+--EXPECT--
+object(Test)#1 (0) {
+}
diff --git a/Zend/tests/generators/generator_in_multipleiterator.phpt b/Zend/tests/generators/generator_in_multipleiterator.phpt
new file mode 100644
index 0000000000..611dbc9652
--- /dev/null
+++ b/Zend/tests/generators/generator_in_multipleiterator.phpt
@@ -0,0 +1,37 @@
+--TEST--
+Generators work properly in MultipleIterator
+--FILE--
+<?php
+
+function gen1() {
+ yield 'a';
+ yield 'aa';
+}
+
+function gen2() {
+ yield 'b';
+ yield 'bb';
+}
+
+$it = new MultipleIterator;
+$it->attachIterator(gen1());
+$it->attachIterator(gen2());
+
+foreach ($it as $values) {
+ var_dump($values);
+}
+
+?>
+--EXPECT--
+array(2) {
+ [0]=>
+ string(1) "a"
+ [1]=>
+ string(1) "b"
+}
+array(2) {
+ [0]=>
+ string(2) "aa"
+ [1]=>
+ string(2) "bb"
+}
diff --git a/Zend/tests/generators/generator_method.phpt b/Zend/tests/generators/generator_method.phpt
new file mode 100644
index 0000000000..b8196c171e
--- /dev/null
+++ b/Zend/tests/generators/generator_method.phpt
@@ -0,0 +1,29 @@
+--TEST--
+Methods can be generators
+--FILE--
+<?php
+
+class Test implements IteratorAggregate {
+ protected $data;
+
+ public function __construct(array $data) {
+ $this->data = $data;
+ }
+
+ public function getIterator() {
+ foreach ($this->data as $value) {
+ yield $value;
+ }
+ }
+}
+
+$test = new Test(['foo', 'bar', 'baz']);
+foreach ($test as $value) {
+ var_dump($value);
+}
+
+?>
+--EXPECT--
+string(3) "foo"
+string(3) "bar"
+string(3) "baz"
diff --git a/Zend/tests/generators/generator_method_by_ref.phpt b/Zend/tests/generators/generator_method_by_ref.phpt
new file mode 100644
index 0000000000..cfe52fe67f
--- /dev/null
+++ b/Zend/tests/generators/generator_method_by_ref.phpt
@@ -0,0 +1,44 @@
+--TEST--
+Generator methods can yield by reference
+--FILE--
+<?php
+
+class Test implements IteratorAggregate {
+ protected $data;
+
+ public function __construct(array $data) {
+ $this->data = $data;
+ }
+
+ public function getData() {
+ return $this->data;
+ }
+
+ public function &getIterator() {
+ foreach ($this->data as $key => &$value) {
+ yield $key => $value;
+ }
+ }
+}
+
+$test = new Test([1, 2, 3, 4, 5]);
+foreach ($test as &$value) {
+ $value *= -1;
+}
+
+var_dump($test->getData());
+
+?>
+--EXPECT--
+array(5) {
+ [0]=>
+ int(-1)
+ [1]=>
+ int(-2)
+ [2]=>
+ int(-3)
+ [3]=>
+ int(-4)
+ [4]=>
+ &int(-5)
+}
diff --git a/Zend/tests/generators/generator_returns_generator.phpt b/Zend/tests/generators/generator_returns_generator.phpt
new file mode 100644
index 0000000000..ad332a3be9
--- /dev/null
+++ b/Zend/tests/generators/generator_returns_generator.phpt
@@ -0,0 +1,18 @@
+--TEST--
+A generator function returns a Generator object
+--FILE--
+<?php
+
+function gen() {
+ // execution is suspended here, so the following never gets run:
+ echo "Foo";
+ // trigger a generator
+ yield;
+}
+
+$generator = gen();
+var_dump($generator instanceof Generator);
+
+?>
+--EXPECT--
+bool(true)
diff --git a/Zend/tests/generators/generator_rewind.phpt b/Zend/tests/generators/generator_rewind.phpt
new file mode 100644
index 0000000000..c4b5bbbdf4
--- /dev/null
+++ b/Zend/tests/generators/generator_rewind.phpt
@@ -0,0 +1,62 @@
+--TEST--
+A generator can only be rewinded before or at the first yield
+--FILE--
+<?php
+
+function gen() {
+ echo "before yield\n";
+ yield;
+ echo "after yield\n";
+ yield;
+}
+
+$gen = gen();
+$gen->rewind();
+$gen->rewind();
+$gen->next();
+
+try {
+ $gen->rewind();
+} catch (Exception $e) {
+ echo "\n", $e, "\n\n";
+}
+
+function &gen2() {
+ $foo = 'bar';
+ yield $foo;
+ yield $foo;
+}
+
+$gen = gen2();
+foreach ($gen as $v) { }
+try {
+ foreach ($gen as $v) { }
+} catch (Exception $e) {
+ echo $e, "\n\n";
+}
+
+function gen3() {
+ echo "in generator\n";
+
+ if (false) yield;
+}
+
+$gen = gen3();
+$gen->rewind();
+
+?>
+--EXPECTF--
+before yield
+after yield
+
+exception 'Exception' with message 'Cannot rewind a generator that was already run' in %s:%d
+Stack trace:
+#0 %s(%d): Generator->rewind()
+#1 {main}
+
+exception 'Exception' with message 'Cannot traverse an already closed generator' in %s:%d
+Stack trace:
+#0 %s(%d): unknown()
+#1 {main}
+
+in generator
diff --git a/Zend/tests/generators/generator_send.phpt b/Zend/tests/generators/generator_send.phpt
new file mode 100644
index 0000000000..074d815389
--- /dev/null
+++ b/Zend/tests/generators/generator_send.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Values can be sent back to the generator
+--FILE--
+<?php
+
+function gen() {
+ var_dump(yield "yield foo");
+ var_dump(yield "yield bar");
+}
+
+$gen = gen();
+var_dump($gen->current());
+$gen->send("send bar");
+var_dump($gen->current());
+$gen->send("send foo");
+
+?>
+--EXPECT--
+string(9) "yield foo"
+string(8) "send bar"
+string(9) "yield bar"
+string(8) "send foo"
diff --git a/Zend/tests/generators/generator_static_method.phpt b/Zend/tests/generators/generator_static_method.phpt
new file mode 100644
index 0000000000..cd9b450a76
--- /dev/null
+++ b/Zend/tests/generators/generator_static_method.phpt
@@ -0,0 +1,29 @@
+--TEST--
+A static method can be a generator
+--FILE--
+<?php
+
+class Test {
+ public static function gen() {
+ var_dump(get_class());
+ var_dump(get_called_class());
+ yield 1;
+ yield 2;
+ yield 3;
+ }
+}
+
+class ExtendedTest extends Test {
+}
+
+foreach (ExtendedTest::gen() as $i) {
+ var_dump($i);
+}
+
+?>
+--EXPECT--
+string(4) "Test"
+string(12) "ExtendedTest"
+int(1)
+int(2)
+int(3)
diff --git a/Zend/tests/generators/generator_throwing_during_function_call.phpt b/Zend/tests/generators/generator_throwing_during_function_call.phpt
new file mode 100644
index 0000000000..bd0d2448b7
--- /dev/null
+++ b/Zend/tests/generators/generator_throwing_during_function_call.phpt
@@ -0,0 +1,32 @@
+--TEST--
+Stack is cleaned up properly when an exception is thrown during a function call
+--FILE--
+<?php
+
+function throwException() {
+ throw new Exception('test');
+}
+
+function gen() {
+ yield 'foo';
+ strlen("foo", "bar", throwException());
+ yield 'bar';
+}
+
+$gen = gen();
+
+var_dump($gen->current());
+
+try {
+ $gen->next();
+} catch (Exception $e) {
+ echo 'Caught exception with message "', $e->getMessage(), '"', "\n";
+}
+
+var_dump($gen->current());
+
+?>
+--EXPECT--
+string(3) "foo"
+Caught exception with message "test"
+NULL
diff --git a/Zend/tests/generators/generator_throwing_exception.phpt b/Zend/tests/generators/generator_throwing_exception.phpt
new file mode 100644
index 0000000000..f537c3fc77
--- /dev/null
+++ b/Zend/tests/generators/generator_throwing_exception.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Generators can throw exceptions
+--FILE--
+<?php
+
+function gen() {
+ yield 'foo';
+ throw new Exception('test');
+ yield 'bar';
+}
+
+$gen = gen();
+
+var_dump($gen->current());
+
+try {
+ $gen->next();
+} catch (Exception $e) {
+ echo 'Caught exception with message "', $e->getMessage(), '"', "\n";
+}
+
+var_dump($gen->current());
+
+?>
+--EXPECT--
+string(3) "foo"
+Caught exception with message "test"
+NULL
diff --git a/Zend/tests/generators/generator_throwing_in_foreach.phpt b/Zend/tests/generators/generator_throwing_in_foreach.phpt
new file mode 100644
index 0000000000..dbf20c2ca1
--- /dev/null
+++ b/Zend/tests/generators/generator_throwing_in_foreach.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Exceptions throwing by generators during foreach iteration are properly handled
+--FILE--
+<?php
+
+function gen() {
+ throw new Exception("foo");
+ yield; // force generator
+}
+
+foreach (gen() as $value) { }
+
+?>
+--EXPECTF--
+Fatal error: Uncaught exception 'Exception' with message 'foo' in %s:%d
+Stack trace:
+#0 %s(%d): gen()
+#1 {main}
+ thrown in %s on line %d
+
diff --git a/Zend/tests/generators/generator_with_keys.phpt b/Zend/tests/generators/generator_with_keys.phpt
new file mode 100644
index 0000000000..efb377679e
--- /dev/null
+++ b/Zend/tests/generators/generator_with_keys.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Generators can also yield keys
+--FILE--
+<?php
+
+function reverse(array $array) {
+ end($array);
+ while (null !== $key = key($array)) {
+ yield $key => current($array);
+ prev($array);
+ }
+}
+
+$array = [
+ 'foo' => 'bar',
+ 'bar' => 'foo',
+];
+
+foreach (reverse($array) as $key => $value) {
+ echo $key, ' => ', $value, "\n";
+}
+
+?>
+--EXPECT--
+bar => foo
+foo => bar
diff --git a/Zend/tests/generators/generator_with_nonscalar_keys.phpt b/Zend/tests/generators/generator_with_nonscalar_keys.phpt
new file mode 100644
index 0000000000..5ae55a1be0
--- /dev/null
+++ b/Zend/tests/generators/generator_with_nonscalar_keys.phpt
@@ -0,0 +1,52 @@
+--TEST--
+Generators can return non-scalar keys
+--FILE--
+<?php
+
+function gen() {
+ yield [1, 2, 3] => [4, 5, 6];
+ yield (object) ['a' => 'b'] => (object) ['b' => 'a'];
+ yield 3.14 => 2.73;
+ yield false => true;
+ yield true => false;
+ yield null => null;
+}
+
+foreach (gen() as $k => $v) {
+ var_dump($k, $v);
+}
+
+?>
+--EXPECT--
+array(3) {
+ [0]=>
+ int(1)
+ [1]=>
+ int(2)
+ [2]=>
+ int(3)
+}
+array(3) {
+ [0]=>
+ int(4)
+ [1]=>
+ int(5)
+ [2]=>
+ int(6)
+}
+object(stdClass)#3 (1) {
+ ["a"]=>
+ string(1) "b"
+}
+object(stdClass)#4 (1) {
+ ["b"]=>
+ string(1) "a"
+}
+float(3.14)
+float(2.73)
+bool(false)
+bool(true)
+bool(true)
+bool(false)
+NULL
+NULL
diff --git a/Zend/tests/generators/ignored_send_leak.phpt b/Zend/tests/generators/ignored_send_leak.phpt
new file mode 100644
index 0000000000..352ba406ba
--- /dev/null
+++ b/Zend/tests/generators/ignored_send_leak.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Ignoring a sent value shouldn't leak memory
+--FILE--
+<?php
+
+function gen() {
+ yield;
+}
+
+$gen = gen();
+$gen->send(NULL);
+
+echo "DONE";
+
+?>
+--EXPECT--
+DONE
diff --git a/Zend/tests/generators/nested_calls_with_die.phpt b/Zend/tests/generators/nested_calls_with_die.phpt
new file mode 100644
index 0000000000..f43d89ba21
--- /dev/null
+++ b/Zend/tests/generators/nested_calls_with_die.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Test nested calls with die() in a generator
+--FILE--
+<?php
+
+function gen() {
+ die('Test');
+ yield; // force generator
+}
+
+function function_with_3_args() {
+ $gen = gen();
+ $gen->rewind();
+}
+
+function function_with_4_args() {
+ function_with_3_args(4, 5, 6);
+}
+
+function outerGen() {
+ function_with_4_args(0, 1, 2, 3);
+ yield; // force generator
+}
+
+$outerGen = outerGen();
+$outerGen->rewind();
+
+?>
+--EXPECT--
+Test
diff --git a/Zend/tests/generators/nested_method_calls.phpt b/Zend/tests/generators/nested_method_calls.phpt
new file mode 100644
index 0000000000..0d640b31c6
--- /dev/null
+++ b/Zend/tests/generators/nested_method_calls.phpt
@@ -0,0 +1,36 @@
+--TEST--
+Yield can be used in nested method calls
+--FILE--
+<?php
+
+class A {
+ function foo() {
+ echo "Called A::foo\n";
+ }
+}
+
+class B {
+ function foo() {
+ echo "Called B::foo\n";
+ }
+}
+
+function gen($obj) {
+ $obj->foo($obj->foo(yield));
+}
+
+$g1 = gen(new A);
+$g1->current();
+
+$g2 = gen(new B);
+$g2->current();
+
+$g1->next();
+$g2->next();
+
+?>
+--EXPECT--
+Called A::foo
+Called A::foo
+Called B::foo
+Called B::foo
diff --git a/Zend/tests/generators/no_foreach_var_leaks.phpt b/Zend/tests/generators/no_foreach_var_leaks.phpt
new file mode 100644
index 0000000000..62743895eb
--- /dev/null
+++ b/Zend/tests/generators/no_foreach_var_leaks.phpt
@@ -0,0 +1,19 @@
+--TEST--
+foreach() (and other) variables aren't leaked on premature close
+--FILE--
+<?php
+
+function gen(array $array) {
+ foreach ($array as $value) {
+ yield $value;
+ }
+}
+
+$gen = gen(['Foo', 'Bar']);
+var_dump($gen->current());
+
+// generator is closed here, without running SWITCH_FREE
+
+?>
+--EXPECT--
+string(3) "Foo"
diff --git a/Zend/tests/generators/send_after_close.phpt b/Zend/tests/generators/send_after_close.phpt
new file mode 100644
index 0000000000..806baf8cee
--- /dev/null
+++ b/Zend/tests/generators/send_after_close.phpt
@@ -0,0 +1,14 @@
+--TEST--
+Calls to send() after close should do nothing
+--FILE--
+<?php
+
+function gen() { var_dump(yield); }
+
+$gen = gen();
+$gen->send('foo');
+$gen->send('bar');
+
+?>
+--EXPECT--
+string(3) "foo"
diff --git a/Zend/tests/generators/send_returns_current.phpt b/Zend/tests/generators/send_returns_current.phpt
new file mode 100644
index 0000000000..27ba74bc1b
--- /dev/null
+++ b/Zend/tests/generators/send_returns_current.phpt
@@ -0,0 +1,20 @@
+--TEST--
+$generator->send() returns the yielded value
+--FILE--
+<?php
+
+function reverseEchoGenerator() {
+ $data = yield;
+ while (true) {
+ $data = (yield strrev($data));
+ }
+}
+
+$gen = reverseEchoGenerator();
+var_dump($gen->send('foo'));
+var_dump($gen->send('bar'));
+
+?>
+--EXPECT--
+string(3) "oof"
+string(3) "rab"
diff --git a/Zend/tests/generators/throw_already_closed.phpt b/Zend/tests/generators/throw_already_closed.phpt
new file mode 100644
index 0000000000..e918e540ab
--- /dev/null
+++ b/Zend/tests/generators/throw_already_closed.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Generator::throw() on an already closed generator
+--FILE--
+<?php
+
+function gen() {
+ yield;
+}
+
+$gen = gen();
+$gen->next();
+$gen->next();
+var_dump($gen->valid());
+$gen->throw(new Exception('test'));
+
+?>
+--EXPECTF--
+bool(false)
+
+Fatal error: Uncaught exception 'Exception' with message 'test' in %s:%d
+Stack trace:
+#0 {main}
+ thrown in %s on line %d
diff --git a/Zend/tests/generators/throw_caught.phpt b/Zend/tests/generators/throw_caught.phpt
new file mode 100644
index 0000000000..c5e9d81ebc
--- /dev/null
+++ b/Zend/tests/generators/throw_caught.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Generator::throw() where the exception is caught in the generator
+--FILE--
+<?php
+
+function gen() {
+ echo "before yield\n";
+ try {
+ yield;
+ } catch (RuntimeException $e) {
+ echo $e, "\n\n";
+ }
+
+ yield 'result';
+}
+
+$gen = gen();
+var_dump($gen->throw(new RuntimeException('Test')));
+
+?>
+--EXPECTF--
+before yield
+exception 'RuntimeException' with message 'Test' in %s:%d
+Stack trace:
+#0 {main}
+
+string(6) "result"
diff --git a/Zend/tests/generators/throw_not_an_exception.phpt b/Zend/tests/generators/throw_not_an_exception.phpt
new file mode 100644
index 0000000000..d93903e215
--- /dev/null
+++ b/Zend/tests/generators/throw_not_an_exception.phpt
@@ -0,0 +1,15 @@
+--TEST--
+Generator::throw() with something that's not an exception
+--FILE--
+<?php
+
+function gen() {
+ yield;
+}
+
+$gen = gen();
+$gen->throw(new stdClass);
+
+?>
+--EXPECTF--
+Fatal error: Exceptions must be valid objects derived from the Exception base class in %s on line %d
diff --git a/Zend/tests/generators/throw_rethrow.phpt b/Zend/tests/generators/throw_rethrow.phpt
new file mode 100644
index 0000000000..65044ee3f3
--- /dev/null
+++ b/Zend/tests/generators/throw_rethrow.phpt
@@ -0,0 +1,34 @@
+--TEST--
+Generator::throw() where the generator throws a different exception
+--FILE--
+<?php
+
+function gen() {
+ echo "before yield\n";
+ try {
+ yield;
+ } catch (RuntimeException $e) {
+ echo 'Caught: ', $e, "\n\n";
+
+ throw new LogicException('new throw');
+ }
+}
+
+$gen = gen();
+var_dump($gen->throw(new RuntimeException('throw')));
+
+?>
+--EXPECTF--
+before yield
+Caught: exception 'RuntimeException' with message 'throw' in %s:%d
+Stack trace:
+#0 {main}
+
+
+Fatal error: Uncaught exception 'LogicException' with message 'new throw' in %s:%d
+Stack trace:
+#0 [internal function]: gen()
+#1 %s(%d): Generator->throw(Object(RuntimeException))
+#2 {main}
+ thrown in %s on line %d
+
diff --git a/Zend/tests/generators/throw_uncaught.phpt b/Zend/tests/generators/throw_uncaught.phpt
new file mode 100644
index 0000000000..f06cff1b8e
--- /dev/null
+++ b/Zend/tests/generators/throw_uncaught.phpt
@@ -0,0 +1,19 @@
+--TEST--
+Generator::throw() where the exception is not caught in the generator
+--FILE--
+<?php
+
+function gen() {
+ yield 'thisThrows';
+ yield 'notReached';
+}
+
+$gen = gen();
+var_dump($gen->throw(new RuntimeException('test')));
+
+?>
+--EXPECTF--
+Fatal error: Uncaught exception 'RuntimeException' with message 'test' in %s:%d
+Stack trace:
+#0 {main}
+ thrown in %s on line %d
diff --git a/Zend/tests/generators/unused_return_value.phpt b/Zend/tests/generators/unused_return_value.phpt
new file mode 100644
index 0000000000..ddce64542c
--- /dev/null
+++ b/Zend/tests/generators/unused_return_value.phpt
@@ -0,0 +1,13 @@
+--TEST--
+There shouldn't be any leaks when the genertor's return value isn't used
+--FILE--
+<?php
+
+function gen($foo) { yield; }
+
+gen('foo'); // return value not used
+
+?>
+===DONE===
+--EXPECT--
+===DONE===
diff --git a/Zend/tests/generators/xrange.phpt b/Zend/tests/generators/xrange.phpt
new file mode 100644
index 0000000000..4d8b60fa90
--- /dev/null
+++ b/Zend/tests/generators/xrange.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Simple generator xrange() test
+--FILE--
+<?php
+
+function xrange($start, $end, $step = 1) {
+ for ($i = $start; $i <= $end; $i += $step) {
+ yield $i;
+ }
+}
+
+foreach (xrange(10, 20, 2) as $i) {
+ var_dump($i);
+}
+
+?>
+--EXPECT--
+int(10)
+int(12)
+int(14)
+int(16)
+int(18)
+int(20)
diff --git a/Zend/tests/generators/yield_array_key.phpt b/Zend/tests/generators/yield_array_key.phpt
new file mode 100644
index 0000000000..5afba00de8
--- /dev/null
+++ b/Zend/tests/generators/yield_array_key.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Array keys can be yielded from generators
+--FILE--
+<?php
+
+function gen() {
+ yield [] => 1;
+}
+
+$gen = gen();
+var_dump($gen->key());
+var_dump($gen->current());
+
+?>
+--EXPECT--
+array(0) {
+}
+int(1)
diff --git a/Zend/tests/generators/yield_array_offset_by_ref.phpt b/Zend/tests/generators/yield_array_offset_by_ref.phpt
new file mode 100644
index 0000000000..544108e64d
--- /dev/null
+++ b/Zend/tests/generators/yield_array_offset_by_ref.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Array offsets can be yielded by reference
+--FILE--
+<?php
+
+function &gen(array &$array) {
+ yield $array[0];
+}
+
+$array = [1, 2, 3];
+$gen = gen($array);
+foreach ($gen as &$val) {
+ $val *= -1;
+}
+var_dump($array);
+
+?>
+--EXPECT--
+array(3) {
+ [0]=>
+ &int(-1)
+ [1]=>
+ int(2)
+ [2]=>
+ int(3)
+}
diff --git a/Zend/tests/generators/yield_by_reference.phpt b/Zend/tests/generators/yield_by_reference.phpt
new file mode 100644
index 0000000000..dba0791c0d
--- /dev/null
+++ b/Zend/tests/generators/yield_by_reference.phpt
@@ -0,0 +1,42 @@
+--TEST--
+Generators can yield by-reference
+--FILE--
+<?php
+
+function &iter(array &$array) {
+ foreach ($array as $key => &$value) {
+ yield $key => $value;
+ }
+}
+
+$array = [1, 2, 3];
+$iter = iter($array);
+foreach ($iter as &$value) {
+ $value *= -1;
+}
+var_dump($array);
+
+$array = [1, 2, 3];
+foreach (iter($array) as &$value) {
+ $value *= -1;
+}
+var_dump($array);
+
+?>
+--EXPECT--
+array(3) {
+ [0]=>
+ int(-1)
+ [1]=>
+ int(-2)
+ [2]=>
+ &int(-3)
+}
+array(3) {
+ [0]=>
+ int(-1)
+ [1]=>
+ int(-2)
+ [2]=>
+ &int(-3)
+}
diff --git a/Zend/tests/generators/yield_closure.phpt b/Zend/tests/generators/yield_closure.phpt
new file mode 100644
index 0000000000..e380b29946
--- /dev/null
+++ b/Zend/tests/generators/yield_closure.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Generator shouldn't crash if last yielded value is a closure
+--FILE--
+<?php
+
+function gen() {
+ yield function() {};
+}
+
+$gen = gen();
+$gen->next();
+
+echo "Done!";
+
+?>
+--EXPECT--
+Done!
diff --git a/Zend/tests/generators/yield_during_function_call.phpt b/Zend/tests/generators/yield_during_function_call.phpt
new file mode 100644
index 0000000000..21071f9fb4
--- /dev/null
+++ b/Zend/tests/generators/yield_during_function_call.phpt
@@ -0,0 +1,15 @@
+--TEST--
+"yield" can occur during a function call
+--FILE--
+<?php
+
+function gen() {
+ var_dump(str_repeat("x", yield));
+}
+
+$gen = gen();
+$gen->send(10);
+
+?>
+--EXPECT--
+string(10) "xxxxxxxxxx"
diff --git a/Zend/tests/generators/yield_during_method_call.phpt b/Zend/tests/generators/yield_during_method_call.phpt
new file mode 100644
index 0000000000..3a9914d58b
--- /dev/null
+++ b/Zend/tests/generators/yield_during_method_call.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Yield can be used during a method call
+--FILE--
+<?php
+
+class A {
+ public function b($c) {
+ echo $c, "\n";
+ }
+}
+
+function gen() {
+ $a = new A;
+ $a->b(yield);
+}
+
+$gen = gen();
+$gen->send('foo');
+
+// test resource cleanup
+$gen = gen();
+$gen->rewind();
+unset($gen);
+
+?>
+--EXPECT--
+foo
diff --git a/Zend/tests/generators/yield_in_finally.phpt b/Zend/tests/generators/yield_in_finally.phpt
new file mode 100644
index 0000000000..805484ad1d
--- /dev/null
+++ b/Zend/tests/generators/yield_in_finally.phpt
@@ -0,0 +1,29 @@
+--TEST--
+yield can be used in finally (apart from forced closes)
+--FILE--
+<?php
+
+function gen() {
+ try {
+ echo "before return\n";
+ return;
+ echo "after return\n";
+ } finally {
+ echo "before yield\n";
+ yield "yielded value";
+ echo "after yield\n";
+ }
+
+ echo "after finally\n";
+}
+
+$gen = gen();
+var_dump($gen->current());
+$gen->next();
+
+?>
+--EXPECTF--
+before return
+before yield
+string(%d) "yielded value"
+after yield
diff --git a/Zend/tests/generators/yield_in_parenthesis.phpt b/Zend/tests/generators/yield_in_parenthesis.phpt
new file mode 100644
index 0000000000..4a603f4cc1
--- /dev/null
+++ b/Zend/tests/generators/yield_in_parenthesis.phpt
@@ -0,0 +1,23 @@
+--TEST--
+No additional parenthesis are required around yield if they are already present
+--FILE--
+<?php
+
+function gen() {
+ if (yield $foo); elseif (yield $foo);
+ if (yield $foo): elseif (yield $foo): endif;
+ while (yield $foo);
+ do {} while (yield $foo);
+ switch (yield $foo) {}
+ (yield $foo);
+ die(yield $foo);
+ func(yield $foo);
+ $foo->func(yield $foo);
+ new Foo(yield $foo);
+}
+
+echo "Done";
+
+?>
+--EXPECT--
+Done
diff --git a/Zend/tests/generators/yield_ref_function_call_by_reference.phpt b/Zend/tests/generators/yield_ref_function_call_by_reference.phpt
new file mode 100644
index 0000000000..e371affd92
--- /dev/null
+++ b/Zend/tests/generators/yield_ref_function_call_by_reference.phpt
@@ -0,0 +1,24 @@
+--TEST--
+The result of a by-ref function call can be yielded just fine
+--FILE--
+<?php
+
+function &nop(&$var) {
+ return $var;
+}
+
+function &gen(&$var) {
+ yield nop($var);
+}
+
+$var = "foo";
+$gen = gen($var);
+foreach ($gen as &$varRef) {
+ $varRef = "bar";
+}
+
+var_dump($var);
+
+?>
+--EXPECT--
+string(3) "bar"
diff --git a/Zend/tests/generators/yield_without_value.phpt b/Zend/tests/generators/yield_without_value.phpt
new file mode 100644
index 0000000000..52292b737c
--- /dev/null
+++ b/Zend/tests/generators/yield_without_value.phpt
@@ -0,0 +1,27 @@
+--TEST--
+yield can be used without a value
+--FILE--
+<?php
+
+function recv() {
+ while (true) {
+ var_dump(yield);
+ }
+}
+
+$receiver = recv();
+var_dump($receiver->current());
+$receiver->send(1);
+var_dump($receiver->current());
+$receiver->send(2);
+var_dump($receiver->current());
+$receiver->send(3);
+
+?>
+--EXPECT--
+NULL
+int(1)
+NULL
+int(2)
+NULL
+int(3)
diff --git a/Zend/tests/isset_expr_error.phpt b/Zend/tests/isset_expr_error.phpt
new file mode 100644
index 0000000000..27fc6cd8d3
--- /dev/null
+++ b/Zend/tests/isset_expr_error.phpt
@@ -0,0 +1,8 @@
+--TEST--
+Error message for isset(func())
+--FILE--
+<?php
+isset(1 + 1);
+?>
+--EXPECTF--
+Fatal error: Cannot use isset() on the result of an expression (you can use "null !== expression" instead) in %s on line %d
diff --git a/Zend/tests/isset_func_error.phpt b/Zend/tests/isset_func_error.phpt
new file mode 100644
index 0000000000..7d1036def8
--- /dev/null
+++ b/Zend/tests/isset_func_error.phpt
@@ -0,0 +1,8 @@
+--TEST--
+Error message for isset(func())
+--FILE--
+<?php
+isset(abc());
+?>
+--EXPECTF--
+Fatal error: Cannot use isset() on the result of a function call (you can use "null !== func()" instead) in %s on line %d
diff --git a/Zend/tests/ns_026.phpt b/Zend/tests/ns_026.phpt
index af2bf2ca55..45f88750eb 100644
--- a/Zend/tests/ns_026.phpt
+++ b/Zend/tests/ns_026.phpt
@@ -1,5 +1,7 @@
--TEST--
026: Name ambiguity (class name & namespace name)
+--INI--
+opcache.optimization_level=0
--FILE--
<?php
namespace Foo;
diff --git a/Zend/tests/offset_assign.phpt b/Zend/tests/offset_assign.phpt
index 6a00591095..721516f53c 100644
--- a/Zend/tests/offset_assign.phpt
+++ b/Zend/tests/offset_assign.phpt
@@ -3,11 +3,11 @@ Crash on $x['x']['y'] += 1 when $x is string
--FILE--
<?php
$x = "a";
-$x['x']['y'] += 1;
+$x['x']['y'] += 1;
echo "Done\n";
?>
---EXPECTF--
+--EXPECTF--
Warning: Illegal string offset 'x' in %soffset_assign.php on line %d
Fatal error: Cannot use string offset as an array in %soffset_assign.php on line %d
diff --git a/Zend/tests/offset_string.phpt b/Zend/tests/offset_string.phpt
index f7cb81bb20..c546b37183 100644
--- a/Zend/tests/offset_string.phpt
+++ b/Zend/tests/offset_string.phpt
@@ -27,7 +27,7 @@ var_dump($str[$arr]);
echo "Done\n";
?>
---EXPECTF--
+--EXPECTF--
string(1) "i"
Notice: String offset cast occurred in %s on line %d
diff --git a/Zend/tests/try_catch_finally_001.phpt b/Zend/tests/try_catch_finally_001.phpt
new file mode 100644
index 0000000000..3d478f461a
--- /dev/null
+++ b/Zend/tests/try_catch_finally_001.phpt
@@ -0,0 +1,36 @@
+--TEST--
+Try catch finally
+--FILE--
+<?php
+
+class AE extends Exception {};
+class BE extends Exception {};
+
+function foo () {
+ try {
+ try {
+ try {
+ throw new Exception("try");
+ } catch (AE $e) {
+ echo "0";
+ die("error");
+ } finally {
+ echo "1";
+ }
+ } finally {
+ echo "2";
+ }
+ } catch (BE $e) {
+ die("error");
+ } catch (Exception $e) {
+ echo "3";
+ } finally {
+ echo "4";
+ }
+ return 1;
+}
+
+var_dump(foo());
+?>
+--EXPECTF--
+1234int(1)
diff --git a/Zend/tests/try_catch_finally_002.phpt b/Zend/tests/try_catch_finally_002.phpt
new file mode 100644
index 0000000000..79efcb3de8
--- /dev/null
+++ b/Zend/tests/try_catch_finally_002.phpt
@@ -0,0 +1,42 @@
+--TEST--
+Try catch finally catch(multi catch blocks)
+--FILE--
+<?php
+
+class AE extends Exception {};
+class BE extends Exception {};
+
+function foo () {
+ try {
+ try {
+ try {
+ try {
+ echo "1";
+ throw new Exception("try");
+ } catch (AE $e) {
+ die("error");
+ } finally {
+ echo "2";
+ }
+ } finally {
+ echo "3";
+ }
+ } catch (BE $e) {
+ die("error");
+ } finally {
+ echo "4";
+ }
+ } catch (Exception $e) {
+ echo "5";
+ } catch (AE $e) {
+ die("error");
+ } finally {
+ echo "6";
+ }
+ return 7;
+}
+
+var_dump(foo());
+?>
+--EXPECTF--
+123456int(7)
diff --git a/Zend/tests/try_catch_finally_003.phpt b/Zend/tests/try_catch_finally_003.phpt
new file mode 100644
index 0000000000..7ec8ec82db
--- /dev/null
+++ b/Zend/tests/try_catch_finally_003.phpt
@@ -0,0 +1,36 @@
+--TEST--
+Try catch finally (multi catch blocks with return)
+--FILE--
+<?php
+
+class AE extends Exception {};
+class BE extends Exception {};
+
+function foo () {
+ try {
+ try {
+ try {
+ throw new Exception("try");
+ } catch (AE $e) {
+ die("error");
+ } finally {
+ echo "1";
+ }
+ } finally {
+ echo "2";
+ }
+ } catch (BE $e) {
+ die("error");
+ } catch (Exception $e) {
+ echo "3";
+ } finally {
+ echo "4";
+ return 4;
+ }
+ return 5;
+}
+
+var_dump(foo());
+?>
+--EXPECTF--
+1234int(4)
diff --git a/Zend/tests/try_catch_finally_004.phpt b/Zend/tests/try_catch_finally_004.phpt
new file mode 100644
index 0000000000..eb8d0966a1
--- /dev/null
+++ b/Zend/tests/try_catch_finally_004.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Try catch finally (re-throw exception in catch block)
+--CREDITS--
+adoy
+--FILE--
+<?php
+function dummy($msg) {
+ var_dump($msg);
+}
+try {
+ try {
+ var_dump("try");
+ return;
+ } catch (Exception $e) {
+ dummy("catch");
+ throw $e;
+ } finally {
+ dummy("finally");
+ }
+} catch (Exception $e) {
+ dummy("catch2");
+} finally {
+ dummy("finally2");
+}
+var_dump("end");
+?>
+--EXPECTF--
+string(3) "try"
+string(7) "finally"
+string(8) "finally2"
diff --git a/Zend/tests/try_catch_finally_005.phpt b/Zend/tests/try_catch_finally_005.phpt
new file mode 100644
index 0000000000..dafeb6bbe0
--- /dev/null
+++ b/Zend/tests/try_catch_finally_005.phpt
@@ -0,0 +1,52 @@
+--TEST--
+Try catch finally (break / cont in try block)
+--CREDITS--
+adoy
+--FILE--
+<?php
+for ($i = 0; $i < 100 ; $i ++) {
+ try {
+ break;
+ } finally {
+ var_dump("break");
+ }
+}
+
+
+for ($i = 0; $i < 2; $i ++) {
+ try {
+ continue;
+ } finally {
+ var_dump("continue1");
+ }
+}
+
+for ($i = 0; $i < 3; $i ++) {
+ try {
+ try {
+ continue;
+ } finally {
+ var_dump("continue2");
+ if ($i == 1) {
+ throw new Exception("continue exception");
+ }
+ }
+ } catch (Exception $e) {
+ var_dump("cactched");
+ } finally {
+ var_dump("finally");
+ }
+}
+
+?>
+--EXPECTF--
+string(5) "break"
+string(9) "continue1"
+string(9) "continue1"
+string(9) "continue2"
+string(7) "finally"
+string(9) "continue2"
+string(8) "cactched"
+string(7) "finally"
+string(9) "continue2"
+string(7) "finally"
diff --git a/Zend/tests/try_catch_finally_006.phpt b/Zend/tests/try_catch_finally_006.phpt
new file mode 100644
index 0000000000..dab6af6a58
--- /dev/null
+++ b/Zend/tests/try_catch_finally_006.phpt
@@ -0,0 +1,39 @@
+--TEST--
+Try catch finally (goto in try/catch block)
+--CREDITS--
+adoy
+--FILE--
+<?php
+function foo($ex = NULL) {
+ try {
+ try {
+ goto label;
+ } finally {
+ var_dump("finally1");
+ if ($ex) throw $ex;
+ }
+ } catch (Exception $e) {
+ var_dump("catched");
+ if ($ex) return "return1";
+ } finally {
+ var_dump("finally2");
+ }
+
+label:
+ var_dump("label");
+ return "return2";
+}
+
+var_dump(foo());
+var_dump(foo(new Exception()));
+
+?>
+--EXPECTF--
+string(8) "finally1"
+string(8) "finally2"
+string(5) "label"
+string(7) "return2"
+string(8) "finally1"
+string(7) "catched"
+string(8) "finally2"
+string(7) "return1"
diff --git a/Zend/tests/try_catch_finally_007.phpt b/Zend/tests/try_catch_finally_007.phpt
new file mode 100644
index 0000000000..ad33c68131
--- /dev/null
+++ b/Zend/tests/try_catch_finally_007.phpt
@@ -0,0 +1,46 @@
+--TEST--
+Try catch finally (goto in try/catch block)
+--CREDITS--
+adoy
+--FILE--
+<?php
+function foo($ret = FALSE) {
+ try {
+ try {
+ do {
+ goto label;
+ } while(0);
+ foreach (array() as $val) {
+ continue;
+ }
+ } finally {
+ var_dump("finally1");
+ throw new Exception("exception");
+ }
+ } catch (Exception $e) {
+ goto local;
+local:
+ var_dump("catched");
+ if ($ret) return "return";
+ } finally {
+ var_dump("finally2");
+ }
+
+label:
+ var_dump("label");
+}
+
+var_dump(foo());
+var_dump(foo(true));
+
+?>
+--EXPECTF--
+string(8) "finally1"
+string(7) "catched"
+string(8) "finally2"
+string(5) "label"
+NULL
+string(8) "finally1"
+string(7) "catched"
+string(8) "finally2"
+string(6) "return"
diff --git a/Zend/tests/try_finally_001.phpt b/Zend/tests/try_finally_001.phpt
new file mode 100644
index 0000000000..0f740872c2
--- /dev/null
+++ b/Zend/tests/try_finally_001.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Try finally (basic test)
+--FILE--
+<?php
+function foo ($a) {
+ try {
+ throw new Exception("ex");
+ } finally {
+ var_dump($a);
+ }
+}
+
+foo("finally");
+?>
+--EXPECTF--
+string(7) "finally"
+
+Fatal error: Uncaught exception 'Exception' with message 'ex' %s
+Stack trace:
+#0 %stry_finally_001.php(%d): foo('finally')
+#1 {main}
+ thrown in %stry_finally_001.php on line %d
diff --git a/Zend/tests/try_finally_002.phpt b/Zend/tests/try_finally_002.phpt
new file mode 100644
index 0000000000..99a34f62fb
--- /dev/null
+++ b/Zend/tests/try_finally_002.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Try finally (re-throw exception in finally block)
+--FILE--
+<?php
+function foo () {
+ try {
+ throw new Exception("try");
+ } finally {
+ throw new Exception("finally");
+ }
+}
+
+try {
+ foo();
+} catch (Exception $e) {
+ do {
+ var_dump($e->getMessage());
+ } while ($e = $e->getPrevious());
+}
+?>
+--EXPECT--
+string(7) "finally"
+string(3) "try"
diff --git a/Zend/tests/try_finally_003.phpt b/Zend/tests/try_finally_003.phpt
new file mode 100644
index 0000000000..c1294911bd
--- /dev/null
+++ b/Zend/tests/try_finally_003.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Try finally (call sequence test)
+--FILE--
+<?php
+function foo () {
+ try {
+ echo "1";
+ try {
+ echo "2";
+ throw new Exception("ex");
+ } finally {
+ echo "3";
+ }
+ } finally {
+ echo "4";
+ }
+}
+
+foo();
+?>
+--EXPECTF--
+1234
+Fatal error: Uncaught exception 'Exception' with message 'ex' %s
+Stack trace:
+#0 %stry_finally_003.php(%d): foo()
+#1 {main}
+ thrown in %stry_finally_003.php on line %d
diff --git a/Zend/tests/try_finally_004.phpt b/Zend/tests/try_finally_004.phpt
new file mode 100644
index 0000000000..08930a40c5
--- /dev/null
+++ b/Zend/tests/try_finally_004.phpt
@@ -0,0 +1,14 @@
+--TEST--
+Try finally (without catch/finally block)
+--FILE--
+<?php
+function foo () {
+ try {
+ echo "3";
+ }
+}
+
+foo();
+?>
+--EXPECTF--
+Fatal error: Cannot use try without catch or finally in %stry_finally_004.php on line %d
diff --git a/Zend/tests/try_finally_005.phpt b/Zend/tests/try_finally_005.phpt
new file mode 100644
index 0000000000..8664d6b1bf
--- /dev/null
+++ b/Zend/tests/try_finally_005.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Try finally (with long goto)
+--FILE--
+<?php
+function foo () {
+ try {
+ } finally {
+ goto label;
+ }
+label:
+ return 1;
+}
+
+foo();
+?>
+--EXPECTF--
+Fatal error: jump out of a finally block is disallowed in %stry_finally_005.php on line %d
diff --git a/Zend/tests/try_finally_006.phpt b/Zend/tests/try_finally_006.phpt
new file mode 100644
index 0000000000..f53e6b5bc1
--- /dev/null
+++ b/Zend/tests/try_finally_006.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Try finally (with near goto)
+--FILE--
+<?php
+function foo () {
+ $jmp = 1;
+ try {
+ } finally {
+previous:
+ if ($jmp) {
+ goto label;
+ echo "dummy";
+label:
+ echo "label\n";
+ $jmp = 0;
+ goto previous;
+ }
+ echo "okey";
+ }
+}
+
+foo();
+?>
+--EXPECTF--
+label
+okey
diff --git a/Zend/tests/try_finally_007.phpt b/Zend/tests/try_finally_007.phpt
new file mode 100644
index 0000000000..634937495c
--- /dev/null
+++ b/Zend/tests/try_finally_007.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Try finally (with goto previous label)
+--FILE--
+<?php
+function foo () {
+ try {
+label:
+ echo "label";
+ try {
+ } finally {
+ goto label;
+ echo "dummy";
+ }
+ } catch (Exception $e) {
+ } finally {
+ }
+}
+
+foo();
+?>
+--EXPECTF--
+Fatal error: jump out of a finally block is disallowed in %stry_finally_007.php on line %d
diff --git a/Zend/tests/try_finally_008.phpt b/Zend/tests/try_finally_008.phpt
new file mode 100644
index 0000000000..cee37aedab
--- /dev/null
+++ b/Zend/tests/try_finally_008.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Try finally (with break in do...while)
+--FILE--
+<?php
+function foo () {
+ do {
+ try {
+ try {
+ } finally {
+ break;
+ }
+ } catch (Exception $e) {
+ } finally {
+ }
+ } while (0);
+}
+
+foo();
+?>
+--EXPECTF--
+Fatal error: jump out of a finally block is disallowed in %stry_finally_008.php on line %d
diff --git a/Zend/tests/try_finally_009.phpt b/Zend/tests/try_finally_009.phpt
new file mode 100644
index 0000000000..b29930a75e
--- /dev/null
+++ b/Zend/tests/try_finally_009.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Try finally (with for continue)
+--FILE--
+<?php
+function foo () {
+ for($i = 0; $i < 5; $i++) {
+ do {
+ try {
+ try {
+ } finally {
+ }
+ } catch (Exception $e) {
+ } finally {
+ continue;
+ }
+ } while (0);
+ }
+}
+
+foo();
+?>
+--EXPECTF--
+Fatal error: jump out of a finally block is disallowed in %stry_finally_009.php on line %d
diff --git a/Zend/tests/try_finally_010.phpt b/Zend/tests/try_finally_010.phpt
new file mode 100644
index 0000000000..bbac8dd1e5
--- /dev/null
+++ b/Zend/tests/try_finally_010.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Try finally (function call in the finaly block after exception)
+--FILE--
+<?php
+function foo() {
+ echo "4";
+}
+function bar() {
+ try {
+ echo "2";
+ throw new Exception();
+ echo "x";
+ } catch (MyEx $ex) {
+ echo "x";
+ } finally {
+ echo "3";
+ foo();
+ echo "5";
+ }
+}
+try {
+ echo "1";
+ bar();
+ echo "x";
+} catch (Exception $ex) {
+ echo "6";
+}
+echo "\n";
+--EXPECT--
+123456
diff --git a/Zend/zend.c b/Zend/zend.c
index 1189875f37..23b16ce234 100644
--- a/Zend/zend.c
+++ b/Zend/zend.c
@@ -154,9 +154,10 @@ static void print_hash(zend_write_func_t write_func, HashTable *ht, int indent,
case HASH_KEY_IS_STRING:
if (is_object) {
const char *prop_name, *class_name;
- int mangled = zend_unmangle_property_name(string_key, str_len - 1, &class_name, &prop_name);
+ int prop_len;
+ int mangled = zend_unmangle_property_name_ex(string_key, str_len - 1, &class_name, &prop_name, &prop_len);
- ZEND_PUTS_EX(prop_name);
+ ZEND_WRITE_EX(prop_name, prop_len);
if (class_name && mangled == SUCCESS) {
if (class_name[0]=='*') {
ZEND_PUTS_EX(":protected");
@@ -679,11 +680,11 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions TS
#if HAVE_DTRACE
/* build with dtrace support */
zend_compile_file = dtrace_compile_file;
- zend_execute = dtrace_execute;
+ zend_execute_ex = dtrace_execute_ex;
zend_execute_internal = dtrace_execute_internal;
#else
zend_compile_file = compile_file;
- zend_execute = execute;
+ zend_execute_ex = execute_ex;
zend_execute_internal = NULL;
#endif /* HAVE_SYS_SDT_H */
zend_compile_string = compile_string;
diff --git a/Zend/zend.h b/Zend/zend.h
index d1710548d6..d021dd6f6e 100644
--- a/Zend/zend.h
+++ b/Zend/zend.h
@@ -22,7 +22,7 @@
#ifndef ZEND_H
#define ZEND_H
-#define ZEND_VERSION "2.4.0"
+#define ZEND_VERSION "2.5.0"
#define ZEND_ENGINE_2
@@ -133,6 +133,11 @@ char *alloca ();
# endif
#endif
+/* Compatibility with non-clang compilers */
+#ifndef __has_attribute
+# define __has_attribute(x) 0
+#endif
+
/* GCC x.y.z supplies __GNUC__ = x and __GNUC_MINOR__ = y */
#ifdef __GNUC__
# define ZEND_GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
@@ -146,6 +151,14 @@ char *alloca ();
# define ZEND_ATTRIBUTE_MALLOC
#endif
+#if ZEND_GCC_VERSION >= 4003 || __has_attribute(alloc_size)
+# define ZEND_ATTRIBUTE_ALLOC_SIZE(X) __attribute__ ((alloc_size(X)))
+# define ZEND_ATTRIBUTE_ALLOC_SIZE2(X,Y) __attribute__ ((alloc_size(X,Y)))
+#else
+# define ZEND_ATTRIBUTE_ALLOC_SIZE(X)
+# define ZEND_ATTRIBUTE_ALLOC_SIZE2(X,Y)
+#endif
+
#if ZEND_GCC_VERSION >= 2007
# define ZEND_ATTRIBUTE_FORMAT(type, idx, first) __attribute__ ((format(type, idx, first)))
#else
@@ -212,6 +225,7 @@ char *alloca ();
#define ZEND_FILE_LINE_EMPTY_CC , ZEND_FILE_LINE_EMPTY_C
#define ZEND_FILE_LINE_ORIG_RELAY_C __zend_orig_filename, __zend_orig_lineno
#define ZEND_FILE_LINE_ORIG_RELAY_CC , ZEND_FILE_LINE_ORIG_RELAY_C
+#define ZEND_ASSERT(c) assert(c)
#else
#define ZEND_FILE_LINE_D
#define ZEND_FILE_LINE_DC
@@ -225,6 +239,7 @@ char *alloca ();
#define ZEND_FILE_LINE_EMPTY_CC
#define ZEND_FILE_LINE_ORIG_RELAY_C
#define ZEND_FILE_LINE_ORIG_RELAY_CC
+#define ZEND_ASSERT(c)
#endif /* ZEND_DEBUG */
#ifdef ZTS
@@ -263,10 +278,10 @@ static const char long_min_digits[] = "9223372036854775808";
#define MAX_LENGTH_OF_DOUBLE 32
-#undef SUCCESS
-#undef FAILURE
-#define SUCCESS 0
-#define FAILURE -1 /* this MUST stay a negative number, or it may affect functions! */
+typedef enum {
+ SUCCESS = 0,
+ FAILURE = -1, /* this MUST stay a negative number, or it may affect functions! */
+} ZEND_RESULT_CODE;
#include "zend_hash.h"
#include "zend_ts_hash.h"
@@ -284,7 +299,6 @@ void zend_error_noreturn(int type, const char *format, ...) __attribute__ ((nore
/*
* zval
*/
-typedef struct _zval_struct zval;
typedef struct _zend_class_entry zend_class_entry;
typedef struct _zend_guard {
@@ -440,8 +454,6 @@ struct _zend_trait_precedence {
zend_trait_method_reference *trait_method;
zend_class_entry** exclude_from_classes;
-
- union _zend_function* function; /* FIXME: kept in 5.4 for BC, not used */
};
typedef struct _zend_trait_precedence zend_trait_precedence;
@@ -458,8 +470,6 @@ struct _zend_trait_alias {
* modifiers to be set on trait method
*/
zend_uint modifiers;
-
- union _zend_function* function; /* FIXME: kept in 5.4 for BC, not used */
};
typedef struct _zend_trait_alias zend_trait_alias;
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index 1a661d7056..a852246407 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -306,16 +306,14 @@ static const char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, con
{
const char *spec_walk = *spec;
char c = *spec_walk++;
- int return_null = 0;
+ int check_null = 0;
/* scan through modifiers */
while (1) {
if (*spec_walk == '/') {
SEPARATE_ZVAL_IF_NOT_REF(arg);
} else if (*spec_walk == '!') {
- if (Z_TYPE_PP(arg) == IS_NULL) {
- return_null = 1;
- }
+ check_null = 1;
} else {
break;
}
@@ -327,6 +325,12 @@ static const char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, con
case 'L':
{
long *p = va_arg(*va, long *);
+
+ if (check_null) {
+ zend_bool *p = va_arg(*va, zend_bool *);
+ *p = (Z_TYPE_PP(arg) == IS_NULL);
+ }
+
switch (Z_TYPE_PP(arg)) {
case IS_STRING:
{
@@ -380,6 +384,12 @@ static const char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, con
case 'd':
{
double *p = va_arg(*va, double *);
+
+ if (check_null) {
+ zend_bool *p = va_arg(*va, zend_bool *);
+ *p = (Z_TYPE_PP(arg) == IS_NULL);
+ }
+
switch (Z_TYPE_PP(arg)) {
case IS_STRING:
{
@@ -418,7 +428,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, con
int *pl = va_arg(*va, int *);
switch (Z_TYPE_PP(arg)) {
case IS_NULL:
- if (return_null) {
+ if (check_null) {
*p = NULL;
*pl = 0;
break;
@@ -462,6 +472,12 @@ static const char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, con
case 'b':
{
zend_bool *p = va_arg(*va, zend_bool *);
+
+ if (check_null) {
+ zend_bool *p = va_arg(*va, zend_bool *);
+ *p = (Z_TYPE_PP(arg) == IS_NULL);
+ }
+
switch (Z_TYPE_PP(arg)) {
case IS_NULL:
case IS_STRING:
@@ -484,7 +500,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, con
case 'r':
{
zval **p = va_arg(*va, zval **);
- if (return_null) {
+ if (check_null && Z_TYPE_PP(arg) == IS_NULL) {
*p = NULL;
break;
}
@@ -499,7 +515,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, con
case 'a':
{
zval **p = va_arg(*va, zval **);
- if (return_null) {
+ if (check_null && Z_TYPE_PP(arg) == IS_NULL) {
*p = NULL;
break;
}
@@ -514,7 +530,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, con
case 'h':
{
HashTable **p = va_arg(*va, HashTable **);
- if (return_null) {
+ if (check_null && Z_TYPE_PP(arg) == IS_NULL) {
*p = NULL;
break;
}
@@ -534,7 +550,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, con
case 'o':
{
zval **p = va_arg(*va, zval **);
- if (return_null) {
+ if (check_null && Z_TYPE_PP(arg) == IS_NULL) {
*p = NULL;
break;
}
@@ -551,7 +567,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, con
zval **p = va_arg(*va, zval **);
zend_class_entry *ce = va_arg(*va, zend_class_entry *);
- if (return_null) {
+ if (check_null && Z_TYPE_PP(arg) == IS_NULL) {
*p = NULL;
break;
}
@@ -573,7 +589,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, con
zend_class_entry **lookup, **pce = va_arg(*va, zend_class_entry **);
zend_class_entry *ce_base = *pce;
- if (return_null) {
+ if (check_null && Z_TYPE_PP(arg) == IS_NULL) {
*pce = NULL;
break;
}
@@ -607,7 +623,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, con
zend_fcall_info_cache *fcc = va_arg(*va, zend_fcall_info_cache *);
char *is_callable_error = NULL;
- if (return_null) {
+ if (check_null && Z_TYPE_PP(arg) == IS_NULL) {
fci->size = 0;
fcc->initialized = 0;
break;
@@ -637,7 +653,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, con
case 'z':
{
zval **p = va_arg(*va, zval **);
- if (return_null) {
+ if (check_null && Z_TYPE_PP(arg) == IS_NULL) {
*p = NULL;
} else {
*p = *arg;
@@ -648,7 +664,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, con
case 'Z':
{
zval ***p = va_arg(*va, zval ***);
- if (return_null) {
+ if (check_null && Z_TYPE_PP(arg) == IS_NULL) {
*p = NULL;
} else {
*p = arg;
@@ -697,6 +713,19 @@ static int zend_parse_arg(int arg_num, zval **arg, va_list *va, const char **spe
}
/* }}} */
+ZEND_API int zend_parse_parameter(int flags, int arg_num TSRMLS_DC, zval **arg, const char *spec, ...)
+{
+ va_list va;
+ int ret;
+ int quiet = flags & ZEND_PARSE_PARAMS_QUIET;
+
+ va_start(va, spec);
+ ret = zend_parse_arg(arg_num, arg, &va, &spec, quiet TSRMLS_CC);
+ va_end(va);
+
+ return ret;
+}
+
static int zend_parse_va_args(int num_args, const char *type_spec, va_list *va, int flags TSRMLS_DC) /* {{{ */
{
const char *spec_walk;
@@ -1508,6 +1537,40 @@ ZEND_API int add_get_index_stringl(zval *arg, ulong index, const char *str, uint
}
/* }}} */
+ZEND_API int array_set_zval_key(HashTable *ht, zval *key, zval *value) /* {{{ */
+{
+ int result;
+
+ switch (Z_TYPE_P(key)) {
+ case IS_STRING:
+ result = zend_symtable_update(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &value, sizeof(zval *), NULL);
+ break;
+ case IS_NULL:
+ result = zend_symtable_update(ht, "", 1, &value, sizeof(zval *), NULL);
+ break;
+ case IS_RESOURCE:
+ zend_error(E_STRICT, "Resource ID#%ld used as offset, casting to integer (%ld)", Z_LVAL_P(key), Z_LVAL_P(key));
+ /* break missing intentionally */
+ case IS_BOOL:
+ case IS_LONG:
+ result = zend_hash_index_update(ht, Z_LVAL_P(key), &value, sizeof(zval *), NULL);
+ break;
+ case IS_DOUBLE:
+ result = zend_hash_index_update(ht, zend_dval_to_lval(Z_DVAL_P(key)), &value, sizeof(zval *), NULL);
+ break;
+ default:
+ zend_error(E_WARNING, "Illegal offset type");
+ result = FAILURE;
+ }
+
+ if (result == SUCCESS) {
+ Z_ADDREF_P(value);
+ }
+
+ return result;
+}
+/* }}} */
+
ZEND_API int add_property_long_ex(zval *arg, const char *key, uint key_len, long n TSRMLS_DC) /* {{{ */
{
zval *tmp;
diff --git a/Zend/zend_API.h b/Zend/zend_API.h
index 84acfcac88..59bcd59acb 100644
--- a/Zend/zend_API.h
+++ b/Zend/zend_API.h
@@ -258,6 +258,8 @@ ZEND_API char *zend_zval_type_name(const zval *arg);
ZEND_API int zend_parse_method_parameters(int num_args TSRMLS_DC, zval *this_ptr, const char *type_spec, ...);
ZEND_API int zend_parse_method_parameters_ex(int flags, int num_args TSRMLS_DC, zval *this_ptr, const char *type_spec, ...);
+ZEND_API int zend_parse_parameter(int flags, int arg_num TSRMLS_DC, zval **arg, const char *spec, ...);
+
/* End of parameter parsing API -- andrei */
ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_function_entry *functions, HashTable *function_table, int type TSRMLS_DC);
@@ -424,6 +426,8 @@ ZEND_API int add_get_index_double(zval *arg, ulong idx, double d, void **dest);
ZEND_API int add_get_index_string(zval *arg, ulong idx, const char *str, void **dest, int duplicate);
ZEND_API int add_get_index_stringl(zval *arg, ulong idx, const char *str, uint length, void **dest, int duplicate);
+ZEND_API int array_set_zval_key(HashTable *ht, zval *key, zval *value);
+
ZEND_API int add_property_long_ex(zval *arg, const char *key, uint key_len, long l TSRMLS_DC);
ZEND_API int add_property_null_ex(zval *arg, const char *key, uint key_len TSRMLS_DC);
ZEND_API int add_property_bool_ex(zval *arg, const char *key, uint key_len, int b TSRMLS_DC);
diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c
index ae88b5dae9..bdcee5cbe4 100644
--- a/Zend/zend_alloc.c
+++ b/Zend/zend_alloc.c
@@ -201,7 +201,7 @@ static int zend_mm_dev_zero_fd = -1;
static zend_mm_storage* zend_mm_mem_mmap_zero_init(void *params)
{
- if (zend_mm_dev_zero_fd != -1) {
+ if (zend_mm_dev_zero_fd == -1) {
zend_mm_dev_zero_fd = open("/dev/zero", O_RDWR, S_IRUSR | S_IWUSR);
}
if (zend_mm_dev_zero_fd >= 0) {
@@ -658,26 +658,28 @@ static unsigned int _mem_block_end_magic = 0;
#define ZEND_MM_LARGE_BUCKET_INDEX(S) zend_mm_high_bit(S)
-static void *_zend_mm_alloc_int(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
+static void *_zend_mm_alloc_int(zend_mm_heap *heap, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC ZEND_ATTRIBUTE_ALLOC_SIZE(2);
static void _zend_mm_free_int(zend_mm_heap *heap, void *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
-static void *_zend_mm_realloc_int(zend_mm_heap *heap, void *p, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
+static void *_zend_mm_realloc_int(zend_mm_heap *heap, void *p, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_ALLOC_SIZE(3);
static inline unsigned int zend_mm_high_bit(size_t _size)
{
#if defined(__GNUC__) && (defined(__native_client__) || defined(i386))
unsigned int n;
- __asm__("bsrl %1,%0\n\t" : "=r" (n) : "rm" (_size));
+ __asm__("bsrl %1,%0\n\t" : "=r" (n) : "rm" (_size) : "cc");
return n;
#elif defined(__GNUC__) && defined(__x86_64__)
unsigned long n;
- __asm__("bsr %1,%0\n\t" : "=r" (n) : "rm" (_size));
+ __asm__("bsr %1,%0\n\t" : "=r" (n) : "rm" (_size) : "cc");
return (unsigned int)n;
#elif defined(_MSC_VER) && defined(_M_IX86)
__asm {
bsr eax, _size
}
+#elif defined(__GNUC__) && (defined(__arm__) || defined(__aarch64__))
+ return (8 * SIZEOF_SIZE_T - 1) - __builtin_clzl(_size);
#else
unsigned int n = 0;
while (_size != 0) {
@@ -693,17 +695,19 @@ static inline unsigned int zend_mm_low_bit(size_t _size)
#if defined(__GNUC__) && (defined(__native_client__) || defined(i386))
unsigned int n;
- __asm__("bsfl %1,%0\n\t" : "=r" (n) : "rm" (_size));
+ __asm__("bsfl %1,%0\n\t" : "=r" (n) : "rm" (_size) : "cc");
return n;
#elif defined(__GNUC__) && defined(__x86_64__)
unsigned long n;
- __asm__("bsf %1,%0\n\t" : "=r" (n) : "rm" (_size));
+ __asm__("bsf %1,%0\n\t" : "=r" (n) : "rm" (_size) : "cc");
return (unsigned int)n;
#elif defined(_MSC_VER) && defined(_M_IX86)
__asm {
bsf eax, _size
- }
+ }
+#elif defined(__GNUC__) && (defined(__arm__) || defined(__aarch64__))
+ return __builtin_ctzl(_size);
#else
static const int offset[16] = {4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0};
unsigned int n;
@@ -2496,6 +2500,46 @@ static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
"rm"(offset));
#undef LP_SUFF
+ if (UNEXPECTED(overflow)) {
+ zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
+ return 0;
+ }
+ return res;
+}
+
+#elif defined(__GNUC__) && defined(__arm__)
+
+static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
+{
+ size_t res;
+ unsigned long overflow;
+
+ __asm__ ("umlal %0,%1,%2,%3"
+ : "=r"(res), "=r"(overflow)
+ : "r"(nmemb),
+ "r"(size),
+ "0"(offset),
+ "1"(0));
+
+ if (UNEXPECTED(overflow)) {
+ zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
+ return 0;
+ }
+ return res;
+}
+
+#elif defined(__GNUC__) && defined(__aarch64__)
+
+static inline size_t safe_address(size_t nmemb, size_t size, size_t offset)
+{
+ size_t res;
+ unsigned long overflow;
+
+ __asm__ ("mul %0,%2,%3\n\tumulh %1,%2,%3\n\tadds %0,%0,%4\n\tadc %1,%1,xzr"
+ : "=&r"(res), "=&r"(overflow)
+ : "r"(nmemb),
+ "r"(size),
+ "r"(offset));
if (UNEXPECTED(overflow)) {
zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", nmemb, size, offset);
diff --git a/Zend/zend_alloc.h b/Zend/zend_alloc.h
index 3e9747d2ae..05494ee37c 100644
--- a/Zend/zend_alloc.h
+++ b/Zend/zend_alloc.h
@@ -54,12 +54,12 @@ BEGIN_EXTERN_C()
ZEND_API char *zend_strndup(const char *s, unsigned int length) ZEND_ATTRIBUTE_MALLOC;
-ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
+ZEND_API void *_emalloc(size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC ZEND_ATTRIBUTE_ALLOC_SIZE(1);
ZEND_API void *_safe_emalloc(size_t nmemb, size_t size, size_t offset ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
ZEND_API void *_safe_malloc(size_t nmemb, size_t size, size_t offset) ZEND_ATTRIBUTE_MALLOC;
ZEND_API void _efree(void *ptr ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
-ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
-ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
+ZEND_API void *_ecalloc(size_t nmemb, size_t size ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC ZEND_ATTRIBUTE_ALLOC_SIZE2(1,2);
+ZEND_API void *_erealloc(void *ptr, size_t size, int allow_failure ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_ALLOC_SIZE(2);
ZEND_API void *_safe_erealloc(void *ptr, size_t nmemb, size_t size, size_t offset ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC);
ZEND_API void *_safe_realloc(void *ptr, size_t nmemb, size_t size, size_t offset);
ZEND_API char *_estrdup(const char *s ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) ZEND_ATTRIBUTE_MALLOC;
diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c
index f3dd12346d..3ce28fa0fe 100644
--- a/Zend/zend_builtin_functions.c
+++ b/Zend/zend_builtin_functions.c
@@ -987,7 +987,7 @@ ZEND_FUNCTION(get_object_vars)
HashPosition pos;
char *key;
const char *prop_name, *class_name;
- uint key_len;
+ uint key_len, prop_len;
ulong num_index;
zend_object *zobj;
@@ -1014,10 +1014,10 @@ ZEND_FUNCTION(get_object_vars)
while (zend_hash_get_current_data_ex(properties, (void **) &value, &pos) == SUCCESS) {
if (zend_hash_get_current_key_ex(properties, &key, &key_len, &num_index, 0, &pos) == HASH_KEY_IS_STRING) {
if (zend_check_property_access(zobj, key, key_len-1 TSRMLS_CC) == SUCCESS) {
- zend_unmangle_property_name(key, key_len-1, &class_name, &prop_name);
+ zend_unmangle_property_name_ex(key, key_len - 1, &class_name, &prop_name, (int*) &prop_len);
/* Not separating references */
Z_ADDREF_PP(value);
- add_assoc_zval_ex(return_value, prop_name, strlen(prop_name)+1, *value);
+ add_assoc_zval_ex(return_value, prop_name, prop_len + 1, *value);
}
}
zend_hash_move_forward_ex(properties, &pos);
@@ -1524,7 +1524,6 @@ ZEND_FUNCTION(trigger_error)
ZEND_FUNCTION(set_error_handler)
{
zval *error_handler;
- zend_bool had_orig_error_handler=0;
char *error_handler_name = NULL;
long error_type = E_ALL;
@@ -1532,38 +1531,31 @@ ZEND_FUNCTION(set_error_handler)
return;
}
- if (!zend_is_callable(error_handler, 0, &error_handler_name TSRMLS_CC)) {
- zend_error(E_WARNING, "%s() expects the argument (%s) to be a valid callback",
- get_active_function_name(TSRMLS_C), error_handler_name?error_handler_name:"unknown");
+ if (Z_TYPE_P(error_handler) != IS_NULL) { /* NULL == unset */
+ if (!zend_is_callable(error_handler, 0, &error_handler_name TSRMLS_CC)) {
+ zend_error(E_WARNING, "%s() expects the argument (%s) to be a valid callback",
+ get_active_function_name(TSRMLS_C), error_handler_name?error_handler_name:"unknown");
+ efree(error_handler_name);
+ return;
+ }
efree(error_handler_name);
- return;
}
- efree(error_handler_name);
if (EG(user_error_handler)) {
- had_orig_error_handler = 1;
- *return_value = *EG(user_error_handler);
- zval_copy_ctor(return_value);
- INIT_PZVAL(return_value);
+ RETVAL_ZVAL(EG(user_error_handler), 1, 0);
+
zend_stack_push(&EG(user_error_handlers_error_reporting), &EG(user_error_handler_error_reporting), sizeof(EG(user_error_handler_error_reporting)));
zend_ptr_stack_push(&EG(user_error_handlers), EG(user_error_handler));
}
- ALLOC_ZVAL(EG(user_error_handler));
- if (!zend_is_true(error_handler)) { /* unset user-defined handler */
- FREE_ZVAL(EG(user_error_handler));
+ if (Z_TYPE_P(error_handler) == IS_NULL) { /* unset user-defined handler */
EG(user_error_handler) = NULL;
- RETURN_TRUE;
+ return;
}
+ ALLOC_ZVAL(EG(user_error_handler));
+ MAKE_COPY_ZVAL(&error_handler, EG(user_error_handler));
EG(user_error_handler_error_reporting) = (int)error_type;
- *EG(user_error_handler) = *error_handler;
- zval_copy_ctor(EG(user_error_handler));
- INIT_PZVAL(EG(user_error_handler));
-
- if (!had_orig_error_handler) {
- RETURN_NULL();
- }
}
/* }}} */
@@ -1597,7 +1589,6 @@ ZEND_FUNCTION(set_exception_handler)
{
zval *exception_handler;
char *exception_handler_name = NULL;
- zend_bool had_orig_exception_handler=0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &exception_handler) == FAILURE) {
return;
@@ -1614,24 +1605,18 @@ ZEND_FUNCTION(set_exception_handler)
}
if (EG(user_exception_handler)) {
- had_orig_exception_handler = 1;
- *return_value = *EG(user_exception_handler);
- zval_copy_ctor(return_value);
+ RETVAL_ZVAL(EG(user_exception_handler), 1, 0);
+
zend_ptr_stack_push(&EG(user_exception_handlers), EG(user_exception_handler));
}
- ALLOC_ZVAL(EG(user_exception_handler));
if (Z_TYPE_P(exception_handler) == IS_NULL) { /* unset user-defined handler */
- FREE_ZVAL(EG(user_exception_handler));
EG(user_exception_handler) = NULL;
- RETURN_TRUE;
+ return;
}
+ ALLOC_ZVAL(EG(user_exception_handler));
MAKE_COPY_ZVAL(&exception_handler, EG(user_exception_handler))
-
- if (!had_orig_exception_handler) {
- RETURN_NULL();
- }
}
/* }}} */
diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c
index c18972a7f1..fcea56d811 100644
--- a/Zend/zend_closures.c
+++ b/Zend/zend_closures.c
@@ -5,7 +5,7 @@
| Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 2.00 of the Zend license, |
- | that is bundled with this package in the file LICENSE, and is |
+ | that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.zend.com/license/2_00.txt. |
| If you did not receive a copy of the Zend license and are unable to |
@@ -88,7 +88,7 @@ ZEND_METHOD(Closure, bind)
RETURN_NULL();
}
- closure = (zend_closure *)zend_object_store_get_object(zclosure TSRMLS_CC);
+ closure = (zend_closure *)zend_object_store_get_object(zclosure TSRMLS_CC);
if ((newthis != NULL) && (closure->func.common.fn_flags & ZEND_ACC_STATIC)) {
zend_error(E_WARNING, "Cannot bind an instance to a static closure");
@@ -152,7 +152,7 @@ static int zend_closure_compare_objects(zval *o1, zval *o2 TSRMLS_DC) /* {{{ */
ZEND_API zend_function *zend_get_closure_invoke_method(zval *obj TSRMLS_DC) /* {{{ */
{
- zend_closure *closure = (zend_closure *)zend_object_store_get_object(obj TSRMLS_CC);
+ zend_closure *closure = (zend_closure *)zend_object_store_get_object(obj TSRMLS_CC);
zend_function *invoke = (zend_function*)emalloc(sizeof(zend_function));
invoke->common = closure->func.common;
@@ -168,14 +168,14 @@ ZEND_API zend_function *zend_get_closure_invoke_method(zval *obj TSRMLS_DC) /* {
ZEND_API const zend_function *zend_get_closure_method_def(zval *obj TSRMLS_DC) /* {{{ */
{
- zend_closure *closure = (zend_closure *)zend_object_store_get_object(obj TSRMLS_CC);
+ zend_closure *closure = (zend_closure *)zend_object_store_get_object(obj TSRMLS_CC);
return &closure->func;
}
/* }}} */
ZEND_API zval* zend_get_closure_this_ptr(zval *obj TSRMLS_DC) /* {{{ */
{
- zend_closure *closure = (zend_closure *)zend_object_store_get_object(obj TSRMLS_CC);
+ zend_closure *closure = (zend_closure *)zend_object_store_get_object(obj TSRMLS_CC);
return closure->this_ptr;
}
/* }}} */
@@ -212,7 +212,7 @@ static void zend_closure_write_property(zval *object, zval *member, zval *value,
}
/* }}} */
-static zval **zend_closure_get_property_ptr_ptr(zval *object, zval *member, const zend_literal *key TSRMLS_DC) /* {{{ */
+static zval **zend_closure_get_property_ptr_ptr(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */
{
ZEND_CLOSURE_PROPERTY_ERROR();
return NULL;
@@ -291,7 +291,6 @@ static zend_object_value zend_closure_clone(zval *zobject TSRMLS_DC) /* {{{ */
}
/* }}} */
-
int zend_closure_get_closure(zval *obj, zend_class_entry **ce_ptr, zend_function **fptr_ptr, zval **zobj_ptr TSRMLS_DC) /* {{{ */
{
zend_closure *closure;
@@ -378,7 +377,7 @@ static HashTable *zend_closure_get_debug_info(zval *object, int *is_temp TSRMLS_
static HashTable *zend_closure_get_gc(zval *obj, zval ***table, int *n TSRMLS_DC) /* {{{ */
{
- zend_closure *closure = (zend_closure *)zend_object_store_get_object(obj TSRMLS_CC);
+ zend_closure *closure = (zend_closure *)zend_object_store_get_object(obj TSRMLS_CC);
*table = closure->this_ptr ? &closure->this_ptr : NULL;
*n = closure->this_ptr ? 1 : 0;
@@ -474,7 +473,7 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent
zend_error(E_WARNING, "Cannot bind function %s::%s to scope class %s", func->common.scope->name, func->common.function_name, scope->name);
scope = NULL;
}
- if(scope && this_ptr && (func->common.fn_flags & ZEND_ACC_STATIC) == 0 &&
+ if(scope && this_ptr && (func->common.fn_flags & ZEND_ACC_STATIC) == 0 &&
!instanceof_function(Z_OBJCE_P(this_ptr), closure->func.common.scope TSRMLS_CC)) {
zend_error(E_WARNING, "Cannot bind function %s::%s to object of class %s", func->common.scope->name, func->common.function_name, Z_OBJCE_P(this_ptr)->name);
scope = NULL;
diff --git a/Zend/zend_closures.h b/Zend/zend_closures.h
index eb0c89b8c5..fa66e9747d 100644
--- a/Zend/zend_closures.h
+++ b/Zend/zend_closures.h
@@ -24,8 +24,6 @@
BEGIN_EXTERN_C()
-#define ZEND_INVOKE_FUNC_NAME "__invoke"
-
void zend_register_closure_ce(TSRMLS_D);
extern ZEND_API zend_class_entry *zend_ce_closure;
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index f26766964a..b0a611cab1 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -5,7 +5,7 @@
| Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 2.00 of the Zend license, |
- | that is bundled with this package in the file LICENSE, and is |
+ | that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.zend.com/license/2_00.txt. |
| If you did not receive a copy of the Zend license and are unable to |
@@ -107,7 +107,7 @@ ZEND_API zend_executor_globals executor_globals;
static void zend_duplicate_property_info(zend_property_info *property_info) /* {{{ */
{
- if (!IS_INTERNED(property_info->name)) {
+ if (!IS_INTERNED(property_info->name)) {
property_info->name = estrndup(property_info->name, property_info->name_length);
}
if (property_info->doc_comment) {
@@ -118,7 +118,7 @@ static void zend_duplicate_property_info(zend_property_info *property_info) /* {
static void zend_duplicate_property_info_internal(zend_property_info *property_info) /* {{{ */
{
- if (!IS_INTERNED(property_info->name)) {
+ if (!IS_INTERNED(property_info->name)) {
property_info->name = zend_strndup(property_info->name, property_info->name_length);
}
}
@@ -179,6 +179,9 @@ void zend_init_compiler_context(TSRMLS_D) /* {{{ */
CG(context).literals_size = 0;
CG(context).current_brk_cont = -1;
CG(context).backpatch_count = 0;
+ CG(context).nested_calls = 0;
+ CG(context).used_stack = 0;
+ CG(context).in_finally = 0;
CG(context).labels = NULL;
}
/* }}} */
@@ -285,7 +288,7 @@ ZEND_API zend_bool zend_is_compiling(TSRMLS_D) /* {{{ */
static zend_uint get_temporary_variable(zend_op_array *op_array) /* {{{ */
{
- return (op_array->T)++ * ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable));
+ return (zend_uint)(zend_uintptr_t)EX_TMP_VAR_NUM(0, (op_array->T)++);
}
/* }}} */
@@ -380,7 +383,7 @@ int zend_add_func_name_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC
zval c;
int lc_literal;
- if (op_array->last_literal > 0 &&
+ if (op_array->last_literal > 0 &&
&op_array->literals[op_array->last_literal - 1].constant == zv &&
op_array->literals[op_array->last_literal - 1].cache_slot == -1) {
/* we already have function name as last literal (do nothing) */
@@ -388,7 +391,7 @@ int zend_add_func_name_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC
} else {
ret = zend_add_literal(op_array, zv TSRMLS_CC);
}
-
+
lc_name = zend_str_tolower_dup(Z_STRVAL_P(zv), Z_STRLEN_P(zv));
ZVAL_STRINGL(&c, lc_name, Z_STRLEN_P(zv), 0);
lc_literal = zend_add_literal(CG(active_op_array), &c TSRMLS_CC);
@@ -407,7 +410,7 @@ int zend_add_ns_func_name_literal(zend_op_array *op_array, const zval *zv TSRMLS
zval c;
int lc_literal;
- if (op_array->last_literal > 0 &&
+ if (op_array->last_literal > 0 &&
&op_array->literals[op_array->last_literal - 1].constant == zv &&
op_array->literals[op_array->last_literal - 1].cache_slot == -1) {
/* we already have function name as last literal (do nothing) */
@@ -440,7 +443,7 @@ int zend_add_class_name_literal(zend_op_array *op_array, const zval *zv TSRMLS_D
zval c;
int lc_literal;
- if (op_array->last_literal > 0 &&
+ if (op_array->last_literal > 0 &&
&op_array->literals[op_array->last_literal - 1].constant == zv &&
op_array->literals[op_array->last_literal - 1].cache_slot == -1) {
/* we already have function name as last literal (do nothing) */
@@ -474,7 +477,7 @@ int zend_add_const_name_literal(zend_op_array *op_array, const zval *zv, int unq
int name_len, ns_len;
zval c;
- if (op_array->last_literal > 0 &&
+ if (op_array->last_literal > 0 &&
&op_array->literals[op_array->last_literal - 1].constant == zv &&
op_array->literals[op_array->last_literal - 1].cache_slot == -1) {
/* we already have function name as last literal (do nothing) */
@@ -483,7 +486,7 @@ int zend_add_const_name_literal(zend_op_array *op_array, const zval *zv, int unq
ret = zend_add_literal(op_array, zv TSRMLS_CC);
}
- /* skip leading '\\' */
+ /* skip leading '\\' */
if (Z_STRVAL_P(zv)[0] == '\\') {
name_len = Z_STRLEN_P(zv) - 1;
name = Z_STRVAL_P(zv) + 1;
@@ -813,7 +816,7 @@ void fetch_array_dim(znode *result, const znode *parent, const znode *dim TSRMLS
opline.result.var = opline.op1.var;
zend_llist_add_element(fetch_list_ptr, &opline);
}
-
+
init_op(&opline TSRMLS_CC);
opline.opcode = ZEND_FETCH_DIM_W; /* the backpatching routine assumes W */
opline.result_type = IS_VAR;
@@ -827,12 +830,12 @@ void fetch_array_dim(znode *result, const znode *parent, const znode *dim TSRMLS
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL(CONSTANT(opline.op2.constant)), Z_STRLEN(CONSTANT(opline.op2.constant))+1, index, numeric = 1);
if (numeric) {
zval_dtor(&CONSTANT(opline.op2.constant));
- ZVAL_LONG(&CONSTANT(opline.op2.constant), index);
+ ZVAL_LONG(&CONSTANT(opline.op2.constant), index);
} else {
CALCULATE_LITERAL_HASH(opline.op2.constant);
}
}
-
+
GET_NODE(result, opline.result);
zend_llist_add_element(fetch_list_ptr, &opline);
@@ -938,7 +941,7 @@ void zend_do_assign(znode *result, znode *variable, znode *value TSRMLS_DC) /* {
opline->result.var = get_temporary_variable(CG(active_op_array));
opline->op1_type = IS_CONST;
LITERAL_STRINGL(opline->op1,
- CG(active_op_array)->vars[value->u.op.var].name,
+ CG(active_op_array)->vars[value->u.op.var].name,
CG(active_op_array)->vars[value->u.op.var].name_len, 1);
CALCULATE_LITERAL_HASH(opline->op1.constant);
SET_UNUSED(opline->op2);
@@ -1567,7 +1570,7 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
if (is_method) {
int result;
-
+
lcname = zend_new_interned_string(zend_str_tolower_dup(name, name_len), name_len + 1, 1 TSRMLS_CC);
if (IS_INTERNED(lcname)) {
@@ -1619,10 +1622,14 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
zend_error(E_WARNING, "The magic method __toString() must have public visibility and cannot be static");
}
+ } else if ((name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1))) {
+ if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
+ zend_error(E_WARNING, "The magic method __invoke() must have public visibility and cannot be static");
+ }
}
} else {
char *class_lcname;
-
+
class_lcname = do_alloca(CG(active_class_entry)->name_length + 1, use_heap);
zend_str_tolower_copy(class_lcname, CG(active_class_entry)->name, CG(active_class_entry)->name_length);
/* Improve after RC: cache the lowercase class name */
@@ -1673,8 +1680,12 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
} else if ((name_len == sizeof(ZEND_TOSTRING_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_TOSTRING_FUNC_NAME, sizeof(ZEND_TOSTRING_FUNC_NAME)-1))) {
if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
zend_error(E_WARNING, "The magic method __toString() must have public visibility and cannot be static");
- }
+ }
CG(active_class_entry)->__tostring = (zend_function *) CG(active_op_array);
+ } else if ((name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1) && (!memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1))) {
+ if (fn_flags & ((ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC) ^ ZEND_ACC_PUBLIC)) {
+ zend_error(E_WARNING, "The magic method __invoke() must have public visibility and cannot be static");
+ }
} else if (!(fn_flags & ZEND_ACC_STATIC)) {
CG(active_op_array)->fn_flags |= ZEND_ACC_ALLOW_STATIC;
}
@@ -1724,7 +1735,7 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
}
{
- /* Push a separator to the switch and foreach stacks */
+ /* Push a separator to the switch stack */
zend_switch_entry switch_entry;
switch_entry.cond.op_type = IS_UNUSED;
@@ -1732,16 +1743,15 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
switch_entry.control_var = 0;
zend_stack_push(&CG(switch_cond_stack), (void *) &switch_entry, sizeof(switch_entry));
+ }
- {
- /* Foreach stack separator */
- zend_op dummy_opline;
+ {
+ /* Push a separator to the foreach stack */
+ zend_op dummy_opline;
- dummy_opline.result_type = IS_UNUSED;
- dummy_opline.op1_type = IS_UNUSED;
+ dummy_opline.result_type = IS_UNUSED;
- zend_stack_push(&CG(foreach_copy_stack), (void *) &dummy_opline, sizeof(zend_op));
- }
+ zend_stack_push(&CG(foreach_copy_stack), (void *) &dummy_opline, sizeof(zend_op));
}
if (CG(doc_comment)) {
@@ -1804,14 +1814,14 @@ void zend_do_end_function_declaration(const znode *function_token TSRMLS_DC) /*
if (CG(active_class_entry)) {
zend_check_magic_method_implementation(CG(active_class_entry), (zend_function*)CG(active_op_array), E_COMPILE_ERROR TSRMLS_CC);
} else {
- /* we don't care if the function name is longer, in fact lowercasing only
+ /* we don't care if the function name is longer, in fact lowercasing only
* the beginning of the name speeds up the check process */
name_len = strlen(CG(active_op_array)->function_name);
zend_str_tolower_copy(lcname, CG(active_op_array)->function_name, MIN(name_len, sizeof(lcname)-1));
lcname[sizeof(lcname)-1] = '\0'; /* zend_str_tolower_copy won't necessarily set the zero byte */
if (name_len == sizeof(ZEND_AUTOLOAD_FUNC_NAME) - 1 && !memcmp(lcname, ZEND_AUTOLOAD_FUNC_NAME, sizeof(ZEND_AUTOLOAD_FUNC_NAME)) && CG(active_op_array)->num_args != 1) {
zend_error(E_COMPILE_ERROR, "%s() must take exactly 1 argument", ZEND_AUTOLOAD_FUNC_NAME);
- }
+ }
}
CG(active_op_array)->line_end = zend_get_compiled_lineno(TSRMLS_C);
@@ -1937,7 +1947,7 @@ int zend_do_begin_function_call(znode *function_name, zend_bool check_namespace
internal function with short name */
zend_do_begin_dynamic_function_call(function_name, 1 TSRMLS_CC);
return 1;
- }
+ }
lcname = zend_str_tolower_dup(function_name->u.constant.value.str.val, function_name->u.constant.value.str.len);
if ((zend_hash_find(CG(function_table), lcname, function_name->u.constant.value.str.len+1, (void **) &function)==FAILURE) ||
@@ -1946,11 +1956,14 @@ int zend_do_begin_function_call(znode *function_name, zend_bool check_namespace
zend_do_begin_dynamic_function_call(function_name, 0 TSRMLS_CC);
efree(lcname);
return 1; /* Dynamic */
- }
+ }
efree(function_name->u.constant.value.str.val);
function_name->u.constant.value.str.val = lcname;
-
+
zend_stack_push(&CG(function_call_stack), (void *) &function, sizeof(zend_function *));
+ if (CG(context).nested_calls + 1 > CG(active_op_array)->nested_calls) {
+ CG(active_op_array)->nested_calls = CG(context).nested_calls + 1;
+ }
zend_do_extended_fcall_begin(TSRMLS_C);
return 0;
}
@@ -1979,7 +1992,7 @@ void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC) /* {{{ */
name = CONSTANT(last_op->op2.constant);
if (Z_TYPE(name) != IS_STRING) {
zend_error(E_COMPILE_ERROR, "Method name must be a string");
- }
+ }
if (!IS_INTERNED(Z_STRVAL(name))) {
Z_STRVAL(name) = estrndup(Z_STRVAL(name), Z_STRLEN(name));
}
@@ -1989,11 +2002,13 @@ void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC) /* {{{ */
GET_POLYMORPHIC_CACHE_SLOT(last_op->op2.constant);
}
last_op->opcode = ZEND_INIT_METHOD_CALL;
- SET_UNUSED(last_op->result);
+ last_op->result_type = IS_UNUSED;
+ last_op->result.num = CG(context).nested_calls;
Z_LVAL(left_bracket->u.constant) = ZEND_INIT_FCALL_BY_NAME;
} else {
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
opline->opcode = ZEND_INIT_FCALL_BY_NAME;
+ opline->result.num = CG(context).nested_calls;
SET_UNUSED(opline->op1);
if (left_bracket->op_type == IS_CONST) {
opline->op2_type = IS_CONST;
@@ -2005,6 +2020,9 @@ void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC) /* {{{ */
}
zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *));
+ if (++CG(context).nested_calls > CG(active_op_array)->nested_calls) {
+ CG(active_op_array)->nested_calls = CG(context).nested_calls;
+ }
zend_do_extended_fcall_begin(TSRMLS_C);
}
/* }}} */
@@ -2032,12 +2050,14 @@ void zend_do_begin_dynamic_function_call(znode *function_name, int ns_call TSRML
/* In run-time PHP will check for function with full name and
internal function with short name */
opline->opcode = ZEND_INIT_NS_FCALL_BY_NAME;
+ opline->result.num = CG(context).nested_calls;
SET_UNUSED(opline->op1);
opline->op2_type = IS_CONST;
opline->op2.constant = zend_add_ns_func_name_literal(CG(active_op_array), &function_name->u.constant TSRMLS_CC);
GET_CACHE_SLOT(opline->op2.constant);
} else {
opline->opcode = ZEND_INIT_FCALL_BY_NAME;
+ opline->result.num = CG(context).nested_calls;
SET_UNUSED(opline->op1);
if (function_name->op_type == IS_CONST) {
opline->op2_type = IS_CONST;
@@ -2049,6 +2069,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 *));
+ if (++CG(context).nested_calls > CG(active_op_array)->nested_calls) {
+ CG(active_op_array)->nested_calls = CG(context).nested_calls;
+ }
zend_do_extended_fcall_begin(TSRMLS_C);
}
/* }}} */
@@ -2104,6 +2127,53 @@ void zend_resolve_non_class_name(znode *element_name, zend_bool check_namespace
}
/* }}} */
+void zend_do_resolve_class_name(znode *result, znode *class_name, int is_static TSRMLS_DC) /* {{{ */
+{
+ char *lcname;
+ int lctype;
+ znode constant_name;
+
+ lcname = zend_str_tolower_dup(Z_STRVAL(class_name->u.constant), class_name->u.constant.value.str.len);
+ lctype = zend_get_class_fetch_type(lcname, strlen(lcname));
+ switch (lctype) {
+ case ZEND_FETCH_CLASS_SELF:
+ if (!CG(active_class_entry)) {
+ zend_error(E_COMPILE_ERROR, "Cannot access self::class when no class scope is active");
+ }
+ zval_dtor(&class_name->u.constant);
+ class_name->op_type = IS_CONST;
+ ZVAL_STRINGL(&class_name->u.constant, CG(active_class_entry)->name, CG(active_class_entry)->name_length, 1);
+ *result = *class_name;
+ break;
+ case ZEND_FETCH_CLASS_STATIC:
+ case ZEND_FETCH_CLASS_PARENT:
+ if (is_static) {
+ zend_error(E_COMPILE_ERROR,
+ "%s::class cannot be used for compile-time class name resolution",
+ lctype == ZEND_FETCH_CLASS_STATIC ? "static" : "parent"
+ );
+ }
+ if (!CG(active_class_entry)) {
+ zend_error(E_COMPILE_ERROR,
+ "Cannot access %s::class when no class scope is active",
+ lctype == ZEND_FETCH_CLASS_STATIC ? "static" : "parent"
+ );
+ }
+ constant_name.op_type = IS_CONST;
+ ZVAL_STRINGL(&constant_name.u.constant, "class", sizeof("class")-1, 1);
+ zend_do_fetch_constant(result, class_name, &constant_name, ZEND_RT, 1 TSRMLS_CC);
+ break;
+ case ZEND_FETCH_CLASS_DEFAULT:
+ zend_resolve_class_name(class_name, ZEND_FETCH_CLASS_GLOBAL, 1 TSRMLS_CC);
+ *result = *class_name;
+ break;
+ }
+
+ efree(lcname);
+
+}
+/* }}} */
+
void zend_resolve_class_name(znode *class_name, ulong fetch_type, int check_ns_name TSRMLS_DC) /* {{{ */
{
char *compound;
@@ -2126,7 +2196,7 @@ void zend_resolve_class_name(znode *class_name, ulong fetch_type, int check_ns_n
if (ZEND_FETCH_CLASS_DEFAULT != zend_get_class_fetch_type(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant))) {
zend_error(E_COMPILE_ERROR, "'\\%s' is an invalid class name", Z_STRVAL(class_name->u.constant));
}
- } else {
+ } else {
if (CG(current_import)) {
len = compound - Z_STRVAL(class_name->u.constant);
lcname = zend_str_tolower_dup(Z_STRVAL(class_name->u.constant), len);
@@ -2397,6 +2467,7 @@ int zend_do_begin_class_member_function_call(znode *class_name, znode *method_na
opline->extended_value = class_node.EA ;
}
opline->opcode = ZEND_INIT_STATIC_METHOD_CALL;
+ opline->result.num = CG(context).nested_calls;
if (class_node.op_type == IS_CONST) {
opline->op1_type = IS_CONST;
opline->op1.constant =
@@ -2418,6 +2489,9 @@ int zend_do_begin_class_member_function_call(znode *class_name, znode *method_na
}
zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *));
+ if (++CG(context).nested_calls > CG(active_op_array)->nested_calls) {
+ CG(active_op_array)->nested_calls = CG(context).nested_calls;
+ }
zend_do_extended_fcall_begin(TSRMLS_C);
return 1; /* Dynamic */
}
@@ -2438,21 +2512,29 @@ void zend_do_end_function_call(znode *function_name, znode *result, const znode
if (!is_method && !is_dynamic_fcall && function_name->op_type==IS_CONST) {
opline->opcode = ZEND_DO_FCALL;
SET_NODE(opline->op1, function_name);
+ SET_UNUSED(opline->op2);
+ opline->op2.num = CG(context).nested_calls;
CALCULATE_LITERAL_HASH(opline->op1.constant);
GET_CACHE_SLOT(opline->op1.constant);
} else {
opline->opcode = ZEND_DO_FCALL_BY_NAME;
SET_UNUSED(opline->op1);
+ SET_UNUSED(opline->op2);
+ opline->op2.num = --CG(context).nested_calls;
}
}
opline->result.var = get_temporary_variable(CG(active_op_array));
opline->result_type = IS_VAR;
- GET_NODE(result, opline->result) ;
- SET_UNUSED(opline->op2);
+ GET_NODE(result, opline->result);
zend_stack_del_top(&CG(function_call_stack));
opline->extended_value = Z_LVAL(argument_list->u.constant);
+
+ if (CG(context).used_stack + 1 > CG(active_op_array)->used_stack) {
+ CG(active_op_array)->used_stack = CG(context).used_stack + 1;
+ }
+ CG(context).used_stack -= Z_LVAL(argument_list->u.constant);
}
/* }}} */
@@ -2480,8 +2562,8 @@ void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC) /* {{
zend_error(E_COMPILE_ERROR, "Call-time pass-by-reference has been removed");
}
return;
- }
-
+ }
+
if (function_ptr) {
if (ARG_MAY_BE_SENT_BY_REF(function_ptr, (zend_uint) offset)) {
if (param->op_type & (IS_VAR|IS_CV) && original_op != ZEND_SEND_VAL) {
@@ -2560,6 +2642,10 @@ void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC) /* {{
SET_NODE(opline->op1, param);
opline->op2.opline_num = offset;
SET_UNUSED(opline->op2);
+
+ if (++CG(context).used_stack > CG(active_op_array)->used_stack) {
+ CG(active_op_array)->used_stack = CG(context).used_stack;
+ }
}
/* }}} */
@@ -2576,7 +2662,7 @@ static int generate_free_switch_expr(const zend_switch_entry *switch_entry TSRML
opline->opcode = (switch_entry->cond.op_type == IS_TMP_VAR) ? ZEND_FREE : ZEND_SWITCH_FREE;
SET_NODE(opline->op1, &switch_entry->cond);
SET_UNUSED(opline->op2);
- opline->extended_value = 0;
+
return 0;
}
/* }}} */
@@ -2586,7 +2672,7 @@ static int generate_free_foreach_copy(const zend_op *foreach_copy TSRMLS_DC) /*
zend_op *opline;
/* If we reach the separator then stop applying the stack */
- if (foreach_copy->result_type == IS_UNUSED && foreach_copy->op1_type == IS_UNUSED) {
+ if (foreach_copy->result_type == IS_UNUSED) {
return 1;
}
@@ -2595,16 +2681,6 @@ static int generate_free_foreach_copy(const zend_op *foreach_copy TSRMLS_DC) /*
opline->opcode = (foreach_copy->result_type == IS_TMP_VAR) ? ZEND_FREE : ZEND_SWITCH_FREE;
COPY_NODE(opline->op1, foreach_copy->result);
SET_UNUSED(opline->op2);
- opline->extended_value = 1;
-
- if (foreach_copy->op1_type != IS_UNUSED) {
- opline = get_next_op(CG(active_op_array) TSRMLS_CC);
-
- opline->opcode = (foreach_copy->op1_type == IS_TMP_VAR) ? ZEND_FREE : ZEND_SWITCH_FREE;
- COPY_NODE(opline->op1, foreach_copy->op1);
- SET_UNUSED(opline->op2);
- opline->extended_value = 0;
- }
return 0;
}
@@ -2614,9 +2690,12 @@ void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC) /* {{{ */
{
zend_op *opline;
int start_op_number, end_op_number;
+ zend_bool returns_reference = (CG(active_op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0;
+
+ /* The error for use of return inside a generator is thrown in pass_two. */
if (do_end_vparse) {
- if ((CG(active_op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) && !zend_is_function_or_method_call(expr)) {
+ if (returns_reference && !zend_is_function_or_method_call(expr)) {
zend_do_end_variable_parse(expr, BP_VAR_W, 0 TSRMLS_CC);
} else {
zend_do_end_variable_parse(expr, BP_VAR_R, 0 TSRMLS_CC);
@@ -2639,9 +2718,16 @@ void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC) /* {{{ */
start_op_number++;
}
+ if (CG(context).in_finally) {
+ opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+ opline->opcode = ZEND_DISCARD_EXCEPTION;
+ SET_UNUSED(opline->op1);
+ SET_UNUSED(opline->op2);
+ }
+
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
- opline->opcode = (CG(active_op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) ? ZEND_RETURN_BY_REF : ZEND_RETURN;
+ opline->opcode = returns_reference ? ZEND_RETURN_BY_REF : ZEND_RETURN;
if (expr) {
SET_NODE(opline->op1, expr);
@@ -2658,12 +2744,59 @@ void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC) /* {{{ */
}
/* }}} */
+void zend_do_yield(znode *result, znode *value, const znode *key, zend_bool is_variable TSRMLS_DC) /* {{{ */
+{
+ zend_op *opline;
+
+ if (!CG(active_op_array)->function_name) {
+ zend_error(E_COMPILE_ERROR, "The \"yield\" expression can only be used inside a function");
+ }
+
+ CG(active_op_array)->fn_flags |= ZEND_ACC_GENERATOR;
+
+ if (is_variable) {
+ if ((CG(active_op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) && !zend_is_function_or_method_call(value)) {
+ zend_do_end_variable_parse(value, BP_VAR_W, 0 TSRMLS_CC);
+ } else {
+ zend_do_end_variable_parse(value, BP_VAR_R, 0 TSRMLS_CC);
+ }
+ }
+
+ opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+
+ opline->opcode = ZEND_YIELD;
+
+ if (value) {
+ SET_NODE(opline->op1, value);
+
+ if (is_variable && zend_is_function_or_method_call(value)) {
+ opline->extended_value = ZEND_RETURNS_FUNCTION;
+ }
+ } else {
+ SET_UNUSED(opline->op1);
+ }
+
+ if (key) {
+ SET_NODE(opline->op2, key);
+ } else {
+ SET_UNUSED(opline->op2);
+ }
+
+ opline->result_type = IS_VAR;
+ opline->result.var = get_temporary_variable(CG(active_op_array));
+ GET_NODE(result, opline->result);
+}
+/* }}} */
+
static int zend_add_try_element(zend_uint try_op TSRMLS_DC) /* {{{ */
{
int try_catch_offset = CG(active_op_array)->last_try_catch++;
CG(active_op_array)->try_catch_array = erealloc(CG(active_op_array)->try_catch_array, sizeof(zend_try_catch_element)*CG(active_op_array)->last_try_catch);
CG(active_op_array)->try_catch_array[try_catch_offset].try_op = try_op;
+ CG(active_op_array)->try_catch_array[try_catch_offset].catch_op = 0;
+ CG(active_op_array)->try_catch_array[try_catch_offset].finally_op = 0;
+ CG(active_op_array)->try_catch_array[try_catch_offset].finally_end = 0;
return try_catch_offset;
}
/* }}} */
@@ -2680,7 +2813,7 @@ void zend_do_first_catch(znode *open_parentheses TSRMLS_DC) /* {{{ */
}
/* }}} */
-void zend_initialize_try_catch_element(const znode *try_token TSRMLS_DC) /* {{{ */
+void zend_initialize_try_catch_element(znode *catch_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);
@@ -2697,7 +2830,7 @@ void zend_initialize_try_catch_element(const znode *try_token TSRMLS_DC) /* {{{
zend_stack_top(&CG(bp_stack), (void **) &jmp_list_ptr);
zend_llist_add_element(jmp_list_ptr, &jmp_op_number);
- zend_add_catch_element(try_token->u.op.opline_num, get_next_op_number(CG(active_op_array)) TSRMLS_CC);
+ catch_token->EA = get_next_op_number(CG(active_op_array));
}
/* }}} */
@@ -2723,7 +2856,29 @@ void zend_do_try(znode *try_token TSRMLS_DC) /* {{{ */
}
/* }}} */
-void zend_do_begin_catch(znode *try_token, znode *class_name, znode *catch_var, znode *first_catch TSRMLS_DC) /* {{{ */
+void zend_do_finally(znode *finally_token TSRMLS_DC) /* {{{ */
+{
+ zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+
+ finally_token->u.op.opline_num = get_next_op_number(CG(active_op_array));
+ /* call the the "finally" block */
+ opline->opcode = ZEND_FAST_CALL;
+ SET_UNUSED(opline->op1);
+ opline->op1.opline_num = finally_token->u.op.opline_num + 1;
+ SET_UNUSED(opline->op2);
+ /* jump to code after the "finally" block,
+ * the actual jump address is going to be set in zend_do_end_finally()
+ */
+ opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+ opline->opcode = ZEND_JMP;
+ SET_UNUSED(opline->op1);
+ SET_UNUSED(opline->op2);
+
+ CG(context).in_finally++;
+}
+/* }}} */
+
+void zend_do_begin_catch(znode *catch_token, znode *class_name, znode *catch_var, znode *first_catch TSRMLS_DC) /* {{{ */
{
long catch_op_number;
zend_op *opline;
@@ -2751,11 +2906,11 @@ void zend_do_begin_catch(znode *try_token, znode *class_name, znode *catch_var,
Z_STRVAL(catch_var->u.constant) = (char*)CG(active_op_array)->vars[opline->op2.var].name;
opline->result.num = 0; /* 1 means it's the last catch in the block */
- try_token->u.op.opline_num = catch_op_number;
+ catch_token->u.op.opline_num = catch_op_number;
}
/* }}} */
-void zend_do_end_catch(const znode *try_token TSRMLS_DC) /* {{{ */
+void zend_do_end_catch(znode *catch_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);
@@ -2769,7 +2924,38 @@ void zend_do_end_catch(const znode *try_token TSRMLS_DC) /* {{{ */
zend_stack_top(&CG(bp_stack), (void **) &jmp_list_ptr);
zend_llist_add_element(jmp_list_ptr, &jmp_op_number);
- CG(active_op_array)->opcodes[try_token->u.op.opline_num].extended_value = get_next_op_number(CG(active_op_array));
+ CG(active_op_array)->opcodes[catch_token->u.op.opline_num].extended_value = get_next_op_number(CG(active_op_array));
+}
+/* }}} */
+
+void zend_do_bind_catch(znode *try_token, znode *catch_token TSRMLS_DC) /* {{{ */ {
+ if (catch_token->op_type != IS_UNUSED) {
+ zend_add_catch_element(try_token->u.op.opline_num, catch_token->EA TSRMLS_CC);
+ }
+}
+/* }}} */
+
+void zend_do_end_finally(znode *try_token, znode* catch_token, znode *finally_token TSRMLS_DC) /* {{{ */
+{
+ if (catch_token->op_type == IS_UNUSED && finally_token->op_type == IS_UNUSED) {
+ zend_error(E_COMPILE_ERROR, "Cannot use try without catch or finally");
+ }
+ if (finally_token->op_type != IS_UNUSED) {
+ zend_op *opline;
+
+ CG(active_op_array)->try_catch_array[try_token->u.op.opline_num].finally_op = finally_token->u.op.opline_num + 1;
+ CG(active_op_array)->try_catch_array[try_token->u.op.opline_num].finally_end = get_next_op_number(CG(active_op_array));
+ CG(active_op_array)->has_finally_block = 1;
+
+ opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+ opline->opcode = ZEND_FAST_RET;
+ SET_UNUSED(opline->op1);
+ SET_UNUSED(opline->op2);
+
+ CG(active_op_array)->opcodes[finally_token->u.op.opline_num].op1.opline_num = get_next_op_number(CG(active_op_array));
+
+ CG(context).in_finally--;
+ }
}
/* }}} */
@@ -2876,7 +3062,7 @@ static void do_inherit_parent_constructor(zend_class_entry *ce) /* {{{ */
lc_class_name = zend_str_tolower_dup(ce->name, ce->name_length);
if (!zend_hash_exists(&ce->function_table, lc_class_name, ce->name_length+1)) {
lc_parent_class_name = zend_str_tolower_dup(ce->parent->name, ce->parent->name_length);
- if (!zend_hash_exists(&ce->function_table, lc_parent_class_name, ce->parent->name_length+1) &&
+ if (!zend_hash_exists(&ce->function_table, lc_parent_class_name, ce->parent->name_length+1) &&
zend_hash_find(&ce->parent->function_table, lc_parent_class_name, ce->parent->name_length+1, (void **)&function)==SUCCESS) {
if (function->common.fn_flags & ZEND_ACC_CTOR) {
/* inherit parent's constructor */
@@ -3015,8 +3201,8 @@ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, c
return 0;
}
}
- }
- }
+ }
+ }
if (fe->common.arg_info[i].type_hint != proto->common.arg_info[i].type_hint) {
/* Incompatible type hint */
return 0;
@@ -3045,7 +3231,7 @@ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, c
buf = erealloc(buf, length); \
}
-static char * zend_get_function_declaration(zend_function *fptr TSRMLS_DC) /* {{{ */
+static char * zend_get_function_declaration(zend_function *fptr TSRMLS_DC) /* {{{ */
{
char *offset, *buf;
zend_uint length = 1024;
@@ -3062,7 +3248,7 @@ static char * zend_get_function_declaration(zend_function *fptr TSRMLS_DC) /* {{
*(offset++) = ':';
*(offset++) = ':';
}
-
+
{
size_t name_len = strlen(fptr->common.function_name);
REALLOC_BUF_IF_EXCEED(buf, offset, length, name_len);
@@ -3103,7 +3289,7 @@ static char * zend_get_function_declaration(zend_function *fptr TSRMLS_DC) /* {{
offset += type_name_len;
*(offset++) = ' ';
}
-
+
if (arg_info->pass_by_reference) {
*(offset++) = '&';
}
@@ -3205,7 +3391,7 @@ static char * zend_get_function_declaration(zend_function *fptr TSRMLS_DC) /* {{
*offset = '\0';
return buf;
-}
+}
/* }}} */
static void do_inheritance_check_on_method(zend_function *child, zend_function *parent TSRMLS_DC) /* {{{ */
@@ -3217,7 +3403,7 @@ static void do_inheritance_check_on_method(zend_function *child, zend_function *
&& parent->common.fn_flags & ZEND_ACC_ABSTRACT
&& parent->common.scope != (child->common.prototype ? child->common.prototype->common.scope : child->common.scope)
&& child->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_IMPLEMENTED_ABSTRACT)) {
- zend_error(E_COMPILE_ERROR, "Can't inherit abstract function %s::%s() (previously declared abstract in %s)",
+ zend_error(E_COMPILE_ERROR, "Can't inherit abstract function %s::%s() (previously declared abstract in %s)",
parent->common.scope->name,
child->common.function_name,
child->common.prototype ? child->common.prototype->common.scope->name : child->common.scope->name);
@@ -3257,7 +3443,7 @@ static void do_inheritance_check_on_method(zend_function *child, zend_function *
}
if (parent_flags & ZEND_ACC_PRIVATE) {
- child->common.prototype = NULL;
+ child->common.prototype = NULL;
} else if (parent_flags & ZEND_ACC_ABSTRACT) {
child->common.fn_flags |= ZEND_ACC_IMPLEMENTED_ABSTRACT;
child->common.prototype = parent;
@@ -3268,12 +3454,12 @@ static void do_inheritance_check_on_method(zend_function *child, zend_function *
if (child->common.prototype && (child->common.prototype->common.fn_flags & ZEND_ACC_ABSTRACT)) {
if (!zend_do_perform_implementation_check(child, child->common.prototype TSRMLS_CC)) {
- zend_error(E_COMPILE_ERROR, "Declaration of %s::%s() must be compatible with %s", ZEND_FN_SCOPE_NAME(child), child->common.function_name, zend_get_function_declaration(child->common.prototype TSRMLS_CC));
+ zend_error(E_COMPILE_ERROR, "Declaration of %s::%s() must be compatible with %s", ZEND_FN_SCOPE_NAME(child), child->common.function_name, zend_get_function_declaration(child->common.prototype TSRMLS_CC));
}
} else if (EG(error_reporting) & E_STRICT || EG(user_error_handler)) { /* Check E_STRICT (or custom error handler) before the check so that we save some time */
if (!zend_do_perform_implementation_check(child, parent TSRMLS_CC)) {
char *method_prototype = zend_get_function_declaration(parent TSRMLS_CC);
- zend_error(E_STRICT, "Declaration of %s::%s() should be compatible with %s", ZEND_FN_SCOPE_NAME(child), child->common.function_name, method_prototype);
+ zend_error(E_STRICT, "Declaration of %s::%s() should be compatible with %s", ZEND_FN_SCOPE_NAME(child), child->common.function_name, method_prototype);
efree(method_prototype);
}
}
@@ -3292,9 +3478,9 @@ static zend_bool do_inherit_method_check(HashTable *child_function_table, zend_f
}
return 1; /* method doesn't exist in child, copy from parent */
}
-
+
do_inheritance_check_on_method(child, parent TSRMLS_CC);
-
+
return 0;
}
/* }}} */
@@ -3325,7 +3511,7 @@ static zend_bool do_inherit_property_access_check(HashTable *target_ht, zend_pro
zend_error(E_COMPILE_ERROR, "Cannot redeclare %s%s::$%s as %s%s::$%s",
(parent_info->flags & ZEND_ACC_STATIC) ? "static " : "non static ", parent_ce->name, hash_key->arKey,
(child_info->flags & ZEND_ACC_STATIC) ? "static " : "non static ", ce->name, hash_key->arKey);
-
+
}
if(parent_info->flags & ZEND_ACC_CHANGED) {
@@ -3591,10 +3777,10 @@ ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry
}
}
ce->interfaces[ce->num_interfaces++] = iface;
-
+
zend_hash_merge_ex(&ce->constants_table, &iface->constants_table, (copy_ctor_func_t) zval_add_ref, sizeof(zval *), (merge_checker_func_t) do_inherit_constant_check, iface);
zend_hash_merge_ex(&ce->function_table, &iface->function_table, (copy_ctor_func_t) do_inherit_method, sizeof(zend_function), (merge_checker_func_t) do_inherit_method_check, ce);
-
+
do_implement_interface(ce, iface TSRMLS_CC);
zend_do_inherit_interfaces(ce, iface TSRMLS_CC);
}
@@ -3634,10 +3820,10 @@ static zend_bool zend_traits_method_compatibility_check(zend_function *fn, zend_
{
zend_uint fn_flags = fn->common.scope->ce_flags;
zend_uint other_flags = other_fn->common.scope->ce_flags;
-
+
return zend_do_perform_implementation_check(fn, other_fn TSRMLS_CC)
&& ((other_fn->common.scope->ce_flags & ZEND_ACC_INTERFACE) || zend_do_perform_implementation_check(other_fn, fn TSRMLS_CC))
- && ((fn_flags & (ZEND_ACC_FINAL|ZEND_ACC_STATIC)) ==
+ && ((fn_flags & (ZEND_ACC_FINAL|ZEND_ACC_STATIC)) ==
(other_flags & (ZEND_ACC_FINAL|ZEND_ACC_STATIC))); /* equal final and static qualifier */
}
/* }}} */
@@ -3650,7 +3836,7 @@ static void zend_add_magic_methods(zend_class_entry* ce, const char* mname, uint
if (ce->constructor) {
zend_error(E_COMPILE_ERROR, "%s has colliding constructor definitions coming from traits", ce->name);
}
- ce->constructor = fe; fe->common.fn_flags |= ZEND_ACC_CTOR;
+ ce->constructor = fe; fe->common.fn_flags |= ZEND_ACC_CTOR;
} else if (!strncmp(mname, ZEND_DESTRUCTOR_FUNC_NAME, mname_len)) {
ce->destructor = fe; fe->common.fn_flags |= ZEND_ACC_DTOR;
} else if (!strncmp(mname, ZEND_GET_FUNC_NAME, mname_len)) {
@@ -3787,7 +3973,7 @@ static int zend_traits_copy_functions(zend_function *fn TSRMLS_DC, int num_args,
ce = va_arg(args, zend_class_entry*);
overriden = va_arg(args, HashTable**);
exclude_table = va_arg(args, HashTable*);
-
+
fnname_len = hash_key->nKeyLength - 1;
/* apply aliases which are qualified with a class name, there should not be any ambiguity */
@@ -3801,9 +3987,9 @@ static int zend_traits_copy_functions(zend_function *fn TSRMLS_DC, int num_args,
&& alias->trait_method->mname_len == fnname_len
&& (zend_binary_strcasecmp(alias->trait_method->method_name, alias->trait_method->mname_len, hash_key->arKey, fnname_len) == 0)) {
fn_copy = *fn;
-
+
/* if it is 0, no modifieres has been changed */
- if (alias->modifiers) {
+ if (alias->modifiers) {
fn_copy.common.fn_flags = alias->modifiers | (fn->common.fn_flags ^ (fn->common.fn_flags & ZEND_ACC_PPP_MASK));
}
@@ -3908,7 +4094,7 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce TSRMLS_DC) /*
cur_method_ref->ce->name,
cur_method_ref->method_name);
}
-
+
/** With the other traits, we are more permissive.
We do not give errors for those. This allows to be more
defensive in such definitions.
@@ -3922,20 +4108,20 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce TSRMLS_DC) /*
if (!(cur_precedence->exclude_from_classes[j] = zend_fetch_class(class_name, name_length, ZEND_FETCH_CLASS_TRAIT |ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC))) {
zend_error(E_COMPILE_ERROR, "Could not find trait %s", class_name);
- }
+ }
zend_check_trait_usage(ce, cur_precedence->exclude_from_classes[j] TSRMLS_CC);
/* make sure that the trait method is not from a class mentioned in
exclude_from_classes, for consistency */
if (cur_precedence->trait_method->ce == cur_precedence->exclude_from_classes[i]) {
zend_error(E_COMPILE_ERROR,
- "Inconsistent insteadof definition. "
+ "Inconsistent insteadof definition. "
"The method %s is to be used from %s, but %s is also on the exclude list",
cur_method_ref->method_name,
cur_precedence->trait_method->ce->name,
cur_precedence->trait_method->ce->name);
}
-
+
efree(class_name);
j++;
}
@@ -3975,7 +4161,7 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce TSRMLS_DC) /*
static void zend_traits_compile_exclude_table(HashTable* exclude_table, zend_trait_precedence **precedences, zend_class_entry *trait) /* {{{ */
{
size_t i = 0, j;
-
+
if (!precedences) {
return;
}
@@ -3986,7 +4172,7 @@ static void zend_traits_compile_exclude_table(HashTable* exclude_table, zend_tra
if (precedences[i]->exclude_from_classes[j] == trait) {
zend_uint lcname_len = precedences[i]->trait_method->mname_len;
char *lcname = zend_str_tolower_dup(precedences[i]->trait_method->method_name, lcname_len);
-
+
if (zend_hash_add(exclude_table, lcname, lcname_len, NULL, 0, NULL) == FAILURE) {
efree(lcname);
zend_error(E_COMPILE_ERROR, "Failed to evaluate a trait precedence (%s). Method of trait %s was defined to be excluded multiple times", precedences[i]->trait_method->method_name, trait->name);
@@ -4023,7 +4209,7 @@ static void zend_do_traits_method_binding(zend_class_entry *ce TSRMLS_DC) /* {{{
zend_hash_apply_with_arguments(&ce->traits[i]->function_table TSRMLS_CC, (apply_func_args_t)zend_traits_copy_functions, 3, ce, &overriden, NULL);
}
}
-
+
zend_hash_apply_with_argument(&ce->function_table, (apply_func_arg_t)zend_fixup_trait_method, ce TSRMLS_CC);
if (overriden) {
@@ -4061,7 +4247,7 @@ static void zend_do_traits_property_binding(zend_class_entry *ce TSRMLS_DC) /* {
const char* class_name_unused;
zend_bool not_compatible;
zval* prop_value;
- char* doc_comment;
+ char* doc_comment;
zend_uint flags;
/* In the following steps the properties are inserted into the property table
@@ -4083,18 +4269,17 @@ static void zend_do_traits_property_binding(zend_class_entry *ce TSRMLS_DC) /* {
prop_name_length = property_info->name_length;
} else {
/* for private and protected we need to unmangle the names */
- zend_unmangle_property_name(property_info->name, property_info->name_length,
- &class_name_unused, &prop_name);
- prop_name_length = strlen(prop_name);
+ zend_unmangle_property_name_ex(property_info->name, property_info->name_length,
+ &class_name_unused, &prop_name, &prop_name_length);
prop_hash = zend_get_hash_value(prop_name, prop_name_length + 1);
}
/* next: check for conflicts with current class */
if (zend_hash_quick_find(&ce->properties_info, prop_name, prop_name_length+1, prop_hash, (void **) &coliding_prop) == SUCCESS) {
- if (coliding_prop->flags & ZEND_ACC_SHADOW) {
+ if (coliding_prop->flags & ZEND_ACC_SHADOW) {
zend_hash_quick_del(&ce->properties_info, prop_name, prop_name_length+1, prop_hash);
flags |= ZEND_ACC_CHANGED;
- } else {
+ } else {
if ((coliding_prop->flags & (ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC))
== (flags & (ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC))) {
/* flags are identical, now the value needs to be checked */
@@ -4115,14 +4300,14 @@ static void zend_do_traits_property_binding(zend_class_entry *ce TSRMLS_DC) /* {
}
if (not_compatible) {
- zend_error(E_COMPILE_ERROR,
+ zend_error(E_COMPILE_ERROR,
"%s and %s define the same property ($%s) in the composition of %s. However, the definition differs and is considered incompatible. Class was composed",
find_first_definition(ce, i, prop_name, prop_name_length, prop_hash, coliding_prop->ce)->name,
property_info->ce->name,
prop_name,
ce->name);
} else {
- zend_error(E_STRICT,
+ zend_error(E_STRICT,
"%s and %s define the same property ($%s) in the composition of %s. This might be incompatible, to improve maintainability consider using accessor methods in traits instead. Class was composed",
find_first_definition(ce, i, prop_name, prop_name_length, prop_hash, coliding_prop->ce)->name,
property_info->ce->name,
@@ -4142,8 +4327,8 @@ static void zend_do_traits_property_binding(zend_class_entry *ce TSRMLS_DC) /* {
Z_ADDREF_P(prop_value);
doc_comment = property_info->doc_comment ? estrndup(property_info->doc_comment, property_info->doc_comment_len) : NULL;
- zend_declare_property_ex(ce, prop_name, prop_name_length,
- prop_value, flags,
+ zend_declare_property_ex(ce, prop_name, prop_name_length,
+ prop_value, flags,
doc_comment, property_info->doc_comment_len TSRMLS_CC);
}
}
@@ -4155,7 +4340,7 @@ static void zend_do_check_for_inconsistent_traits_aliasing(zend_class_entry *ce
int i = 0;
zend_trait_alias* cur_alias;
char* lc_method_name;
-
+
if (ce->trait_aliases) {
while (ce->trait_aliases[i]) {
cur_alias = ce->trait_aliases[i];
@@ -4176,7 +4361,7 @@ static void zend_do_check_for_inconsistent_traits_aliasing(zend_class_entry *ce
we check against it and abort.
2) it is just a plain old inconsitency/typo/bug
as in the case where alias is set. */
-
+
lc_method_name = zend_str_tolower_dup(cur_alias->trait_method->method_name,
cur_alias->trait_method->mname_len);
if (zend_hash_exists(&ce->function_table,
@@ -4213,7 +4398,7 @@ ZEND_API void zend_do_bind_traits(zend_class_entry *ce TSRMLS_DC) /* {{{ */
/* first care about all methods to be flattened into the class */
zend_do_traits_method_binding(ce TSRMLS_CC);
-
+
/* Aliases which have not been applied indicate typos/bugs. */
zend_do_check_for_inconsistent_traits_aliasing(ce TSRMLS_CC);
@@ -4222,7 +4407,7 @@ ZEND_API void zend_do_bind_traits(zend_class_entry *ce TSRMLS_DC) /* {{{ */
/* verify that all abstract methods from traits have been implemented */
zend_verify_abstract_class(ce TSRMLS_CC);
-
+
/* now everything should be fine and an added ZEND_ACC_IMPLICIT_ABSTRACT_CLASS should be removed */
if (ce->ce_flags & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) {
ce->ce_flags -= ZEND_ACC_IMPLICIT_ABSTRACT_CLASS;
@@ -4272,7 +4457,7 @@ void zend_prepare_reference(znode *result, znode *class_name, znode *method_name
zend_trait_method_reference *method_ref = emalloc(sizeof(zend_trait_method_reference));
method_ref->ce = NULL;
- /* REM: There should not be a need for copying,
+ /* REM: There should not be a need for copying,
zend_do_begin_class_declaration is also just using that string */
if (class_name) {
zend_resolve_class_name(class_name, ZEND_FETCH_CLASS_GLOBAL, 1 TSRMLS_CC);
@@ -4316,8 +4501,6 @@ void zend_add_trait_alias(znode *method_reference, znode *modifiers, znode *alia
} else {
trait_alias->alias = NULL;
}
- trait_alias->function = NULL;
-
zend_add_to_list(&ce->trait_aliases, trait_alias TSRMLS_CC);
}
/* }}} */
@@ -4330,8 +4513,6 @@ void zend_add_trait_precedence(znode *method_reference, znode *trait_list TSRMLS
trait_precedence->trait_method = (zend_trait_method_reference*)method_reference->u.op.ptr;
trait_precedence->exclude_from_classes = (zend_class_entry**) trait_list->u.op.ptr;
- trait_precedence->function = NULL;
-
zend_add_to_list(&ce->trait_precedences, trait_precedence TSRMLS_CC);
}
/* }}} */
@@ -4850,7 +5031,7 @@ void zend_do_begin_class_declaration(const znode *class_token, znode *class_name
build_runtime_defined_function_key(&key, lcname, new_class_entry->name_length TSRMLS_CC);
opline->op1.constant = zend_add_literal(CG(active_op_array), &key TSRMLS_CC);
Z_HASH_P(&CONSTANT(opline->op1.constant)) = zend_hash_func(Z_STRVAL(CONSTANT(opline->op1.constant)), Z_STRLEN(CONSTANT(opline->op1.constant)));
-
+
opline->op2_type = IS_CONST;
if (doing_inheritance) {
@@ -4867,7 +5048,7 @@ void zend_do_begin_class_declaration(const znode *class_token, znode *class_name
LITERAL_STRINGL(opline->op2, lcname, new_class_entry->name_length, 0);
CALCULATE_LITERAL_HASH(opline->op2.constant);
-
+
zend_hash_quick_update(CG(class_table), Z_STRVAL(key), Z_STRLEN(key), Z_HASH_P(&CONSTANT(opline->op1.constant)), &new_class_entry, sizeof(zend_class_entry *), NULL);
CG(active_class_entry) = new_class_entry;
@@ -4918,7 +5099,7 @@ void zend_do_end_class_declaration(const znode *class_token, const znode *parent
}
ce->info.user.line_end = zend_get_compiled_lineno(TSRMLS_C);
-
+
/* Check for traits and proceed like with interfaces.
* The only difference will be a combined handling of them in the end.
* Thus, we need another opcode here. */
@@ -4943,7 +5124,7 @@ void zend_do_end_class_declaration(const znode *class_token, const znode *parent
}
}
/* Inherit interfaces; reset number to zero, we need it for above check and
- * will restore it during actual implementation.
+ * will restore it during actual implementation.
* The ZEND_ACC_IMPLEMENT_INTERFACES flag disables double call to
* zend_verify_abstract_class() */
if (ce->num_interfaces > 0) {
@@ -5044,7 +5225,7 @@ static int zend_strnlen(const char* s, int maxlen) /* {{{ */
}
/* }}} */
-ZEND_API int zend_unmangle_property_name(const char *mangled_property, int len, const char **class_name, const char **prop_name) /* {{{ */
+ZEND_API int zend_unmangle_property_name_ex(const char *mangled_property, int len, const char **class_name, const char **prop_name, int *prop_len) /* {{{ */
{
int class_name_len;
@@ -5052,22 +5233,34 @@ ZEND_API int zend_unmangle_property_name(const char *mangled_property, int len,
if (mangled_property[0]!=0) {
*prop_name = mangled_property;
+ if (prop_len) {
+ *prop_len = len;
+ }
return SUCCESS;
}
if (len < 3 || mangled_property[1]==0) {
zend_error(E_NOTICE, "Illegal member variable name");
*prop_name = mangled_property;
+ if (prop_len) {
+ *prop_len = len;
+ }
return FAILURE;
}
- class_name_len = zend_strnlen(mangled_property+1, --len - 1) + 1;
+ class_name_len = zend_strnlen(mangled_property + 1, --len - 1) + 1;
if (class_name_len >= len || mangled_property[class_name_len]!=0) {
zend_error(E_NOTICE, "Corrupt member variable name");
*prop_name = mangled_property;
+ if (prop_len) {
+ *prop_len = len + 1;
+ }
return FAILURE;
}
- *class_name = mangled_property+1;
- *prop_name = (*class_name)+class_name_len;
+ *class_name = mangled_property + 1;
+ *prop_name = (*class_name) + class_name_len;
+ if (prop_len) {
+ *prop_len = len - class_name_len;
+ }
return SUCCESS;
}
/* }}} */
@@ -5133,7 +5326,7 @@ void zend_do_declare_class_constant(znode *var_name, const znode *value TSRMLS_D
ALLOC_ZVAL(property);
*property = value->u.constant;
-
+
cname = zend_new_interned_string(var_name->u.constant.value.str.val, var_name->u.constant.value.str.len+1, 0 TSRMLS_CC);
if (IS_INTERNED(cname)) {
@@ -5146,7 +5339,7 @@ void zend_do_declare_class_constant(znode *var_name, const znode *value TSRMLS_D
zend_error(E_COMPILE_ERROR, "Cannot redefine class constant %s::%s", CG(active_class_entry)->name, var_name->u.constant.value.str.val);
}
FREE_PNODE(var_name);
-
+
if (CG(doc_comment)) {
efree(CG(doc_comment));
CG(doc_comment) = NULL;
@@ -5235,17 +5428,17 @@ void zend_do_halt_compiler_register(TSRMLS_D) /* {{{ */
char *name, *cfilename;
char haltoff[] = "__COMPILER_HALT_OFFSET__";
int len, clen;
-
+
if (CG(has_bracketed_namespaces) && CG(in_namespace)) {
zend_error(E_COMPILE_ERROR, "__HALT_COMPILER() can only be used from the outermost scope");
}
-
+
cfilename = zend_get_compiled_filename(TSRMLS_C);
clen = strlen(cfilename);
zend_mangle_property_name(&name, &len, haltoff, sizeof(haltoff) - 1, cfilename, clen, 0);
zend_register_long_constant(name, len+1, zend_get_scanned_file_offset(TSRMLS_C), CONST_CS, 0 TSRMLS_CC);
pefree(name, 0);
-
+
if (CG(in_namespace)) {
zend_do_end_namespace(TSRMLS_C);
}
@@ -5278,12 +5471,16 @@ void zend_do_begin_new_object(znode *new_token, znode *class_type TSRMLS_DC) /*
new_token->u.op.opline_num = get_next_op_number(CG(active_op_array));
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
opline->opcode = ZEND_NEW;
+ opline->extended_value = CG(context).nested_calls;
opline->result_type = IS_VAR;
opline->result.var = get_temporary_variable(CG(active_op_array));
SET_NODE(opline->op1, class_type);
SET_UNUSED(opline->op2);
zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(unsigned char *));
+ if (++CG(context).nested_calls > CG(active_op_array)->nested_calls) {
+ CG(active_op_array)->nested_calls = CG(context).nested_calls;
+ }
}
/* }}} */
@@ -5318,7 +5515,7 @@ static zend_constant* zend_get_ct_const(const zval *const_name, int all_internal
}
} else if (zend_hash_find(EG(zend_constants), Z_STRVAL_P(const_name), Z_STRLEN_P(const_name)+1, (void **) &c) == FAILURE) {
char *lookup_name = zend_str_tolower_dup(Z_STRVAL_P(const_name), Z_STRLEN_P(const_name));
-
+
if (zend_hash_find(EG(zend_constants), lookup_name, Z_STRLEN_P(const_name)+1, (void **) &c)==SUCCESS) {
if ((c->flags & CONST_CT_SUBST) && !(c->flags & CONST_CS)) {
efree(lookup_name);
@@ -5371,7 +5568,7 @@ void zend_do_fetch_constant(znode *result, znode *constant_container, znode *con
case ZEND_CT:
/* this is a class constant */
type = zend_get_class_fetch_type(Z_STRVAL(constant_container->u.constant), Z_STRLEN(constant_container->u.constant));
-
+
if (ZEND_FETCH_CLASS_STATIC == type) {
zend_error(E_ERROR, "\"static::\" is not allowed in compile-time constants");
} else if (ZEND_FETCH_CLASS_DEFAULT == type) {
@@ -5435,7 +5632,7 @@ void zend_do_fetch_constant(znode *result, znode *constant_container, znode *con
compound = memchr(Z_STRVAL(constant_name->u.constant), '\\', Z_STRLEN(constant_name->u.constant));
zend_resolve_non_class_name(constant_name, check_namespace TSRMLS_CC);
-
+
if(zend_constant_ct_subst(result, &constant_name->u.constant, 1 TSRMLS_CC)) {
break;
}
@@ -5451,7 +5648,7 @@ void zend_do_fetch_constant(znode *result, znode *constant_container, znode *con
/* the name is unambiguous */
opline->extended_value = 0;
opline->op2.constant = zend_add_const_name_literal(CG(active_op_array), &constant_name->u.constant, 0 TSRMLS_CC);
- } else {
+ } else {
opline->extended_value = IS_CONSTANT_UNQUALIFIED;
if (CG(current_namespace)) {
opline->extended_value |= IS_CONSTANT_IN_NAMESPACE;
@@ -5495,7 +5692,15 @@ void zend_do_shell_exec(znode *result, const znode *cmd TSRMLS_DC) /* {{{ */
GET_CACHE_SLOT(opline->op1.constant);
opline->extended_value = 1;
SET_UNUSED(opline->op2);
+ opline->op2.num = CG(context).nested_calls;
GET_NODE(result, opline->result);
+
+ if (CG(context).nested_calls + 1 > CG(active_op_array)->nested_calls) {
+ CG(active_op_array)->nested_calls = CG(context).nested_calls + 1;
+ }
+ if (CG(context).used_stack + 2 > CG(active_op_array)->used_stack) {
+ CG(active_op_array)->used_stack = CG(context).used_stack + 2;
+ }
}
/* }}} */
@@ -5518,7 +5723,7 @@ void zend_do_init_array(znode *result, const znode *expr, const znode *offset, z
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL(CONSTANT(opline->op2.constant)), Z_STRLEN(CONSTANT(opline->op2.constant))+1, index, numeric = 1);
if (numeric) {
zval_dtor(&CONSTANT(opline->op2.constant));
- ZVAL_LONG(&CONSTANT(opline->op2.constant), index);
+ ZVAL_LONG(&CONSTANT(opline->op2.constant), index);
} else {
CALCULATE_LITERAL_HASH(opline->op2.constant);
}
@@ -5550,7 +5755,7 @@ void zend_do_add_array_element(znode *result, const znode *expr, const znode *of
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL(CONSTANT(opline->op2.constant)), Z_STRLEN(CONSTANT(opline->op2.constant))+1, index, numeric = 1);
if (numeric) {
zval_dtor(&CONSTANT(opline->op2.constant));
- ZVAL_LONG(&CONSTANT(opline->op2.constant), index);
+ ZVAL_LONG(&CONSTANT(opline->op2.constant), index);
} else {
CALCULATE_LITERAL_HASH(opline->op2.constant);
}
@@ -5810,7 +6015,7 @@ void zend_do_fetch_lexical_variable(znode *varname, zend_bool is_ref TSRMLS_DC)
Z_TYPE(value.u.constant) |= is_ref ? IS_LEXICAL_REF : IS_LEXICAL_VAR;
Z_SET_REFCOUNT_P(&value.u.constant, 1);
Z_UNSET_ISREF_P(&value.u.constant);
-
+
zend_do_fetch_static_variable(varname, &value, is_ref ? ZEND_FETCH_STATIC : ZEND_FETCH_LEXICAL TSRMLS_CC);
}
/* }}} */
@@ -5940,7 +6145,16 @@ void zend_do_isset_or_isempty(int type, znode *result, znode *variable TSRMLS_DC
zend_do_end_variable_parse(variable, BP_VAR_IS, 0 TSRMLS_CC);
- zend_check_writable_variable(variable);
+ if (zend_is_function_or_method_call(variable)) {
+ if (type == ZEND_ISEMPTY) {
+ /* empty(func()) can be transformed to !func() */
+ zend_do_unary_op(ZEND_BOOL_NOT, result, variable TSRMLS_CC);
+ } else {
+ zend_error(E_COMPILE_ERROR, "Cannot use isset() on the result of a function call (you can use \"null !== func()\" instead)");
+ }
+
+ return;
+ }
if (variable->op_type == IS_CV) {
last_op = get_next_op(CG(active_op_array) TSRMLS_CC);
@@ -6003,7 +6217,6 @@ void zend_do_foreach_begin(znode *foreach_token, znode *open_brackets_token, zno
{
zend_op *opline;
zend_bool is_variable;
- zend_bool push_container = 0;
zend_op dummy_opline;
if (variable) {
@@ -6015,14 +6228,6 @@ void zend_do_foreach_begin(znode *foreach_token, znode *open_brackets_token, zno
/* save the location of FETCH_W instruction(s) */
open_brackets_token->u.op.opline_num = get_next_op_number(CG(active_op_array));
zend_do_end_variable_parse(array, BP_VAR_W, 0 TSRMLS_CC);
- if (CG(active_op_array)->last > 0 &&
- CG(active_op_array)->opcodes[CG(active_op_array)->last-1].opcode == ZEND_FETCH_OBJ_W) {
- /* Only lock the container if we are fetching from a real container and not $this */
- if (CG(active_op_array)->opcodes[CG(active_op_array)->last-1].op1_type == IS_VAR) {
- CG(active_op_array)->opcodes[CG(active_op_array)->last-1].extended_value |= ZEND_FETCH_ADD_LOCK;
- push_container = 1;
- }
- }
} else {
is_variable = 0;
open_brackets_token->u.op.opline_num = get_next_op_number(CG(active_op_array));
@@ -6042,11 +6247,6 @@ void zend_do_foreach_begin(znode *foreach_token, znode *open_brackets_token, zno
opline->extended_value = is_variable ? ZEND_FE_RESET_VARIABLE : 0;
COPY_NODE(dummy_opline.result, opline->result);
- if (push_container) {
- COPY_NODE(dummy_opline.op1, CG(active_op_array)->opcodes[CG(active_op_array)->last-2].op1);
- } else {
- dummy_opline.op1_type = IS_UNUSED;
- }
zend_stack_push(&CG(foreach_copy_stack), (void *) &dummy_opline, sizeof(zend_op));
/* save the location of FE_FETCH */
@@ -6087,20 +6287,22 @@ void zend_do_foreach_cont(znode *foreach_token, const znode *open_brackets_token
opline->extended_value |= ZEND_FE_FETCH_WITH_KEY;
}
- if ((key->op_type != IS_UNUSED) && (key->EA & ZEND_PARSED_REFERENCE_VARIABLE)) {
- zend_error(E_COMPILE_ERROR, "Key element cannot be a reference");
+ if ((key->op_type != IS_UNUSED)) {
+ if (key->EA & ZEND_PARSED_REFERENCE_VARIABLE) {
+ zend_error(E_COMPILE_ERROR, "Key element cannot be a reference");
+ }
+ if (key->EA & ZEND_PARSED_LIST_EXPR) {
+ zend_error(E_COMPILE_ERROR, "Cannot use list as key element");
+ }
}
if (value->EA & ZEND_PARSED_REFERENCE_VARIABLE) {
assign_by_ref = 1;
- if (!(opline-1)->extended_value) {
- zend_error(E_COMPILE_ERROR, "Cannot create references to elements of a temporary array expression");
- }
+
/* Mark extended_value for assign-by-reference */
opline->extended_value |= ZEND_FE_FETCH_BYREF;
CG(active_op_array)->opcodes[foreach_token->u.op.opline_num].extended_value |= ZEND_FE_RESET_REFERENCE;
} else {
- zend_op *foreach_copy;
zend_op *fetch = &CG(active_op_array)->opcodes[foreach_token->u.op.opline_num];
zend_op *end = &CG(active_op_array)->opcodes[open_brackets_token->u.op.opline_num];
@@ -6117,20 +6319,25 @@ void zend_do_foreach_cont(znode *foreach_token, const znode *open_brackets_token
fetch->opcode -= 3; /* FETCH_W -> FETCH_R */
}
}
- /* prevent double SWITCH_FREE */
- zend_stack_top(&CG(foreach_copy_stack), (void **) &foreach_copy);
- foreach_copy->op1_type = IS_UNUSED;
}
GET_NODE(&value_node, opline->result);
- if (assign_by_ref) {
- zend_do_end_variable_parse(value, BP_VAR_W, 0 TSRMLS_CC);
- /* Mark FE_FETCH as IS_VAR as it holds the data directly as a value */
- zend_do_assign_ref(NULL, value, &value_node TSRMLS_CC);
- } else {
- zend_do_assign(&dummy, value, &value_node TSRMLS_CC);
+ if (value->EA & ZEND_PARSED_LIST_EXPR) {
+ if (!CG(list_llist).head) {
+ zend_error(E_COMPILE_ERROR, "Cannot use empty list");
+ }
+ zend_do_list_end(&dummy, &value_node TSRMLS_CC);
zend_do_free(&dummy TSRMLS_CC);
+ } else {
+ if (assign_by_ref) {
+ zend_do_end_variable_parse(value, BP_VAR_W, 0 TSRMLS_CC);
+ /* Mark FE_FETCH as IS_VAR as it holds the data directly as a value */
+ zend_do_assign_ref(NULL, value, &value_node TSRMLS_CC);
+ } else {
+ zend_do_assign(&dummy, value, &value_node TSRMLS_CC);
+ zend_do_free(&dummy TSRMLS_CC);
+ }
}
if (key->op_type != IS_UNUSED) {
@@ -6306,7 +6513,7 @@ void zend_do_jmp_set(const znode *value, znode *jmp_token, znode *colon_token TS
opline->result.var = get_temporary_variable(CG(active_op_array));
SET_NODE(opline->op1, value);
SET_UNUSED(opline->op2);
-
+
GET_NODE(colon_token, opline->result);
jmp_token->u.op.opline_num = op_number;
@@ -6335,11 +6542,11 @@ void zend_do_jmp_set_else(znode *result, const znode *false_value, const znode *
opline->extended_value = 0;
SET_NODE(opline->op1, false_value);
SET_UNUSED(opline->op2);
-
+
GET_NODE(result, opline->result);
CG(active_op_array)->opcodes[jmp_token->u.op.opline_num].op2.opline_num = get_next_op_number(CG(active_op_array));
-
+
DEC_BPC(CG(active_op_array));
}
/* }}} */
@@ -6552,16 +6759,13 @@ again:
CG(increment_lineno) = 1;
}
if (CG(has_bracketed_namespaces) && !CG(in_namespace)) {
- goto again;
+ goto again;
}
retval = ';'; /* implicit ; */
break;
case T_OPEN_TAG_WITH_ECHO:
retval = T_ECHO;
break;
- case T_END_HEREDOC:
- efree(Z_STRVAL(zendlval->u.constant));
- break;
}
INIT_PZVAL(&zendlval->u.constant);
@@ -6645,13 +6849,13 @@ ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify
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)) {
- return ZEND_FETCH_CLASS_SELF;
+ !strncasecmp(class_name, "self", sizeof("self")-1)) {
+ return ZEND_FETCH_CLASS_SELF;
} else if ((class_name_len == sizeof("parent")-1) &&
- !memcmp(class_name, "parent", sizeof("parent")-1)) {
+ !strncasecmp(class_name, "parent", sizeof("parent")-1)) {
return ZEND_FETCH_CLASS_PARENT;
} else if ((class_name_len == sizeof("static")-1) &&
- !memcmp(class_name, "static", sizeof("static")-1)) {
+ !strncasecmp(class_name, "static", sizeof("static")-1)) {
return ZEND_FETCH_CLASS_STATIC;
} else {
return ZEND_FETCH_CLASS_DEFAULT;
@@ -6764,7 +6968,7 @@ void zend_do_begin_namespace(const znode *name, zend_bool with_bracket TSRMLS_DC
efree(CG(current_import));
CG(current_import) = NULL;
}
-
+
if (CG(doc_comment)) {
efree(CG(doc_comment));
CG(doc_comment) = NULL;
@@ -6936,7 +7140,7 @@ ZEND_API size_t zend_dirname(char *path, size_t len)
len_adjust += 2;
if (2 == len) {
/* Return "c:" on Win32 for dirname("c:").
- * It would be more consistent to return "c:."
+ * It would be more consistent to return "c:."
* but that would require making the string *longer*.
*/
return len;
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index 1490307df4..2a3d58e490 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -59,6 +59,9 @@ typedef struct _zend_compiler_context {
int literals_size;
int current_brk_cont;
int backpatch_count;
+ int nested_calls;
+ int used_stack;
+ int in_finally;
HashTable *labels;
} zend_compiler_context;
@@ -80,7 +83,7 @@ typedef union _znode_op {
zend_op *jmp_addr;
zval *zv;
zend_literal *literal;
- void *ptr; /* Used for passing pointers from the compile to execution phase, currently used for traits */
+ void *ptr; /* Used for passing pointers from the compile to execution phase, currently used for traits */
} znode_op;
typedef struct _znode { /* used only during compilation */
@@ -132,6 +135,8 @@ typedef struct _zend_label {
typedef struct _zend_try_catch_element {
zend_uint try_op;
zend_uint catch_op; /* ketchup! */
+ zend_uint finally_op;
+ zend_uint finally_end;
} zend_try_catch_element;
#if SIZEOF_LONG == 8
@@ -194,6 +199,7 @@ typedef struct _zend_try_catch_element {
#define ZEND_ACC_CLOSURE 0x100000
+#define ZEND_ACC_GENERATOR 0x800000
/* function flag for internal user call handlers __call, __callstatic */
#define ZEND_ACC_CALL_VIA_HANDLER 0x200000
@@ -274,11 +280,15 @@ struct _zend_op_array {
zend_uint T;
+ zend_uint nested_calls;
+ zend_uint used_stack;
+
zend_brk_cont_element *brk_cont_array;
int last_brk_cont;
zend_try_catch_element *try_catch_array;
int last_try_catch;
+ zend_bool has_finally_block;
/* static variables support */
HashTable *static_variables;
@@ -363,15 +373,19 @@ typedef struct _list_llist_element {
union _temp_variable;
+typedef struct _call_slot {
+ zend_function *fbc;
+ zval *object;
+ zend_class_entry *called_scope;
+ zend_bool is_ctor_call;
+ zend_bool is_ctor_result_used;
+} call_slot;
+
struct _zend_execute_data {
struct _zend_op *opline;
zend_function_state function_state;
- zend_function *fbc; /* Function Being Called */
- zend_class_entry *called_scope;
zend_op_array *op_array;
zval *object;
- union _temp_variable *Ts;
- zval ***CVs;
HashTable *symbol_table;
struct _zend_execute_data *prev_execute_data;
zval *old_error_reporting;
@@ -380,11 +394,18 @@ struct _zend_execute_data {
zend_class_entry *current_scope;
zend_class_entry *current_called_scope;
zval *current_this;
- zval *current_object;
+ struct _zend_op *fast_ret; /* used by FAST_CALL/FAST_RET (finally keyword) */
+ call_slot *call_slots;
+ call_slot *call;
};
#define EX(element) execute_data.element
+#define EX_TMP_VAR(ex, n) ((temp_variable*)(((char*)(ex)) + ((int)(n))))
+#define EX_TMP_VAR_NUM(ex, n) (EX_TMP_VAR(ex, 0) - (1 + (n)))
+
+#define EX_CV_NUM(ex, n) (((zval***)(((char*)(ex))+ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data))))+(n))
+
#define IS_CONST (1<<0)
#define IS_TMP_VAR (1<<1)
@@ -489,6 +510,7 @@ void zend_do_build_full_name(znode *result, znode *prefix, znode *name, int is_c
int zend_do_begin_class_member_function_call(znode *class_name, znode *method_name 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);
void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC);
+void zend_do_yield(znode *result, znode *value, const znode *key, zend_bool is_variable TSRMLS_DC);
void zend_do_handle_exception(TSRMLS_D);
void zend_do_begin_lambda_function_declaration(znode *result, znode *function_token, int return_reference, int is_static TSRMLS_DC);
@@ -496,7 +518,10 @@ void zend_do_fetch_lexical_variable(znode *varname, zend_bool is_ref TSRMLS_DC);
void zend_do_try(znode *try_token TSRMLS_DC);
void zend_do_begin_catch(znode *try_token, znode *catch_class, znode *catch_var, znode *first_catch TSRMLS_DC);
-void zend_do_end_catch(const znode *try_token TSRMLS_DC);
+void zend_do_bind_catch(znode *try_token, znode *catch_token TSRMLS_DC);
+void zend_do_end_catch(znode *catch_token TSRMLS_DC);
+void zend_do_finally(znode *finally_token TSRMLS_DC);
+void zend_do_end_finally(znode *try_token, znode* catch_token, znode *finally_token TSRMLS_DC);
void zend_do_throw(const znode *expr TSRMLS_DC);
ZEND_API int do_bind_function(const zend_op_array *op_array, zend_op *opline, HashTable *function_table, zend_bool compile_time);
@@ -613,6 +638,8 @@ void zend_verify_namespace(TSRMLS_D);
void zend_do_use(znode *name, znode *new_name, int is_global TSRMLS_DC);
void zend_do_end_compilation(TSRMLS_D);
+void zend_do_resolve_class_name(znode *result, znode *class_name, int is_static TSRMLS_DC);
+
void zend_do_label(znode *label TSRMLS_DC);
void zend_do_goto(const znode *label TSRMLS_DC);
void zend_resolve_goto_label(zend_op_array *op_array, zend_op *opline, int pass2 TSRMLS_DC);
@@ -646,7 +673,9 @@ ZEND_API void destroy_zend_class(zend_class_entry **pce);
void zend_class_add_ref(zend_class_entry **ce);
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 int zend_unmangle_property_name(const char *mangled_property, int mangled_property_len, const char **class_name, const char **prop_name);
+#define zend_unmangle_property_name(mangled_property, mangled_property_len, class_name, prop_name) \
+ zend_unmangle_property_name_ex(mangled_property, mangled_property_len, class_name, prop_name, NULL)
+ZEND_API int zend_unmangle_property_name_ex(const char *mangled_property, int mangled_property_len, const char **class_name, const char **prop_name, int *prop_len);
#define ZEND_FUNCTION_DTOR (void (*)(void *)) zend_function_dtor
#define ZEND_CLASS_DTOR (void (*)(void *)) destroy_zend_class
@@ -659,7 +688,7 @@ void print_op_array(zend_op_array *op_array, int optimizations);
ZEND_API int pass_two(zend_op_array *op_array TSRMLS_DC);
zend_brk_cont_element *get_next_brk_cont_element(zend_op_array *op_array);
void zend_do_first_catch(znode *open_parentheses TSRMLS_DC);
-void zend_initialize_try_catch_element(const znode *try_token TSRMLS_DC);
+void zend_initialize_try_catch_element(znode *catch_token TSRMLS_DC);
void zend_do_mark_last_catch(const znode *first_catch, const znode *last_additional_catch TSRMLS_DC);
ZEND_API zend_bool zend_is_compiling(TSRMLS_D);
ZEND_API char *zend_make_compiled_string_description(const char *name TSRMLS_DC);
@@ -715,6 +744,7 @@ int zend_add_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC);
#define ZEND_PARSED_VARIABLE (1<<4)
#define ZEND_PARSED_REFERENCE_VARIABLE (1<<5)
#define ZEND_PARSED_NEW (1<<6)
+#define ZEND_PARSED_LIST_EXPR (1<<7)
/* unset types */
@@ -810,6 +840,9 @@ int zend_add_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC);
#define ZEND_RETURNS_FUNCTION 1<<0
#define ZEND_RETURNS_NEW 1<<1
+#define ZEND_FAST_RET_TO_CATCH 1
+#define ZEND_FAST_RET_TO_FINALLY 2
+
END_EXTERN_C()
#define ZEND_CLONE_FUNC_NAME "__clone"
@@ -823,6 +856,7 @@ END_EXTERN_C()
#define ZEND_CALLSTATIC_FUNC_NAME "__callstatic"
#define ZEND_TOSTRING_FUNC_NAME "__tostring"
#define ZEND_AUTOLOAD_FUNC_NAME "__autoload"
+#define ZEND_INVOKE_FUNC_NAME "__invoke"
/* The following constants may be combined in CG(compiler_options)
* to change the default compiler behavior */
diff --git a/Zend/zend_config.w32.h b/Zend/zend_config.w32.h
index f779a506e6..6ea67602b4 100644
--- a/Zend/zend_config.w32.h
+++ b/Zend/zend_config.w32.h
@@ -62,10 +62,15 @@ typedef unsigned int uint;
/* This will cause the compilation process to be MUCH longer, but will generate
* a much quicker PHP binary
*/
-#undef inline
#ifdef ZEND_WIN32_FORCE_INLINE
+/* _ALLOW_KEYWORD_MACROS is only relevant for C++ */
+# if (_MSC_VER >= 1700) && !defined(_ALLOW_KEYWORD_MACROS)
+# define _ALLOW_KEYWORD_MACROS
+# endif
+# undef inline
# define inline __forceinline
-#else
+#elif !defined(ZEND_WIN32_KEEP_INLINE)
+# undef inline
# define inline
#endif
diff --git a/Zend/zend_default_classes.c b/Zend/zend_default_classes.c
index 1889451a00..40b28f7a23 100644
--- a/Zend/zend_default_classes.c
+++ b/Zend/zend_default_classes.c
@@ -25,6 +25,7 @@
#include "zend_interfaces.h"
#include "zend_exceptions.h"
#include "zend_closures.h"
+#include "zend_generators.h"
ZEND_API void zend_register_default_classes(TSRMLS_D)
@@ -33,6 +34,7 @@ ZEND_API void zend_register_default_classes(TSRMLS_D)
zend_register_default_exception(TSRMLS_C);
zend_register_iterator_wrapper(TSRMLS_C);
zend_register_closure_ce(TSRMLS_C);
+ zend_register_generator_ce(TSRMLS_C);
}
/*
diff --git a/Zend/zend_dtrace.c b/Zend/zend_dtrace.c
index 65c0193850..51bd1f421c 100644
--- a/Zend/zend_dtrace.c
+++ b/Zend/zend_dtrace.c
@@ -44,7 +44,7 @@ ZEND_API zend_op_array *dtrace_compile_file(zend_file_handle *file_handle, int t
}
/* We wrap the execute function to have fire the execute-entry/return and function-entry/return probes */
-ZEND_API void dtrace_execute(zend_op_array *op_array TSRMLS_DC)
+ZEND_API void dtrace_execute_ex(zend_execute_data *execute_data TSRMLS_DC)
{
int lineno;
const char *scope, *filename, *funcname, *classname;
@@ -70,7 +70,7 @@ ZEND_API void dtrace_execute(zend_op_array *op_array TSRMLS_DC)
DTRACE_FUNCTION_ENTRY((char *)funcname, (char *)filename, lineno, (char *)classname, (char *)scope);
}
- execute(op_array TSRMLS_CC);
+ execute_ex(execute_data TSRMLS_CC);
if (DTRACE_FUNCTION_RETURN_ENABLED() && funcname != NULL) {
DTRACE_FUNCTION_RETURN((char *)funcname, (char *)filename, lineno, (char *)classname, (char *)scope);
@@ -81,7 +81,7 @@ ZEND_API void dtrace_execute(zend_op_array *op_array TSRMLS_DC)
}
}
-ZEND_API void dtrace_execute_internal(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC)
+ZEND_API void dtrace_execute_internal(zend_execute_data *execute_data_ptr, zend_fcall_info *fci, int return_value_used TSRMLS_DC)
{
int lineno;
const char *filename;
@@ -94,7 +94,7 @@ ZEND_API void dtrace_execute_internal(zend_execute_data *execute_data_ptr, int r
DTRACE_EXECUTE_ENTRY((char *)filename, lineno);
}
- execute_internal(execute_data_ptr, return_value_used TSRMLS_CC);
+ execute_internal(execute_data_ptr, fci, return_value_used TSRMLS_CC);
if (DTRACE_EXECUTE_RETURN_ENABLED()) {
DTRACE_EXECUTE_RETURN((char *)filename, lineno);
diff --git a/Zend/zend_dtrace.h b/Zend/zend_dtrace.h
index 65d19ef346..26008afb6b 100644
--- a/Zend/zend_dtrace.h
+++ b/Zend/zend_dtrace.h
@@ -32,11 +32,11 @@ extern "C" {
#ifdef HAVE_DTRACE
ZEND_API zend_op_array *(*zend_dtrace_compile_file)(zend_file_handle *file_handle, int type TSRMLS_DC);
ZEND_API void (*zend_dtrace_execute)(zend_op_array *op_array TSRMLS_DC);
-ZEND_API void (*zend_dtrace_execute_internal)(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC);
+ZEND_API void (*zend_dtrace_execute_internal)(zend_execute_data *execute_data_ptr, zend_fcall_info *fci, int return_value_used TSRMLS_DC);
ZEND_API zend_op_array *dtrace_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC);
-ZEND_API void dtrace_execute(zend_op_array *op_array TSRMLS_DC);
-ZEND_API void dtrace_execute_internal(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC);
+ZEND_API void dtrace_execute_ex(zend_execute_data *execute_data TSRMLS_DC);
+ZEND_API void dtrace_execute_internal(zend_execute_data *execute_data_ptr, zend_fcall_info *fci, int return_value_used TSRMLS_DC);
#include <zend_dtrace_gen.h>
#endif /* HAVE_DTRACE */
diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c
index 2ef74ad106..e973a67a92 100644
--- a/Zend/zend_exceptions.c
+++ b/Zend/zend_exceptions.c
@@ -560,7 +560,7 @@ ZEND_METHOD(exception, getPrevious)
RETURN_ZVAL(previous, 1, 0);
}
-int zend_spprintf(char **message, int max_len, char *format, ...) /* {{{ */
+int zend_spprintf(char **message, int max_len, const char *format, ...) /* {{{ */
{
va_list arg;
int len;
@@ -732,7 +732,7 @@ ZEND_API zend_class_entry *zend_get_error_exception(TSRMLS_D) /* {{{ */
}
/* }}} */
-ZEND_API zval * zend_throw_exception(zend_class_entry *exception_ce, char *message, long code TSRMLS_DC) /* {{{ */
+ZEND_API zval * zend_throw_exception(zend_class_entry *exception_ce, const char *message, long code TSRMLS_DC) /* {{{ */
{
zval *ex;
@@ -760,7 +760,7 @@ ZEND_API zval * zend_throw_exception(zend_class_entry *exception_ce, char *messa
}
/* }}} */
-ZEND_API zval * zend_throw_exception_ex(zend_class_entry *exception_ce, long code TSRMLS_DC, char *format, ...) /* {{{ */
+ZEND_API zval * zend_throw_exception_ex(zend_class_entry *exception_ce, long code TSRMLS_DC, const char *format, ...) /* {{{ */
{
va_list arg;
char *message;
@@ -775,7 +775,7 @@ ZEND_API zval * zend_throw_exception_ex(zend_class_entry *exception_ce, long cod
}
/* }}} */
-ZEND_API zval * zend_throw_error_exception(zend_class_entry *exception_ce, char *message, long code, int severity TSRMLS_DC) /* {{{ */
+ZEND_API zval * zend_throw_error_exception(zend_class_entry *exception_ce, const char *message, long code, int severity TSRMLS_DC) /* {{{ */
{
zval *ex = zend_throw_exception(exception_ce, message, code TSRMLS_CC);
zend_update_property_long(default_exception_ce, ex, "severity", sizeof("severity")-1, severity TSRMLS_CC);
diff --git a/Zend/zend_exceptions.h b/Zend/zend_exceptions.h
index ff73a22417..2ce9c1295c 100644
--- a/Zend/zend_exceptions.h
+++ b/Zend/zend_exceptions.h
@@ -40,12 +40,12 @@ ZEND_API void zend_register_default_classes(TSRMLS_D);
/* exception_ce NULL or zend_exception_get_default() or a derived class
* message NULL or the message of the exception */
-ZEND_API zval * zend_throw_exception(zend_class_entry *exception_ce, char *message, long code TSRMLS_DC);
-ZEND_API zval * zend_throw_exception_ex(zend_class_entry *exception_ce, long code TSRMLS_DC, char *format, ...);
+ZEND_API zval * zend_throw_exception(zend_class_entry *exception_ce, const char *message, long code TSRMLS_DC);
+ZEND_API zval * zend_throw_exception_ex(zend_class_entry *exception_ce, long code TSRMLS_DC, const char *format, ...);
ZEND_API void zend_throw_exception_object(zval *exception TSRMLS_DC);
ZEND_API void zend_clear_exception(TSRMLS_D);
-ZEND_API zval * zend_throw_error_exception(zend_class_entry *exception_ce, char *message, long code, int severity TSRMLS_DC);
+ZEND_API zval * zend_throw_error_exception(zend_class_entry *exception_ce, const char *message, long code, int severity TSRMLS_DC);
extern ZEND_API void (*zend_throw_exception_hook)(zval *ex TSRMLS_DC);
@@ -53,7 +53,7 @@ extern ZEND_API void (*zend_throw_exception_hook)(zval *ex TSRMLS_DC);
ZEND_API void zend_exception_error(zval *exception, int severity TSRMLS_DC);
/* do not export, in php it's available thru spprintf directly */
-int zend_spprintf(char **message, int max_len, char *format, ...);
+int zend_spprintf(char **message, int max_len, const char *format, ...);
END_EXTERN_C()
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index a329a65202..1df0cb5514 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -35,6 +35,7 @@
#include "zend_exceptions.h"
#include "zend_interfaces.h"
#include "zend_closures.h"
+#include "zend_generators.h"
#include "zend_vm.h"
#include "zend_dtrace.h"
@@ -49,10 +50,10 @@
typedef int (*incdec_t)(zval *);
-#define get_zval_ptr(op_type, node, Ts, should_free, type) _get_zval_ptr(op_type, node, Ts, should_free, type TSRMLS_CC)
-#define get_zval_ptr_ptr(op_type, node, Ts, should_free, type) _get_zval_ptr_ptr(op_type, node, Ts, should_free, type TSRMLS_CC)
-#define get_obj_zval_ptr(op_type, node, Ts, should_free, type) _get_obj_zval_ptr(op_type, node, Ts, should_free, type TSRMLS_CC)
-#define get_obj_zval_ptr_ptr(op_type, node, Ts, should_free, type) _get_obj_zval_ptr_ptr(op_type, node, Ts, should_free, type TSRMLS_CC)
+#define get_zval_ptr(op_type, node, ex, should_free, type) _get_zval_ptr(op_type, node, ex, should_free, type TSRMLS_CC)
+#define get_zval_ptr_ptr(op_type, node, ex, should_free, type) _get_zval_ptr_ptr(op_type, node, ex, should_free, type TSRMLS_CC)
+#define get_obj_zval_ptr(op_type, node, ex, should_free, type) _get_obj_zval_ptr(op_type, node, ex, should_free, type TSRMLS_CC)
+#define get_obj_zval_ptr_ptr(op_type, node, ex, should_free, type) _get_obj_zval_ptr_ptr(op_type, node, ex, should_free, type TSRMLS_CC)
/* Prototypes */
static void zend_extension_statement_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC);
@@ -61,8 +62,8 @@ static void zend_extension_fcall_end_handler(const zend_extension *extension, ze
#define RETURN_VALUE_USED(opline) (!((opline)->result_type & EXT_TYPE_UNUSED))
-#define T(offset) (*(temp_variable *)((char *) Ts + offset))
-#define CV(var) CVs[var]
+#define EX_T(offset) (*EX_TMP_VAR(execute_data, offset))
+#define EX_CV(var) (*EX_CV_NUM(execute_data, var))
#define TEMP_VAR_STACK_LIMIT 2000
@@ -85,11 +86,10 @@ static zend_always_inline void zend_pzval_unlock_func(zval *z, zend_free_op *sho
static zend_always_inline void zend_pzval_unlock_free_func(zval *z TSRMLS_DC)
{
if (!Z_DELREF_P(z)) {
- if (z != &EG(uninitialized_zval)) {
- GC_REMOVE_ZVAL_FROM_BUFFER(z);
- zval_dtor(z);
- efree(z);
- }
+ ZEND_ASSERT(z != &EG(uninitialized_zval));
+ GC_REMOVE_ZVAL_FROM_BUFFER(z);
+ zval_dtor(z);
+ efree(z);
}
}
@@ -153,7 +153,6 @@ static zend_always_inline void zend_pzval_unlock_free_func(zval *z TSRMLS_DC)
/* End of zend_execute_locks.h */
-#define CV_OF(i) (EG(current_execute_data)->CVs[i])
#define CV_DEF_OF(i) (EG(active_op_array)->vars[i])
#define CTOR_CALL_BIT 0x1
@@ -167,19 +166,22 @@ static zend_always_inline void zend_pzval_unlock_free_func(zval *z TSRMLS_DC)
#define DECODE_CTOR(ce) \
((zend_class_entry*)(((zend_uintptr_t)(ce)) & ~(CTOR_CALL_BIT|CTOR_USED_BIT)))
-ZEND_API zval** zend_get_compiled_variable_value(const zend_execute_data *execute_data_ptr, zend_uint var)
+#undef EX
+#define EX(element) execute_data->element
+
+ZEND_API zval** zend_get_compiled_variable_value(const zend_execute_data *execute_data, zend_uint var)
{
- return execute_data_ptr->CVs[var];
+ return EX_CV(var);
}
-static zend_always_inline zval *_get_zval_ptr_tmp(zend_uint var, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC)
+static zend_always_inline zval *_get_zval_ptr_tmp(zend_uint var, const zend_execute_data *execute_data, zend_free_op *should_free TSRMLS_DC)
{
- return should_free->var = &T(var).tmp_var;
+ return should_free->var = &EX_T(var).tmp_var;
}
-static zend_always_inline zval *_get_zval_ptr_var(zend_uint var, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC)
+static zend_always_inline zval *_get_zval_ptr_var(zend_uint var, const zend_execute_data *execute_data, zend_free_op *should_free TSRMLS_DC)
{
- zval *ptr = T(var).var.ptr;
+ zval *ptr = EX_T(var).var.ptr;
PZVAL_UNLOCK(ptr, should_free);
return ptr;
@@ -205,7 +207,7 @@ static zend_never_inline zval **_get_zval_cv_lookup(zval ***ptr, zend_uint var,
case BP_VAR_W:
Z_ADDREF(EG(uninitialized_zval));
if (!EG(active_symbol_table)) {
- *ptr = (zval**)EG(current_execute_data)->CVs + (EG(active_op_array)->last_var + var);
+ *ptr = (zval**)EX_CV_NUM(EG(current_execute_data), EG(active_op_array)->last_var + var);
**ptr = &EG(uninitialized_zval);
} else {
zend_hash_quick_update(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, &EG(uninitialized_zval_ptr), sizeof(zval *), (void **)ptr);
@@ -257,7 +259,7 @@ static zend_never_inline zval **_get_zval_cv_lookup_BP_VAR_RW(zval ***ptr, zend_
if (!EG(active_symbol_table)) {
Z_ADDREF(EG(uninitialized_zval));
- *ptr = (zval**)EG(current_execute_data)->CVs + (EG(active_op_array)->last_var + var);
+ *ptr = (zval**)EX_CV_NUM(EG(current_execute_data), EG(active_op_array)->last_var + var);
**ptr = &EG(uninitialized_zval);
zend_error(E_NOTICE, "Undefined variable: %s", cv->name);
} else if (zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
@@ -274,7 +276,7 @@ static zend_never_inline zval **_get_zval_cv_lookup_BP_VAR_W(zval ***ptr, zend_u
if (!EG(active_symbol_table)) {
Z_ADDREF(EG(uninitialized_zval));
- *ptr = (zval**)EG(current_execute_data)->CVs + (EG(active_op_array)->last_var + var);
+ *ptr = (zval**)EX_CV_NUM(EG(current_execute_data), EG(active_op_array)->last_var + var);
**ptr = &EG(uninitialized_zval);
} else if (zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
Z_ADDREF(EG(uninitialized_zval));
@@ -285,7 +287,7 @@ static zend_never_inline zval **_get_zval_cv_lookup_BP_VAR_W(zval ***ptr, zend_u
static zend_always_inline zval *_get_zval_ptr_cv(zend_uint var, int type TSRMLS_DC)
{
- zval ***ptr = &CV_OF(var);
+ zval ***ptr = EX_CV_NUM(EG(current_execute_data), var);
if (UNEXPECTED(*ptr == NULL)) {
return *_get_zval_cv_lookup(ptr, var, type TSRMLS_CC);
@@ -293,9 +295,9 @@ static zend_always_inline zval *_get_zval_ptr_cv(zend_uint var, int type TSRMLS_
return **ptr;
}
-static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_R(zval ***CVs, zend_uint var TSRMLS_DC)
+static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_R(const zend_execute_data *execute_data, zend_uint var TSRMLS_DC)
{
- zval ***ptr = &CV(var);
+ zval ***ptr = EX_CV_NUM(execute_data, var);
if (UNEXPECTED(*ptr == NULL)) {
return *_get_zval_cv_lookup_BP_VAR_R(ptr, var TSRMLS_CC);
@@ -303,9 +305,9 @@ static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_R(zval ***CVs, zend_uint
return **ptr;
}
-static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_UNSET(zval ***CVs, zend_uint var TSRMLS_DC)
+static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_UNSET(const zend_execute_data *execute_data, zend_uint var TSRMLS_DC)
{
- zval ***ptr = &CV(var);
+ zval ***ptr = EX_CV_NUM(execute_data, var);
if (UNEXPECTED(*ptr == NULL)) {
return *_get_zval_cv_lookup_BP_VAR_UNSET(ptr, var TSRMLS_CC);
@@ -313,9 +315,9 @@ static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_UNSET(zval ***CVs, zend_
return **ptr;
}
-static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_IS(zval ***CVs, zend_uint var TSRMLS_DC)
+static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_IS(const zend_execute_data *execute_data, zend_uint var TSRMLS_DC)
{
- zval ***ptr = &CV(var);
+ zval ***ptr = EX_CV_NUM(execute_data, var);
if (UNEXPECTED(*ptr == NULL)) {
return *_get_zval_cv_lookup_BP_VAR_IS(ptr, var TSRMLS_CC);
@@ -323,9 +325,9 @@ static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_IS(zval ***CVs, zend_uin
return **ptr;
}
-static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_RW(zval ***CVs, zend_uint var TSRMLS_DC)
+static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_RW(const zend_execute_data *execute_data, zend_uint var TSRMLS_DC)
{
- zval ***ptr = &CV(var);
+ zval ***ptr = EX_CV_NUM(execute_data, var);
if (UNEXPECTED(*ptr == NULL)) {
return *_get_zval_cv_lookup_BP_VAR_RW(ptr, var TSRMLS_CC);
@@ -333,9 +335,9 @@ static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_RW(zval ***CVs, zend_uin
return **ptr;
}
-static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_W(zval ***CVs, zend_uint var TSRMLS_DC)
+static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_W(const zend_execute_data *execute_data, zend_uint var TSRMLS_DC)
{
- zval ***ptr = &CV(var);
+ zval ***ptr = EX_CV_NUM(execute_data, var);
if (UNEXPECTED(*ptr == NULL)) {
return *_get_zval_cv_lookup_BP_VAR_W(ptr, var TSRMLS_CC);
@@ -343,7 +345,7 @@ static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_W(zval ***CVs, zend_uint
return **ptr;
}
-static inline zval *_get_zval_ptr(int op_type, const znode_op *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC)
+static inline zval *_get_zval_ptr(int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type TSRMLS_DC)
{
/* should_free->is_var = 0; */
switch (op_type) {
@@ -352,11 +354,11 @@ static inline zval *_get_zval_ptr(int op_type, const znode_op *node, const temp_
return node->zv;
break;
case IS_TMP_VAR:
- should_free->var = TMP_FREE(&T(node->var).tmp_var);
- return &T(node->var).tmp_var;
+ should_free->var = TMP_FREE(&EX_T(node->var).tmp_var);
+ return &EX_T(node->var).tmp_var;
break;
case IS_VAR:
- return _get_zval_ptr_var(node->var, Ts, should_free TSRMLS_CC);
+ return _get_zval_ptr_var(node->var, execute_data, should_free TSRMLS_CC);
break;
case IS_UNUSED:
should_free->var = 0;
@@ -371,22 +373,22 @@ static inline zval *_get_zval_ptr(int op_type, const znode_op *node, const temp_
return NULL;
}
-static zend_always_inline zval **_get_zval_ptr_ptr_var(zend_uint var, const temp_variable *Ts, zend_free_op *should_free TSRMLS_DC)
+static zend_always_inline zval **_get_zval_ptr_ptr_var(zend_uint var, const zend_execute_data *execute_data, zend_free_op *should_free TSRMLS_DC)
{
- zval** ptr_ptr = T(var).var.ptr_ptr;
+ zval** ptr_ptr = EX_T(var).var.ptr_ptr;
if (EXPECTED(ptr_ptr != NULL)) {
PZVAL_UNLOCK(*ptr_ptr, should_free);
} else {
/* string offset */
- PZVAL_UNLOCK(T(var).str_offset.str, should_free);
+ PZVAL_UNLOCK(EX_T(var).str_offset.str, should_free);
}
return ptr_ptr;
}
static zend_always_inline zval **_get_zval_ptr_ptr_cv(zend_uint var, int type TSRMLS_DC)
{
- zval ***ptr = &CV_OF(var);
+ zval ***ptr = EX_CV_NUM(EG(current_execute_data), var);
if (UNEXPECTED(*ptr == NULL)) {
return _get_zval_cv_lookup(ptr, var, type TSRMLS_CC);
@@ -394,9 +396,9 @@ static zend_always_inline zval **_get_zval_ptr_ptr_cv(zend_uint var, int type TS
return *ptr;
}
-static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_R(zval ***CVs, zend_uint var TSRMLS_DC)
+static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_R(const zend_execute_data *execute_data, zend_uint var TSRMLS_DC)
{
- zval ***ptr = &CV(var);
+ zval ***ptr = EX_CV_NUM(execute_data, var);
if (UNEXPECTED(*ptr == NULL)) {
return _get_zval_cv_lookup_BP_VAR_R(ptr, var TSRMLS_CC);
@@ -404,9 +406,9 @@ static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_R(zval ***CVs, zend
return *ptr;
}
-static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_UNSET(zval ***CVs, zend_uint var TSRMLS_DC)
+static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_UNSET(const zend_execute_data *execute_data, zend_uint var TSRMLS_DC)
{
- zval ***ptr = &CV(var);
+ zval ***ptr = EX_CV_NUM(execute_data, var);
if (UNEXPECTED(*ptr == NULL)) {
return _get_zval_cv_lookup_BP_VAR_UNSET(ptr, var TSRMLS_CC);
@@ -414,9 +416,9 @@ static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_UNSET(zval ***CVs,
return *ptr;
}
-static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_IS(zval ***CVs, zend_uint var TSRMLS_DC)
+static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_IS(const zend_execute_data *execute_data, zend_uint var TSRMLS_DC)
{
- zval ***ptr = &CV(var);
+ zval ***ptr = EX_CV_NUM(execute_data, var);
if (UNEXPECTED(*ptr == NULL)) {
return _get_zval_cv_lookup_BP_VAR_IS(ptr, var TSRMLS_CC);
@@ -424,9 +426,9 @@ static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_IS(zval ***CVs, zen
return *ptr;
}
-static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_RW(zval ***CVs, zend_uint var TSRMLS_DC)
+static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_RW(const zend_execute_data *execute_data, zend_uint var TSRMLS_DC)
{
- zval ***ptr = &CV(var);
+ zval ***ptr = EX_CV_NUM(execute_data, var);
if (UNEXPECTED(*ptr == NULL)) {
return _get_zval_cv_lookup_BP_VAR_RW(ptr, var TSRMLS_CC);
@@ -434,9 +436,9 @@ static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_RW(zval ***CVs, zen
return *ptr;
}
-static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_W(zval ***CVs, zend_uint var TSRMLS_DC)
+static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_W(const zend_execute_data *execute_data, zend_uint var TSRMLS_DC)
{
- zval ***ptr = &CV(var);
+ zval ***ptr = EX_CV_NUM(execute_data, var);
if (UNEXPECTED(*ptr == NULL)) {
return _get_zval_cv_lookup_BP_VAR_W(ptr, var TSRMLS_CC);
@@ -444,13 +446,13 @@ static zend_always_inline zval **_get_zval_ptr_ptr_cv_BP_VAR_W(zval ***CVs, zend
return *ptr;
}
-static inline zval **_get_zval_ptr_ptr(int op_type, const znode_op *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC)
+static inline zval **_get_zval_ptr_ptr(int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type TSRMLS_DC)
{
if (op_type == IS_CV) {
should_free->var = 0;
return _get_zval_ptr_ptr_cv(node->var, type TSRMLS_CC);
} else if (op_type == IS_VAR) {
- return _get_zval_ptr_ptr_var(node->var, Ts, should_free TSRMLS_CC);
+ return _get_zval_ptr_ptr_var(node->var, execute_data, should_free TSRMLS_CC);
} else {
should_free->var = 0;
return NULL;
@@ -467,7 +469,7 @@ static zend_always_inline zval *_get_obj_zval_ptr_unused(TSRMLS_D)
}
}
-static inline zval **_get_obj_zval_ptr_ptr(int op_type, const znode_op *op, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC)
+static inline zval **_get_obj_zval_ptr_ptr(int op_type, const znode_op *op, const zend_execute_data *execute_data, zend_free_op *should_free, int type TSRMLS_DC)
{
if (op_type == IS_UNUSED) {
if (EXPECTED(EG(This) != NULL)) {
@@ -479,7 +481,7 @@ static inline zval **_get_obj_zval_ptr_ptr(int op_type, const znode_op *op, cons
zend_error_noreturn(E_ERROR, "Using $this when not in object context");
}
}
- return get_zval_ptr_ptr(op_type, op, Ts, should_free, type);
+ return get_zval_ptr_ptr(op_type, op, execute_data, should_free, type);
}
static zend_always_inline zval **_get_obj_zval_ptr_ptr_unused(TSRMLS_D)
@@ -492,7 +494,7 @@ static zend_always_inline zval **_get_obj_zval_ptr_ptr_unused(TSRMLS_D)
}
}
-static inline zval *_get_obj_zval_ptr(int op_type, znode_op *op, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC)
+static inline zval *_get_obj_zval_ptr(int op_type, znode_op *op, const zend_execute_data *execute_data, zend_free_op *should_free, int type TSRMLS_DC)
{
if (op_type == IS_UNUSED) {
if (EXPECTED(EG(This) != NULL)) {
@@ -502,7 +504,7 @@ static inline zval *_get_obj_zval_ptr(int op_type, znode_op *op, const temp_vari
zend_error_noreturn(E_ERROR, "Using $this when not in object context");
}
}
- return get_zval_ptr(op_type, op, Ts, should_free, type);
+ return get_zval_ptr(op_type, op, execute_data, should_free, type);
}
static void zend_assign_to_variable_reference(zval **variable_ptr_ptr, zval **value_ptr_ptr TSRMLS_DC)
@@ -653,11 +655,11 @@ static inline int zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zva
return 1;
}
-static inline void zend_assign_to_object(zval **retval, zval **object_ptr, zval *property_name, int value_type, znode_op *value_op, const temp_variable *Ts, int opcode, const zend_literal *key TSRMLS_DC)
+static inline void zend_assign_to_object(zval **retval, zval **object_ptr, zval *property_name, int value_type, znode_op *value_op, const zend_execute_data *execute_data, int opcode, const zend_literal *key TSRMLS_DC)
{
zval *object = *object_ptr;
zend_free_op free_value;
- zval *value = get_zval_ptr(value_type, value_op, Ts, &free_value, BP_VAR_R);
+ zval *value = get_zval_ptr(value_type, value_op, execute_data, &free_value, BP_VAR_R);
if (Z_TYPE_P(object) != IS_OBJECT) {
if (object == &EG(error_zval)) {
@@ -896,13 +898,10 @@ static inline zval* zend_assign_to_variable(zval **variable_ptr_ptr, zval *value
} else if (EXPECTED(!PZVAL_IS_REF(value))) {
Z_ADDREF_P(value);
*variable_ptr_ptr = value;
- if (EXPECTED(variable_ptr != &EG(uninitialized_zval))) {
- GC_REMOVE_ZVAL_FROM_BUFFER(variable_ptr);
- zval_dtor(variable_ptr);
- efree(variable_ptr);
- } else {
- Z_DELREF_P(variable_ptr);
- }
+ ZEND_ASSERT(variable_ptr != &EG(uninitialized_zval));
+ GC_REMOVE_ZVAL_FROM_BUFFER(variable_ptr);
+ zval_dtor(variable_ptr);
+ efree(variable_ptr);
return value;
} else {
goto copy_value;
@@ -1382,7 +1381,7 @@ static void zend_fetch_property_address(temp_variable *result, zval **container_
}
if (Z_OBJ_HT_P(container)->get_property_ptr_ptr) {
- zval **ptr_ptr = Z_OBJ_HT_P(container)->get_property_ptr_ptr(container, prop_ptr, key TSRMLS_CC);
+ zval **ptr_ptr = Z_OBJ_HT_P(container)->get_property_ptr_ptr(container, prop_ptr, type, key TSRMLS_CC);
if (NULL == ptr_ptr) {
zval *ptr;
@@ -1409,7 +1408,7 @@ static void zend_fetch_property_address(temp_variable *result, zval **container_
}
}
-static inline zend_brk_cont_element* zend_brk_cont(int nest_levels, int array_offset, const zend_op_array *op_array, const temp_variable *Ts TSRMLS_DC)
+static inline zend_brk_cont_element* zend_brk_cont(int nest_levels, int array_offset, const zend_op_array *op_array, const zend_execute_data *execute_data TSRMLS_DC)
{
int original_nest_levels = nest_levels;
zend_brk_cont_element *jmp_to;
@@ -1425,12 +1424,12 @@ static inline zend_brk_cont_element* zend_brk_cont(int nest_levels, int array_of
switch (brk_opline->opcode) {
case ZEND_SWITCH_FREE:
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
- zval_ptr_dtor(&T(brk_opline->op1.var).var.ptr);
+ zval_ptr_dtor(&EX_T(brk_opline->op1.var).var.ptr);
}
break;
case ZEND_FREE:
if (!(brk_opline->extended_value & EXT_TYPE_FREE_ON_RETURN)) {
- zendi_zval_dtor(T(brk_opline->op1.var).tmp_var);
+ zendi_zval_dtor(EX_T(brk_opline->op1.var).tmp_var);
}
break;
}
@@ -1474,11 +1473,212 @@ static int zend_check_symbol(zval **pz TSRMLS_DC)
ZEND_API opcode_handler_t *zend_opcode_handlers;
-ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC)
+ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, zend_fcall_info *fci, int return_value_used TSRMLS_DC)
+{
+ if(fci != NULL) {
+ ((zend_internal_function *) execute_data_ptr->function_state.function)->handler(fci->param_count,
+ *fci->retval_ptr_ptr, fci->retval_ptr_ptr, fci->object_ptr, 1 TSRMLS_CC);
+
+ } else {
+ zval **return_value_ptr = &EX_TMP_VAR(execute_data_ptr, execute_data_ptr->opline->result.var)->var.ptr;
+ ((zend_internal_function *) execute_data_ptr->function_state.function)->handler(execute_data_ptr->opline->extended_value, *return_value_ptr,
+ (execute_data_ptr->function_state.function->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)?return_value_ptr:NULL,
+ execute_data_ptr->object, return_value_used TSRMLS_CC);
+ }
+}
+
+void zend_clean_and_cache_symbol_table(HashTable *symbol_table TSRMLS_DC) /* {{{ */
+{
+ if (EG(symtable_cache_ptr) >= EG(symtable_cache_limit)) {
+ zend_hash_destroy(symbol_table);
+ FREE_HASHTABLE(symbol_table);
+ } else {
+ /* clean before putting into the cache, since clean
+ could call dtors, which could use cached hash */
+ zend_hash_clean(symbol_table);
+ *(++EG(symtable_cache_ptr)) = symbol_table;
+ }
+}
+/* }}} */
+
+static zend_always_inline void i_free_compiled_variables(zend_execute_data *execute_data) /* {{{ */
+{
+ zval ***cv = EX_CV_NUM(execute_data, 0);
+ zval ***end = cv + EX(op_array)->last_var;
+ while (cv != end) {
+ if (*cv) {
+ zval_ptr_dtor(*cv);
+ }
+ cv++;
+ }
+}
+/* }}} */
+
+void zend_free_compiled_variables(zend_execute_data *execute_data) /* {{{ */
+{
+ i_free_compiled_variables(execute_data);
+}
+/* }}} */
+
+/*
+ * Stack Frame Layout (the whole stack frame is allocated at once)
+ * ==================
+ *
+ * +========================================+
+ * | zend_execute_data |<---+
+ * | EX(function_state).arguments |--+ |
+ * | ... | | |
+ * | ARGUMENT [1] | | |
+ * | ... | | |
+ * | ARGUMENT [ARGS_NUMBER] | | |
+ * | ARGS_NUMBER |<-+ |
+ * +========================================+ |
+ * |
+ * +========================================+ |
+ * | TMP_VAR[op_arrat->T-1] | |
+ * | ... | |
+ * EX_TMP_VAR_NUM(0) ----> | TMP_VAR[0] | |
+ * +----------------------------------------+ |
+ * EG(current_execute_data) -> | zend_execute_data | |
+ * | EX(prev_execute_data) |----+
+ * +----------------------------------------+
+ * EX_CV_NUM(0) ---------> | CV[0] |--+
+ * | ... | |
+ * | CV[op_array->last_var-1] | |
+ * +----------------------------------------+ |
+ * | Optional slot for CV[0] zval* |<-+
+ * | ... |
+ * | ...for CV [op_array->last_var-1] zval* |
+ * +----------------------------------------+
+ * EX(call_slots) -> | CALL_SLOT[0] |
+ * | ... |
+ * | CALL_SLOT[op_array->nested_calls-1] |
+ * +----------------------------------------+
+ * zend_vm_stack_frame_base -> | ARGUMENTS STACK [0] |
+ * | ... |
+ * zend_vm_stack_top --------> | ... |
+ * | ... |
+ * | ARGUMENTS STACK [op_array->used_stack] |
+ * +----------------------------------------+
+ */
+
+static zend_always_inline zend_execute_data *i_create_execute_data_from_op_array(zend_op_array *op_array, zend_bool nested TSRMLS_DC) /* {{{ */
+{
+ zend_execute_data *execute_data;
+
+ /*
+ * When allocating the execute_data, memory for compiled variables and
+ * temporary variables is also allocated before and after the actual
+ * zend_execute_data struct. In addition we also allocate space to store
+ * information about syntactically nested called functions and actual
+ * parameters. op_array->last_var specifies the number of compiled
+ * variables and op_array->T is the number of temporary variables. If there
+ * is no symbol table, then twice as much memory is allocated for compiled
+ * variables. In that case the first half contains zval**s and the second
+ * half the actual zval*s (which would otherwise be in the symbol table).
+ */
+ size_t execute_data_size = ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data));
+ size_t CVs_size = ZEND_MM_ALIGNED_SIZE(sizeof(zval **) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2));
+ size_t Ts_size = ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * op_array->T;
+ size_t call_slots_size = ZEND_MM_ALIGNED_SIZE(sizeof(call_slot)) * op_array->nested_calls;
+ size_t stack_size = ZEND_MM_ALIGNED_SIZE(sizeof(zval*)) * op_array->used_stack;
+ size_t total_size = execute_data_size + Ts_size + CVs_size + call_slots_size + stack_size;
+
+ /*
+ * Normally the execute_data is allocated on the VM stack (because it does
+ * not actually do any allocation and thus is faster). For generators
+ * though this behavior would be suboptimal, because the (rather large)
+ * structure would have to be copied back and forth every time execution is
+ * suspended or resumed. That's why for generators the execution context
+ * is allocated using a separate VM stack, thus allowing to save and
+ * restore it simply by replacing a pointer. The same segment also keeps
+ * a copy of previous execute_data and passed parameters.
+ */
+ if (UNEXPECTED((op_array->fn_flags & ZEND_ACC_GENERATOR) != 0)) {
+ /* Prepend the regular stack frame with a copy of prev_execute_data
+ * and the passed arguments
+ */
+ int args_count = zend_vm_stack_get_args_count_ex(EG(current_execute_data));
+ size_t args_size = ZEND_MM_ALIGNED_SIZE(sizeof(zval*)) * (args_count + 1);
+
+ total_size += args_size + execute_data_size;
+
+ EG(argument_stack) = zend_vm_stack_new_page((total_size + (sizeof(void*) - 1)) / sizeof(void*));
+ EG(argument_stack)->prev = NULL;
+ execute_data = (zend_execute_data*)((char*)ZEND_VM_STACK_ELEMETS(EG(argument_stack)) + args_size + execute_data_size + Ts_size);
+
+ /* copy prev_execute_data */
+ EX(prev_execute_data) = (zend_execute_data*)((char*)ZEND_VM_STACK_ELEMETS(EG(argument_stack)) + args_size);
+ memset(EX(prev_execute_data), 0, sizeof(zend_execute_data));
+ EX(prev_execute_data)->function_state.function = (zend_function*)op_array;
+ EX(prev_execute_data)->function_state.arguments = (void**)((char*)ZEND_VM_STACK_ELEMETS(EG(argument_stack)) + ZEND_MM_ALIGNED_SIZE(sizeof(zval*)) * args_count);
+
+ /* copy arguments */
+ *EX(prev_execute_data)->function_state.arguments = (void*)(zend_uintptr_t)args_count;
+ if (args_count > 0) {
+ zval **arg_src = (zval**)zend_vm_stack_get_arg_ex(EG(current_execute_data), 1);
+ zval **arg_dst = (zval**)zend_vm_stack_get_arg_ex(EX(prev_execute_data), 1);
+ int i;
+
+ for (i = 0; i < args_count; i++) {
+ arg_dst[i] = arg_src[i];
+ Z_ADDREF_P(arg_dst[i]);
+ }
+ }
+ } else {
+ execute_data = zend_vm_stack_alloc(total_size TSRMLS_CC);
+ execute_data = (zend_execute_data*)((char*)execute_data + Ts_size);
+ EX(prev_execute_data) = EG(current_execute_data);
+ }
+
+ memset(EX_CV_NUM(execute_data, 0), 0, sizeof(zval **) * op_array->last_var);
+
+ EX(call_slots) = (call_slot*)((char *)execute_data + execute_data_size + CVs_size);
+
+
+ EX(op_array) = op_array;
+
+ EG(argument_stack)->top = zend_vm_stack_frame_base(execute_data);
+
+ EX(object) = NULL;
+ EX(current_this) = NULL;
+ EX(old_error_reporting) = NULL;
+ EX(symbol_table) = EG(active_symbol_table);
+ EX(call) = NULL;
+ EG(current_execute_data) = execute_data;
+ EX(nested) = nested;
+
+ if (!op_array->run_time_cache && op_array->last_cache_slot) {
+ op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*));
+ }
+
+ if (op_array->this_var != -1 && EG(This)) {
+ Z_ADDREF_P(EG(This)); /* For $this pointer */
+ if (!EG(active_symbol_table)) {
+ EX_CV(op_array->this_var) = (zval **) EX_CV_NUM(execute_data, op_array->last_var + op_array->this_var);
+ *EX_CV(op_array->this_var) = EG(This);
+ } else {
+ if (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), (void **) EX_CV_NUM(execute_data, op_array->this_var))==FAILURE) {
+ Z_DELREF_P(EG(This));
+ }
+ }
+ }
+
+ EX(opline) = UNEXPECTED((op_array->fn_flags & ZEND_ACC_INTERACTIVE) != 0) && EG(start_op) ? EG(start_op) : op_array->opcodes;
+ EG(opline_ptr) = &EX(opline);
+
+ EX(function_state).function = (zend_function *) op_array;
+ EX(function_state).arguments = NULL;
+
+ return execute_data;
+}
+/* }}} */
+
+zend_execute_data *zend_create_execute_data_from_op_array(zend_op_array *op_array, zend_bool nested TSRMLS_DC) /* {{{ */
{
- zval **return_value_ptr = &(*(temp_variable *)((char *) execute_data_ptr->Ts + execute_data_ptr->opline->result.var)).var.ptr;
- ((zend_internal_function *) execute_data_ptr->function_state.function)->handler(execute_data_ptr->opline->extended_value, *return_value_ptr, (execute_data_ptr->function_state.function->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)?return_value_ptr:NULL, execute_data_ptr->object, return_value_used TSRMLS_CC);
+ return i_create_execute_data_from_op_array(op_array, nested TSRMLS_CC);
}
+/* }}} */
#define ZEND_VM_NEXT_OPCODE() \
CHECK_SYMBOL_TABLES() \
@@ -1512,7 +1712,7 @@ ZEND_API int zend_set_user_opcode_handler(zend_uchar opcode, user_opcode_handler
{
if (opcode != ZEND_USER_OPCODE) {
if (handler == NULL) {
- /* restore the original handler */
+ /* restore the original handler */
zend_user_opcodes[opcode] = opcode;
} else {
zend_user_opcodes[opcode] = ZEND_USER_OPCODE;
@@ -1528,12 +1728,12 @@ ZEND_API user_opcode_handler_t zend_get_user_opcode_handler(zend_uchar opcode)
return zend_user_opcode_handlers[opcode];
}
-ZEND_API zval *zend_get_zval_ptr(int op_type, const znode_op *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC) {
- return get_zval_ptr(op_type, node, Ts, should_free, type);
+ZEND_API zval *zend_get_zval_ptr(int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type TSRMLS_DC) {
+ return get_zval_ptr(op_type, node, execute_data, should_free, type);
}
-ZEND_API zval **zend_get_zval_ptr_ptr(int op_type, const znode_op *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC) {
- return get_zval_ptr_ptr(op_type, node, Ts, should_free, type);
+ZEND_API zval **zend_get_zval_ptr_ptr(int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type TSRMLS_DC) {
+ return get_zval_ptr_ptr(op_type, node, execute_data, should_free, type);
}
/*
diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h
index b74fd9614d..ea06328d93 100644
--- a/Zend/zend_execute.h
+++ b/Zend/zend_execute.h
@@ -5,7 +5,7 @@
| Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 2.00 of the Zend license, |
- | that is bundled with this package in the file LICENSE, and is |
+ | that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.zend.com/license/2_00.txt. |
| If you did not receive a copy of the Zend license and are unable to |
@@ -49,24 +49,18 @@ typedef union _temp_variable {
BEGIN_EXTERN_C()
-ZEND_API extern void (*zend_execute)(zend_op_array *op_array TSRMLS_DC);
-ZEND_API extern void (*zend_execute_internal)(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC);
+struct _zend_fcall_info;
+ZEND_API extern void (*zend_execute_ex)(zend_execute_data *execute_data TSRMLS_DC);
+ZEND_API extern void (*zend_execute_internal)(zend_execute_data *execute_data_ptr, struct _zend_fcall_info *fci, int return_value_used TSRMLS_DC);
void init_executor(TSRMLS_D);
void shutdown_executor(TSRMLS_D);
void shutdown_destructors(TSRMLS_D);
-ZEND_API void execute(zend_op_array *op_array TSRMLS_DC);
-ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC);
+zend_execute_data *zend_create_execute_data_from_op_array(zend_op_array *op_array, zend_bool nested TSRMLS_DC);
+ZEND_API void zend_execute(zend_op_array *op_array TSRMLS_DC);
+ZEND_API void execute_ex(zend_execute_data *execute_data TSRMLS_DC);
+ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, struct _zend_fcall_info *fci, int return_value_used TSRMLS_DC);
ZEND_API int zend_is_true(zval *op);
-#define safe_free_zval_ptr(p) safe_free_zval_ptr_rel(p ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC)
-static zend_always_inline void safe_free_zval_ptr_rel(zval *p ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC)
-{
- TSRMLS_FETCH();
-
- if (p!=EG(uninitialized_zval_ptr)) {
- FREE_ZVAL_REL(p);
- }
-}
ZEND_API int zend_lookup_class(const char *name, int name_length, zend_class_entry ***ce TSRMLS_DC);
ZEND_API int zend_lookup_class_ex(const char *name, int name_length, const zend_literal *key, int use_autoload, zend_class_entry ***ce TSRMLS_DC);
ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC);
@@ -82,11 +76,10 @@ static zend_always_inline void i_zval_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC)
if (!Z_DELREF_P(zval_ptr)) {
TSRMLS_FETCH();
- if (zval_ptr != &EG(uninitialized_zval)) {
- GC_REMOVE_ZVAL_FROM_BUFFER(zval_ptr);
- zval_dtor(zval_ptr);
- efree_rel(zval_ptr);
- }
+ ZEND_ASSERT(zval_ptr != &EG(uninitialized_zval));
+ GC_REMOVE_ZVAL_FROM_BUFFER(zval_ptr);
+ zval_dtor(zval_ptr);
+ efree_rel(zval_ptr);
} else {
TSRMLS_FETCH();
@@ -219,12 +212,6 @@ static zend_always_inline void **zend_vm_stack_top(TSRMLS_D)
static zend_always_inline void zend_vm_stack_push(void *ptr TSRMLS_DC)
{
- ZEND_VM_STACK_GROW_IF_NEEDED(1);
- *(EG(argument_stack)->top++) = ptr;
-}
-
-static zend_always_inline void zend_vm_stack_push_nocheck(void *ptr TSRMLS_DC)
-{
*(EG(argument_stack)->top++) = ptr;
}
@@ -232,11 +219,6 @@ static zend_always_inline void *zend_vm_stack_pop(TSRMLS_D)
{
void *el = *(--EG(argument_stack)->top);
- 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);
- }
return el;
}
@@ -269,8 +251,14 @@ static zend_always_inline void *zend_vm_stack_alloc(size_t size TSRMLS_DC)
return ret;
}
+static zend_always_inline void** zend_vm_stack_frame_base(zend_execute_data *ex)
+{
+ return (void**)((char*)ex->call_slots +
+ ZEND_MM_ALIGNED_SIZE(sizeof(call_slot)) * ex->op_array->nested_calls);
+}
+
static zend_always_inline void zend_vm_stack_free_int(void *ptr TSRMLS_DC)
-{
+{
if (UNEXPECTED(ZEND_VM_STACK_ELEMETS(EG(argument_stack)) == (void**)ptr)) {
zend_vm_stack p = EG(argument_stack);
@@ -282,7 +270,7 @@ static zend_always_inline void zend_vm_stack_free_int(void *ptr TSRMLS_DC)
}
static zend_always_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);
@@ -299,51 +287,36 @@ static zend_always_inline void zend_vm_stack_free(void *ptr TSRMLS_DC)
}
}
-static zend_always_inline void** zend_vm_stack_push_args(int count TSRMLS_DC)
+static zend_always_inline void zend_vm_stack_clear_multiple(int nested TSRMLS_DC)
{
+ void **p = EG(argument_stack)->top - 1;
+ void **end = p - (int)(zend_uintptr_t)*p;
- 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);
-
- zend_vm_stack_extend(count + 1 TSRMLS_CC);
-
- EG(argument_stack)->top += count;
- *(EG(argument_stack)->top) = (void*)(zend_uintptr_t)count;
- while (count-- > 0) {
- void *data = *(--p->top);
-
- 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);
- }
- *(ZEND_VM_STACK_ELEMETS(EG(argument_stack)) + count) = data;
- }
- return EG(argument_stack)->top++;
+ while (p != end) {
+ zval *q = (zval *) *(--p);
+ *p = NULL;
+ i_zval_ptr_dtor(q ZEND_FILE_LINE_CC);
+ }
+ if (nested) {
+ EG(argument_stack)->top = p;
+ } else {
+ zend_vm_stack_free_int(p TSRMLS_CC);
}
- *(EG(argument_stack)->top) = (void*)(zend_uintptr_t)count;
- return EG(argument_stack)->top++;
}
-static zend_always_inline void zend_vm_stack_clear_multiple(TSRMLS_D)
+static zend_always_inline int zend_vm_stack_get_args_count_ex(zend_execute_data *ex)
{
- void **p = EG(argument_stack)->top - 1;
- int delete_count = (int)(zend_uintptr_t) *p;
-
- while (--delete_count>=0) {
- zval *q = *(zval **)(--p);
- *p = NULL;
- i_zval_ptr_dtor(q ZEND_FILE_LINE_CC);
+ if (ex) {
+ void **p = ex->function_state.arguments;
+ return (int)(zend_uintptr_t) *p;
+ } else {
+ return 0;
}
- zend_vm_stack_free_int(p TSRMLS_CC);
}
-static zend_always_inline zval** zend_vm_stack_get_arg(int requested_arg TSRMLS_DC)
+static zend_always_inline zval** zend_vm_stack_get_arg_ex(zend_execute_data *ex, int requested_arg)
{
- void **p = EG(current_execute_data)->prev_execute_data->function_state.arguments;
+ void **p = ex->function_state.arguments;
int arg_count = (int)(zend_uintptr_t) *p;
if (UNEXPECTED(requested_arg > arg_count)) {
@@ -352,25 +325,14 @@ static zend_always_inline zval** zend_vm_stack_get_arg(int requested_arg TSRMLS_
return (zval**)p - arg_count + requested_arg - 1;
}
-static zend_always_inline void zend_arg_types_stack_2_pop(zend_ptr_stack *stack, zval **object, zend_function **fbc)
+static zend_always_inline int zend_vm_stack_get_args_count(TSRMLS_D)
{
- void *a, *b;
-
- zend_ptr_stack_2_pop(stack, &a, &b);
-
- *object = (zval *) a;
- *fbc = (zend_function *) b;
+ return zend_vm_stack_get_args_count_ex(EG(current_execute_data)->prev_execute_data);
}
-static zend_always_inline void zend_arg_types_stack_3_pop(zend_ptr_stack *stack, zend_class_entry **called_scope, zval **object, zend_function **fbc)
+static zend_always_inline zval** zend_vm_stack_get_arg(int requested_arg TSRMLS_DC)
{
- void *a, *b, *c;
-
- zend_ptr_stack_3_pop(stack, &a, &b, &c);
-
- *called_scope = (zend_class_entry *) a;
- *object = (zval *) b;
- *fbc = (zend_function *) c;
+ return zend_vm_stack_get_arg_ex(EG(current_execute_data)->prev_execute_data, requested_arg);
}
void execute_new_code(TSRMLS_D);
@@ -426,11 +388,14 @@ typedef struct _zend_free_op {
/* int is_var; */
} zend_free_op;
-ZEND_API zval *zend_get_zval_ptr(int op_type, const znode_op *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC);
-ZEND_API zval **zend_get_zval_ptr_ptr(int op_type, const znode_op *node, const temp_variable *Ts, zend_free_op *should_free, int type TSRMLS_DC);
+ZEND_API zval *zend_get_zval_ptr(int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type TSRMLS_DC);
+ZEND_API zval **zend_get_zval_ptr_ptr(int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type TSRMLS_DC);
ZEND_API int zend_do_fcall(ZEND_OPCODE_HANDLER_ARGS);
+void zend_clean_and_cache_symbol_table(HashTable *symbol_table TSRMLS_DC);
+void zend_free_compiled_variables(zend_execute_data *execute_data);
+
#define CACHED_PTR(num) \
EG(active_op_array)->run_time_cache[(num)]
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index e79abdc944..45ad5c38bf 100644
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -31,14 +31,15 @@
#include "zend_extensions.h"
#include "zend_exceptions.h"
#include "zend_closures.h"
+#include "zend_generators.h"
#include "zend_vm.h"
#include "zend_float.h"
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
-ZEND_API void (*zend_execute)(zend_op_array *op_array TSRMLS_DC);
-ZEND_API void (*zend_execute_internal)(zend_execute_data *execute_data_ptr, int return_value_used TSRMLS_DC);
+ZEND_API void (*zend_execute_ex)(zend_execute_data *execute_data TSRMLS_DC);
+ZEND_API void (*zend_execute_internal)(zend_execute_data *execute_data_ptr, zend_fcall_info *fci, int return_value_used TSRMLS_DC);
/* true globals */
ZEND_API const zend_fcall_info empty_fcall_info = { 0, NULL, NULL, NULL, NULL, 0, NULL, NULL, 0 };
@@ -136,7 +137,6 @@ void init_executor(TSRMLS_D) /* {{{ */
INIT_ZVAL(EG(error_zval));
EG(uninitialized_zval_ptr)=&EG(uninitialized_zval);
EG(error_zval_ptr)=&EG(error_zval);
- zend_ptr_stack_init(&EG(arg_types_stack));
/* destroys stack frame, therefore makes core dumps worthless */
#if 0&&ZEND_DEBUG
original_sigsegv_handler = signal(SIGSEGV, zend_handle_sigsegv);
@@ -290,10 +290,10 @@ void shutdown_executor(TSRMLS_D) /* {{{ */
} zend_end_try();
zend_try {
- zend_vm_stack_destroy(TSRMLS_C);
-
zend_objects_store_free_object_storage(&EG(objects_store) TSRMLS_CC);
+ zend_vm_stack_destroy(TSRMLS_C);
+
/* Destroy all op arrays */
if (EG(full_tables_cleanup)) {
zend_hash_reverse_apply(EG(function_table), (apply_func_t) clean_non_persistent_function_full TSRMLS_CC);
@@ -321,7 +321,6 @@ void shutdown_executor(TSRMLS_D) /* {{{ */
zend_hash_destroy(&EG(included_files));
- zend_ptr_stack_destroy(&EG(arg_types_stack));
zend_stack_destroy(&EG(user_error_handlers_error_reporting));
zend_ptr_stack_destroy(&EG(user_error_handlers));
zend_ptr_stack_destroy(&EG(user_exception_handlers));
@@ -404,7 +403,7 @@ ZEND_API const char *zend_get_executed_filename(TSRMLS_D) /* {{{ */
ZEND_API uint zend_get_executed_lineno(TSRMLS_D) /* {{{ */
{
- if(EG(exception) && EG(opline_ptr) && active_opline->opcode == ZEND_HANDLE_EXCEPTION &&
+ if(EG(exception) && EG(opline_ptr) && active_opline->opcode == ZEND_HANDLE_EXCEPTION &&
active_opline->lineno == 0 && EG(opline_before_exception)) {
return EG(opline_before_exception)->lineno;
}
@@ -424,27 +423,7 @@ ZEND_API zend_bool zend_is_executing(TSRMLS_D) /* {{{ */
ZEND_API void _zval_ptr_dtor(zval **zval_ptr ZEND_FILE_LINE_DC) /* {{{ */
{
-#if DEBUG_ZEND>=2
- printf("Reducing refcount for %x (%x): %d->%d\n", *zval_ptr, zval_ptr, Z_REFCOUNT_PP(zval_ptr), Z_REFCOUNT_PP(zval_ptr) - 1);
-#endif
- Z_DELREF_PP(zval_ptr);
- if (Z_REFCOUNT_PP(zval_ptr) == 0) {
- TSRMLS_FETCH();
-
- if (*zval_ptr != &EG(uninitialized_zval)) {
- GC_REMOVE_ZVAL_FROM_BUFFER(*zval_ptr);
- zval_dtor(*zval_ptr);
- efree_rel(*zval_ptr);
- }
- } else {
- TSRMLS_FETCH();
-
- if (Z_REFCOUNT_PP(zval_ptr) == 1) {
- Z_UNSET_ISREF_PP(zval_ptr);
- }
-
- GC_ZVAL_CHECK_POSSIBLE_ROOT(*zval_ptr);
- }
+ i_zval_ptr_dtor(*zval_ptr ZEND_FILE_LINE_RELAY_CC);
}
/* }}} */
@@ -598,7 +577,7 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco
zend_hash_init(tmp_ht, zend_hash_num_elements(Z_ARRVAL_P(p)), NULL, ZVAL_PTR_DTOR, 0);
zend_hash_copy(tmp_ht, Z_ARRVAL_P(p), (copy_ctor_func_t) zval_deep_copy, (void *) &tmp, sizeof(zval *));
Z_ARRVAL_P(p) = tmp_ht;
- }
+ }
/* First go over the array and see if there are any constant indices */
zend_hash_internal_pointer_reset(Z_ARRVAL_P(p));
@@ -859,8 +838,8 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
!ARG_MAY_BE_SENT_BY_REF(EX(function_state).function, i + 1)) {
if (i || UNEXPECTED(ZEND_VM_STACK_ELEMETS(EG(argument_stack)) == (EG(argument_stack)->top))) {
/* hack to clean up the stack */
- zend_vm_stack_push_nocheck((void *) (zend_uintptr_t)i TSRMLS_CC);
- zend_vm_stack_clear_multiple(TSRMLS_C);
+ zend_vm_stack_push((void *) (zend_uintptr_t)i TSRMLS_CC);
+ zend_vm_stack_clear_multiple(0 TSRMLS_CC);
}
zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given",
@@ -896,11 +875,11 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
*param = **(fci->params[i]);
INIT_PZVAL(param);
}
- zend_vm_stack_push_nocheck(param TSRMLS_CC);
+ zend_vm_stack_push(param TSRMLS_CC);
}
EX(function_state).arguments = zend_vm_stack_top(TSRMLS_C);
- zend_vm_stack_push_nocheck((void*)(zend_uintptr_t)fci->param_count TSRMLS_CC);
+ zend_vm_stack_push((void*)(zend_uintptr_t)fci->param_count TSRMLS_CC);
current_scope = EG(scope);
EG(scope) = calling_scope;
@@ -953,17 +932,15 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
EG(return_value_ptr_ptr) = fci->retval_ptr_ptr;
EG(active_op_array) = (zend_op_array *) EX(function_state).function;
original_opline_ptr = EG(opline_ptr);
- zend_execute(EG(active_op_array) TSRMLS_CC);
+
+ if (EG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) {
+ *fci->retval_ptr_ptr = zend_generator_create_zval(EG(active_op_array) TSRMLS_CC);
+ } else {
+ zend_execute(EG(active_op_array) TSRMLS_CC);
+ }
+
if (!fci->symbol_table && EG(active_symbol_table)) {
- if (EG(symtable_cache_ptr)>=EG(symtable_cache_limit)) {
- zend_hash_destroy(EG(active_symbol_table));
- FREE_HASHTABLE(EG(active_symbol_table));
- } else {
- /* clean before putting into the cache, since clean
- could call dtors, which could use cached hash */
- zend_hash_clean(EG(active_symbol_table));
- *(++EG(symtable_cache_ptr)) = EG(active_symbol_table);
- }
+ zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC);
}
EG(active_symbol_table) = calling_symbol_table;
EG(active_op_array) = original_op_array;
@@ -975,7 +952,12 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
if (EX(function_state).function->common.scope) {
EG(scope) = EX(function_state).function->common.scope;
}
- ((zend_internal_function *) EX(function_state).function)->handler(fci->param_count, *fci->retval_ptr_ptr, fci->retval_ptr_ptr, fci->object_ptr, 1 TSRMLS_CC);
+ if(EXPECTED(zend_execute_internal == NULL)) {
+ /* saves one function call if zend_execute_internal is not used */
+ ((zend_internal_function *) EX(function_state).function)->handler(fci->param_count, *fci->retval_ptr_ptr, fci->retval_ptr_ptr, fci->object_ptr, 1 TSRMLS_CC);
+ } else {
+ zend_execute_internal(&execute_data, fci, 1 TSRMLS_CC);
+ }
/* We shouldn't fix bad extensions here,
because it can break proper ones (Bug #34045)
if (!EX(function_state).function->common.return_reference)
@@ -1011,7 +993,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
*fci->retval_ptr_ptr = NULL;
}
}
- zend_vm_stack_clear_multiple(TSRMLS_C);
+ zend_vm_stack_clear_multiple(0 TSRMLS_CC);
if (EG(This)) {
zval_ptr_dtor(&EG(This));
@@ -1318,9 +1300,9 @@ void execute_new_code(TSRMLS_D) /* {{{ */
ZEND_VM_SET_OPCODE_HANDLER(opline);
opline++;
}
-
+
zend_release_labels(1 TSRMLS_CC);
-
+
EG(return_value_ptr_ptr) = NULL;
EG(active_op_array) = CG(active_op_array);
orig_interactive = CG(interactive);
@@ -1343,11 +1325,11 @@ ZEND_API void zend_timeout(int dummy) /* {{{ */
if (zend_on_timeout) {
#ifdef ZEND_SIGNALS
- /*
+ /*
We got here because we got a timeout signal, so we are in a signal handler
at this point. However, we want to be able to timeout any user-supplied
shutdown functions, so pretend we are not in a signal handler while we are
- calling these
+ calling these
*/
SIGG(running) = 0;
#endif
@@ -1596,7 +1578,7 @@ check_fetch_type:
zend_error(E_ERROR, "Trait '%s' not found", class_name);
} else {
zend_error(E_ERROR, "Class '%s' not found", class_name);
- }
+ }
}
}
return NULL;
@@ -1619,7 +1601,7 @@ zend_class_entry *zend_fetch_class_by_name(const char *class_name, uint class_na
zend_error(E_ERROR, "Trait '%s' not found", class_name);
} else {
zend_error(E_ERROR, "Class '%s' not found", class_name);
- }
+ }
}
}
return NULL;
@@ -1693,7 +1675,7 @@ ZEND_API void zend_reset_all_cv(HashTable *symbol_table TSRMLS_DC) /* {{{ */
for (ex = EG(current_execute_data); ex; ex = ex->prev_execute_data) {
if (ex->op_array && ex->symbol_table == symbol_table) {
for (i = 0; i < ex->op_array->last_var; i++) {
- ex->CVs[i] = NULL;
+ *EX_CV_NUM(ex, i) = NULL;
}
}
}
@@ -1712,7 +1694,7 @@ ZEND_API void zend_delete_variable(zend_execute_data *ex, HashTable *ht, const c
if (ex->op_array->vars[i].hash_value == hash_value &&
ex->op_array->vars[i].name_len == name_len &&
!memcmp(ex->op_array->vars[i].name, name, name_len)) {
- ex->CVs[i] = NULL;
+ *EX_CV_NUM(ex, i) = NULL;
break;
}
}
@@ -1736,7 +1718,7 @@ ZEND_API int zend_delete_global_variable_ex(const char *name, int name_len, ulon
ex->op_array->vars[i].name_len == name_len &&
!memcmp(ex->op_array->vars[i].name, name, name_len)
) {
- ex->CVs[i] = NULL;
+ *EX_CV_NUM(ex, i) = NULL;
break;
}
}
@@ -1760,7 +1742,7 @@ ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */
zend_execute_data *ex;
if (!EG(active_symbol_table)) {
-
+
/* Search for last called user function */
ex = EG(current_execute_data);
while (ex && !ex->op_array) {
@@ -1783,20 +1765,20 @@ ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */
ex->symbol_table = EG(active_symbol_table);
if (ex->op_array->this_var != -1 &&
- !ex->CVs[ex->op_array->this_var] &&
+ !*EX_CV_NUM(ex, ex->op_array->this_var) &&
EG(This)) {
- ex->CVs[ex->op_array->this_var] = (zval**)ex->CVs + ex->op_array->last_var + ex->op_array->this_var;
- *ex->CVs[ex->op_array->this_var] = EG(This);
+ *EX_CV_NUM(ex, ex->op_array->this_var) = (zval**)EX_CV_NUM(ex, ex->op_array->last_var + ex->op_array->this_var);
+ **EX_CV_NUM(ex, ex->op_array->this_var) = EG(This);
}
for (i = 0; i < ex->op_array->last_var; i++) {
- if (ex->CVs[i]) {
+ if (*EX_CV_NUM(ex, i)) {
zend_hash_quick_update(EG(active_symbol_table),
ex->op_array->vars[i].name,
ex->op_array->vars[i].name_len + 1,
ex->op_array->vars[i].hash_value,
- (void**)ex->CVs[i],
+ (void**)*EX_CV_NUM(ex, i),
sizeof(zval*),
- (void**)&ex->CVs[i]);
+ (void**)EX_CV_NUM(ex, i));
}
}
}
diff --git a/Zend/zend_extensions.h b/Zend/zend_extensions.h
index df7a7d5f14..cae689b670 100644
--- a/Zend/zend_extensions.h
+++ b/Zend/zend_extensions.h
@@ -28,7 +28,7 @@
/* The first number is the engine version and the rest is the date.
* This way engine 2/3 API no. is always greater than engine 1 API no..
*/
-#define ZEND_EXTENSION_API_NO 220100525
+#define ZEND_EXTENSION_API_NO 220121212
typedef struct _zend_extension_version_info {
int zend_extension_api_no;
diff --git a/Zend/zend_float.h b/Zend/zend_float.h
index b69f4de101..33f8e93fbf 100644
--- a/Zend/zend_float.h
+++ b/Zend/zend_float.h
@@ -65,11 +65,13 @@ extern ZEND_API void zend_ensure_fpu_mode(TSRMLS_D);
MS Visual C:
- Since MSVC users tipically don't use autoconf or CMake, we will detect
- MSVC via compile time define.
+ MSVC via compile time define. Floating point precision change isn't
+ supported on 64 bit platforms, so it's NOP. See
+ http://msdn.microsoft.com/en-us/library/c9676k6h(v=vs.110).aspx
*/
/* MSVC detection (MSVC people usually don't use autoconf) */
-#ifdef _MSC_VER
+#if defined(_MSC_VER) && !defined(_WIN64)
# if _MSC_VER >= 1500
/* Visual C++ 2008 or higher, supports _controlfp_s */
# define HAVE__CONTROLFP_S
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
new file mode 100644
index 0000000000..a5313dc1a3
--- /dev/null
+++ b/Zend/zend_generators.c
@@ -0,0 +1,759 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend Engine |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 2.00 of the Zend license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.zend.com/license/2_00.txt. |
+ | If you did not receive a copy of the Zend license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@zend.com so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Nikita Popov <nikic@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#include "zend.h"
+#include "zend_API.h"
+#include "zend_interfaces.h"
+#include "zend_exceptions.h"
+#include "zend_generators.h"
+
+ZEND_API zend_class_entry *zend_ce_generator;
+static zend_object_handlers zend_generator_handlers;
+
+static zend_object_value zend_generator_create(zend_class_entry *class_type TSRMLS_DC);
+
+static void zend_generator_cleanup_unfinished_execution(zend_generator *generator TSRMLS_DC) /* {{{ */
+{
+ zend_execute_data *execute_data = generator->execute_data;
+ zend_op_array *op_array = execute_data->op_array;
+
+ if (generator->send_target) {
+ Z_DELREF_PP(generator->send_target);
+ generator->send_target = NULL;
+ }
+
+ /* Manually free loop variables, as execution couldn't reach their
+ * SWITCH_FREE / FREE opcodes. */
+ {
+ /* -1 required because we want the last run opcode, not the
+ * next to-be-run one. */
+ zend_uint op_num = execute_data->opline - op_array->opcodes - 1;
+
+ int i;
+ for (i = 0; i < op_array->last_brk_cont; ++i) {
+ zend_brk_cont_element *brk_cont = op_array->brk_cont_array + i;
+
+ if (brk_cont->start < 0) {
+ continue;
+ } else if (brk_cont->start > op_num) {
+ break;
+ } else if (brk_cont->brk > op_num) {
+ zend_op *brk_opline = op_array->opcodes + brk_cont->brk;
+
+ switch (brk_opline->opcode) {
+ case ZEND_SWITCH_FREE:
+ {
+ temp_variable *var = EX_TMP_VAR(execute_data, brk_opline->op1.var);
+ zval_ptr_dtor(&var->var.ptr);
+ }
+ break;
+ case ZEND_FREE:
+ {
+ temp_variable *var = EX_TMP_VAR(execute_data, brk_opline->op1.var);
+ zval_dtor(&var->tmp_var);
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ /* Clear any backed up stack arguments */
+ {
+ void **ptr = generator->stack->top - 1;
+ void **end = zend_vm_stack_frame_base(execute_data);
+
+ for (; ptr >= end; --ptr) {
+ zval_ptr_dtor((zval **) ptr);
+ }
+ }
+
+ /* If yield was used as a function argument there may be active
+ * method calls those objects need to be freed */
+ while (execute_data->call >= execute_data->call_slots) {
+ if (execute_data->call->object) {
+ zval_ptr_dtor(&execute_data->call->object);
+ }
+ execute_data->call--;
+ }
+}
+/* }}} */
+
+ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished_execution TSRMLS_DC) /* {{{ */
+{
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ generator->value = NULL;
+ }
+
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ generator->key = NULL;
+ }
+
+ if (generator->execute_data) {
+ zend_execute_data *execute_data = generator->execute_data;
+ zend_op_array *op_array = execute_data->op_array;
+
+ if (!execute_data->symbol_table) {
+ zend_free_compiled_variables(execute_data);
+ } else {
+ zend_clean_and_cache_symbol_table(execute_data->symbol_table TSRMLS_CC);
+ }
+
+ if (execute_data->current_this) {
+ zval_ptr_dtor(&execute_data->current_this);
+ }
+
+ /* A fatal error / die occurred during the generator execution. Trying to clean
+ * up the stack may not be safe in this case. */
+ if (CG(unclean_shutdown)) {
+ return;
+ }
+
+ /* We have added an additional stack frame in prev_execute_data, so we
+ * have to free it. It also contains the arguments passed to the
+ * generator (for func_get_args) so those have to be freed too. */
+ {
+ zend_execute_data *prev_execute_data = execute_data->prev_execute_data;
+ void **arguments = prev_execute_data->function_state.arguments;
+
+ if (arguments) {
+ int arguments_count = (int) (zend_uintptr_t) *arguments;
+ zval **arguments_start = (zval **) (arguments - arguments_count);
+ int i;
+
+ for (i = 0; i < arguments_count; ++i) {
+ zval_ptr_dtor(arguments_start + i);
+ }
+ }
+ }
+
+ /* Some cleanups are only necessary if the generator was closued
+ * before it could finish execution (reach a return statement). */
+ if (!finished_execution) {
+ zend_generator_cleanup_unfinished_execution(generator TSRMLS_CC);
+ }
+
+ /* Free a clone of closure */
+ if (op_array->fn_flags & ZEND_ACC_CLOSURE) {
+ destroy_op_array(op_array TSRMLS_CC);
+ efree(op_array);
+ }
+
+ efree(generator->stack);
+ generator->execute_data = NULL;
+ }
+}
+/* }}} */
+
+static void zend_generator_dtor_storage(zend_generator *generator, zend_object_handle handle TSRMLS_DC) /* {{{ */
+{
+ zend_execute_data *ex = generator->execute_data;
+ zend_uint op_num, finally_op_num;
+ int i;
+
+ if (!ex || !ex->op_array->has_finally_block) {
+ return;
+ }
+
+ /* -1 required because we want the last run opcode, not the
+ * next to-be-run one. */
+ op_num = ex->opline - ex->op_array->opcodes - 1;
+
+ /* Find next finally block */
+ finally_op_num = 0;
+ for (i = 0; i < ex->op_array->last_try_catch; i++) {
+ zend_try_catch_element *try_catch = &ex->op_array->try_catch_array[i];
+
+ if (op_num < try_catch->try_op) {
+ break;
+ }
+
+ if (op_num < try_catch->finally_op) {
+ finally_op_num = try_catch->finally_op;
+ }
+ }
+
+ /* If a finally block was found we jump directly to it and
+ * resume the generator. */
+ if (finally_op_num) {
+ ex->opline = &ex->op_array->opcodes[finally_op_num];
+ ex->fast_ret = NULL;
+ generator->flags |= ZEND_GENERATOR_FORCED_CLOSE;
+ zend_generator_resume(generator TSRMLS_CC);
+ }
+}
+/* }}} */
+
+static void zend_generator_free_storage(zend_generator *generator TSRMLS_DC) /* {{{ */
+{
+ zend_generator_close(generator, 0 TSRMLS_CC);
+
+ zend_object_std_dtor(&generator->std TSRMLS_CC);
+ efree(generator);
+}
+/* }}} */
+
+static zend_object_value zend_generator_create(zend_class_entry *class_type TSRMLS_DC) /* {{{ */
+{
+ zend_generator *generator;
+ zend_object_value object;
+
+ generator = emalloc(sizeof(zend_generator));
+ memset(generator, 0, sizeof(zend_generator));
+
+ /* The key will be incremented on first use, so it'll start at 0 */
+ generator->largest_used_integer_key = -1;
+
+ zend_object_std_init(&generator->std, class_type TSRMLS_CC);
+
+ object.handle = zend_objects_store_put(generator,
+ (zend_objects_store_dtor_t) zend_generator_dtor_storage,
+ (zend_objects_free_object_storage_t) zend_generator_free_storage,
+ NULL TSRMLS_CC
+ );
+ object.handlers = &zend_generator_handlers;
+
+ return object;
+}
+/* }}} */
+
+static void copy_closure_static_var(zval **var TSRMLS_DC, int num_args, va_list args, zend_hash_key *key) /* {{{ */
+{
+ HashTable *target = va_arg(args, HashTable *);
+
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(var);
+ Z_ADDREF_PP(var);
+ zend_hash_quick_update(target, key->arKey, key->nKeyLength, key->h, var, sizeof(zval *), NULL);
+}
+/* }}} */
+
+/* Requires globals EG(scope), EG(current_scope), EG(This),
+ * EG(active_symbol_table) and EG(current_execute_data). */
+ZEND_API zval *zend_generator_create_zval(zend_op_array *op_array TSRMLS_DC) /* {{{ */
+{
+ zval *return_value;
+ zend_generator *generator;
+ zend_execute_data *current_execute_data;
+ zend_op **opline_ptr;
+ HashTable *current_symbol_table;
+ zend_execute_data *execute_data;
+ zend_vm_stack current_stack = EG(argument_stack);
+
+ /* Create a clone of closure, because it may be destroyed */
+ if (op_array->fn_flags & ZEND_ACC_CLOSURE) {
+ zend_op_array *op_array_copy = (zend_op_array*)emalloc(sizeof(zend_op_array));
+ *op_array_copy = *op_array;
+
+ (*op_array->refcount)++;
+ op_array->run_time_cache = NULL;
+ if (op_array->static_variables) {
+ ALLOC_HASHTABLE(op_array_copy->static_variables);
+ zend_hash_init(
+ op_array_copy->static_variables,
+ zend_hash_num_elements(op_array->static_variables),
+ NULL, ZVAL_PTR_DTOR, 0
+ );
+ zend_hash_apply_with_arguments(
+ op_array->static_variables TSRMLS_CC,
+ (apply_func_args_t) copy_closure_static_var,
+ 1, op_array_copy->static_variables
+ );
+ }
+
+ op_array = op_array_copy;
+ }
+
+ /* Create new execution context. We have to back up and restore
+ * EG(current_execute_data), EG(opline_ptr) and EG(active_symbol_table)
+ * here because the function modifies or uses them */
+ current_execute_data = EG(current_execute_data);
+ opline_ptr = EG(opline_ptr);
+ current_symbol_table = EG(active_symbol_table);
+ EG(active_symbol_table) = NULL;
+ execute_data = zend_create_execute_data_from_op_array(op_array, 0 TSRMLS_CC);
+ EG(active_symbol_table) = current_symbol_table;
+ EG(current_execute_data) = current_execute_data;
+ EG(opline_ptr) = opline_ptr;
+
+ ALLOC_INIT_ZVAL(return_value);
+ object_init_ex(return_value, zend_ce_generator);
+
+ if (EG(This)) {
+ Z_ADDREF_P(EG(This));
+ }
+
+ /* Back up executor globals. */
+ execute_data->current_scope = EG(scope);
+ execute_data->current_called_scope = EG(called_scope);
+ execute_data->symbol_table = EG(active_symbol_table);
+ execute_data->current_this = EG(This);
+
+ /* Save execution context in generator object. */
+ generator = (zend_generator *) zend_object_store_get_object(return_value TSRMLS_CC);
+ generator->execute_data = execute_data;
+ generator->stack = EG(argument_stack);
+ EG(argument_stack) = current_stack;
+
+ return return_value;
+}
+/* }}} */
+
+static zend_function *zend_generator_get_constructor(zval *object TSRMLS_DC) /* {{{ */
+{
+ zend_error(E_RECOVERABLE_ERROR, "The \"Generator\" class is reserved for internal use and cannot be manually instantiated");
+
+ return NULL;
+}
+/* }}} */
+
+ZEND_API void zend_generator_resume(zend_generator *generator TSRMLS_DC) /* {{{ */
+{
+ /* The generator is already closed, thus can't resume */
+ if (!generator->execute_data) {
+ return;
+ }
+
+ if (generator->flags & ZEND_GENERATOR_CURRENTLY_RUNNING) {
+ zend_error(E_ERROR, "Cannot resume an already running generator");
+ }
+
+ /* Drop the AT_FIRST_YIELD flag */
+ generator->flags &= ~ZEND_GENERATOR_AT_FIRST_YIELD;
+
+ {
+ /* Backup executor globals */
+ zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr);
+ zend_execute_data *original_execute_data = EG(current_execute_data);
+ zend_op **original_opline_ptr = EG(opline_ptr);
+ zend_op_array *original_active_op_array = EG(active_op_array);
+ HashTable *original_active_symbol_table = EG(active_symbol_table);
+ zval *original_This = EG(This);
+ zend_class_entry *original_scope = EG(scope);
+ zend_class_entry *original_called_scope = EG(called_scope);
+ zend_vm_stack original_stack = EG(argument_stack);
+
+ /* We (mis)use the return_value_ptr_ptr to provide the generator object
+ * to the executor, so YIELD will be able to set the yielded value */
+ EG(return_value_ptr_ptr) = (zval **) generator;
+
+ /* Set executor globals */
+ EG(current_execute_data) = generator->execute_data;
+ EG(opline_ptr) = &generator->execute_data->opline;
+ EG(active_op_array) = generator->execute_data->op_array;
+ EG(active_symbol_table) = generator->execute_data->symbol_table;
+ EG(This) = generator->execute_data->current_this;
+ EG(scope) = generator->execute_data->current_scope;
+ EG(called_scope) = generator->execute_data->current_called_scope;
+ EG(argument_stack) = generator->stack;
+
+ /* We want the backtrace to look as if the generator function was
+ * called from whatever method we are current running (e.g. next()).
+ * The first prev_execute_data contains an additional stack frame,
+ * which makes the generator function show up in the backtrace and
+ * makes the arguments available to func_get_args(). So we have to
+ * set the prev_execute_data of that prev_execute_data :) */
+ generator->execute_data->prev_execute_data->prev_execute_data = original_execute_data;
+
+ /* Resume execution */
+ generator->flags |= ZEND_GENERATOR_CURRENTLY_RUNNING;
+ zend_execute_ex(generator->execute_data TSRMLS_CC);
+ generator->flags &= ~ZEND_GENERATOR_CURRENTLY_RUNNING;
+
+ /* Restore executor globals */
+ EG(return_value_ptr_ptr) = original_return_value_ptr_ptr;
+ EG(current_execute_data) = original_execute_data;
+ EG(opline_ptr) = original_opline_ptr;
+ EG(active_op_array) = original_active_op_array;
+ EG(active_symbol_table) = original_active_symbol_table;
+ EG(This) = original_This;
+ EG(scope) = original_scope;
+ EG(called_scope) = original_called_scope;
+ EG(argument_stack) = original_stack;
+
+ /* If an exception was thrown in the generator we have to internally
+ * rethrow it in the parent scope. */
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ zend_throw_exception_internal(NULL TSRMLS_CC);
+ }
+ }
+}
+/* }}} */
+
+static void zend_generator_ensure_initialized(zend_generator *generator TSRMLS_DC) /* {{{ */
+{
+ if (generator->execute_data && !generator->value) {
+ zend_generator_resume(generator TSRMLS_CC);
+ generator->flags |= ZEND_GENERATOR_AT_FIRST_YIELD;
+ }
+}
+/* }}} */
+
+static void zend_generator_rewind(zend_generator *generator TSRMLS_DC) /* {{{ */
+{
+ zend_generator_ensure_initialized(generator TSRMLS_CC);
+
+ if (!(generator->flags & ZEND_GENERATOR_AT_FIRST_YIELD)) {
+ zend_throw_exception(NULL, "Cannot rewind a generator that was already run", 0 TSRMLS_CC);
+ }
+}
+/* }}} */
+
+/* {{{ proto void Generator::rewind()
+ * Rewind the generator */
+ZEND_METHOD(Generator, rewind)
+{
+ zend_generator *generator;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ generator = (zend_generator *) zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ zend_generator_rewind(generator TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto bool Generator::valid()
+ * Check whether the generator is valid */
+ZEND_METHOD(Generator, valid)
+{
+ zend_generator *generator;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ generator = (zend_generator *) zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ zend_generator_ensure_initialized(generator TSRMLS_CC);
+
+ RETURN_BOOL(generator->value != NULL);
+}
+/* }}} */
+
+/* {{{ proto mixed Generator::current()
+ * Get the current value */
+ZEND_METHOD(Generator, current)
+{
+ zend_generator *generator;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ generator = (zend_generator *) zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ zend_generator_ensure_initialized(generator TSRMLS_CC);
+
+ if (generator->value) {
+ RETURN_ZVAL(generator->value, 1, 0);
+ }
+}
+/* }}} */
+
+/* {{{ proto mixed Generator::key()
+ * Get the current key */
+ZEND_METHOD(Generator, key)
+{
+ zend_generator *generator;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ generator = (zend_generator *) zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ zend_generator_ensure_initialized(generator TSRMLS_CC);
+
+ if (generator->key) {
+ RETURN_ZVAL(generator->key, 1, 0);
+ }
+}
+/* }}} */
+
+/* {{{ proto void Generator::next()
+ * Advances the generator */
+ZEND_METHOD(Generator, next)
+{
+ zend_generator *generator;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ generator = (zend_generator *) zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ zend_generator_ensure_initialized(generator TSRMLS_CC);
+
+ zend_generator_resume(generator TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto mixed Generator::send(mixed $value)
+ * Sends a value to the generator */
+ZEND_METHOD(Generator, send)
+{
+ zval *value;
+ zend_generator *generator;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &value) == FAILURE) {
+ return;
+ }
+
+ generator = (zend_generator *) zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ zend_generator_ensure_initialized(generator TSRMLS_CC);
+
+ /* The generator is already closed, thus can't send anything */
+ if (!generator->execute_data) {
+ return;
+ }
+
+ /* Put sent value in the target VAR slot, if it is used */
+ if (generator->send_target) {
+ Z_DELREF_PP(generator->send_target);
+ Z_ADDREF_P(value);
+ *generator->send_target = value;
+ }
+
+ zend_generator_resume(generator TSRMLS_CC);
+
+ if (generator->value) {
+ RETURN_ZVAL(generator->value, 1, 0);
+ }
+}
+/* }}} */
+
+/* {{{ proto mixed Generator::throw(Exception $exception)
+ * Throws an exception into the generator */
+ZEND_METHOD(Generator, throw)
+{
+ zval *exception, *exception_copy;
+ zend_generator *generator;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &exception) == FAILURE) {
+ return;
+ }
+
+ ALLOC_ZVAL(exception_copy);
+ MAKE_COPY_ZVAL(&exception, exception_copy);
+
+ generator = (zend_generator *) zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ zend_generator_ensure_initialized(generator TSRMLS_CC);
+
+ if (generator->execute_data) {
+ /* Throw the exception in the context of the generator */
+ zend_execute_data *current_execute_data = EG(current_execute_data);
+ EG(current_execute_data) = generator->execute_data;
+
+ zend_throw_exception_object(exception_copy TSRMLS_CC);
+
+ EG(current_execute_data) = current_execute_data;
+
+ zend_generator_resume(generator TSRMLS_CC);
+
+ if (generator->value) {
+ RETURN_ZVAL(generator->value, 1, 0);
+ }
+ } else {
+ /* If the generator is already closed throw the exception in the
+ * current context */
+ zend_throw_exception_object(exception_copy TSRMLS_CC);
+ }
+}
+/* }}} */
+
+/* {{{ proto void Generator::__wakeup()
+ * Throws an Exception as generators can't be serialized */
+ZEND_METHOD(Generator, __wakeup)
+{
+ /* Just specifying the zend_class_unserialize_deny handler is not enough,
+ * because it is only invoked for C unserialization. For O the error has
+ * to be thrown in __wakeup. */
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ zend_throw_exception(NULL, "Unserialization of 'Generator' is not allowed", 0 TSRMLS_CC);
+}
+/* }}} */
+
+/* get_iterator implementation */
+
+static void zend_generator_iterator_dtor(zend_object_iterator *iterator TSRMLS_DC) /* {{{ */
+{
+ zval *object = ((zend_generator_iterator *) iterator)->object;
+
+ zval_ptr_dtor(&object);
+}
+/* }}} */
+
+static int zend_generator_iterator_valid(zend_object_iterator *iterator TSRMLS_DC) /* {{{ */
+{
+ zend_generator *generator = (zend_generator *) iterator->data;
+
+ zend_generator_ensure_initialized(generator TSRMLS_CC);
+
+ return generator->value != NULL ? SUCCESS : FAILURE;
+}
+/* }}} */
+
+static void zend_generator_iterator_get_data(zend_object_iterator *iterator, zval ***data TSRMLS_DC) /* {{{ */
+{
+ zend_generator *generator = (zend_generator *) iterator->data;
+
+ zend_generator_ensure_initialized(generator TSRMLS_CC);
+
+ if (generator->value) {
+ *data = &generator->value;
+ } else {
+ *data = NULL;
+ }
+}
+/* }}} */
+
+static void zend_generator_iterator_get_key(zend_object_iterator *iterator, zval *key TSRMLS_DC) /* {{{ */
+{
+ zend_generator *generator = (zend_generator *) iterator->data;
+
+ zend_generator_ensure_initialized(generator TSRMLS_CC);
+
+ if (generator->key) {
+ ZVAL_ZVAL(key, generator->key, 1, 0);
+ } else {
+ ZVAL_NULL(key);
+ }
+}
+/* }}} */
+
+static void zend_generator_iterator_move_forward(zend_object_iterator *iterator TSRMLS_DC) /* {{{ */
+{
+ zend_generator *generator = (zend_generator *) iterator->data;
+
+ zend_generator_ensure_initialized(generator TSRMLS_CC);
+
+ zend_generator_resume(generator TSRMLS_CC);
+}
+/* }}} */
+
+static void zend_generator_iterator_rewind(zend_object_iterator *iterator TSRMLS_DC) /* {{{ */
+{
+ zend_generator *generator = (zend_generator *) iterator->data;
+
+ zend_generator_rewind(generator TSRMLS_CC);
+}
+/* }}} */
+
+static zend_object_iterator_funcs zend_generator_iterator_functions = {
+ zend_generator_iterator_dtor,
+ zend_generator_iterator_valid,
+ zend_generator_iterator_get_data,
+ zend_generator_iterator_get_key,
+ zend_generator_iterator_move_forward,
+ zend_generator_iterator_rewind
+};
+
+zend_object_iterator *zend_generator_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC) /* {{{ */
+{
+ zend_generator_iterator *iterator;
+ zend_generator *generator;
+
+ generator = (zend_generator *) zend_object_store_get_object(object TSRMLS_CC);
+
+ if (!generator->execute_data) {
+ zend_throw_exception(NULL, "Cannot traverse an already closed generator", 0 TSRMLS_CC);
+ return NULL;
+ }
+
+ if (by_ref && !(generator->execute_data->op_array->fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
+ zend_throw_exception(NULL, "You can only iterate a generator by-reference if it declared that it yields by-reference", 0 TSRMLS_CC);
+ return NULL;
+ }
+
+ iterator = &generator->iterator;
+ iterator->intern.funcs = &zend_generator_iterator_functions;
+ iterator->intern.data = (void *) generator;
+
+ /* We have to keep a reference to the generator object zval around,
+ * otherwise the generator may be destroyed during iteration. */
+ Z_ADDREF_P(object);
+ iterator->object = object;
+
+ return (zend_object_iterator *) iterator;
+}
+/* }}} */
+
+ZEND_BEGIN_ARG_INFO(arginfo_generator_void, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_generator_send, 0, 0, 1)
+ ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_generator_throw, 0, 0, 1)
+ ZEND_ARG_INFO(0, exception)
+ZEND_END_ARG_INFO()
+
+static const zend_function_entry generator_functions[] = {
+ ZEND_ME(Generator, rewind, arginfo_generator_void, ZEND_ACC_PUBLIC)
+ ZEND_ME(Generator, valid, arginfo_generator_void, ZEND_ACC_PUBLIC)
+ ZEND_ME(Generator, current, arginfo_generator_void, ZEND_ACC_PUBLIC)
+ ZEND_ME(Generator, key, arginfo_generator_void, ZEND_ACC_PUBLIC)
+ ZEND_ME(Generator, next, arginfo_generator_void, ZEND_ACC_PUBLIC)
+ ZEND_ME(Generator, send, arginfo_generator_send, ZEND_ACC_PUBLIC)
+ ZEND_ME(Generator, throw, arginfo_generator_throw, ZEND_ACC_PUBLIC)
+ ZEND_ME(Generator, __wakeup, arginfo_generator_void, ZEND_ACC_PUBLIC)
+ ZEND_FE_END
+};
+
+void zend_register_generator_ce(TSRMLS_D) /* {{{ */
+{
+ zend_class_entry ce;
+
+ INIT_CLASS_ENTRY(ce, "Generator", generator_functions);
+ zend_ce_generator = zend_register_internal_class(&ce TSRMLS_CC);
+ zend_ce_generator->ce_flags |= ZEND_ACC_FINAL_CLASS;
+ zend_ce_generator->create_object = zend_generator_create;
+ zend_ce_generator->serialize = zend_class_serialize_deny;
+ zend_ce_generator->unserialize = zend_class_unserialize_deny;
+
+ /* get_iterator has to be assigned *after* implementing the inferface */
+ zend_class_implements(zend_ce_generator TSRMLS_CC, 1, zend_ce_iterator);
+ zend_ce_generator->get_iterator = zend_generator_get_iterator;
+ zend_ce_generator->iterator_funcs.funcs = &zend_generator_iterator_functions;
+
+ memcpy(&zend_generator_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ zend_generator_handlers.get_constructor = zend_generator_get_constructor;
+ zend_generator_handlers.clone_obj = NULL;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * indent-tabs-mode: t
+ * End:
+ */
diff --git a/Zend/zend_generators.h b/Zend/zend_generators.h
new file mode 100644
index 0000000000..2373a1a7c8
--- /dev/null
+++ b/Zend/zend_generators.h
@@ -0,0 +1,79 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend Engine |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 2.00 of the Zend license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.zend.com/license/2_00.txt. |
+ | If you did not receive a copy of the Zend license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@zend.com so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Authors: Nikita Popov <nikic@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef ZEND_GENERATORS_H
+#define ZEND_GENERATORS_H
+
+BEGIN_EXTERN_C()
+
+extern ZEND_API zend_class_entry *zend_ce_generator;
+
+typedef struct _zend_generator_iterator {
+ zend_object_iterator intern;
+
+ /* The generator object zval has to be stored, because the iterator is
+ * holding a ref to it, which has to be dtored. */
+ zval *object;
+} zend_generator_iterator;
+
+typedef struct _zend_generator {
+ zend_object std;
+
+ zend_generator_iterator iterator;
+
+ /* The suspended execution context. */
+ zend_execute_data *execute_data;
+
+ /* The separate stack used by generator */
+ zend_vm_stack stack;
+
+ /* Current value */
+ zval *value;
+ /* Current key */
+ zval *key;
+ /* Variable to put sent value into */
+ zval **send_target;
+ /* Largest used integer key for auto-incrementing keys */
+ long largest_used_integer_key;
+
+ /* ZEND_GENERATOR_* flags */
+ zend_uchar flags;
+} zend_generator;
+
+static const zend_uchar ZEND_GENERATOR_CURRENTLY_RUNNING = 0x1;
+static const zend_uchar ZEND_GENERATOR_FORCED_CLOSE = 0x2;
+static const zend_uchar ZEND_GENERATOR_AT_FIRST_YIELD = 0x4;
+
+void zend_register_generator_ce(TSRMLS_D);
+ZEND_API zval *zend_generator_create_zval(zend_op_array *op_array TSRMLS_DC);
+ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished_execution TSRMLS_DC);
+ZEND_API void zend_generator_resume(zend_generator *generator TSRMLS_DC);
+
+END_EXTERN_C()
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * indent-tabs-mode: t
+ * End:
+ */
diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h
index e779ac4d74..6dc022dac8 100644
--- a/Zend/zend_globals.h
+++ b/Zend/zend_globals.h
@@ -89,9 +89,6 @@ struct _zend_compiler_globals {
int zend_lineno;
- char *heredoc;
- int heredoc_len;
-
zend_op_array *active_op_array;
HashTable *function_table; /* function symbol table */
@@ -170,8 +167,6 @@ struct _zend_executor_globals {
zval error_zval;
zval *error_zval_ptr;
- zend_ptr_stack arg_types_stack;
-
/* symbol table cache */
HashTable *symtable_cache[SYMTABLE_CACHE_SIZE];
HashTable **symtable_cache_limit;
@@ -297,6 +292,7 @@ struct _zend_php_scanner_globals {
unsigned char *yy_limit;
int yy_state;
zend_stack state_stack;
+ zend_ptr_stack heredoc_label_stack;
/* original (unfiltered) script */
unsigned char *script_org;
diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c
index bfff87a67e..d7188ea564 100644
--- a/Zend/zend_hash.c
+++ b/Zend/zend_hash.c
@@ -527,6 +527,7 @@ ZEND_API int zend_hash_del_key_or_index(HashTable *ht, const char *arKey, uint n
if (ht->pInternalPointer == p) {
ht->pInternalPointer = p->pListNext;
}
+ ht->nNumOfElements--;
if (ht->pDestructor) {
ht->pDestructor(p->pData);
}
@@ -535,7 +536,6 @@ ZEND_API int zend_hash_del_key_or_index(HashTable *ht, const char *arKey, uint n
}
pefree(p, ht->persistent);
HANDLE_UNBLOCK_INTERRUPTIONS();
- ht->nNumOfElements--;
return SUCCESS;
}
p = p->pNext;
@@ -1168,9 +1168,27 @@ ZEND_API int zend_hash_get_current_key_ex(const HashTable *ht, char **str_index,
return HASH_KEY_IS_LONG;
}
}
- return HASH_KEY_NON_EXISTANT;
+ return HASH_KEY_NON_EXISTENT;
}
+ZEND_API void zend_hash_get_current_key_zval_ex(const HashTable *ht, zval *key, HashPosition *pos) {
+ Bucket *p;
+
+ IS_CONSISTENT(ht);
+
+ p = pos ? (*pos) : ht->pInternalPointer;
+
+ if (!p) {
+ Z_TYPE_P(key) = IS_NULL;
+ } else if (p->nKeyLength) {
+ Z_TYPE_P(key) = IS_STRING;
+ Z_STRVAL_P(key) = estrndup(p->arKey, p->nKeyLength - 1);
+ Z_STRLEN_P(key) = p->nKeyLength - 1;
+ } else {
+ Z_TYPE_P(key) = IS_LONG;
+ Z_LVAL_P(key) = p->h;
+ }
+}
ZEND_API int zend_hash_get_current_key_type_ex(HashTable *ht, HashPosition *pos)
{
@@ -1187,7 +1205,7 @@ ZEND_API int zend_hash_get_current_key_type_ex(HashTable *ht, HashPosition *pos)
return HASH_KEY_IS_LONG;
}
}
- return HASH_KEY_NON_EXISTANT;
+ return HASH_KEY_NON_EXISTENT;
}
@@ -1302,6 +1320,7 @@ ZEND_API int zend_hash_update_current_key_ex(HashTable *ht, int key_type, const
if (ht->pInternalPointer == p) {
ht->pInternalPointer = p->pListNext;
}
+ ht->nNumOfElements--;
if (ht->pDestructor) {
ht->pDestructor(p->pData);
}
@@ -1309,7 +1328,6 @@ ZEND_API int zend_hash_update_current_key_ex(HashTable *ht, int key_type, const
pefree(p->pData, ht->persistent);
}
pefree(p, ht->persistent);
- ht->nNumOfElements--;
HANDLE_UNBLOCK_INTERRUPTIONS();
return FAILURE;
}
@@ -1337,6 +1355,7 @@ ZEND_API int zend_hash_update_current_key_ex(HashTable *ht, int key_type, const
if (ht->pInternalPointer == q) {
ht->pInternalPointer = q->pListNext;
}
+ ht->nNumOfElements--;
if (ht->pDestructor) {
ht->pDestructor(q->pData);
}
@@ -1344,7 +1363,6 @@ ZEND_API int zend_hash_update_current_key_ex(HashTable *ht, int key_type, const
pefree(q->pData, ht->persistent);
}
pefree(q, ht->persistent);
- ht->nNumOfElements--;
}
if (p->pNext) {
diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h
index 4ab811eeb0..cebb898ffd 100644
--- a/Zend/zend_hash.h
+++ b/Zend/zend_hash.h
@@ -27,7 +27,8 @@
#define HASH_KEY_IS_STRING 1
#define HASH_KEY_IS_LONG 2
-#define HASH_KEY_NON_EXISTANT 3
+#define HASH_KEY_NON_EXISTENT 3
+#define HASH_KEY_NON_EXISTANT HASH_KEY_NON_EXISTENT /* Keeping old define (with typo) for backward compatibility */
#define HASH_UPDATE (1<<0)
#define HASH_ADD (1<<1)
@@ -170,13 +171,13 @@ ZEND_API int zend_hash_quick_exists(const HashTable *ht, const char *arKey, uint
ZEND_API int zend_hash_index_exists(const HashTable *ht, ulong h);
ZEND_API ulong zend_hash_next_free_element(const HashTable *ht);
-
/* traversing */
#define zend_hash_has_more_elements_ex(ht, pos) \
- (zend_hash_get_current_key_type_ex(ht, pos) == HASH_KEY_NON_EXISTANT ? FAILURE : SUCCESS)
+ (zend_hash_get_current_key_type_ex(ht, pos) == HASH_KEY_NON_EXISTENT ? FAILURE : SUCCESS)
ZEND_API int zend_hash_move_forward_ex(HashTable *ht, HashPosition *pos);
ZEND_API int zend_hash_move_backwards_ex(HashTable *ht, HashPosition *pos);
ZEND_API int zend_hash_get_current_key_ex(const HashTable *ht, char **str_index, uint *str_length, ulong *num_index, zend_bool duplicate, HashPosition *pos);
+ZEND_API void zend_hash_get_current_key_zval_ex(const HashTable *ht, zval *key, HashPosition *pos);
ZEND_API int zend_hash_get_current_key_type_ex(HashTable *ht, HashPosition *pos);
ZEND_API int zend_hash_get_current_data_ex(HashTable *ht, void **pData, HashPosition *pos);
ZEND_API void zend_hash_internal_pointer_reset_ex(HashTable *ht, HashPosition *pos);
@@ -199,6 +200,8 @@ ZEND_API int zend_hash_set_pointer(HashTable *ht, const HashPointer *ptr);
zend_hash_move_backwards_ex(ht, NULL)
#define zend_hash_get_current_key(ht, str_index, num_index, duplicate) \
zend_hash_get_current_key_ex(ht, str_index, NULL, num_index, duplicate, NULL)
+#define zend_hash_get_current_key_zval(ht, key) \
+ zend_hash_get_current_key_zval_ex(ht, key, NULL)
#define zend_hash_get_current_key_type(ht) \
zend_hash_get_current_key_type_ex(ht, NULL)
#define zend_hash_get_current_data(ht, pData) \
diff --git a/Zend/zend_highlight.c b/Zend/zend_highlight.c
index 5ea55155c2..ffec587806 100644
--- a/Zend/zend_highlight.c
+++ b/Zend/zend_highlight.c
@@ -153,8 +153,6 @@ ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini
efree(token.value.str.val);
break;
}
- } else if (token_type == T_END_HEREDOC) {
- efree(token.value.str.val);
}
token.type = 0;
}
@@ -188,7 +186,6 @@ ZEND_API void zend_strip(TSRMLS_D)
case T_END_HEREDOC:
zend_write((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng));
- efree(token.value.str.val);
/* read the following character, either newline or ; */
if (lex_scan(&token TSRMLS_CC) != T_WHITESPACE) {
zend_write((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng));
diff --git a/Zend/zend_ini_parser.y b/Zend/zend_ini_parser.y
index aa6e0594b3..3823efd413 100644
--- a/Zend/zend_ini_parser.y
+++ b/Zend/zend_ini_parser.y
@@ -67,6 +67,9 @@ static void zend_ini_do_op(char type, zval *result, zval *op1, zval *op2)
case '&':
i_result = i_op1 & i_op2;
break;
+ case '^':
+ i_result = i_op1 ^ i_op2;
+ break;
case '~':
i_result = ~i_op1;
break;
@@ -264,7 +267,7 @@ ZEND_API int zend_parse_ini_string(char *str, zend_bool unbuffered_errors, int s
%token BOOL_FALSE
%token END_OF_LINE
%token '=' ':' ',' '.' '"' '\'' '^' '+' '-' '/' '*' '%' '$' '~' '<' '>' '?' '@' '{' '}'
-%left '|' '&'
+%left '|' '&' '^'
%right '~' '!'
%%
@@ -348,6 +351,7 @@ expr:
var_string_list { $$ = $1; }
| expr '|' expr { zend_ini_do_op('|', &$$, &$1, &$3); }
| expr '&' expr { zend_ini_do_op('&', &$$, &$1, &$3); }
+ | expr '^' expr { zend_ini_do_op('^', &$$, &$1, &$3); }
| '~' expr { zend_ini_do_op('~', &$$, &$2, NULL); }
| '!' expr { zend_ini_do_op('!', &$$, &$2, NULL); }
| '(' expr ')' { $$ = $2; }
diff --git a/Zend/zend_ini_scanner.c b/Zend/zend_ini_scanner.c
index fd7e08aa33..521e98e257 100644
--- a/Zend/zend_ini_scanner.c
+++ b/Zend/zend_ini_scanner.c
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.13.5 on Fri Nov 16 18:24:06 2012 */
+/* Generated by re2c 0.13.5 */
#line 1 "Zend/zend_ini_scanner.l"
/*
+----------------------------------------------------------------------+
@@ -381,7 +381,7 @@ yyc_INITIAL:
144, 144, 144, 144, 144, 144, 144, 144,
144, 144, 144, 144, 144, 144, 144, 144,
144, 144, 144, 144, 144, 144, 144, 144,
- 144, 144, 144, 128, 144, 144, 144, 144,
+ 144, 144, 144, 128, 144, 144, 128, 144,
144, 144, 144, 144, 144, 144, 144, 144,
144, 144, 144, 144, 144, 144, 144, 144,
144, 144, 144, 144, 144, 144, 144, 144,
@@ -419,6 +419,7 @@ yyc_INITIAL:
case '&':
case '(':
case ')':
+ case '^':
case '{':
case '|':
case '}':
@@ -437,8 +438,7 @@ yyc_INITIAL:
case '>':
case '?':
case '@':
- case ']':
- case '^': goto yy13;
+ case ']': goto yy13;
case ';': goto yy14;
case '=': goto yy16;
case 'F':
@@ -695,35 +695,33 @@ yy31:
if (yybm[0+yych] & 64) {
goto yy31;
}
- if (yych <= '&') {
- if (yych <= '\r') {
- if (yych <= '\t') {
+ if (yych <= '\'') {
+ if (yych <= ' ') {
+ if (yych <= '\n') {
if (yych <= 0x08) goto yy25;
- goto yy34;
+ if (yych <= '\t') goto yy34;
} else {
- if (yych <= '\n') goto yy33;
- if (yych <= '\f') goto yy25;
+ if (yych != '\r') goto yy25;
}
} else {
- if (yych <= '#') {
- if (yych <= ' ') goto yy25;
- if (yych >= '#') goto yy25;
+ if (yych <= '$') {
+ if (yych == '#') goto yy25;
} else {
- if (yych == '%') goto yy25;
+ if (yych != '&') goto yy25;
}
}
} else {
- if (yych <= '<') {
- if (yych <= ')') {
- if (yych <= '\'') goto yy25;
+ if (yych <= 'Z') {
+ if (yych <= ';') {
+ if (yych <= ')') goto yy33;
+ if (yych <= ':') goto yy25;
} else {
- if (yych != ';') goto yy25;
+ if (yych != '=') goto yy25;
}
} else {
- if (yych <= '[') {
- if (yych <= '=') goto yy33;
- if (yych <= 'Z') goto yy25;
- goto yy28;
+ if (yych <= '^') {
+ if (yych <= '[') goto yy28;
+ if (yych <= ']') goto yy25;
} else {
if (yych <= 'z') goto yy25;
if (yych >= 0x7F) goto yy25;
@@ -737,7 +735,7 @@ yy33:
{ /* TRUE value (when used outside option value/offset this causes parse error!) */
RETURN_TOKEN(BOOL_TRUE, "1", 1);
}
-#line 741 "Zend/zend_ini_scanner.c"
+#line 739 "Zend/zend_ini_scanner.c"
yy34:
YYDEBUG(34, *YYCURSOR);
++YYCURSOR;
@@ -769,36 +767,36 @@ yy39:
YYFILL(1);
yych = *YYCURSOR;
YYDEBUG(40, *YYCURSOR);
- if (yych <= '%') {
- if (yych <= '\r') {
- if (yych <= '\t') {
+ if (yych <= '&') {
+ if (yych <= 0x1F) {
+ if (yych <= '\n') {
if (yych <= 0x08) goto yy25;
- goto yy42;
+ if (yych <= '\t') goto yy42;
} else {
- if (yych <= '\n') goto yy41;
- if (yych <= '\f') goto yy25;
+ if (yych != '\r') goto yy25;
}
} else {
- if (yych <= '"') {
- if (yych <= 0x1F) goto yy25;
+ if (yych <= '#') {
if (yych <= ' ') goto yy39;
+ if (yych >= '#') goto yy25;
} else {
- if (yych != '$') goto yy25;
+ if (yych == '%') goto yy25;
}
}
} else {
- if (yych <= '<') {
- if (yych <= ')') {
- if (yych == '\'') goto yy25;
+ if (yych <= '=') {
+ if (yych <= ':') {
+ if (yych <= '\'') goto yy25;
+ if (yych >= '*') goto yy25;
} else {
- if (yych != ';') goto yy25;
+ if (yych == '<') goto yy25;
}
} else {
- if (yych <= '[') {
- if (yych <= '=') goto yy41;
- if (yych <= 'Z') goto yy25;
- goto yy28;
+ if (yych <= ']') {
+ if (yych == '[') goto yy28;
+ goto yy25;
} else {
+ if (yych <= '^') goto yy41;
if (yych <= 'z') goto yy25;
if (yych >= 0x7F) goto yy25;
}
@@ -811,7 +809,7 @@ yy41:
{ /* FALSE value (when used outside option value/offset this causes parse error!)*/
RETURN_TOKEN(BOOL_FALSE, "", 0);
}
-#line 815 "Zend/zend_ini_scanner.c"
+#line 813 "Zend/zend_ini_scanner.c"
yy42:
YYDEBUG(42, *YYCURSOR);
++YYCURSOR;
@@ -824,7 +822,7 @@ yy42:
yy44:
YYDEBUG(44, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych <= '&') {
+ if (yych <= '\'') {
if (yych <= 0x1F) {
if (yych <= '\n') {
if (yych <= 0x08) goto yy26;
@@ -841,22 +839,24 @@ yy44:
goto yy26;
} else {
if (yych == '%') goto yy26;
- goto yy41;
+ if (yych <= '&') goto yy41;
+ goto yy26;
}
}
} else {
- if (yych <= '=') {
- if (yych <= ':') {
- if (yych <= '\'') goto yy26;
+ if (yych <= 'N') {
+ if (yych <= ';') {
if (yych <= ')') goto yy41;
- goto yy26;
- } else {
- if (yych == '<') goto yy26;
+ if (yych <= ':') goto yy26;
goto yy41;
+ } else {
+ if (yych == '=') goto yy41;
+ if (yych <= 'M') goto yy26;
+ goto yy47;
}
} else {
if (yych <= 'm') {
- if (yych == 'N') goto yy47;
+ if (yych == '^') goto yy41;
goto yy26;
} else {
if (yych <= 'n') goto yy47;
@@ -946,35 +946,34 @@ yy58:
yych = *YYCURSOR;
yy59:
YYDEBUG(59, *YYCURSOR);
- if (yych <= '&') {
- if (yych <= '\r') {
- if (yych <= '\t') {
+ if (yych <= '\'') {
+ if (yych <= ' ') {
+ if (yych <= '\n') {
if (yych <= 0x08) goto yy58;
+ if (yych >= '\n') goto yy64;
} else {
- if (yych <= '\n') goto yy64;
- if (yych <= '\f') goto yy58;
- goto yy66;
+ if (yych == '\r') goto yy66;
+ goto yy58;
}
} else {
- if (yych <= '#') {
- if (yych <= ' ') goto yy58;
- if (yych >= '#') goto yy58;
+ if (yych <= '$') {
+ if (yych == '#') goto yy58;
} else {
- if (yych == '%') goto yy58;
+ if (yych != '&') goto yy58;
}
}
} else {
- if (yych <= '<') {
- if (yych <= ')') {
- if (yych <= '\'') goto yy58;
+ if (yych <= 'Z') {
+ if (yych <= ';') {
+ if (yych <= ')') goto yy60;
+ if (yych <= ':') goto yy58;
} else {
- if (yych != ';') goto yy58;
+ if (yych != '=') goto yy58;
}
} else {
- if (yych <= '[') {
- if (yych <= '=') goto yy60;
- if (yych <= 'Z') goto yy58;
- goto yy62;
+ if (yych <= '^') {
+ if (yych <= '[') goto yy62;
+ if (yych <= ']') goto yy58;
} else {
if (yych <= 'z') goto yy58;
if (yych >= 0x7F) goto yy58;
@@ -1019,7 +1018,7 @@ yy65:
SCNG(lineno)++;
return END_OF_LINE;
}
-#line 1023 "Zend/zend_ini_scanner.c"
+#line 1022 "Zend/zend_ini_scanner.c"
yy66:
YYDEBUG(66, *YYCURSOR);
yych = *++YYCURSOR;
@@ -1060,42 +1059,42 @@ yy69:
YYFILL(2);
yych = *YYCURSOR;
YYDEBUG(70, *YYCURSOR);
- if (yych <= '%') {
- if (yych <= '\r') {
- if (yych <= '\t') {
+ if (yych <= '&') {
+ if (yych <= 0x1F) {
+ if (yych <= '\n') {
if (yych <= 0x08) goto yy25;
- goto yy67;
+ if (yych <= '\t') goto yy67;
} else {
- if (yych <= '\n') goto yy71;
- if (yych <= '\f') goto yy25;
- goto yy72;
+ if (yych == '\r') goto yy72;
+ goto yy25;
}
} else {
- if (yych <= '"') {
- if (yych <= 0x1F) goto yy25;
+ if (yych <= '#') {
if (yych <= ' ') goto yy69;
- goto yy3;
+ if (yych <= '"') goto yy3;
+ goto yy58;
} else {
- if (yych <= '#') goto yy58;
- if (yych <= '$') goto yy3;
- goto yy25;
+ if (yych == '%') goto yy25;
+ goto yy3;
}
}
} else {
- if (yych <= '<') {
- if (yych <= ')') {
- if (yych == '\'') goto yy25;
- goto yy3;
- } else {
- if (yych == ';') goto yy53;
+ if (yych <= '=') {
+ if (yych <= ':') {
+ if (yych <= '\'') goto yy25;
+ if (yych <= ')') goto yy3;
goto yy25;
+ } else {
+ if (yych <= ';') goto yy53;
+ if (yych <= '<') goto yy25;
+ goto yy51;
}
} else {
- if (yych <= '[') {
- if (yych <= '=') goto yy51;
- if (yych <= 'Z') goto yy25;
- goto yy28;
+ if (yych <= ']') {
+ if (yych == '[') goto yy28;
+ goto yy25;
} else {
+ if (yych <= '^') goto yy3;
if (yych <= 'z') goto yy25;
if (yych <= '~') goto yy3;
goto yy25;
@@ -1195,7 +1194,7 @@ yy76:
zend_ini_escape_string(ini_lval, yytext, yyleng, '"' TSRMLS_CC);
return TC_QUOTED_STRING;
}
-#line 1199 "Zend/zend_ini_scanner.c"
+#line 1198 "Zend/zend_ini_scanner.c"
yy77:
YYDEBUG(77, *YYCURSOR);
++YYCURSOR;
@@ -1209,7 +1208,7 @@ yy78:
yy_pop_state(TSRMLS_C);
return '"';
}
-#line 1213 "Zend/zend_ini_scanner.c"
+#line 1212 "Zend/zend_ini_scanner.c"
yy79:
YYDEBUG(79, *YYCURSOR);
yych = *++YYCURSOR;
@@ -1223,7 +1222,7 @@ yy79:
yy_push_state(ST_VARNAME TSRMLS_CC);
return TC_DOLLAR_CURLY;
}
-#line 1227 "Zend/zend_ini_scanner.c"
+#line 1226 "Zend/zend_ini_scanner.c"
yy82:
YYDEBUG(82, *YYCURSOR);
++YYCURSOR;
@@ -1327,7 +1326,7 @@ yy87:
{ /* Get rest as section/offset value */
RETURN_TOKEN(TC_STRING, yytext, yyleng);
}
-#line 1331 "Zend/zend_ini_scanner.c"
+#line 1330 "Zend/zend_ini_scanner.c"
yy88:
YYDEBUG(88, *YYCURSOR);
yyaccept = 0;
@@ -1348,7 +1347,7 @@ yy90:
{
return 0;
}
-#line 1352 "Zend/zend_ini_scanner.c"
+#line 1351 "Zend/zend_ini_scanner.c"
yy91:
YYDEBUG(91, *YYCURSOR);
++YYCURSOR;
@@ -1360,7 +1359,7 @@ yy92:
yy_push_state(ST_DOUBLE_QUOTES TSRMLS_CC);
return '"';
}
-#line 1364 "Zend/zend_ini_scanner.c"
+#line 1363 "Zend/zend_ini_scanner.c"
yy93:
YYDEBUG(93, *YYCURSOR);
yych = *++YYCURSOR;
@@ -1426,7 +1425,7 @@ yy98:
{ /* Get number option value as string */
RETURN_TOKEN(TC_NUMBER, yytext, yyleng);
}
-#line 1430 "Zend/zend_ini_scanner.c"
+#line 1429 "Zend/zend_ini_scanner.c"
yy99:
YYDEBUG(99, *YYCURSOR);
yyaccept = 3;
@@ -1456,7 +1455,7 @@ yy100:
{ /* Get constant option value */
RETURN_TOKEN(TC_CONSTANT, yytext, yyleng);
}
-#line 1460 "Zend/zend_ini_scanner.c"
+#line 1459 "Zend/zend_ini_scanner.c"
yy101:
YYDEBUG(101, *YYCURSOR);
yych = *++YYCURSOR;
@@ -1472,7 +1471,7 @@ yy103:
BEGIN(INITIAL);
return ']';
}
-#line 1476 "Zend/zend_ini_scanner.c"
+#line 1475 "Zend/zend_ini_scanner.c"
yy104:
YYDEBUG(104, *YYCURSOR);
yyaccept = 0;
@@ -1771,7 +1770,7 @@ yy125:
}
RETURN_TOKEN(TC_RAW, yytext, yyleng);
}
-#line 1775 "Zend/zend_ini_scanner.c"
+#line 1774 "Zend/zend_ini_scanner.c"
yy129:
YYDEBUG(129, *YYCURSOR);
++YYCURSOR;
@@ -1782,7 +1781,7 @@ yy129:
yy_push_state(ST_VARNAME TSRMLS_CC);
return TC_DOLLAR_CURLY;
}
-#line 1786 "Zend/zend_ini_scanner.c"
+#line 1785 "Zend/zend_ini_scanner.c"
yy131:
YYDEBUG(131, *YYCURSOR);
yyaccept = 0;
@@ -1892,7 +1891,7 @@ yyc_ST_RAW:
BEGIN(INITIAL);
return END_OF_LINE;
}
-#line 1896 "Zend/zend_ini_scanner.c"
+#line 1895 "Zend/zend_ini_scanner.c"
yy139:
YYDEBUG(139, *YYCURSOR);
++YYCURSOR;
@@ -1936,7 +1935,7 @@ end_raw_value_chars:
}
RETURN_TOKEN(TC_RAW, yytext, yyleng);
}
-#line 1940 "Zend/zend_ini_scanner.c"
+#line 1939 "Zend/zend_ini_scanner.c"
yy141:
YYDEBUG(141, *YYCURSOR);
yyaccept = 0;
@@ -1967,7 +1966,7 @@ yy143:
SCNG(lineno)++;
return END_OF_LINE;
}
-#line 1971 "Zend/zend_ini_scanner.c"
+#line 1970 "Zend/zend_ini_scanner.c"
yy144:
YYDEBUG(144, *YYCURSOR);
yych = *++YYCURSOR;
@@ -2001,7 +2000,7 @@ yy149:
SCNG(lineno)++;
return END_OF_LINE;
}
-#line 2005 "Zend/zend_ini_scanner.c"
+#line 2004 "Zend/zend_ini_scanner.c"
yy150:
YYDEBUG(150, *YYCURSOR);
yych = *++YYCURSOR;
@@ -2035,7 +2034,7 @@ yy153:
/* eat whitespace */
goto restart;
}
-#line 2039 "Zend/zend_ini_scanner.c"
+#line 2038 "Zend/zend_ini_scanner.c"
yy155:
YYDEBUG(155, *YYCURSOR);
++YYCURSOR;
@@ -2099,7 +2098,7 @@ yy159:
{ /* Raw value, only used when SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW. */
RETURN_TOKEN(TC_RAW, yytext, yyleng);
}
-#line 2103 "Zend/zend_ini_scanner.c"
+#line 2102 "Zend/zend_ini_scanner.c"
yy160:
YYDEBUG(160, *YYCURSOR);
++YYCURSOR;
@@ -2109,7 +2108,7 @@ yy160:
{
return 0;
}
-#line 2113 "Zend/zend_ini_scanner.c"
+#line 2112 "Zend/zend_ini_scanner.c"
yy162:
YYDEBUG(162, *YYCURSOR);
++YYCURSOR;
@@ -2124,7 +2123,7 @@ yy163:
SCNG(lineno)++;
return ']';
}
-#line 2128 "Zend/zend_ini_scanner.c"
+#line 2127 "Zend/zend_ini_scanner.c"
yy164:
YYDEBUG(164, *YYCURSOR);
++YYCURSOR;
@@ -2250,7 +2249,7 @@ yy173:
{ /* Get rest as section/offset value */
RETURN_TOKEN(TC_STRING, yytext, yyleng);
}
-#line 2254 "Zend/zend_ini_scanner.c"
+#line 2253 "Zend/zend_ini_scanner.c"
yy174:
YYDEBUG(174, *YYCURSOR);
yyaccept = 0;
@@ -2273,7 +2272,7 @@ yy176:
{
return 0;
}
-#line 2277 "Zend/zend_ini_scanner.c"
+#line 2276 "Zend/zend_ini_scanner.c"
yy177:
YYDEBUG(177, *YYCURSOR);
++YYCURSOR;
@@ -2285,7 +2284,7 @@ yy178:
yy_push_state(ST_DOUBLE_QUOTES TSRMLS_CC);
return '"';
}
-#line 2289 "Zend/zend_ini_scanner.c"
+#line 2288 "Zend/zend_ini_scanner.c"
yy179:
YYDEBUG(179, *YYCURSOR);
yych = *++YYCURSOR;
@@ -2351,7 +2350,7 @@ yy184:
{ /* Get number option value as string */
RETURN_TOKEN(TC_NUMBER, yytext, yyleng);
}
-#line 2355 "Zend/zend_ini_scanner.c"
+#line 2354 "Zend/zend_ini_scanner.c"
yy185:
YYDEBUG(185, *YYCURSOR);
yyaccept = 3;
@@ -2381,7 +2380,7 @@ yy186:
{ /* Get constant option value */
RETURN_TOKEN(TC_CONSTANT, yytext, yyleng);
}
-#line 2385 "Zend/zend_ini_scanner.c"
+#line 2384 "Zend/zend_ini_scanner.c"
yy187:
YYDEBUG(187, *YYCURSOR);
yych = *++YYCURSOR;
@@ -2400,7 +2399,7 @@ yy189:
SCNG(lineno)++;
return ']';
}
-#line 2404 "Zend/zend_ini_scanner.c"
+#line 2403 "Zend/zend_ini_scanner.c"
yy190:
YYDEBUG(190, *YYCURSOR);
++YYCURSOR;
@@ -2721,7 +2720,7 @@ yy215:
}
RETURN_TOKEN(TC_RAW, yytext, yyleng);
}
-#line 2725 "Zend/zend_ini_scanner.c"
+#line 2724 "Zend/zend_ini_scanner.c"
yy219:
YYDEBUG(219, *YYCURSOR);
++YYCURSOR;
@@ -2732,7 +2731,7 @@ yy219:
yy_push_state(ST_VARNAME TSRMLS_CC);
return TC_DOLLAR_CURLY;
}
-#line 2736 "Zend/zend_ini_scanner.c"
+#line 2735 "Zend/zend_ini_scanner.c"
yy221:
YYDEBUG(221, *YYCURSOR);
yyaccept = 0;
@@ -2796,7 +2795,7 @@ yyc_ST_VALUE:
162, 166, 166, 166, 166, 166, 166, 166,
166, 166, 166, 166, 166, 166, 166, 166,
166, 166, 166, 166, 166, 166, 166, 166,
- 166, 166, 166, 162, 162, 162, 162, 166,
+ 166, 166, 166, 162, 162, 162, 160, 166,
162, 166, 166, 166, 166, 166, 166, 166,
166, 166, 166, 166, 166, 166, 166, 166,
166, 166, 166, 166, 166, 166, 166, 166,
@@ -2832,6 +2831,7 @@ yyc_ST_VALUE:
case '&':
case '(':
case ')':
+ case '^':
case '|':
case '~': goto yy235;
case '"': goto yy237;
@@ -3024,35 +3024,34 @@ yy243:
YYDEBUG(243, *YYCURSOR);
yyaccept = 3;
yych = *(YYMARKER = ++YYCURSOR);
- if (yych <= '.') {
- if (yych <= '\r') {
- if (yych <= 0x08) {
- if (yych >= 0x01) goto yy256;
+ if (yych <= '/') {
+ if (yych <= 0x1F) {
+ if (yych <= '\n') {
+ if (yych <= 0x00) goto yy244;
+ if (yych <= 0x08) goto yy256;
} else {
- if (yych <= '\n') goto yy244;
- if (yych <= '\f') goto yy256;
+ if (yych != '\r') goto yy256;
}
} else {
- if (yych <= '%') {
- if (yych <= 0x1F) goto yy256;
- if (yych >= '#') goto yy256;
+ if (yych <= ')') {
+ if (yych <= '"') goto yy244;
+ if (yych <= '%') goto yy256;
} else {
- if (yych <= ')') goto yy244;
- if (yych <= '-') goto yy256;
- goto yy288;
+ if (yych == '.') goto yy288;
+ goto yy256;
}
}
} else {
- if (yych <= '<') {
- if (yych <= '9') {
- if (yych <= '/') goto yy256;
- goto yy290;
+ if (yych <= ']') {
+ if (yych <= ';') {
+ if (yych <= '9') goto yy290;
+ if (yych <= ':') goto yy256;
} else {
- if (yych != ';') goto yy256;
+ if (yych != '=') goto yy256;
}
} else {
if (yych <= '|') {
- if (yych <= '=') goto yy244;
+ if (yych <= '^') goto yy244;
if (yych <= '{') goto yy256;
} else {
if (yych != '~') goto yy256;
@@ -3066,7 +3065,7 @@ yy244:
{ /* Get number option value as string */
RETURN_TOKEN(TC_NUMBER, yytext, yyleng);
}
-#line 3070 "Zend/zend_ini_scanner.c"
+#line 3069 "Zend/zend_ini_scanner.c"
yy245:
YYDEBUG(245, *YYCURSOR);
yyaccept = 2;
@@ -3083,7 +3082,7 @@ yy246:
BEGIN(INITIAL);
return END_OF_LINE;
}
-#line 3087 "Zend/zend_ini_scanner.c"
+#line 3086 "Zend/zend_ini_scanner.c"
yy248:
YYDEBUG(248, *YYCURSOR);
yyaccept = 4;
@@ -3091,23 +3090,30 @@ yy248:
if (yybm[0+yych] & 4) {
goto yy257;
}
- if (yych <= ')') {
- if (yych <= '\f') {
- if (yych <= 0x00) goto yy249;
- if (yych <= 0x08) goto yy256;
- if (yych >= '\v') goto yy256;
+ if (yych <= ':') {
+ if (yych <= '\r') {
+ if (yych <= 0x08) {
+ if (yych >= 0x01) goto yy256;
+ } else {
+ if (yych <= '\n') goto yy249;
+ if (yych <= '\f') goto yy256;
+ }
} else {
- if (yych <= 0x1F) {
- if (yych >= 0x0E) goto yy256;
+ if (yych <= '"') {
+ if (yych <= 0x1F) goto yy256;
} else {
- if (yych <= '"') goto yy249;
if (yych <= '%') goto yy256;
+ if (yych >= '*') goto yy256;
}
}
} else {
- if (yych <= '=') {
- if (yych == ';') goto yy249;
- if (yych <= '<') goto yy256;
+ if (yych <= '^') {
+ if (yych <= '<') {
+ if (yych >= '<') goto yy256;
+ } else {
+ if (yych <= '=') goto yy249;
+ if (yych <= ']') goto yy256;
+ }
} else {
if (yych <= '|') {
if (yych <= '{') goto yy256;
@@ -3123,7 +3129,7 @@ yy249:
{ /* Get constant option value */
RETURN_TOKEN(TC_CONSTANT, yytext, yyleng);
}
-#line 3127 "Zend/zend_ini_scanner.c"
+#line 3133 "Zend/zend_ini_scanner.c"
yy250:
YYDEBUG(250, *YYCURSOR);
yyaccept = 4;
@@ -3151,18 +3157,20 @@ yy250:
}
}
} else {
- if (yych <= '`') {
+ if (yych <= '_') {
if (yych <= 'A') {
if (yych <= '=') goto yy249;
if (yych <= '@') goto yy256;
goto yy280;
} else {
if (yych <= 'Z') goto yy257;
- if (yych == '_') goto yy257;
- goto yy256;
+ if (yych <= ']') goto yy256;
+ if (yych <= '^') goto yy249;
+ goto yy257;
}
} else {
if (yych <= '{') {
+ if (yych <= '`') goto yy256;
if (yych <= 'a') goto yy280;
if (yych <= 'z') goto yy257;
goto yy256;
@@ -3214,9 +3222,13 @@ yy251:
if (yych == 'U') goto yy277;
goto yy257;
} else {
- if (yych == '_') goto yy257;
- if (yych <= '`') goto yy256;
- goto yy257;
+ if (yych <= '^') {
+ if (yych <= ']') goto yy256;
+ goto yy249;
+ } else {
+ if (yych == '`') goto yy256;
+ goto yy257;
+ }
}
} else {
if (yych <= 'z') {
@@ -3275,9 +3287,13 @@ yy252:
if (yych == 'N') goto yy265;
goto yy257;
} else {
- if (yych == '_') goto yy257;
- if (yych <= '`') goto yy256;
- goto yy257;
+ if (yych <= '^') {
+ if (yych <= ']') goto yy256;
+ goto yy249;
+ } else {
+ if (yych == '`') goto yy256;
+ goto yy257;
+ }
}
} else {
if (yych <= 'z') {
@@ -3324,13 +3340,14 @@ yy253:
}
} else {
if (yych <= '`') {
- if (yych <= 'R') {
+ if (yych <= 'Z') {
if (yych <= '@') goto yy256;
- if (yych <= 'Q') goto yy257;
- goto yy269;
+ if (yych == 'R') goto yy269;
+ goto yy257;
} else {
- if (yych <= 'Z') goto yy257;
- if (yych == '_') goto yy257;
+ if (yych <= ']') goto yy256;
+ if (yych <= '^') goto yy249;
+ if (yych <= '_') goto yy257;
goto yy256;
}
} else {
@@ -3374,13 +3391,14 @@ yy254:
}
} else {
if (yych <= '`') {
- if (yych <= 'E') {
+ if (yych <= 'Z') {
if (yych <= '@') goto yy256;
- if (yych <= 'D') goto yy257;
- goto yy259;
+ if (yych == 'E') goto yy259;
+ goto yy257;
} else {
- if (yych <= 'Z') goto yy257;
- if (yych == '_') goto yy257;
+ if (yych <= ']') goto yy256;
+ if (yych <= '^') goto yy249;
+ if (yych <= '_') goto yy257;
goto yy256;
}
} else {
@@ -3418,7 +3436,7 @@ yy257:
if (yybm[0+yych] & 4) {
goto yy257;
}
- if (yych <= '%') {
+ if (yych <= ')') {
if (yych <= '\r') {
if (yych <= 0x08) {
if (yych <= 0x00) goto yy249;
@@ -3429,25 +3447,28 @@ yy257:
goto yy249;
}
} else {
- if (yych <= '"') {
+ if (yych <= '#') {
if (yych <= 0x1F) goto yy255;
- goto yy249;
- } else {
- if (yych == '$') goto yy260;
+ if (yych <= '"') goto yy249;
goto yy255;
+ } else {
+ if (yych <= '$') goto yy260;
+ if (yych <= '%') goto yy255;
+ goto yy249;
}
}
} else {
- if (yych <= '=') {
- if (yych <= ':') {
- if (yych <= ')') goto yy249;
- goto yy255;
- } else {
- if (yych == '<') goto yy255;
+ if (yych <= ']') {
+ if (yych <= ';') {
+ if (yych <= ':') goto yy255;
goto yy249;
+ } else {
+ if (yych == '=') goto yy249;
+ goto yy255;
}
} else {
if (yych <= '|') {
+ if (yych <= '^') goto yy249;
if (yych <= '{') goto yy255;
goto yy249;
} else {
@@ -3485,13 +3506,14 @@ yy259:
}
} else {
if (yych <= '`') {
- if (yych <= 'S') {
+ if (yych <= 'Z') {
if (yych <= '@') goto yy256;
- if (yych <= 'R') goto yy257;
- goto yy265;
+ if (yych == 'S') goto yy265;
+ goto yy257;
} else {
- if (yych <= 'Z') goto yy257;
- if (yych == '_') goto yy257;
+ if (yych <= ']') goto yy256;
+ if (yych <= '^') goto yy249;
+ if (yych <= '_') goto yy257;
goto yy256;
}
} else {
@@ -3598,8 +3620,8 @@ yy265:
if (yych != '=') goto yy256;
} else {
if (yych <= 'Z') goto yy257;
- if (yych <= '^') goto yy256;
- goto yy257;
+ if (yych <= ']') goto yy256;
+ if (yych >= '_') goto yy257;
}
} else {
if (yych <= '{') {
@@ -3619,7 +3641,7 @@ yy266:
{ /* TRUE value (when used outside option value/offset this causes parse error!) */
RETURN_TOKEN(BOOL_TRUE, "1", 1);
}
-#line 3623 "Zend/zend_ini_scanner.c"
+#line 3645 "Zend/zend_ini_scanner.c"
yy267:
YYDEBUG(267, *YYCURSOR);
++YYCURSOR;
@@ -3659,12 +3681,13 @@ yy269:
}
} else {
if (yych <= '`') {
- if (yych <= 'U') {
+ if (yych <= 'Z') {
if (yych <= '@') goto yy256;
- if (yych <= 'T') goto yy257;
+ if (yych != 'U') goto yy257;
} else {
- if (yych <= 'Z') goto yy257;
- if (yych == '_') goto yy257;
+ if (yych <= ']') goto yy256;
+ if (yych <= '^') goto yy249;
+ if (yych <= '_') goto yy257;
goto yy256;
}
} else {
@@ -3708,13 +3731,14 @@ yy270:
}
} else {
if (yych <= '`') {
- if (yych <= 'E') {
+ if (yych <= 'Z') {
if (yych <= '@') goto yy256;
- if (yych <= 'D') goto yy257;
- goto yy265;
+ if (yych == 'E') goto yy265;
+ goto yy257;
} else {
- if (yych <= 'Z') goto yy257;
- if (yych == '_') goto yy257;
+ if (yych <= ']') goto yy256;
+ if (yych <= '^') goto yy249;
+ if (yych <= '_') goto yy257;
goto yy256;
}
} else {
@@ -3758,12 +3782,13 @@ yy271:
}
} else {
if (yych <= '`') {
- if (yych <= 'F') {
+ if (yych <= 'Z') {
if (yych <= '@') goto yy256;
- if (yych <= 'E') goto yy257;
+ if (yych != 'F') goto yy257;
} else {
- if (yych <= 'Z') goto yy257;
- if (yych == '_') goto yy257;
+ if (yych <= ']') goto yy256;
+ if (yych <= '^') goto yy249;
+ if (yych <= '_') goto yy257;
goto yy256;
}
} else {
@@ -3785,7 +3810,7 @@ yy272:
if (yybm[0+yych] & 4) {
goto yy257;
}
- if (yych <= '%') {
+ if (yych <= ')') {
if (yych <= '\f') {
if (yych <= 0x08) {
if (yych >= 0x01) goto yy256;
@@ -3794,22 +3819,25 @@ yy272:
if (yych >= '\v') goto yy256;
}
} else {
- if (yych <= 0x1F) {
- if (yych >= 0x0E) goto yy256;
+ if (yych <= ' ') {
+ if (yych <= '\r') goto yy273;
+ if (yych <= 0x1F) goto yy256;
+ goto yy274;
} else {
- if (yych <= ' ') goto yy274;
- if (yych >= '#') goto yy256;
+ if (yych <= '"') goto yy273;
+ if (yych <= '%') goto yy256;
}
}
} else {
- if (yych <= '=') {
- if (yych <= ':') {
- if (yych >= '*') goto yy256;
+ if (yych <= ']') {
+ if (yych <= ';') {
+ if (yych <= ':') goto yy256;
} else {
- if (yych == '<') goto yy256;
+ if (yych != '=') goto yy256;
}
} else {
if (yych <= '|') {
+ if (yych <= '^') goto yy273;
if (yych <= '{') goto yy256;
} else {
if (yych != '~') goto yy256;
@@ -3823,7 +3851,7 @@ yy273:
{ /* FALSE value (when used outside option value/offset this causes parse error!)*/
RETURN_TOKEN(BOOL_FALSE, "", 0);
}
-#line 3827 "Zend/zend_ini_scanner.c"
+#line 3855 "Zend/zend_ini_scanner.c"
yy274:
YYDEBUG(274, *YYCURSOR);
++YYCURSOR;
@@ -3862,7 +3890,7 @@ yy276:
}
}
} else {
- if (yych <= '`') {
+ if (yych <= '_') {
if (yych <= 'N') {
if (yych <= '=') goto yy273;
if (yych <= '@') goto yy256;
@@ -3870,18 +3898,23 @@ yy276:
goto yy279;
} else {
if (yych <= 'Z') goto yy257;
- if (yych == '_') goto yy257;
- goto yy256;
+ if (yych <= ']') goto yy256;
+ if (yych <= '^') goto yy273;
+ goto yy257;
}
} else {
- if (yych <= '{') {
+ if (yych <= 'z') {
+ if (yych <= '`') goto yy256;
if (yych == 'n') goto yy279;
- if (yych <= 'z') goto yy257;
- goto yy256;
+ goto yy257;
} else {
- if (yych == '}') goto yy256;
- if (yych <= '~') goto yy273;
- goto yy256;
+ if (yych <= '|') {
+ if (yych <= '{') goto yy256;
+ goto yy273;
+ } else {
+ if (yych == '~') goto yy273;
+ goto yy256;
+ }
}
}
}
@@ -3914,12 +3947,13 @@ yy277:
}
} else {
if (yych <= '`') {
- if (yych <= 'L') {
+ if (yych <= 'Z') {
if (yych <= '@') goto yy256;
- if (yych <= 'K') goto yy257;
+ if (yych != 'L') goto yy257;
} else {
- if (yych <= 'Z') goto yy257;
- if (yych == '_') goto yy257;
+ if (yych <= ']') goto yy256;
+ if (yych <= '^') goto yy249;
+ if (yych <= '_') goto yy257;
goto yy256;
}
} else {
@@ -3963,13 +3997,14 @@ yy278:
}
} else {
if (yych <= '`') {
- if (yych <= 'L') {
+ if (yych <= 'Z') {
if (yych <= '@') goto yy256;
- if (yych <= 'K') goto yy257;
- goto yy272;
+ if (yych == 'L') goto yy272;
+ goto yy257;
} else {
- if (yych <= 'Z') goto yy257;
- if (yych == '_') goto yy257;
+ if (yych <= ']') goto yy256;
+ if (yych <= '^') goto yy249;
+ if (yych <= '_') goto yy257;
goto yy256;
}
} else {
@@ -4013,13 +4048,14 @@ yy279:
}
} else {
if (yych <= '`') {
- if (yych <= 'E') {
+ if (yych <= 'Z') {
if (yych <= '@') goto yy256;
- if (yych <= 'D') goto yy257;
- goto yy272;
+ if (yych == 'E') goto yy272;
+ goto yy257;
} else {
- if (yych <= 'Z') goto yy257;
- if (yych == '_') goto yy257;
+ if (yych <= ']') goto yy256;
+ if (yych <= '^') goto yy249;
+ if (yych <= '_') goto yy257;
goto yy256;
}
} else {
@@ -4063,12 +4099,13 @@ yy280:
}
} else {
if (yych <= '`') {
- if (yych <= 'L') {
+ if (yych <= 'Z') {
if (yych <= '@') goto yy256;
- if (yych <= 'K') goto yy257;
+ if (yych != 'L') goto yy257;
} else {
- if (yych <= 'Z') goto yy257;
- if (yych == '_') goto yy257;
+ if (yych <= ']') goto yy256;
+ if (yych <= '^') goto yy249;
+ if (yych <= '_') goto yy257;
goto yy256;
}
} else {
@@ -4112,12 +4149,13 @@ yy281:
}
} else {
if (yych <= '`') {
- if (yych <= 'S') {
+ if (yych <= 'Z') {
if (yych <= '@') goto yy256;
- if (yych <= 'R') goto yy257;
+ if (yych != 'S') goto yy257;
} else {
- if (yych <= 'Z') goto yy257;
- if (yych == '_') goto yy257;
+ if (yych <= ']') goto yy256;
+ if (yych <= '^') goto yy249;
+ if (yych <= '_') goto yy257;
goto yy256;
}
} else {
@@ -4161,13 +4199,14 @@ yy282:
}
} else {
if (yych <= '`') {
- if (yych <= 'E') {
+ if (yych <= 'Z') {
if (yych <= '@') goto yy256;
- if (yych <= 'D') goto yy257;
- goto yy272;
+ if (yych == 'E') goto yy272;
+ goto yy257;
} else {
- if (yych <= 'Z') goto yy257;
- if (yych == '_') goto yy257;
+ if (yych <= ']') goto yy256;
+ if (yych <= '^') goto yy249;
+ if (yych <= '_') goto yy257;
goto yy256;
}
} else {
@@ -4205,7 +4244,7 @@ yy286:
SCNG(lineno)++;
return END_OF_LINE;
}
-#line 4209 "Zend/zend_ini_scanner.c"
+#line 4248 "Zend/zend_ini_scanner.c"
yy287:
YYDEBUG(287, *YYCURSOR);
yych = *++YYCURSOR;
@@ -4221,7 +4260,7 @@ yy288:
if (yybm[0+yych] & 64) {
goto yy288;
}
- if (yych <= '%') {
+ if (yych <= ')') {
if (yych <= '\r') {
if (yych <= 0x08) {
if (yych <= 0x00) goto yy244;
@@ -4232,25 +4271,28 @@ yy288:
goto yy244;
}
} else {
- if (yych <= '"') {
+ if (yych <= '#') {
if (yych <= 0x1F) goto yy255;
- goto yy244;
- } else {
- if (yych == '$') goto yy260;
+ if (yych <= '"') goto yy244;
goto yy255;
+ } else {
+ if (yych <= '$') goto yy260;
+ if (yych <= '%') goto yy255;
+ goto yy244;
}
}
} else {
- if (yych <= '=') {
- if (yych <= ':') {
- if (yych <= ')') goto yy244;
- goto yy255;
- } else {
- if (yych == '<') goto yy255;
+ if (yych <= ']') {
+ if (yych <= ';') {
+ if (yych <= ':') goto yy255;
goto yy244;
+ } else {
+ if (yych == '=') goto yy244;
+ goto yy255;
}
} else {
if (yych <= '|') {
+ if (yych <= '^') goto yy244;
if (yych <= '{') goto yy255;
goto yy244;
} else {
@@ -4266,7 +4308,7 @@ yy290:
YYFILL(1);
yych = *YYCURSOR;
YYDEBUG(291, *YYCURSOR);
- if (yych <= '-') {
+ if (yych <= '.') {
if (yych <= 0x1F) {
if (yych <= '\n') {
if (yych <= 0x00) goto yy244;
@@ -4284,26 +4326,27 @@ yy290:
} else {
if (yych <= '%') goto yy255;
if (yych <= ')') goto yy244;
- goto yy255;
+ if (yych <= '-') goto yy255;
+ goto yy288;
}
}
} else {
- if (yych <= '<') {
- if (yych <= '9') {
- if (yych <= '.') goto yy288;
+ if (yych <= '=') {
+ if (yych <= ':') {
if (yych <= '/') goto yy255;
- goto yy290;
- } else {
- if (yych == ';') goto yy244;
+ if (yych <= '9') goto yy290;
goto yy255;
+ } else {
+ if (yych == '<') goto yy255;
+ goto yy244;
}
} else {
- if (yych <= '|') {
- if (yych <= '=') goto yy244;
- if (yych <= '{') goto yy255;
- goto yy244;
+ if (yych <= '{') {
+ if (yych == '^') goto yy244;
+ goto yy255;
} else {
- if (yych == '~') goto yy244;
+ if (yych == '}') goto yy255;
+ if (yych <= '~') goto yy244;
goto yy255;
}
}
@@ -4315,39 +4358,40 @@ yy292:
YYFILL(1);
yych = *YYCURSOR;
YYDEBUG(293, *YYCURSOR);
- if (yych <= ')') {
- if (yych <= '\r') {
- if (yych <= 0x08) {
+ if (yych <= '/') {
+ if (yych <= 0x1F) {
+ if (yych <= '\n') {
if (yych <= 0x00) goto yy244;
- goto yy255;
- } else {
- if (yych <= '\n') goto yy244;
- if (yych <= '\f') goto yy255;
+ if (yych <= 0x08) goto yy255;
goto yy244;
+ } else {
+ if (yych == '\r') goto yy244;
+ goto yy255;
}
} else {
- if (yych <= '#') {
- if (yych <= 0x1F) goto yy255;
+ if (yych <= '$') {
if (yych <= '"') goto yy244;
- goto yy255;
+ if (yych <= '#') goto yy255;
+ goto yy260;
} else {
- if (yych <= '$') goto yy260;
if (yych <= '%') goto yy255;
- goto yy244;
+ if (yych <= ')') goto yy244;
+ goto yy255;
}
}
} else {
- if (yych <= '<') {
- if (yych <= '9') {
- if (yych <= '/') goto yy255;
- goto yy292;
+ if (yych <= ']') {
+ if (yych <= ';') {
+ if (yych <= '9') goto yy292;
+ if (yych <= ':') goto yy255;
+ goto yy244;
} else {
- if (yych == ';') goto yy244;
+ if (yych == '=') goto yy244;
goto yy255;
}
} else {
if (yych <= '|') {
- if (yych <= '=') goto yy244;
+ if (yych <= '^') goto yy244;
if (yych <= '{') goto yy255;
goto yy244;
} else {
@@ -4363,39 +4407,40 @@ yy294:
YYFILL(1);
yych = *YYCURSOR;
YYDEBUG(295, *YYCURSOR);
- if (yych <= ')') {
- if (yych <= '\r') {
- if (yych <= 0x08) {
+ if (yych <= '/') {
+ if (yych <= 0x1F) {
+ if (yych <= '\n') {
if (yych <= 0x00) goto yy244;
- goto yy255;
- } else {
- if (yych <= '\n') goto yy244;
- if (yych <= '\f') goto yy255;
+ if (yych <= 0x08) goto yy255;
goto yy244;
+ } else {
+ if (yych == '\r') goto yy244;
+ goto yy255;
}
} else {
- if (yych <= '#') {
- if (yych <= 0x1F) goto yy255;
+ if (yych <= '$') {
if (yych <= '"') goto yy244;
- goto yy255;
+ if (yych <= '#') goto yy255;
+ goto yy260;
} else {
- if (yych <= '$') goto yy260;
if (yych <= '%') goto yy255;
- goto yy244;
+ if (yych <= ')') goto yy244;
+ goto yy255;
}
}
} else {
- if (yych <= '<') {
- if (yych <= '9') {
- if (yych <= '/') goto yy255;
- goto yy294;
+ if (yych <= ']') {
+ if (yych <= ';') {
+ if (yych <= '9') goto yy294;
+ if (yych <= ':') goto yy255;
+ goto yy244;
} else {
- if (yych == ';') goto yy244;
+ if (yych == '=') goto yy244;
goto yy255;
}
} else {
if (yych <= '|') {
- if (yych <= '=') goto yy244;
+ if (yych <= '^') goto yy244;
if (yych <= '{') goto yy255;
goto yy244;
} else {
@@ -4426,7 +4471,7 @@ yy296:
}
RETURN_TOKEN(TC_RAW, yytext, yyleng);
}
-#line 4430 "Zend/zend_ini_scanner.c"
+#line 4475 "Zend/zend_ini_scanner.c"
yy300:
YYDEBUG(300, *YYCURSOR);
++YYCURSOR;
@@ -4437,7 +4482,7 @@ yy300:
yy_push_state(ST_VARNAME TSRMLS_CC);
return TC_DOLLAR_CURLY;
}
-#line 4441 "Zend/zend_ini_scanner.c"
+#line 4486 "Zend/zend_ini_scanner.c"
yy302:
YYDEBUG(302, *YYCURSOR);
++YYCURSOR;
@@ -4502,7 +4547,7 @@ yyc_ST_VARNAME:
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, 0, 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,
@@ -4527,38 +4572,40 @@ yyc_ST_VARNAME:
YYDEBUG(309, *YYCURSOR);
YYFILL(2);
yych = *YYCURSOR;
- if (yych <= '\'') {
- if (yych <= ' ') {
- if (yych <= '\n') {
- if (yych >= '\t') goto yy313;
+ if (yych <= ')') {
+ if (yych <= '"') {
+ if (yych <= '\f') {
+ if (yych <= 0x08) goto yy311;
+ if (yych <= '\n') goto yy313;
} else {
- if (yych == '\r') goto yy313;
+ if (yych <= '\r') goto yy313;
+ if (yych >= '!') goto yy313;
}
} else {
- if (yych <= '$') {
- if (yych != '#') goto yy313;
+ if (yych <= '%') {
+ if (yych == '$') goto yy313;
} else {
- if (yych == '&') goto yy313;
+ if (yych != '\'') goto yy313;
}
}
} else {
- if (yych <= 'Z') {
- if (yych <= ';') {
- if (yych <= ')') goto yy313;
- if (yych >= ';') goto yy313;
+ if (yych <= '[') {
+ if (yych <= '<') {
+ if (yych == ';') goto yy313;
} else {
- if (yych == '=') goto yy313;
+ if (yych <= '=') goto yy313;
+ if (yych >= '[') goto yy313;
}
} else {
- if (yych <= '|') {
- if (yych <= '[') goto yy313;
- if (yych >= '{') goto yy313;
+ if (yych <= 'z') {
+ if (yych == '^') goto yy313;
} else {
- if (yych <= '}') goto yy315;
+ if (yych == '}') goto yy315;
if (yych <= '~') goto yy313;
}
}
}
+yy311:
YYDEBUG(311, *YYCURSOR);
++YYCURSOR;
yych = *YYCURSOR;
@@ -4576,7 +4623,7 @@ yy312:
RETURN_TOKEN(TC_VARNAME, yytext, yyleng);
}
-#line 4580 "Zend/zend_ini_scanner.c"
+#line 4627 "Zend/zend_ini_scanner.c"
yy313:
YYDEBUG(313, *YYCURSOR);
++YYCURSOR;
@@ -4586,7 +4633,7 @@ yy313:
{
return 0;
}
-#line 4590 "Zend/zend_ini_scanner.c"
+#line 4637 "Zend/zend_ini_scanner.c"
yy315:
YYDEBUG(315, *YYCURSOR);
++YYCURSOR;
@@ -4597,7 +4644,7 @@ yy315:
yy_pop_state(TSRMLS_C);
return '}';
}
-#line 4601 "Zend/zend_ini_scanner.c"
+#line 4648 "Zend/zend_ini_scanner.c"
yy317:
YYDEBUG(317, *YYCURSOR);
++YYCURSOR;
diff --git a/Zend/zend_ini_scanner.l b/Zend/zend_ini_scanner.l
index f27db6ef03..6207c76b27 100644
--- a/Zend/zend_ini_scanner.l
+++ b/Zend/zend_ini_scanner.l
@@ -340,9 +340,9 @@ NEWLINE ("\r"|"\n"|"\r\n")
TABS_AND_SPACES [ \t]
WHITESPACE [ \t]+
CONSTANT [a-zA-Z_][a-zA-Z0-9_]*
-LABEL [^=\n\r\t;|&$~(){}!"\[]+
-TOKENS [:,.\[\]"'()|^&+-/*=%$!~<>?@{}]
-OPERATORS [&|~()!]
+LABEL [^=\n\r\t;&|^$~(){}!"\[]+
+TOKENS [:,.\[\]"'()&|^+-/*=%$!~<>?@{}]
+OPERATORS [&|^~()!]
DOLLAR_CURLY "${"
SECTION_RAW_CHARS [^\]\n\r]
@@ -350,7 +350,7 @@ SINGLE_QUOTED_CHARS [^']
RAW_VALUE_CHARS [^\n\r;\000]
LITERAL_DOLLAR ("$"([^{\000]|("\\"{ANY_CHAR})))
-VALUE_CHARS ([^$= \t\n\r;&|~()!"'\000]|{LITERAL_DOLLAR})
+VALUE_CHARS ([^$= \t\n\r;&|^~()!"'\000]|{LITERAL_DOLLAR})
SECTION_VALUE_CHARS ([^$\n\r;"'\]\\]|("\\"{ANY_CHAR})|{LITERAL_DOLLAR})
<!*> := yyleng = YYCURSOR - SCNG(yy_text);
diff --git a/Zend/zend_ini_scanner_defs.h b/Zend/zend_ini_scanner_defs.h
index 1fe4c0cd44..287d7bc1fb 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 Fri Nov 16 18:24:06 2012 */
+/* Generated by re2c 0.13.5 */
#line 3 "Zend/zend_ini_scanner_defs.h"
enum YYCONDTYPE {
diff --git a/Zend/zend_interfaces.c b/Zend/zend_interfaces.c
index 7a107da8d7..4b01eb3c4f 100644
--- a/Zend/zend_interfaces.c
+++ b/Zend/zend_interfaces.c
@@ -195,7 +195,7 @@ static int zend_user_it_get_current_key_default(zend_object_iterator *_iter, cha
/* }}} */
/* {{{ zend_user_it_get_current_key */
-ZEND_API int zend_user_it_get_current_key(zend_object_iterator *_iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
+ZEND_API void zend_user_it_get_current_key(zend_object_iterator *_iter, zval *key TSRMLS_DC)
{
zend_user_iterator *iter = (zend_user_iterator*)_iter;
zval *object = (zval*)iter->it.data;
@@ -203,42 +203,16 @@ ZEND_API int zend_user_it_get_current_key(zend_object_iterator *_iter, char **st
zend_call_method_with_0_params(&object, iter->ce, &iter->ce->iterator_funcs.zf_key, "key", &retval);
- if (!retval) {
- *int_key = 0;
- if (!EG(exception))
- {
+ if (retval) {
+ ZVAL_ZVAL(key, retval, 1, 1);
+ } else {
+ if (!EG(exception)) {
zend_error(E_WARNING, "Nothing returned from %s::key()", iter->ce->name);
}
- return HASH_KEY_IS_LONG;
- }
- switch (Z_TYPE_P(retval)) {
- default:
- zend_error(E_WARNING, "Illegal type returned from %s::key()", iter->ce->name);
- case IS_NULL:
- *int_key = 0;
- zval_ptr_dtor(&retval);
- return HASH_KEY_IS_LONG;
-
- case IS_STRING:
- *str_key = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
- *str_key_len = Z_STRLEN_P(retval)+1;
- zval_ptr_dtor(&retval);
- return HASH_KEY_IS_STRING;
-
- case IS_DOUBLE:
- *int_key = (long)Z_DVAL_P(retval);
- zval_ptr_dtor(&retval);
- return HASH_KEY_IS_LONG;
- case IS_RESOURCE:
- case IS_BOOL:
- case IS_LONG:
- *int_key = (long)Z_LVAL_P(retval);
- zval_ptr_dtor(&retval);
- return HASH_KEY_IS_LONG;
+ ZVAL_LONG(key, 0);
}
}
-/* }}} */
/* {{{ zend_user_it_move_forward */
ZEND_API void zend_user_it_move_forward(zend_object_iterator *_iter TSRMLS_DC)
diff --git a/Zend/zend_interfaces.h b/Zend/zend_interfaces.h
index 7ff5fe09af..7b70bc49d4 100644
--- a/Zend/zend_interfaces.h
+++ b/Zend/zend_interfaces.h
@@ -51,7 +51,7 @@ ZEND_API zval* zend_call_method(zval **object_pp, zend_class_entry *obj_ce, zend
ZEND_API void zend_user_it_rewind(zend_object_iterator *_iter TSRMLS_DC);
ZEND_API int zend_user_it_valid(zend_object_iterator *_iter TSRMLS_DC);
-ZEND_API int zend_user_it_get_current_key(zend_object_iterator *_iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC);
+ZEND_API void zend_user_it_get_current_key(zend_object_iterator *_iter, zval *key TSRMLS_DC);
ZEND_API void zend_user_it_get_current_data(zend_object_iterator *_iter, zval ***data TSRMLS_DC);
ZEND_API void zend_user_it_move_forward(zend_object_iterator *_iter TSRMLS_DC);
ZEND_API void zend_user_it_invalidate_current(zend_object_iterator *_iter TSRMLS_DC);
diff --git a/Zend/zend_iterators.h b/Zend/zend_iterators.h
index d675e57058..873f36efbe 100644
--- a/Zend/zend_iterators.h
+++ b/Zend/zend_iterators.h
@@ -38,8 +38,11 @@ typedef struct _zend_object_iterator_funcs {
/* fetch the item data for the current element */
void (*get_current_data)(zend_object_iterator *iter, zval ***data TSRMLS_DC);
- /* fetch the key for the current element (return HASH_KEY_IS_STRING or HASH_KEY_IS_LONG) (optional, may be NULL) */
- int (*get_current_key)(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC);
+ /* fetch the key for the current element (optional, may be NULL). The key
+ * should be written into the provided zval* using the ZVAL_* macros. If
+ * this handler is not provided auto-incrementing integer keys will be
+ * used. */
+ void (*get_current_key)(zend_object_iterator *iter, zval *key TSRMLS_DC);
/* step forwards to next element */
void (*move_forward)(zend_object_iterator *iter TSRMLS_DC);
diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y
index 2a69fcfc38..a2026609a5 100644
--- a/Zend/zend_language_parser.y
+++ b/Zend/zend_language_parser.y
@@ -70,6 +70,8 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
%token T_LOGICAL_AND "and (T_LOGICAL_AND)"
%right T_PRINT
%token T_PRINT "print (T_PRINT)"
+%right T_YIELD
+%token T_YIELD "yield (T_YIELD)"
%left '=' T_PLUS_EQUAL T_MINUS_EQUAL T_MUL_EQUAL T_DIV_EQUAL T_CONCAT_EQUAL T_MOD_EQUAL T_AND_EQUAL T_OR_EQUAL T_XOR_EQUAL T_SL_EQUAL T_SR_EQUAL
%token T_PLUS_EQUAL "+= (T_PLUS_EQUAL)"
%token T_MINUS_EQUAL "-= (T_MINUS_EQUAL)"
@@ -162,6 +164,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*);
%token T_RETURN "return (T_RETURN)"
%token T_TRY "try (T_TRY)"
%token T_CATCH "catch (T_CATCH)"
+%token T_FINALLY "finally (T_FINALLY)"
%token T_THROW "throw (T_THROW)"
%token T_USE "use (T_USE)"
%token T_INSTEADOF "insteadof (T_INSTEADOF)"
@@ -278,10 +281,10 @@ statement:
unticked_statement:
'{' inner_statement_list '}'
- | T_IF '(' expr ')' { zend_do_if_cond(&$3, &$4 TSRMLS_CC); } statement { zend_do_if_after_statement(&$4, 1 TSRMLS_CC); } elseif_list else_single { zend_do_if_end(TSRMLS_C); }
- | T_IF '(' expr ')' ':' { zend_do_if_cond(&$3, &$4 TSRMLS_CC); } inner_statement_list { zend_do_if_after_statement(&$4, 1 TSRMLS_CC); } new_elseif_list new_else_single T_ENDIF ';' { zend_do_if_end(TSRMLS_C); }
- | T_WHILE '(' { $1.u.op.opline_num = get_next_op_number(CG(active_op_array)); } expr ')' { zend_do_while_cond(&$4, &$5 TSRMLS_CC); } while_statement { zend_do_while_end(&$1, &$5 TSRMLS_CC); }
- | T_DO { $1.u.op.opline_num = get_next_op_number(CG(active_op_array)); zend_do_do_while_begin(TSRMLS_C); } statement T_WHILE '(' { $5.u.op.opline_num = get_next_op_number(CG(active_op_array)); } expr ')' ';' { zend_do_do_while_end(&$1, &$5, &$7 TSRMLS_CC); }
+ | T_IF parenthesis_expr { zend_do_if_cond(&$2, &$1 TSRMLS_CC); } statement { zend_do_if_after_statement(&$1, 1 TSRMLS_CC); } elseif_list else_single { zend_do_if_end(TSRMLS_C); }
+ | T_IF parenthesis_expr ':' { zend_do_if_cond(&$2, &$1 TSRMLS_CC); } inner_statement_list { zend_do_if_after_statement(&$1, 1 TSRMLS_CC); } new_elseif_list new_else_single T_ENDIF ';' { zend_do_if_end(TSRMLS_C); }
+ | T_WHILE { $1.u.op.opline_num = get_next_op_number(CG(active_op_array)); } parenthesis_expr { zend_do_while_cond(&$3, &$$ TSRMLS_CC); } while_statement { zend_do_while_end(&$1, &$4 TSRMLS_CC); }
+ | T_DO { $1.u.op.opline_num = get_next_op_number(CG(active_op_array)); zend_do_do_while_begin(TSRMLS_C); } statement T_WHILE { $4.u.op.opline_num = get_next_op_number(CG(active_op_array)); } parenthesis_expr ';' { zend_do_do_while_end(&$1, &$4, &$6 TSRMLS_CC); }
| T_FOR
'('
for_expr
@@ -291,7 +294,7 @@ unticked_statement:
for_expr
')' { zend_do_free(&$9 TSRMLS_CC); zend_do_for_before_statement(&$4, &$7 TSRMLS_CC); }
for_statement { zend_do_for_end(&$7 TSRMLS_CC); }
- | T_SWITCH '(' expr ')' { zend_do_switch_cond(&$3 TSRMLS_CC); } switch_case_list { zend_do_switch_end(&$6 TSRMLS_CC); }
+ | T_SWITCH parenthesis_expr { zend_do_switch_cond(&$2 TSRMLS_CC); } switch_case_list { zend_do_switch_end(&$4 TSRMLS_CC); }
| T_BREAK ';' { zend_do_brk_cont(ZEND_BRK, NULL TSRMLS_CC); }
| T_BREAK expr ';' { zend_do_brk_cont(ZEND_BRK, &$2 TSRMLS_CC); }
| T_CONTINUE ';' { zend_do_brk_cont(ZEND_CONT, NULL TSRMLS_CC); }
@@ -299,6 +302,7 @@ unticked_statement:
| T_RETURN ';' { zend_do_return(NULL, 0 TSRMLS_CC); }
| T_RETURN expr_without_variable ';' { zend_do_return(&$2, 0 TSRMLS_CC); }
| T_RETURN variable ';' { zend_do_return(&$2, 1 TSRMLS_CC); }
+ | yield_expr ';' { zend_do_free(&$1 TSRMLS_CC); }
| T_GLOBAL global_var_list ';'
| T_STATIC static_var_list ';'
| T_ECHO echo_expr_list ';'
@@ -311,20 +315,29 @@ unticked_statement:
foreach_statement { zend_do_foreach_end(&$1, &$4 TSRMLS_CC); }
| T_FOREACH '(' expr_without_variable T_AS
{ zend_do_foreach_begin(&$1, &$2, &$3, &$4, 0 TSRMLS_CC); }
- variable foreach_optional_arg ')' { zend_check_writable_variable(&$6); zend_do_foreach_cont(&$1, &$2, &$4, &$6, &$7 TSRMLS_CC); }
+ foreach_variable foreach_optional_arg ')' { zend_do_foreach_cont(&$1, &$2, &$4, &$6, &$7 TSRMLS_CC); }
foreach_statement { zend_do_foreach_end(&$1, &$4 TSRMLS_CC); }
| T_DECLARE { $1.u.op.opline_num = get_next_op_number(CG(active_op_array)); zend_do_declare_begin(TSRMLS_C); } '(' declare_list ')' declare_statement { zend_do_declare_end(&$1 TSRMLS_CC); }
| ';' /* empty statement */
| T_TRY { zend_do_try(&$1 TSRMLS_CC); } '{' inner_statement_list '}'
- T_CATCH '(' { zend_initialize_try_catch_element(&$1 TSRMLS_CC); }
- fully_qualified_class_name { zend_do_first_catch(&$7 TSRMLS_CC); }
- T_VARIABLE ')' { zend_do_begin_catch(&$1, &$9, &$11, &$7 TSRMLS_CC); }
- '{' inner_statement_list '}' { zend_do_end_catch(&$1 TSRMLS_CC); }
- additional_catches { zend_do_mark_last_catch(&$7, &$18 TSRMLS_CC); }
+ catch_statement { zend_do_bind_catch(&$1, &$6 TSRMLS_CC); }
+ finally_statement { zend_do_end_finally(&$1, &$6, &$8 TSRMLS_CC); }
| T_THROW expr ';' { zend_do_throw(&$2 TSRMLS_CC); }
| T_GOTO T_STRING ';' { zend_do_goto(&$2 TSRMLS_CC); }
;
+catch_statement:
+ /* empty */ { $$.op_type = IS_UNUSED; }
+ | T_CATCH '(' { zend_initialize_try_catch_element(&$1 TSRMLS_CC); }
+ fully_qualified_class_name { zend_do_first_catch(&$2 TSRMLS_CC); }
+ T_VARIABLE ')' { zend_do_begin_catch(&$1, &$4, &$6, &$2 TSRMLS_CC); }
+ '{' inner_statement_list '}' { zend_do_end_catch(&$1 TSRMLS_CC); }
+ additional_catches { zend_do_mark_last_catch(&$2, &$13 TSRMLS_CC); $$ = $1;}
+
+finally_statement:
+ /* empty */ { $$.op_type = IS_UNUSED; }
+ | T_FINALLY { zend_do_finally(&$1 TSRMLS_CC); } '{' inner_statement_list '}' { $$ = $1; }
+;
additional_catches:
non_empty_additional_catches { $$ = $1; }
@@ -336,12 +349,10 @@ non_empty_additional_catches:
| non_empty_additional_catches additional_catch { $$ = $2; }
;
-
additional_catch:
T_CATCH '(' fully_qualified_class_name { $$.u.op.opline_num = get_next_op_number(CG(active_op_array)); } T_VARIABLE ')' { zend_do_begin_catch(&$1, &$3, &$5, NULL TSRMLS_CC); } '{' inner_statement_list '}' { zend_do_end_catch(&$1 TSRMLS_CC); }
;
-
unset_variables:
unset_variable
| unset_variables ',' unset_variable
@@ -359,7 +370,6 @@ class_declaration_statement:
unticked_class_declaration_statement { DO_TICKS(); }
;
-
is_reference:
/* empty */ { $$.op_type = ZEND_RETURN_VAL; }
| '&' { $$.op_type = ZEND_RETURN_REF; }
@@ -368,7 +378,8 @@ is_reference:
unticked_function_declaration_statement:
function is_reference T_STRING { zend_do_begin_function_declaration(&$1, &$3, 0, $2.op_type, NULL TSRMLS_CC); }
- '(' parameter_list ')' '{' inner_statement_list '}' { zend_do_end_function_declaration(&$1 TSRMLS_CC); }
+ '(' parameter_list ')'
+ '{' inner_statement_list '}' { zend_do_end_function_declaration(&$1 TSRMLS_CC); }
;
unticked_class_declaration_statement:
@@ -423,10 +434,10 @@ foreach_optional_arg:
| T_DOUBLE_ARROW foreach_variable { $$ = $2; }
;
-
foreach_variable:
variable { zend_check_writable_variable(&$1); $$ = $1; }
| '&' variable { zend_check_writable_variable(&$2); $$ = $2; $$.EA |= ZEND_PARSED_REFERENCE_VARIABLE; }
+ | T_LIST '(' { zend_do_list_init(TSRMLS_C); } assignment_list ')' { $$ = $1; $$.EA = ZEND_PARSED_LIST_EXPR; }
;
for_statement:
@@ -483,13 +494,13 @@ while_statement:
elseif_list:
/* empty */
- | elseif_list T_ELSEIF '(' expr ')' { zend_do_if_cond(&$4, &$5 TSRMLS_CC); } statement { zend_do_if_after_statement(&$5, 0 TSRMLS_CC); }
+ | elseif_list T_ELSEIF parenthesis_expr { zend_do_if_cond(&$3, &$2 TSRMLS_CC); } statement { zend_do_if_after_statement(&$2, 0 TSRMLS_CC); }
;
new_elseif_list:
/* empty */
- | new_elseif_list T_ELSEIF '(' expr ')' ':' { zend_do_if_cond(&$4, &$5 TSRMLS_CC); } inner_statement_list { zend_do_if_after_statement(&$5, 0 TSRMLS_CC); }
+ | new_elseif_list T_ELSEIF parenthesis_expr ':' { zend_do_if_cond(&$3, &$2 TSRMLS_CC); } inner_statement_list { zend_do_if_after_statement(&$2, 0 TSRMLS_CC); }
;
@@ -532,8 +543,9 @@ optional_class_type:
function_call_parameter_list:
- non_empty_function_call_parameter_list { $$ = $1; }
- | /* empty */ { Z_LVAL($$.u.constant) = 0; }
+ '(' ')' { Z_LVAL($$.u.constant) = 0; }
+ | '(' non_empty_function_call_parameter_list ')' { $$ = $2; }
+ | '(' yield_expr ')' { Z_LVAL($$.u.constant) = 1; zend_do_pass_param(&$2, ZEND_SEND_VAL, Z_LVAL($$.u.constant) TSRMLS_CC); }
;
@@ -578,8 +590,9 @@ class_statement:
variable_modifiers { CG(access_type) = Z_LVAL($1.u.constant); } class_variable_declaration ';'
| class_constant_declaration ';'
| trait_use_statement
- | method_modifiers function is_reference T_STRING { zend_do_begin_function_declaration(&$2, &$4, 1, $3.op_type, &$1 TSRMLS_CC); } '('
- parameter_list ')' method_body { zend_do_abstract_method(&$4, &$1, &$9 TSRMLS_CC); zend_do_end_function_declaration(&$2 TSRMLS_CC); }
+ | method_modifiers function is_reference T_STRING { zend_do_begin_function_declaration(&$2, &$4, 1, $3.op_type, &$1 TSRMLS_CC); }
+ '(' parameter_list ')'
+ method_body { zend_do_abstract_method(&$4, &$1, &$9 TSRMLS_CC); zend_do_end_function_declaration(&$2 TSRMLS_CC); }
;
trait_use_statement:
@@ -772,7 +785,7 @@ expr_without_variable:
| expr '>' expr { zend_do_binary_op(ZEND_IS_SMALLER, &$$, &$3, &$1 TSRMLS_CC); }
| expr T_IS_GREATER_OR_EQUAL expr { zend_do_binary_op(ZEND_IS_SMALLER_OR_EQUAL, &$$, &$3, &$1 TSRMLS_CC); }
| expr T_INSTANCEOF class_name_reference { zend_do_instanceof(&$$, &$1, &$3, 0 TSRMLS_CC); }
- | '(' expr ')' { $$ = $2; }
+ | parenthesis_expr { $$ = $1; }
| new_expr { $$ = $1; }
| '(' new_expr ')' { $$ = $2; } instance_call { $$ = $5; }
| expr '?' { zend_do_begin_qm_op(&$1, &$2 TSRMLS_CC); }
@@ -791,16 +804,35 @@ expr_without_variable:
| T_EXIT exit_expr { zend_do_exit(&$$, &$2 TSRMLS_CC); }
| '@' { zend_do_begin_silence(&$1 TSRMLS_CC); } expr { zend_do_end_silence(&$1 TSRMLS_CC); $$ = $3; }
| scalar { $$ = $1; }
- | T_ARRAY '(' array_pair_list ')' { $$ = $3; }
- | '[' array_pair_list ']' { $$ = $2; }
+ | combined_scalar_offset { zend_do_end_variable_parse(&$1, BP_VAR_R, 0 TSRMLS_CC); }
+ | combined_scalar { $$ = $1; }
| '`' backticks_expr '`' { zend_do_shell_exec(&$$, &$2 TSRMLS_CC); }
| T_PRINT expr { zend_do_print(&$$, &$2 TSRMLS_CC); }
- | function is_reference '(' { zend_do_begin_lambda_function_declaration(&$$, &$1, $2.op_type, 0 TSRMLS_CC); }
- parameter_list ')' lexical_vars '{' inner_statement_list '}' { zend_do_end_function_declaration(&$1 TSRMLS_CC); $$ = $4; }
- | T_STATIC function is_reference '(' { zend_do_begin_lambda_function_declaration(&$$, &$2, $3.op_type, 1 TSRMLS_CC); }
- parameter_list ')' lexical_vars '{' inner_statement_list '}' { zend_do_end_function_declaration(&$2 TSRMLS_CC); $$ = $5; }
+ | T_YIELD { zend_do_yield(&$$, NULL, NULL, 0 TSRMLS_CC); }
+ | function is_reference { zend_do_begin_lambda_function_declaration(&$$, &$1, $2.op_type, 0 TSRMLS_CC); }
+ '(' parameter_list ')' lexical_vars
+ '{' inner_statement_list '}' { zend_do_end_function_declaration(&$1 TSRMLS_CC); $$ = $3; }
+ | T_STATIC function is_reference { zend_do_begin_lambda_function_declaration(&$$, &$2, $3.op_type, 1 TSRMLS_CC); }
+ '(' parameter_list ')' lexical_vars
+ '{' inner_statement_list '}' { zend_do_end_function_declaration(&$2 TSRMLS_CC); $$ = $4; }
+;
+
+yield_expr:
+ T_YIELD expr_without_variable { zend_do_yield(&$$, &$2, NULL, 0 TSRMLS_CC); }
+ | T_YIELD variable { zend_do_yield(&$$, &$2, NULL, 1 TSRMLS_CC); }
+ | T_YIELD expr T_DOUBLE_ARROW expr_without_variable { zend_do_yield(&$$, &$4, &$2, 0 TSRMLS_CC); }
+ | T_YIELD expr T_DOUBLE_ARROW variable { zend_do_yield(&$$, &$4, &$2, 1 TSRMLS_CC); }
;
+combined_scalar_offset:
+ combined_scalar '[' dim_offset ']' { zend_do_begin_variable_parse(TSRMLS_C); fetch_array_dim(&$$, &$1, &$3 TSRMLS_CC); }
+ | combined_scalar_offset '[' dim_offset ']' { fetch_array_dim(&$$, &$1, &$3 TSRMLS_CC); }
+ | T_CONSTANT_ENCAPSED_STRING '[' dim_offset ']' { $1.EA = 0; zend_do_begin_variable_parse(TSRMLS_C); fetch_array_dim(&$$, &$1, &$3 TSRMLS_CC); }
+
+combined_scalar:
+ T_ARRAY '(' array_pair_list ')' { $$ = $3; }
+ | '[' array_pair_list ']' { $$ = $2; }
+
function:
T_FUNCTION { $$.u.op.opline_num = CG(zend_lineno); }
;
@@ -818,30 +850,22 @@ lexical_var_list:
;
function_call:
- namespace_name '(' { $2.u.op.opline_num = zend_do_begin_function_call(&$1, 1 TSRMLS_CC); }
- function_call_parameter_list
- ')' { zend_do_end_function_call(&$1, &$$, &$4, 0, $2.u.op.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); }
- | T_NAMESPACE T_NS_SEPARATOR namespace_name '(' { $1.op_type = IS_CONST; ZVAL_EMPTY_STRING(&$1.u.constant); zend_do_build_namespace_name(&$1, &$1, &$3 TSRMLS_CC); $4.u.op.opline_num = zend_do_begin_function_call(&$1, 0 TSRMLS_CC); }
- function_call_parameter_list
- ')' { zend_do_end_function_call(&$1, &$$, &$6, 0, $4.u.op.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); }
- | T_NS_SEPARATOR namespace_name '(' { $3.u.op.opline_num = zend_do_begin_function_call(&$2, 0 TSRMLS_CC); }
- function_call_parameter_list
- ')' { zend_do_end_function_call(&$2, &$$, &$5, 0, $3.u.op.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); }
- | class_name T_PAAMAYIM_NEKUDOTAYIM variable_name '(' { $4.u.op.opline_num = zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
- function_call_parameter_list
- ')' { zend_do_end_function_call($4.u.op.opline_num?NULL:&$3, &$$, &$6, $4.u.op.opline_num, $4.u.op.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
- | class_name T_PAAMAYIM_NEKUDOTAYIM variable_without_objects '(' { zend_do_end_variable_parse(&$3, BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
- function_call_parameter_list
- ')' { zend_do_end_function_call(NULL, &$$, &$6, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
- | variable_class_name T_PAAMAYIM_NEKUDOTAYIM variable_name '(' { zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
- function_call_parameter_list
- ')' { zend_do_end_function_call(NULL, &$$, &$6, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
- | variable_class_name T_PAAMAYIM_NEKUDOTAYIM variable_without_objects '(' { zend_do_end_variable_parse(&$3, BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
- function_call_parameter_list
- ')' { zend_do_end_function_call(NULL, &$$, &$6, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
- | variable_without_objects '(' { zend_do_end_variable_parse(&$1, BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_dynamic_function_call(&$1, 0 TSRMLS_CC); }
- function_call_parameter_list ')'
- { zend_do_end_function_call(&$1, &$$, &$4, 0, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
+ namespace_name { $$.u.op.opline_num = zend_do_begin_function_call(&$1, 1 TSRMLS_CC); }
+ function_call_parameter_list { zend_do_end_function_call(&$1, &$$, &$3, 0, $2.u.op.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); }
+ | T_NAMESPACE T_NS_SEPARATOR namespace_name { $1.op_type = IS_CONST; ZVAL_EMPTY_STRING(&$1.u.constant); zend_do_build_namespace_name(&$1, &$1, &$3 TSRMLS_CC); $$.u.op.opline_num = zend_do_begin_function_call(&$1, 0 TSRMLS_CC); }
+ function_call_parameter_list { zend_do_end_function_call(&$1, &$$, &$5, 0, $4.u.op.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); }
+ | T_NS_SEPARATOR namespace_name { $$.u.op.opline_num = zend_do_begin_function_call(&$2, 0 TSRMLS_CC); }
+ function_call_parameter_list { zend_do_end_function_call(&$2, &$$, &$4, 0, $3.u.op.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); }
+ | class_name T_PAAMAYIM_NEKUDOTAYIM variable_name { $$.u.op.opline_num = zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
+ function_call_parameter_list { zend_do_end_function_call($4.u.op.opline_num?NULL:&$3, &$$, &$5, $4.u.op.opline_num, $4.u.op.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
+ | class_name T_PAAMAYIM_NEKUDOTAYIM variable_without_objects { zend_do_end_variable_parse(&$3, BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
+ function_call_parameter_list { zend_do_end_function_call(NULL, &$$, &$5, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
+ | variable_class_name T_PAAMAYIM_NEKUDOTAYIM variable_name { zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
+ function_call_parameter_list { zend_do_end_function_call(NULL, &$$, &$5, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
+ | variable_class_name T_PAAMAYIM_NEKUDOTAYIM variable_without_objects { zend_do_end_variable_parse(&$3, BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
+ function_call_parameter_list { zend_do_end_function_call(NULL, &$$, &$5, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
+ | variable_without_objects { zend_do_end_variable_parse(&$1, BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_dynamic_function_call(&$1, 0 TSRMLS_CC); }
+ function_call_parameter_list { zend_do_end_function_call(&$1, &$$, &$3, 0, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
;
class_name:
@@ -886,7 +910,7 @@ dynamic_class_name_variable_property:
exit_expr:
/* empty */ { memset(&$$, 0, sizeof(znode)); $$.op_type = IS_UNUSED; }
| '(' ')' { memset(&$$, 0, sizeof(znode)); $$.op_type = IS_UNUSED; }
- | '(' expr ')' { $$ = $2; }
+ | parenthesis_expr { $$ = $1; }
;
backticks_expr:
@@ -897,8 +921,8 @@ backticks_expr:
ctor_arguments:
- /* empty */ { Z_LVAL($$.u.constant)=0; }
- | '(' function_call_parameter_list ')' { $$ = $2; }
+ /* empty */ { Z_LVAL($$.u.constant) = 0; }
+ | function_call_parameter_list { $$ = $1; }
;
@@ -913,13 +937,14 @@ common_scalar:
| T_METHOD_C { $$ = $1; }
| T_FUNC_C { $$ = $1; }
| T_NS_C { $$ = $1; }
- | T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE T_END_HEREDOC { $$ = $2; CG(heredoc) = Z_STRVAL($1.u.constant); CG(heredoc_len) = Z_STRLEN($1.u.constant); }
- | T_START_HEREDOC T_END_HEREDOC { ZVAL_EMPTY_STRING(&$$.u.constant); INIT_PZVAL(&$$.u.constant); $$.op_type = IS_CONST; CG(heredoc) = Z_STRVAL($1.u.constant); CG(heredoc_len) = Z_STRLEN($1.u.constant); }
+ | T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE T_END_HEREDOC { $$ = $2; }
+ | T_START_HEREDOC T_END_HEREDOC { ZVAL_EMPTY_STRING(&$$.u.constant); INIT_PZVAL(&$$.u.constant); $$.op_type = IS_CONST; }
;
static_scalar: /* compile-time evaluated scalars */
common_scalar { $$ = $1; }
+ | static_class_name_scalar { $$ = $1; }
| namespace_name { zend_do_fetch_constant(&$$, NULL, &$1, ZEND_CT, 1 TSRMLS_CC); }
| T_NAMESPACE T_NS_SEPARATOR namespace_name { $$.op_type = IS_CONST; ZVAL_EMPTY_STRING(&$$.u.constant); zend_do_build_namespace_name(&$$, &$$, &$3 TSRMLS_CC); $3 = $$; zend_do_fetch_constant(&$$, NULL, &$3, ZEND_CT, 0 TSRMLS_CC); }
| T_NS_SEPARATOR namespace_name { char *tmp = estrndup(Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); memcpy(&(tmp[1]), Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); tmp[0] = '\\'; efree(Z_STRVAL($2.u.constant)); Z_STRVAL($2.u.constant) = tmp; ++Z_STRLEN($2.u.constant); zend_do_fetch_constant(&$$, NULL, &$2, ZEND_CT, 0 TSRMLS_CC); }
@@ -937,13 +962,14 @@ static_class_constant:
scalar:
T_STRING_VARNAME { $$ = $1; }
+ | class_name_scalar { $$ = $1; }
| class_constant { $$ = $1; }
| namespace_name { zend_do_fetch_constant(&$$, NULL, &$1, ZEND_RT, 1 TSRMLS_CC); }
| T_NAMESPACE T_NS_SEPARATOR namespace_name { $$.op_type = IS_CONST; ZVAL_EMPTY_STRING(&$$.u.constant); zend_do_build_namespace_name(&$$, &$$, &$3 TSRMLS_CC); $3 = $$; zend_do_fetch_constant(&$$, NULL, &$3, ZEND_RT, 0 TSRMLS_CC); }
| T_NS_SEPARATOR namespace_name { char *tmp = estrndup(Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); memcpy(&(tmp[1]), Z_STRVAL($2.u.constant), Z_STRLEN($2.u.constant)+1); tmp[0] = '\\'; efree(Z_STRVAL($2.u.constant)); Z_STRVAL($2.u.constant) = tmp; ++Z_STRLEN($2.u.constant); zend_do_fetch_constant(&$$, NULL, &$2, ZEND_RT, 0 TSRMLS_CC); }
| common_scalar { $$ = $1; }
| '"' encaps_list '"' { $$ = $2; }
- | T_START_HEREDOC encaps_list T_END_HEREDOC { $$ = $2; CG(heredoc) = Z_STRVAL($1.u.constant); CG(heredoc_len) = Z_STRLEN($1.u.constant); }
+ | T_START_HEREDOC encaps_list T_END_HEREDOC { $$ = $2; }
| T_CLASS_C { if (Z_TYPE($1.u.constant) == IS_CONSTANT) {zend_do_fetch_constant(&$$, NULL, &$1, ZEND_RT, 1 TSRMLS_CC);} else {$$ = $1;} }
;
@@ -970,6 +996,11 @@ expr:
| expr_without_variable { $$ = $1; }
;
+parenthesis_expr:
+ '(' expr ')' { $$ = $2; }
+ | '(' yield_expr ')' { $$ = $2; }
+;
+
r_variable:
variable { zend_do_end_variable_parse(&$1, BP_VAR_R, 0 TSRMLS_CC); $$ = $1; }
@@ -1009,9 +1040,8 @@ array_method_dereference:
;
method:
- '(' { zend_do_pop_object(&$1 TSRMLS_CC); zend_do_begin_method_call(&$1 TSRMLS_CC); }
- function_call_parameter_list ')'
- { zend_do_end_function_call(&$1, &$$, &$3, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); }
+ { zend_do_pop_object(&$$ TSRMLS_CC); zend_do_begin_method_call(&$$ TSRMLS_CC); }
+ function_call_parameter_list { zend_do_end_function_call(&$1, &$$, &$2, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); }
;
method_or_not:
@@ -1151,6 +1181,7 @@ encaps_var_offset:
internal_functions_in_yacc:
T_ISSET '(' isset_variables ')' { $$ = $3; }
| T_EMPTY '(' variable ')' { zend_do_isset_or_isempty(ZEND_ISEMPTY, &$$, &$3 TSRMLS_CC); }
+ | T_EMPTY '(' expr_without_variable ')' { zend_do_unary_op(ZEND_BOOL_NOT, &$$, &$3 TSRMLS_CC); }
| T_INCLUDE expr { zend_do_include_or_eval(ZEND_INCLUDE, &$$, &$2 TSRMLS_CC); }
| T_INCLUDE_ONCE expr { zend_do_include_or_eval(ZEND_INCLUDE_ONCE, &$$, &$2 TSRMLS_CC); }
| T_EVAL '(' expr ')' { zend_do_include_or_eval(ZEND_EVAL, &$$, &$3 TSRMLS_CC); }
@@ -1159,8 +1190,13 @@ internal_functions_in_yacc:
;
isset_variables:
- variable { zend_do_isset_or_isempty(ZEND_ISSET, &$$, &$1 TSRMLS_CC); }
- | isset_variables ',' { zend_do_boolean_and_begin(&$1, &$2 TSRMLS_CC); } variable { znode tmp; zend_do_isset_or_isempty(ZEND_ISSET, &tmp, &$4 TSRMLS_CC); zend_do_boolean_and_end(&$$, &$1, &tmp, &$2 TSRMLS_CC); }
+ isset_variable { $$ = $1; }
+ | isset_variables ',' { zend_do_boolean_and_begin(&$1, &$2 TSRMLS_CC); } isset_variable { zend_do_boolean_and_end(&$$, &$1, &$4, &$2 TSRMLS_CC); }
+;
+
+isset_variable:
+ variable { zend_do_isset_or_isempty(ZEND_ISSET, &$$, &$1 TSRMLS_CC); }
+ | expr_without_variable { zend_error(E_COMPILE_ERROR, "Cannot use isset() on the result of an expression (you can use \"null !== expression\" instead)"); }
;
class_constant:
@@ -1168,6 +1204,14 @@ class_constant:
| variable_class_name T_PAAMAYIM_NEKUDOTAYIM T_STRING { zend_do_fetch_constant(&$$, &$1, &$3, ZEND_RT, 0 TSRMLS_CC); }
;
+static_class_name_scalar:
+ class_name T_PAAMAYIM_NEKUDOTAYIM T_CLASS { zend_do_resolve_class_name(&$$, &$1, 1 TSRMLS_CC); }
+;
+
+class_name_scalar:
+ class_name T_PAAMAYIM_NEKUDOTAYIM T_CLASS { zend_do_resolve_class_name(&$$, &$1, 0 TSRMLS_CC); }
+;
+
%%
/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
diff --git a/Zend/zend_language_scanner.c b/Zend/zend_language_scanner.c
index 68ba75e7c7..7173e91809 100644
--- a/Zend/zend_language_scanner.c
+++ b/Zend/zend_language_scanner.c
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.13.5 on Sun Jun 16 14:52:22 2013 */
+/* Generated by re2c 0.13.5 on Sun Dec 22 13:03:33 2013 */
#line 1 "Zend/zend_language_scanner.l"
/*
+----------------------------------------------------------------------+
@@ -180,22 +180,23 @@ static void yy_scan_buffer(char *str, unsigned int len TSRMLS_DC)
void startup_scanner(TSRMLS_D)
{
CG(parse_error) = 0;
- CG(heredoc) = NULL;
- CG(heredoc_len) = 0;
CG(doc_comment) = NULL;
CG(doc_comment_len) = 0;
zend_stack_init(&SCNG(state_stack));
+ zend_ptr_stack_init(&SCNG(heredoc_label_stack));
+}
+
+static void heredoc_label_dtor(zend_heredoc_label *heredoc_label) {
+ efree(heredoc_label->label);
}
void shutdown_scanner(TSRMLS_D)
{
- if (CG(heredoc)) {
- efree(CG(heredoc));
- CG(heredoc_len)=0;
- }
CG(parse_error) = 0;
- zend_stack_destroy(&SCNG(state_stack));
RESET_DOC_COMMENT();
+ zend_stack_destroy(&SCNG(state_stack));
+ zend_ptr_stack_clean(&SCNG(heredoc_label_stack), (void (*)(void *)) &heredoc_label_dtor, 1);
+ zend_ptr_stack_destroy(&SCNG(heredoc_label_stack));
}
ZEND_API void zend_save_lexical_state(zend_lex_state *lex_state TSRMLS_DC)
@@ -210,6 +211,9 @@ ZEND_API void zend_save_lexical_state(zend_lex_state *lex_state TSRMLS_DC)
lex_state->state_stack = SCNG(state_stack);
zend_stack_init(&SCNG(state_stack));
+ lex_state->heredoc_label_stack = SCNG(heredoc_label_stack);
+ zend_ptr_stack_init(&SCNG(heredoc_label_stack));
+
lex_state->in = SCNG(yy_in);
lex_state->yy_state = YYSTATE;
lex_state->filename = zend_get_compiled_filename(TSRMLS_C);
@@ -236,6 +240,10 @@ ZEND_API void zend_restore_lexical_state(zend_lex_state *lex_state TSRMLS_DC)
zend_stack_destroy(&SCNG(state_stack));
SCNG(state_stack) = lex_state->state_stack;
+ zend_ptr_stack_clean(&SCNG(heredoc_label_stack), (void (*)(void *)) &heredoc_label_dtor, 1);
+ zend_ptr_stack_destroy(&SCNG(heredoc_label_stack));
+ SCNG(heredoc_label_stack) = lex_state->heredoc_label_stack;
+
SCNG(yy_in) = lex_state->in;
YYSETCONDITION(lex_state->yy_state);
CG(zend_lineno) = lex_state->lineno;
@@ -253,11 +261,6 @@ ZEND_API void zend_restore_lexical_state(zend_lex_state *lex_state TSRMLS_DC)
SCNG(output_filter) = lex_state->output_filter;
SCNG(script_encoding) = lex_state->script_encoding;
- if (CG(heredoc)) {
- efree(CG(heredoc));
- CG(heredoc) = NULL;
- CG(heredoc_len) = 0;
- }
RESET_DOC_COMMENT();
}
@@ -1003,7 +1006,7 @@ restart:
yymore_restart:
-#line 1007 "Zend/zend_language_scanner.c"
+#line 1010 "Zend/zend_language_scanner.c"
{
YYCTYPE yych;
unsigned int yyaccept = 0;
@@ -1102,7 +1105,7 @@ yyc_INITIAL:
yy3:
YYDEBUG(3, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1795 "Zend/zend_language_scanner.l"
+#line 1807 "Zend/zend_language_scanner.l"
{
if (YYCURSOR > YYLIMIT) {
return 0;
@@ -1162,7 +1165,7 @@ inline_html:
HANDLE_NEWLINES(yytext, yyleng);
return T_INLINE_HTML;
}
-#line 1166 "Zend/zend_language_scanner.c"
+#line 1169 "Zend/zend_language_scanner.c"
yy4:
YYDEBUG(4, *YYCURSOR);
yych = *++YYCURSOR;
@@ -1180,7 +1183,7 @@ yy5:
yy6:
YYDEBUG(6, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1783 "Zend/zend_language_scanner.l"
+#line 1795 "Zend/zend_language_scanner.l"
{
if (CG(short_tags)) {
zendlval->value.str.val = yytext; /* no copying - intentional */
@@ -1192,14 +1195,14 @@ yy6:
goto inline_char_handler;
}
}
-#line 1196 "Zend/zend_language_scanner.c"
+#line 1199 "Zend/zend_language_scanner.c"
yy7:
YYDEBUG(7, *YYCURSOR);
++YYCURSOR;
if ((yych = *YYCURSOR) == '=') goto yy43;
YYDEBUG(8, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1760 "Zend/zend_language_scanner.l"
+#line 1772 "Zend/zend_language_scanner.l"
{
if (CG(asp_tags)) {
zendlval->value.str.val = yytext; /* no copying - intentional */
@@ -1211,7 +1214,7 @@ yy7:
goto inline_char_handler;
}
}
-#line 1215 "Zend/zend_language_scanner.c"
+#line 1218 "Zend/zend_language_scanner.c"
yy9:
YYDEBUG(9, *YYCURSOR);
yych = *++YYCURSOR;
@@ -1397,7 +1400,7 @@ yy35:
++YYCURSOR;
YYDEBUG(38, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1720 "Zend/zend_language_scanner.l"
+#line 1732 "Zend/zend_language_scanner.l"
{
YYCTYPE *bracket = (YYCTYPE*)zend_memrchr(yytext, '<', yyleng - (sizeof("script language=php>") - 1));
@@ -1414,7 +1417,7 @@ yy35:
BEGIN(ST_IN_SCRIPTING);
return T_OPEN_TAG;
}
-#line 1418 "Zend/zend_language_scanner.c"
+#line 1421 "Zend/zend_language_scanner.c"
yy39:
YYDEBUG(39, *YYCURSOR);
yych = *++YYCURSOR;
@@ -1441,7 +1444,7 @@ yy43:
++YYCURSOR;
YYDEBUG(44, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1738 "Zend/zend_language_scanner.l"
+#line 1750 "Zend/zend_language_scanner.l"
{
if (CG(asp_tags)) {
zendlval->value.str.val = yytext; /* no copying - intentional */
@@ -1453,13 +1456,13 @@ yy43:
goto inline_char_handler;
}
}
-#line 1457 "Zend/zend_language_scanner.c"
+#line 1460 "Zend/zend_language_scanner.c"
yy45:
YYDEBUG(45, *YYCURSOR);
++YYCURSOR;
YYDEBUG(46, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1751 "Zend/zend_language_scanner.l"
+#line 1763 "Zend/zend_language_scanner.l"
{
zendlval->value.str.val = yytext; /* no copying - intentional */
zendlval->value.str.len = yyleng;
@@ -1467,7 +1470,7 @@ yy45:
BEGIN(ST_IN_SCRIPTING);
return T_OPEN_TAG_WITH_ECHO;
}
-#line 1471 "Zend/zend_language_scanner.c"
+#line 1474 "Zend/zend_language_scanner.c"
yy47:
YYDEBUG(47, *YYCURSOR);
yych = *++YYCURSOR;
@@ -1494,7 +1497,7 @@ yy50:
yy51:
YYDEBUG(51, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1773 "Zend/zend_language_scanner.l"
+#line 1785 "Zend/zend_language_scanner.l"
{
zendlval->value.str.val = yytext; /* no copying - intentional */
zendlval->value.str.len = yyleng;
@@ -1503,7 +1506,7 @@ yy51:
BEGIN(ST_IN_SCRIPTING);
return T_OPEN_TAG;
}
-#line 1507 "Zend/zend_language_scanner.c"
+#line 1510 "Zend/zend_language_scanner.c"
yy52:
YYDEBUG(52, *YYCURSOR);
++YYCURSOR;
@@ -1574,7 +1577,7 @@ yyc_ST_BACKQUOTE:
yy56:
YYDEBUG(56, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 2246 "Zend/zend_language_scanner.l"
+#line 2258 "Zend/zend_language_scanner.l"
{
if (YYCURSOR > YYLIMIT) {
return 0;
@@ -1615,7 +1618,7 @@ yy56:
zend_scan_escape_string(zendlval, yytext, yyleng, '`' TSRMLS_CC);
return T_ENCAPSED_AND_WHITESPACE;
}
-#line 1619 "Zend/zend_language_scanner.c"
+#line 1622 "Zend/zend_language_scanner.c"
yy57:
YYDEBUG(57, *YYCURSOR);
yych = *++YYCURSOR;
@@ -1626,12 +1629,12 @@ yy58:
++YYCURSOR;
YYDEBUG(59, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 2190 "Zend/zend_language_scanner.l"
+#line 2202 "Zend/zend_language_scanner.l"
{
BEGIN(ST_IN_SCRIPTING);
return '`';
}
-#line 1635 "Zend/zend_language_scanner.c"
+#line 1638 "Zend/zend_language_scanner.c"
yy60:
YYDEBUG(60, *YYCURSOR);
yych = *++YYCURSOR;
@@ -1641,14 +1644,14 @@ yy61:
++YYCURSOR;
YYDEBUG(62, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 2177 "Zend/zend_language_scanner.l"
+#line 2189 "Zend/zend_language_scanner.l"
{
zendlval->value.lval = (long) '{';
yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
yyless(1);
return T_CURLY_OPEN;
}
-#line 1652 "Zend/zend_language_scanner.c"
+#line 1655 "Zend/zend_language_scanner.c"
yy63:
YYDEBUG(63, *YYCURSOR);
yyaccept = 0;
@@ -1664,24 +1667,24 @@ yy63:
yy65:
YYDEBUG(65, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1877 "Zend/zend_language_scanner.l"
+#line 1889 "Zend/zend_language_scanner.l"
{
zend_copy_value(zendlval, (yytext+1), (yyleng-1));
zendlval->type = IS_STRING;
return T_VARIABLE;
}
-#line 1674 "Zend/zend_language_scanner.c"
+#line 1677 "Zend/zend_language_scanner.c"
yy66:
YYDEBUG(66, *YYCURSOR);
++YYCURSOR;
YYDEBUG(67, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1454 "Zend/zend_language_scanner.l"
+#line 1465 "Zend/zend_language_scanner.l"
{
yy_push_state(ST_LOOKING_FOR_VARNAME TSRMLS_CC);
return T_DOLLAR_OPEN_CURLY_BRACES;
}
-#line 1685 "Zend/zend_language_scanner.c"
+#line 1688 "Zend/zend_language_scanner.c"
yy68:
YYDEBUG(68, *YYCURSOR);
yych = *++YYCURSOR;
@@ -1695,7 +1698,7 @@ yy70:
++YYCURSOR;
YYDEBUG(71, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1869 "Zend/zend_language_scanner.l"
+#line 1881 "Zend/zend_language_scanner.l"
{
yyless(yyleng - 1);
yy_push_state(ST_VAR_OFFSET TSRMLS_CC);
@@ -1703,7 +1706,7 @@ yy70:
zendlval->type = IS_STRING;
return T_VARIABLE;
}
-#line 1707 "Zend/zend_language_scanner.c"
+#line 1710 "Zend/zend_language_scanner.c"
yy72:
YYDEBUG(72, *YYCURSOR);
yych = *++YYCURSOR;
@@ -1721,7 +1724,7 @@ yy73:
++YYCURSOR;
YYDEBUG(74, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1859 "Zend/zend_language_scanner.l"
+#line 1871 "Zend/zend_language_scanner.l"
{
yyless(yyleng - 3);
yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
@@ -1729,7 +1732,7 @@ yy73:
zendlval->type = IS_STRING;
return T_VARIABLE;
}
-#line 1733 "Zend/zend_language_scanner.c"
+#line 1736 "Zend/zend_language_scanner.c"
}
/* *********************************** */
yyc_ST_DOUBLE_QUOTES:
@@ -1797,7 +1800,7 @@ yy77:
yy78:
YYDEBUG(78, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 2196 "Zend/zend_language_scanner.l"
+#line 2208 "Zend/zend_language_scanner.l"
{
if (GET_DOUBLE_QUOTES_SCANNED_LENGTH()) {
YYCURSOR += GET_DOUBLE_QUOTES_SCANNED_LENGTH() - 1;
@@ -1846,7 +1849,7 @@ double_quotes_scan_done:
zend_scan_escape_string(zendlval, yytext, yyleng, '"' TSRMLS_CC);
return T_ENCAPSED_AND_WHITESPACE;
}
-#line 1850 "Zend/zend_language_scanner.c"
+#line 1853 "Zend/zend_language_scanner.c"
yy79:
YYDEBUG(79, *YYCURSOR);
yych = *++YYCURSOR;
@@ -1857,12 +1860,12 @@ yy80:
++YYCURSOR;
YYDEBUG(81, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 2185 "Zend/zend_language_scanner.l"
+#line 2197 "Zend/zend_language_scanner.l"
{
BEGIN(ST_IN_SCRIPTING);
return '"';
}
-#line 1866 "Zend/zend_language_scanner.c"
+#line 1869 "Zend/zend_language_scanner.c"
yy82:
YYDEBUG(82, *YYCURSOR);
yych = *++YYCURSOR;
@@ -1872,14 +1875,14 @@ yy83:
++YYCURSOR;
YYDEBUG(84, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 2177 "Zend/zend_language_scanner.l"
+#line 2189 "Zend/zend_language_scanner.l"
{
zendlval->value.lval = (long) '{';
yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
yyless(1);
return T_CURLY_OPEN;
}
-#line 1883 "Zend/zend_language_scanner.c"
+#line 1886 "Zend/zend_language_scanner.c"
yy85:
YYDEBUG(85, *YYCURSOR);
yyaccept = 0;
@@ -1895,24 +1898,24 @@ yy85:
yy87:
YYDEBUG(87, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1877 "Zend/zend_language_scanner.l"
+#line 1889 "Zend/zend_language_scanner.l"
{
zend_copy_value(zendlval, (yytext+1), (yyleng-1));
zendlval->type = IS_STRING;
return T_VARIABLE;
}
-#line 1905 "Zend/zend_language_scanner.c"
+#line 1908 "Zend/zend_language_scanner.c"
yy88:
YYDEBUG(88, *YYCURSOR);
++YYCURSOR;
YYDEBUG(89, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1454 "Zend/zend_language_scanner.l"
+#line 1465 "Zend/zend_language_scanner.l"
{
yy_push_state(ST_LOOKING_FOR_VARNAME TSRMLS_CC);
return T_DOLLAR_OPEN_CURLY_BRACES;
}
-#line 1916 "Zend/zend_language_scanner.c"
+#line 1919 "Zend/zend_language_scanner.c"
yy90:
YYDEBUG(90, *YYCURSOR);
yych = *++YYCURSOR;
@@ -1926,7 +1929,7 @@ yy92:
++YYCURSOR;
YYDEBUG(93, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1869 "Zend/zend_language_scanner.l"
+#line 1881 "Zend/zend_language_scanner.l"
{
yyless(yyleng - 1);
yy_push_state(ST_VAR_OFFSET TSRMLS_CC);
@@ -1934,7 +1937,7 @@ yy92:
zendlval->type = IS_STRING;
return T_VARIABLE;
}
-#line 1938 "Zend/zend_language_scanner.c"
+#line 1941 "Zend/zend_language_scanner.c"
yy94:
YYDEBUG(94, *YYCURSOR);
yych = *++YYCURSOR;
@@ -1952,7 +1955,7 @@ yy95:
++YYCURSOR;
YYDEBUG(96, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1859 "Zend/zend_language_scanner.l"
+#line 1871 "Zend/zend_language_scanner.l"
{
yyless(yyleng - 3);
yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
@@ -1960,7 +1963,7 @@ yy95:
zendlval->type = IS_STRING;
return T_VARIABLE;
}
-#line 1964 "Zend/zend_language_scanner.c"
+#line 1967 "Zend/zend_language_scanner.c"
}
/* *********************************** */
yyc_ST_END_HEREDOC:
@@ -1971,19 +1974,20 @@ yyc_ST_END_HEREDOC:
++YYCURSOR;
YYDEBUG(100, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 2164 "Zend/zend_language_scanner.l"
+#line 2175 "Zend/zend_language_scanner.l"
{
- YYCURSOR += CG(heredoc_len) - 1;
- yyleng = CG(heredoc_len);
+ zend_heredoc_label *heredoc_label = zend_ptr_stack_pop(&SCNG(heredoc_label_stack));
+
+ YYCURSOR += heredoc_label->length - 1;
+ yyleng = heredoc_label->length;
+
+ heredoc_label_dtor(heredoc_label);
+ efree(heredoc_label);
- Z_STRVAL_P(zendlval) = CG(heredoc);
- Z_STRLEN_P(zendlval) = CG(heredoc_len);
- CG(heredoc) = NULL;
- CG(heredoc_len) = 0;
BEGIN(ST_IN_SCRIPTING);
return T_END_HEREDOC;
}
-#line 1987 "Zend/zend_language_scanner.c"
+#line 1991 "Zend/zend_language_scanner.c"
/* *********************************** */
yyc_ST_HEREDOC:
{
@@ -2045,10 +2049,12 @@ yy103:
yy104:
YYDEBUG(104, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 2288 "Zend/zend_language_scanner.l"
+#line 2300 "Zend/zend_language_scanner.l"
{
int newline = 0;
+ zend_heredoc_label *heredoc_label = zend_ptr_stack_top(&SCNG(heredoc_label_stack));
+
if (YYCURSOR > YYLIMIT) {
return 0;
}
@@ -2064,8 +2070,8 @@ yy104:
/* fall through */
case '\n':
/* Check for ending label on the next line */
- if (IS_LABEL_START(*YYCURSOR) && CG(heredoc_len) < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, CG(heredoc), CG(heredoc_len))) {
- YYCTYPE *end = YYCURSOR + CG(heredoc_len);
+ if (IS_LABEL_START(*YYCURSOR) && heredoc_label->length < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, heredoc_label->label, heredoc_label->length)) {
+ YYCTYPE *end = YYCURSOR + heredoc_label->length;
if (*end == ';') {
end++;
@@ -2116,7 +2122,7 @@ heredoc_scan_done:
zend_scan_escape_string(zendlval, yytext, yyleng - newline, 0 TSRMLS_CC);
return T_ENCAPSED_AND_WHITESPACE;
}
-#line 2120 "Zend/zend_language_scanner.c"
+#line 2126 "Zend/zend_language_scanner.c"
yy105:
YYDEBUG(105, *YYCURSOR);
yych = *++YYCURSOR;
@@ -2131,14 +2137,14 @@ yy107:
++YYCURSOR;
YYDEBUG(108, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 2177 "Zend/zend_language_scanner.l"
+#line 2189 "Zend/zend_language_scanner.l"
{
zendlval->value.lval = (long) '{';
yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
yyless(1);
return T_CURLY_OPEN;
}
-#line 2142 "Zend/zend_language_scanner.c"
+#line 2148 "Zend/zend_language_scanner.c"
yy109:
YYDEBUG(109, *YYCURSOR);
yyaccept = 0;
@@ -2154,24 +2160,24 @@ yy109:
yy111:
YYDEBUG(111, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1877 "Zend/zend_language_scanner.l"
+#line 1889 "Zend/zend_language_scanner.l"
{
zend_copy_value(zendlval, (yytext+1), (yyleng-1));
zendlval->type = IS_STRING;
return T_VARIABLE;
}
-#line 2164 "Zend/zend_language_scanner.c"
+#line 2170 "Zend/zend_language_scanner.c"
yy112:
YYDEBUG(112, *YYCURSOR);
++YYCURSOR;
YYDEBUG(113, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1454 "Zend/zend_language_scanner.l"
+#line 1465 "Zend/zend_language_scanner.l"
{
yy_push_state(ST_LOOKING_FOR_VARNAME TSRMLS_CC);
return T_DOLLAR_OPEN_CURLY_BRACES;
}
-#line 2175 "Zend/zend_language_scanner.c"
+#line 2181 "Zend/zend_language_scanner.c"
yy114:
YYDEBUG(114, *YYCURSOR);
yych = *++YYCURSOR;
@@ -2185,7 +2191,7 @@ yy116:
++YYCURSOR;
YYDEBUG(117, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1869 "Zend/zend_language_scanner.l"
+#line 1881 "Zend/zend_language_scanner.l"
{
yyless(yyleng - 1);
yy_push_state(ST_VAR_OFFSET TSRMLS_CC);
@@ -2193,7 +2199,7 @@ yy116:
zendlval->type = IS_STRING;
return T_VARIABLE;
}
-#line 2197 "Zend/zend_language_scanner.c"
+#line 2203 "Zend/zend_language_scanner.c"
yy118:
YYDEBUG(118, *YYCURSOR);
yych = *++YYCURSOR;
@@ -2211,7 +2217,7 @@ yy119:
++YYCURSOR;
YYDEBUG(120, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1859 "Zend/zend_language_scanner.l"
+#line 1871 "Zend/zend_language_scanner.l"
{
yyless(yyleng - 3);
yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
@@ -2219,7 +2225,7 @@ yy119:
zendlval->type = IS_STRING;
return T_VARIABLE;
}
-#line 2223 "Zend/zend_language_scanner.c"
+#line 2229 "Zend/zend_language_scanner.c"
}
/* *********************************** */
yyc_ST_IN_SCRIPTING:
@@ -2291,32 +2297,32 @@ yyc_ST_IN_SCRIPTING:
case 0x1C:
case 0x1D:
case 0x1E:
- case 0x1F: goto yy183;
+ case 0x1F: goto yy184;
case '\t':
case '\n':
case '\r':
- case ' ': goto yy139;
- case '!': goto yy152;
- case '"': goto yy179;
- case '#': goto yy175;
- case '$': goto yy164;
- case '%': goto yy158;
- case '&': goto yy159;
- case '\'': goto yy177;
- case '(': goto yy146;
+ case ' ': goto yy140;
+ case '!': goto yy153;
+ case '"': goto yy180;
+ case '#': goto yy176;
+ case '$': goto yy165;
+ case '%': goto yy159;
+ case '&': goto yy160;
+ case '\'': goto yy178;
+ case '(': goto yy147;
case ')':
case ',':
case ';':
case '@':
case '[':
case ']':
- case '~': goto yy165;
- case '*': goto yy155;
- case '+': goto yy151;
- case '-': goto yy137;
- case '.': goto yy157;
- case '/': goto yy156;
- case '0': goto yy171;
+ case '~': goto yy166;
+ case '*': goto yy156;
+ case '+': goto yy152;
+ case '-': goto yy138;
+ case '.': goto yy158;
+ case '/': goto yy157;
+ case '0': goto yy172;
case '1':
case '2':
case '3':
@@ -2325,16 +2331,16 @@ yyc_ST_IN_SCRIPTING:
case '6':
case '7':
case '8':
- case '9': goto yy173;
- case ':': goto yy141;
- case '<': goto yy153;
- case '=': goto yy149;
- case '>': goto yy154;
- case '?': goto yy166;
+ case '9': goto yy174;
+ case ':': goto yy142;
+ case '<': goto yy154;
+ case '=': goto yy150;
+ case '>': goto yy155;
+ case '?': goto yy167;
case 'A':
- case 'a': goto yy132;
+ case 'a': goto yy133;
case 'B':
- case 'b': goto yy134;
+ case 'b': goto yy135;
case 'C':
case 'c': goto yy127;
case 'D':
@@ -2344,39 +2350,41 @@ yyc_ST_IN_SCRIPTING:
case 'F':
case 'f': goto yy126;
case 'G':
- case 'g': goto yy135;
+ case 'g': goto yy136;
case 'I':
- case 'i': goto yy130;
+ case 'i': goto yy131;
case 'L':
- case 'l': goto yy150;
+ case 'l': goto yy151;
case 'N':
- case 'n': goto yy144;
+ case 'n': goto yy145;
case 'O':
- case 'o': goto yy162;
+ case 'o': goto yy163;
case 'P':
- case 'p': goto yy136;
+ case 'p': goto yy137;
case 'R':
case 'r': goto yy128;
case 'S':
- case 's': goto yy133;
+ case 's': goto yy134;
case 'T':
- case 't': goto yy129;
+ case 't': goto yy130;
case 'U':
- case 'u': goto yy147;
+ case 'u': goto yy148;
case 'V':
- case 'v': goto yy145;
+ case 'v': goto yy146;
case 'W':
- case 'w': goto yy131;
+ case 'w': goto yy132;
case 'X':
- case 'x': goto yy163;
- case '\\': goto yy142;
- case '^': goto yy161;
- case '_': goto yy148;
- case '`': goto yy181;
- case '{': goto yy167;
- case '|': goto yy160;
- case '}': goto yy169;
- default: goto yy174;
+ case 'x': goto yy164;
+ case 'Y':
+ case 'y': goto yy129;
+ case '\\': goto yy143;
+ case '^': goto yy162;
+ case '_': goto yy149;
+ case '`': goto yy182;
+ case '{': goto yy168;
+ case '|': goto yy161;
+ case '}': goto yy170;
+ default: goto yy175;
}
yy123:
YYDEBUG(123, *YYCURSOR);
@@ -2384,49 +2392,49 @@ yy123:
YYDEBUG(-1, yych);
switch ((yych = *YYCURSOR)) {
case 'C':
- case 'c': goto yy726;
+ case 'c': goto yy735;
case 'L':
- case 'l': goto yy727;
+ case 'l': goto yy736;
case 'M':
- case 'm': goto yy728;
+ case 'm': goto yy737;
case 'N':
- case 'n': goto yy729;
+ case 'n': goto yy738;
case 'V':
- case 'v': goto yy730;
+ case 'v': goto yy739;
case 'X':
- case 'x': goto yy731;
- default: goto yy186;
+ case 'x': goto yy740;
+ default: goto yy187;
}
yy124:
YYDEBUG(124, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1900 "Zend/zend_language_scanner.l"
+#line 1912 "Zend/zend_language_scanner.l"
{
zend_copy_value(zendlval, yytext, yyleng);
zendlval->type = IS_STRING;
return T_STRING;
}
-#line 2410 "Zend/zend_language_scanner.c"
+#line 2418 "Zend/zend_language_scanner.c"
yy125:
YYDEBUG(125, *YYCURSOR);
yych = *++YYCURSOR;
if (yych <= 'O') {
if (yych <= 'H') {
- if (yych == 'E') goto yy708;
- goto yy186;
+ if (yych == 'E') goto yy717;
+ goto yy187;
} else {
- if (yych <= 'I') goto yy709;
- if (yych <= 'N') goto yy186;
- goto yy710;
+ if (yych <= 'I') goto yy718;
+ if (yych <= 'N') goto yy187;
+ goto yy719;
}
} else {
if (yych <= 'h') {
- if (yych == 'e') goto yy708;
- goto yy186;
+ if (yych == 'e') goto yy717;
+ goto yy187;
} else {
- if (yych <= 'i') goto yy709;
- if (yych == 'o') goto yy710;
- goto yy186;
+ if (yych <= 'i') goto yy718;
+ if (yych == 'o') goto yy719;
+ goto yy187;
}
}
yy126:
@@ -2434,21 +2442,21 @@ yy126:
yych = *++YYCURSOR;
if (yych <= 'U') {
if (yych <= 'N') {
- if (yych == 'I') goto yy687;
- goto yy186;
+ if (yych == 'I') goto yy693;
+ goto yy187;
} else {
- if (yych <= 'O') goto yy688;
- if (yych <= 'T') goto yy186;
- goto yy689;
+ if (yych <= 'O') goto yy694;
+ if (yych <= 'T') goto yy187;
+ goto yy695;
}
} else {
if (yych <= 'n') {
- if (yych == 'i') goto yy687;
- goto yy186;
+ if (yych == 'i') goto yy693;
+ goto yy187;
} else {
- if (yych <= 'o') goto yy688;
- if (yych == 'u') goto yy689;
- goto yy186;
+ if (yych <= 'o') goto yy694;
+ if (yych == 'u') goto yy695;
+ goto yy187;
}
}
yy127:
@@ -2456,196 +2464,202 @@ yy127:
yych = *++YYCURSOR;
if (yych <= 'O') {
if (yych <= 'K') {
- if (yych == 'A') goto yy652;
- goto yy186;
+ if (yych == 'A') goto yy658;
+ goto yy187;
} else {
- if (yych <= 'L') goto yy653;
- if (yych <= 'N') goto yy186;
- goto yy654;
+ if (yych <= 'L') goto yy659;
+ if (yych <= 'N') goto yy187;
+ goto yy660;
}
} else {
if (yych <= 'k') {
- if (yych == 'a') goto yy652;
- goto yy186;
+ if (yych == 'a') goto yy658;
+ goto yy187;
} else {
- if (yych <= 'l') goto yy653;
- if (yych == 'o') goto yy654;
- goto yy186;
+ if (yych <= 'l') goto yy659;
+ if (yych == 'o') goto yy660;
+ goto yy187;
}
}
yy128:
YYDEBUG(128, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy634;
- if (yych == 'e') goto yy634;
- goto yy186;
+ if (yych == 'E') goto yy640;
+ if (yych == 'e') goto yy640;
+ goto yy187;
yy129:
YYDEBUG(129, *YYCURSOR);
yych = *++YYCURSOR;
+ if (yych == 'I') goto yy635;
+ if (yych == 'i') goto yy635;
+ goto yy187;
+yy130:
+ YYDEBUG(130, *YYCURSOR);
+ yych = *++YYCURSOR;
if (yych <= 'R') {
- if (yych == 'H') goto yy622;
- if (yych <= 'Q') goto yy186;
- goto yy623;
+ if (yych == 'H') goto yy623;
+ if (yych <= 'Q') goto yy187;
+ goto yy624;
} else {
if (yych <= 'h') {
- if (yych <= 'g') goto yy186;
- goto yy622;
+ if (yych <= 'g') goto yy187;
+ goto yy623;
} else {
- if (yych == 'r') goto yy623;
- goto yy186;
+ if (yych == 'r') goto yy624;
+ goto yy187;
}
}
-yy130:
- YYDEBUG(130, *YYCURSOR);
+yy131:
+ YYDEBUG(131, *YYCURSOR);
yych = *++YYCURSOR;
if (yych <= 'S') {
if (yych <= 'L') {
- if (yych == 'F') goto yy569;
- goto yy186;
+ if (yych == 'F') goto yy570;
+ goto yy187;
} else {
- if (yych <= 'M') goto yy571;
- if (yych <= 'N') goto yy572;
- if (yych <= 'R') goto yy186;
- goto yy573;
+ if (yych <= 'M') goto yy572;
+ if (yych <= 'N') goto yy573;
+ if (yych <= 'R') goto yy187;
+ goto yy574;
}
} else {
if (yych <= 'm') {
- if (yych == 'f') goto yy569;
- if (yych <= 'l') goto yy186;
- goto yy571;
+ if (yych == 'f') goto yy570;
+ if (yych <= 'l') goto yy187;
+ goto yy572;
} else {
- if (yych <= 'n') goto yy572;
- if (yych == 's') goto yy573;
- goto yy186;
+ if (yych <= 'n') goto yy573;
+ if (yych == 's') goto yy574;
+ goto yy187;
}
}
-yy131:
- YYDEBUG(131, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'H') goto yy564;
- if (yych == 'h') goto yy564;
- goto yy186;
yy132:
YYDEBUG(132, *YYCURSOR);
yych = *++YYCURSOR;
+ if (yych == 'H') goto yy565;
+ if (yych == 'h') goto yy565;
+ goto yy187;
+yy133:
+ YYDEBUG(133, *YYCURSOR);
+ yych = *++YYCURSOR;
if (yych <= 'S') {
if (yych <= 'M') {
- if (yych == 'B') goto yy546;
- goto yy186;
+ if (yych == 'B') goto yy547;
+ goto yy187;
} else {
- if (yych <= 'N') goto yy547;
- if (yych <= 'Q') goto yy186;
- if (yych <= 'R') goto yy548;
- goto yy549;
+ if (yych <= 'N') goto yy548;
+ if (yych <= 'Q') goto yy187;
+ if (yych <= 'R') goto yy549;
+ goto yy550;
}
} else {
if (yych <= 'n') {
- if (yych == 'b') goto yy546;
- if (yych <= 'm') goto yy186;
- goto yy547;
+ if (yych == 'b') goto yy547;
+ if (yych <= 'm') goto yy187;
+ goto yy548;
} else {
- if (yych <= 'q') goto yy186;
- if (yych <= 'r') goto yy548;
- if (yych <= 's') goto yy549;
- goto yy186;
+ if (yych <= 'q') goto yy187;
+ if (yych <= 'r') goto yy549;
+ if (yych <= 's') goto yy550;
+ goto yy187;
}
}
-yy133:
- YYDEBUG(133, *YYCURSOR);
+yy134:
+ YYDEBUG(134, *YYCURSOR);
yych = *++YYCURSOR;
if (yych <= 'W') {
- if (yych == 'T') goto yy534;
- if (yych <= 'V') goto yy186;
- goto yy535;
+ if (yych == 'T') goto yy535;
+ if (yych <= 'V') goto yy187;
+ goto yy536;
} else {
if (yych <= 't') {
- if (yych <= 's') goto yy186;
- goto yy534;
+ if (yych <= 's') goto yy187;
+ goto yy535;
} else {
- if (yych == 'w') goto yy535;
- goto yy186;
+ if (yych == 'w') goto yy536;
+ goto yy187;
}
}
-yy134:
- YYDEBUG(134, *YYCURSOR);
+yy135:
+ YYDEBUG(135, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
if (yych <= ';') {
if (yych <= '"') {
- if (yych <= '!') goto yy186;
- goto yy526;
+ if (yych <= '!') goto yy187;
+ goto yy527;
} else {
- if (yych == '\'') goto yy527;
- goto yy186;
+ if (yych == '\'') goto yy528;
+ goto yy187;
}
} else {
if (yych <= 'R') {
- if (yych <= '<') goto yy525;
- if (yych <= 'Q') goto yy186;
- goto yy528;
+ if (yych <= '<') goto yy526;
+ if (yych <= 'Q') goto yy187;
+ goto yy529;
} else {
- if (yych == 'r') goto yy528;
- goto yy186;
+ if (yych == 'r') goto yy529;
+ goto yy187;
}
}
-yy135:
- YYDEBUG(135, *YYCURSOR);
+yy136:
+ YYDEBUG(136, *YYCURSOR);
yych = *++YYCURSOR;
if (yych <= 'O') {
- if (yych == 'L') goto yy515;
- if (yych <= 'N') goto yy186;
- goto yy516;
+ if (yych == 'L') goto yy516;
+ if (yych <= 'N') goto yy187;
+ goto yy517;
} else {
if (yych <= 'l') {
- if (yych <= 'k') goto yy186;
- goto yy515;
+ if (yych <= 'k') goto yy187;
+ goto yy516;
} else {
- if (yych == 'o') goto yy516;
- goto yy186;
+ if (yych == 'o') goto yy517;
+ goto yy187;
}
}
-yy136:
- YYDEBUG(136, *YYCURSOR);
+yy137:
+ YYDEBUG(137, *YYCURSOR);
yych = *++YYCURSOR;
if (yych <= 'U') {
- if (yych == 'R') goto yy491;
- if (yych <= 'T') goto yy186;
- goto yy492;
+ if (yych == 'R') goto yy492;
+ if (yych <= 'T') goto yy187;
+ goto yy493;
} else {
if (yych <= 'r') {
- if (yych <= 'q') goto yy186;
- goto yy491;
+ if (yych <= 'q') goto yy187;
+ goto yy492;
} else {
- if (yych == 'u') goto yy492;
- goto yy186;
+ if (yych == 'u') goto yy493;
+ goto yy187;
}
}
-yy137:
- YYDEBUG(137, *YYCURSOR);
+yy138:
+ YYDEBUG(138, *YYCURSOR);
++YYCURSOR;
if ((yych = *YYCURSOR) <= '<') {
- if (yych == '-') goto yy487;
+ if (yych == '-') goto yy488;
} else {
- if (yych <= '=') goto yy485;
- if (yych <= '>') goto yy489;
+ if (yych <= '=') goto yy486;
+ if (yych <= '>') goto yy490;
}
-yy138:
- YYDEBUG(138, *YYCURSOR);
+yy139:
+ YYDEBUG(139, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1443 "Zend/zend_language_scanner.l"
+#line 1454 "Zend/zend_language_scanner.l"
{
return yytext[0];
}
-#line 2640 "Zend/zend_language_scanner.c"
-yy139:
- YYDEBUG(139, *YYCURSOR);
- ++YYCURSOR;
- yych = *YYCURSOR;
- goto yy484;
+#line 2654 "Zend/zend_language_scanner.c"
yy140:
YYDEBUG(140, *YYCURSOR);
+ ++YYCURSOR;
+ yych = *YYCURSOR;
+ goto yy485;
+yy141:
+ YYDEBUG(141, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1174 "Zend/zend_language_scanner.l"
+#line 1185 "Zend/zend_language_scanner.l"
{
zendlval->value.str.val = yytext; /* no copying - intentional */
zendlval->value.str.len = yyleng;
@@ -2653,261 +2667,261 @@ yy140:
HANDLE_NEWLINES(yytext, yyleng);
return T_WHITESPACE;
}
-#line 2657 "Zend/zend_language_scanner.c"
-yy141:
- YYDEBUG(141, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == ':') goto yy481;
- goto yy138;
+#line 2671 "Zend/zend_language_scanner.c"
yy142:
YYDEBUG(142, *YYCURSOR);
- ++YYCURSOR;
+ yych = *++YYCURSOR;
+ if (yych == ':') goto yy482;
+ goto yy139;
+yy143:
YYDEBUG(143, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(144, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1203 "Zend/zend_language_scanner.l"
+#line 1214 "Zend/zend_language_scanner.l"
{
return T_NS_SEPARATOR;
}
-#line 2672 "Zend/zend_language_scanner.c"
-yy144:
- YYDEBUG(144, *YYCURSOR);
+#line 2686 "Zend/zend_language_scanner.c"
+yy145:
+ YYDEBUG(145, *YYCURSOR);
yych = *++YYCURSOR;
if (yych <= 'E') {
- if (yych == 'A') goto yy469;
- if (yych <= 'D') goto yy186;
- goto yy470;
+ if (yych == 'A') goto yy470;
+ if (yych <= 'D') goto yy187;
+ goto yy471;
} else {
if (yych <= 'a') {
- if (yych <= '`') goto yy186;
- goto yy469;
+ if (yych <= '`') goto yy187;
+ goto yy470;
} else {
- if (yych == 'e') goto yy470;
- goto yy186;
+ if (yych == 'e') goto yy471;
+ goto yy187;
}
}
-yy145:
- YYDEBUG(145, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'A') goto yy466;
- if (yych == 'a') goto yy466;
- goto yy186;
yy146:
YYDEBUG(146, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'A') goto yy467;
+ if (yych == 'a') goto yy467;
+ goto yy187;
+yy147:
+ YYDEBUG(147, *YYCURSOR);
yyaccept = 1;
yych = *(YYMARKER = ++YYCURSOR);
if (yych <= 'S') {
if (yych <= 'D') {
if (yych <= ' ') {
- if (yych == '\t') goto yy391;
- if (yych <= 0x1F) goto yy138;
- goto yy391;
+ if (yych == '\t') goto yy392;
+ if (yych <= 0x1F) goto yy139;
+ goto yy392;
} else {
- if (yych <= '@') goto yy138;
- if (yych == 'C') goto yy138;
- goto yy391;
+ if (yych <= '@') goto yy139;
+ if (yych == 'C') goto yy139;
+ goto yy392;
}
} else {
if (yych <= 'I') {
- if (yych == 'F') goto yy391;
- if (yych <= 'H') goto yy138;
- goto yy391;
+ if (yych == 'F') goto yy392;
+ if (yych <= 'H') goto yy139;
+ goto yy392;
} else {
- if (yych == 'O') goto yy391;
- if (yych <= 'Q') goto yy138;
- goto yy391;
+ if (yych == 'O') goto yy392;
+ if (yych <= 'Q') goto yy139;
+ goto yy392;
}
}
} else {
if (yych <= 'f') {
if (yych <= 'b') {
- if (yych == 'U') goto yy391;
- if (yych <= '`') goto yy138;
- goto yy391;
+ if (yych == 'U') goto yy392;
+ if (yych <= '`') goto yy139;
+ goto yy392;
} else {
- if (yych == 'd') goto yy391;
- if (yych <= 'e') goto yy138;
- goto yy391;
+ if (yych == 'd') goto yy392;
+ if (yych <= 'e') goto yy139;
+ goto yy392;
}
} else {
if (yych <= 'o') {
- if (yych == 'i') goto yy391;
- if (yych <= 'n') goto yy138;
- goto yy391;
+ if (yych == 'i') goto yy392;
+ if (yych <= 'n') goto yy139;
+ goto yy392;
} else {
if (yych <= 's') {
- if (yych <= 'q') goto yy138;
- goto yy391;
+ if (yych <= 'q') goto yy139;
+ goto yy392;
} else {
- if (yych == 'u') goto yy391;
- goto yy138;
+ if (yych == 'u') goto yy392;
+ goto yy139;
}
}
}
}
-yy147:
- YYDEBUG(147, *YYCURSOR);
+yy148:
+ YYDEBUG(148, *YYCURSOR);
yych = *++YYCURSOR;
if (yych <= 'S') {
- if (yych == 'N') goto yy382;
- if (yych <= 'R') goto yy186;
- goto yy383;
+ if (yych == 'N') goto yy383;
+ if (yych <= 'R') goto yy187;
+ goto yy384;
} else {
if (yych <= 'n') {
- if (yych <= 'm') goto yy186;
- goto yy382;
+ if (yych <= 'm') goto yy187;
+ goto yy383;
} else {
- if (yych == 's') goto yy383;
- goto yy186;
+ if (yych == 's') goto yy384;
+ goto yy187;
}
}
-yy148:
- YYDEBUG(148, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == '_') goto yy300;
- goto yy186;
yy149:
YYDEBUG(149, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych <= '<') goto yy138;
- if (yych <= '=') goto yy294;
- if (yych <= '>') goto yy296;
- goto yy138;
+ if (yych == '_') goto yy301;
+ goto yy187;
yy150:
YYDEBUG(150, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'I') goto yy290;
- if (yych == 'i') goto yy290;
- goto yy186;
+ if (yych <= '<') goto yy139;
+ if (yych <= '=') goto yy295;
+ if (yych <= '>') goto yy297;
+ goto yy139;
yy151:
YYDEBUG(151, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == '+') goto yy288;
- if (yych == '=') goto yy286;
- goto yy138;
+ if (yych == 'I') goto yy291;
+ if (yych == 'i') goto yy291;
+ goto yy187;
yy152:
YYDEBUG(152, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == '=') goto yy283;
- goto yy138;
+ if (yych == '+') goto yy289;
+ if (yych == '=') goto yy287;
+ goto yy139;
yy153:
YYDEBUG(153, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == '=') goto yy284;
+ goto yy139;
+yy154:
+ YYDEBUG(154, *YYCURSOR);
yyaccept = 1;
yych = *(YYMARKER = ++YYCURSOR);
if (yych <= ';') {
- if (yych == '/') goto yy255;
- goto yy138;
+ if (yych == '/') goto yy256;
+ goto yy139;
} else {
- if (yych <= '<') goto yy253;
- if (yych <= '=') goto yy256;
- if (yych <= '>') goto yy258;
- goto yy138;
+ if (yych <= '<') goto yy254;
+ if (yych <= '=') goto yy257;
+ if (yych <= '>') goto yy259;
+ goto yy139;
}
-yy154:
- YYDEBUG(154, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych <= '<') goto yy138;
- if (yych <= '=') goto yy249;
- if (yych <= '>') goto yy247;
- goto yy138;
yy155:
YYDEBUG(155, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == '=') goto yy245;
- goto yy138;
+ if (yych <= '<') goto yy139;
+ if (yych <= '=') goto yy250;
+ if (yych <= '>') goto yy248;
+ goto yy139;
yy156:
YYDEBUG(156, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych <= '.') {
- if (yych == '*') goto yy237;
- goto yy138;
- } else {
- if (yych <= '/') goto yy239;
- if (yych == '=') goto yy240;
- goto yy138;
- }
+ if (yych == '=') goto yy246;
+ goto yy139;
yy157:
YYDEBUG(157, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych <= '/') goto yy138;
- if (yych <= '9') goto yy233;
- if (yych == '=') goto yy235;
- goto yy138;
+ if (yych <= '.') {
+ if (yych == '*') goto yy238;
+ goto yy139;
+ } else {
+ if (yych <= '/') goto yy240;
+ if (yych == '=') goto yy241;
+ goto yy139;
+ }
yy158:
YYDEBUG(158, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych <= '<') goto yy138;
- if (yych <= '=') goto yy229;
- if (yych <= '>') goto yy227;
- goto yy138;
+ if (yych <= '/') goto yy139;
+ if (yych <= '9') goto yy234;
+ if (yych == '=') goto yy236;
+ goto yy139;
yy159:
YYDEBUG(159, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == '&') goto yy223;
- if (yych == '=') goto yy225;
- goto yy138;
+ if (yych <= '<') goto yy139;
+ if (yych <= '=') goto yy230;
+ if (yych <= '>') goto yy228;
+ goto yy139;
yy160:
YYDEBUG(160, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == '=') goto yy221;
- if (yych == '|') goto yy219;
- goto yy138;
+ if (yych == '&') goto yy224;
+ if (yych == '=') goto yy226;
+ goto yy139;
yy161:
YYDEBUG(161, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == '=') goto yy217;
- goto yy138;
+ if (yych == '=') goto yy222;
+ if (yych == '|') goto yy220;
+ goto yy139;
yy162:
YYDEBUG(162, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'R') goto yy215;
- if (yych == 'r') goto yy215;
- goto yy186;
+ if (yych == '=') goto yy218;
+ goto yy139;
yy163:
YYDEBUG(163, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'O') goto yy212;
- if (yych == 'o') goto yy212;
- goto yy186;
+ if (yych == 'R') goto yy216;
+ if (yych == 'r') goto yy216;
+ goto yy187;
yy164:
YYDEBUG(164, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych <= '_') {
- if (yych <= '@') goto yy138;
- if (yych <= 'Z') goto yy209;
- if (yych <= '^') goto yy138;
- goto yy209;
- } else {
- if (yych <= '`') goto yy138;
- if (yych <= 'z') goto yy209;
- if (yych <= '~') goto yy138;
- goto yy209;
- }
+ if (yych == 'O') goto yy213;
+ if (yych == 'o') goto yy213;
+ goto yy187;
yy165:
YYDEBUG(165, *YYCURSOR);
yych = *++YYCURSOR;
- goto yy138;
+ if (yych <= '_') {
+ if (yych <= '@') goto yy139;
+ if (yych <= 'Z') goto yy210;
+ if (yych <= '^') goto yy139;
+ goto yy210;
+ } else {
+ if (yych <= '`') goto yy139;
+ if (yych <= 'z') goto yy210;
+ if (yych <= '~') goto yy139;
+ goto yy210;
+ }
yy166:
YYDEBUG(166, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == '>') goto yy205;
- goto yy138;
+ goto yy139;
yy167:
YYDEBUG(167, *YYCURSOR);
- ++YYCURSOR;
+ yych = *++YYCURSOR;
+ if (yych == '>') goto yy206;
+ goto yy139;
+yy168:
YYDEBUG(168, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(169, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1448 "Zend/zend_language_scanner.l"
+#line 1459 "Zend/zend_language_scanner.l"
{
yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
return '{';
}
-#line 2905 "Zend/zend_language_scanner.c"
-yy169:
- YYDEBUG(169, *YYCURSOR);
- ++YYCURSOR;
+#line 2919 "Zend/zend_language_scanner.c"
+yy170:
YYDEBUG(170, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(171, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1460 "Zend/zend_language_scanner.l"
+#line 1471 "Zend/zend_language_scanner.l"
{
RESET_DOC_COMMENT();
if (!zend_stack_is_empty(&SCNG(state_stack))) {
@@ -2915,35 +2929,35 @@ yy169:
}
return '}';
}
-#line 2919 "Zend/zend_language_scanner.c"
-yy171:
- YYDEBUG(171, *YYCURSOR);
+#line 2933 "Zend/zend_language_scanner.c"
+yy172:
+ YYDEBUG(172, *YYCURSOR);
yyaccept = 2;
yych = *(YYMARKER = ++YYCURSOR);
if (yych <= 'E') {
if (yych <= '9') {
- if (yych == '.') goto yy187;
- if (yych >= '0') goto yy190;
+ if (yych == '.') goto yy188;
+ if (yych >= '0') goto yy191;
} else {
- if (yych == 'B') goto yy198;
- if (yych >= 'E') goto yy192;
+ if (yych == 'B') goto yy199;
+ if (yych >= 'E') goto yy193;
}
} else {
if (yych <= 'b') {
- if (yych == 'X') goto yy197;
- if (yych >= 'b') goto yy198;
+ if (yych == 'X') goto yy198;
+ if (yych >= 'b') goto yy199;
} else {
if (yych <= 'e') {
- if (yych >= 'e') goto yy192;
+ if (yych >= 'e') goto yy193;
} else {
- if (yych == 'x') goto yy197;
+ if (yych == 'x') goto yy198;
}
}
}
-yy172:
- YYDEBUG(172, *YYCURSOR);
+yy173:
+ YYDEBUG(173, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1510 "Zend/zend_language_scanner.l"
+#line 1522 "Zend/zend_language_scanner.l"
{
if (yyleng < MAX_LENGTH_OF_LONG - 1) { /* Won't overflow */
zendlval->value.lval = strtol(yytext, NULL, 0);
@@ -2964,35 +2978,35 @@ yy172:
zendlval->type = IS_LONG;
return T_LNUMBER;
}
-#line 2968 "Zend/zend_language_scanner.c"
-yy173:
- YYDEBUG(173, *YYCURSOR);
+#line 2982 "Zend/zend_language_scanner.c"
+yy174:
+ YYDEBUG(174, *YYCURSOR);
yyaccept = 2;
yych = *(YYMARKER = ++YYCURSOR);
if (yych <= '9') {
- if (yych == '.') goto yy187;
- if (yych <= '/') goto yy172;
- goto yy190;
+ if (yych == '.') goto yy188;
+ if (yych <= '/') goto yy173;
+ goto yy191;
} else {
if (yych <= 'E') {
- if (yych <= 'D') goto yy172;
- goto yy192;
+ if (yych <= 'D') goto yy173;
+ goto yy193;
} else {
- if (yych == 'e') goto yy192;
- goto yy172;
+ if (yych == 'e') goto yy193;
+ goto yy173;
}
}
-yy174:
- YYDEBUG(174, *YYCURSOR);
- yych = *++YYCURSOR;
- goto yy186;
yy175:
YYDEBUG(175, *YYCURSOR);
- ++YYCURSOR;
+ yych = *++YYCURSOR;
+ goto yy187;
yy176:
YYDEBUG(176, *YYCURSOR);
+ ++YYCURSOR;
+yy177:
+ YYDEBUG(177, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1907 "Zend/zend_language_scanner.l"
+#line 1919 "Zend/zend_language_scanner.l"
{
while (YYCURSOR < YYLIMIT) {
switch (*YYCURSOR++) {
@@ -3026,14 +3040,14 @@ yy176:
return T_COMMENT;
}
-#line 3030 "Zend/zend_language_scanner.c"
-yy177:
- YYDEBUG(177, *YYCURSOR);
- ++YYCURSOR;
+#line 3044 "Zend/zend_language_scanner.c"
yy178:
YYDEBUG(178, *YYCURSOR);
+ ++YYCURSOR;
+yy179:
+ YYDEBUG(179, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1998 "Zend/zend_language_scanner.l"
+#line 2010 "Zend/zend_language_scanner.l"
{
register char *s, *t;
char *end;
@@ -3101,14 +3115,14 @@ yy178:
}
return T_CONSTANT_ENCAPSED_STRING;
}
-#line 3105 "Zend/zend_language_scanner.c"
-yy179:
- YYDEBUG(179, *YYCURSOR);
- ++YYCURSOR;
+#line 3119 "Zend/zend_language_scanner.c"
yy180:
YYDEBUG(180, *YYCURSOR);
+ ++YYCURSOR;
+yy181:
+ YYDEBUG(181, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 2067 "Zend/zend_language_scanner.l"
+#line 2079 "Zend/zend_language_scanner.l"
{
int bprefix = (yytext[0] != '"') ? 1 : 0;
@@ -3149,24 +3163,24 @@ yy180:
BEGIN(ST_DOUBLE_QUOTES);
return '"';
}
-#line 3153 "Zend/zend_language_scanner.c"
-yy181:
- YYDEBUG(181, *YYCURSOR);
- ++YYCURSOR;
+#line 3167 "Zend/zend_language_scanner.c"
+yy182:
YYDEBUG(182, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(183, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 2158 "Zend/zend_language_scanner.l"
+#line 2169 "Zend/zend_language_scanner.l"
{
BEGIN(ST_BACKQUOTE);
return '`';
}
-#line 3164 "Zend/zend_language_scanner.c"
-yy183:
- YYDEBUG(183, *YYCURSOR);
- ++YYCURSOR;
+#line 3178 "Zend/zend_language_scanner.c"
+yy184:
YYDEBUG(184, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(185, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 2416 "Zend/zend_language_scanner.l"
+#line 2432 "Zend/zend_language_scanner.l"
{
if (YYCURSOR > YYLIMIT) {
return 0;
@@ -3175,132 +3189,132 @@ yy183:
zend_error(E_COMPILE_WARNING,"Unexpected character in input: '%c' (ASCII=%d) state=%d", yytext[0], yytext[0], YYSTATE);
goto restart;
}
-#line 3179 "Zend/zend_language_scanner.c"
-yy185:
- YYDEBUG(185, *YYCURSOR);
+#line 3193 "Zend/zend_language_scanner.c"
+yy186:
+ YYDEBUG(186, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
-yy186:
- YYDEBUG(186, *YYCURSOR);
+yy187:
+ YYDEBUG(187, *YYCURSOR);
if (yybm[0+yych] & 4) {
- goto yy185;
+ goto yy186;
}
goto yy124;
-yy187:
- YYDEBUG(187, *YYCURSOR);
+yy188:
+ YYDEBUG(188, *YYCURSOR);
yyaccept = 3;
YYMARKER = ++YYCURSOR;
YYFILL(3);
yych = *YYCURSOR;
- YYDEBUG(188, *YYCURSOR);
+ YYDEBUG(189, *YYCURSOR);
if (yybm[0+yych] & 8) {
- goto yy187;
+ goto yy188;
}
- if (yych == 'E') goto yy192;
- if (yych == 'e') goto yy192;
-yy189:
- YYDEBUG(189, *YYCURSOR);
+ if (yych == 'E') goto yy193;
+ if (yych == 'e') goto yy193;
+yy190:
+ YYDEBUG(190, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1575 "Zend/zend_language_scanner.l"
+#line 1587 "Zend/zend_language_scanner.l"
{
zendlval->value.dval = zend_strtod(yytext, NULL);
zendlval->type = IS_DOUBLE;
return T_DNUMBER;
}
-#line 3212 "Zend/zend_language_scanner.c"
-yy190:
- YYDEBUG(190, *YYCURSOR);
+#line 3226 "Zend/zend_language_scanner.c"
+yy191:
+ YYDEBUG(191, *YYCURSOR);
yyaccept = 2;
YYMARKER = ++YYCURSOR;
YYFILL(3);
yych = *YYCURSOR;
- YYDEBUG(191, *YYCURSOR);
+ YYDEBUG(192, *YYCURSOR);
if (yych <= '9') {
- if (yych == '.') goto yy187;
- if (yych <= '/') goto yy172;
- goto yy190;
+ if (yych == '.') goto yy188;
+ if (yych <= '/') goto yy173;
+ goto yy191;
} else {
if (yych <= 'E') {
- if (yych <= 'D') goto yy172;
+ if (yych <= 'D') goto yy173;
} else {
- if (yych != 'e') goto yy172;
+ if (yych != 'e') goto yy173;
}
}
-yy192:
- YYDEBUG(192, *YYCURSOR);
+yy193:
+ YYDEBUG(193, *YYCURSOR);
yych = *++YYCURSOR;
if (yych <= ',') {
- if (yych == '+') goto yy194;
+ if (yych == '+') goto yy195;
} else {
- if (yych <= '-') goto yy194;
- if (yych <= '/') goto yy193;
- if (yych <= '9') goto yy195;
+ if (yych <= '-') goto yy195;
+ if (yych <= '/') goto yy194;
+ if (yych <= '9') goto yy196;
}
-yy193:
- YYDEBUG(193, *YYCURSOR);
+yy194:
+ YYDEBUG(194, *YYCURSOR);
YYCURSOR = YYMARKER;
if (yyaccept <= 2) {
if (yyaccept <= 1) {
if (yyaccept <= 0) {
goto yy124;
} else {
- goto yy138;
+ goto yy139;
}
} else {
- goto yy172;
+ goto yy173;
}
} else {
if (yyaccept <= 4) {
if (yyaccept <= 3) {
- goto yy189;
+ goto yy190;
} else {
- goto yy238;
+ goto yy239;
}
} else {
- goto yy254;
+ goto yy255;
}
}
-yy194:
- YYDEBUG(194, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych <= '/') goto yy193;
- if (yych >= ':') goto yy193;
yy195:
YYDEBUG(195, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych <= '/') goto yy194;
+ if (yych >= ':') goto yy194;
+yy196:
+ YYDEBUG(196, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
- YYDEBUG(196, *YYCURSOR);
- if (yych <= '/') goto yy189;
- if (yych <= '9') goto yy195;
- goto yy189;
-yy197:
YYDEBUG(197, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yybm[0+yych] & 32) {
- goto yy202;
- }
- goto yy193;
+ if (yych <= '/') goto yy190;
+ if (yych <= '9') goto yy196;
+ goto yy190;
yy198:
YYDEBUG(198, *YYCURSOR);
yych = *++YYCURSOR;
- if (yybm[0+yych] & 16) {
- goto yy199;
+ if (yybm[0+yych] & 32) {
+ goto yy203;
}
- goto yy193;
+ goto yy194;
yy199:
YYDEBUG(199, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yybm[0+yych] & 16) {
+ goto yy200;
+ }
+ goto yy194;
+yy200:
+ YYDEBUG(200, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
- YYDEBUG(200, *YYCURSOR);
+ YYDEBUG(201, *YYCURSOR);
if (yybm[0+yych] & 16) {
- goto yy199;
+ goto yy200;
}
- YYDEBUG(201, *YYCURSOR);
+ YYDEBUG(202, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1485 "Zend/zend_language_scanner.l"
+#line 1497 "Zend/zend_language_scanner.l"
{
char *bin = yytext + 2; /* Skip "0b" */
int len = yyleng - 2;
@@ -3325,19 +3339,19 @@ yy199:
return T_DNUMBER;
}
}
-#line 3329 "Zend/zend_language_scanner.c"
-yy202:
- YYDEBUG(202, *YYCURSOR);
+#line 3343 "Zend/zend_language_scanner.c"
+yy203:
+ YYDEBUG(203, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
- YYDEBUG(203, *YYCURSOR);
+ YYDEBUG(204, *YYCURSOR);
if (yybm[0+yych] & 32) {
- goto yy202;
+ goto yy203;
}
- YYDEBUG(204, *YYCURSOR);
+ YYDEBUG(205, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1531 "Zend/zend_language_scanner.l"
+#line 1543 "Zend/zend_language_scanner.l"
{
char *hex = yytext + 2; /* Skip "0x" */
int len = yyleng - 2;
@@ -3362,16 +3376,16 @@ yy202:
return T_DNUMBER;
}
}
-#line 3366 "Zend/zend_language_scanner.c"
-yy205:
- YYDEBUG(205, *YYCURSOR);
- ++YYCURSOR;
- if ((yych = *YYCURSOR) == '\n') goto yy207;
- if (yych == '\r') goto yy208;
+#line 3380 "Zend/zend_language_scanner.c"
yy206:
YYDEBUG(206, *YYCURSOR);
+ ++YYCURSOR;
+ if ((yych = *YYCURSOR) == '\n') goto yy208;
+ if (yych == '\r') goto yy209;
+yy207:
+ YYDEBUG(207, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1975 "Zend/zend_language_scanner.l"
+#line 1987 "Zend/zend_language_scanner.l"
{
zendlval->value.str.val = yytext; /* no copying - intentional */
zendlval->value.str.len = yyleng;
@@ -3379,137 +3393,137 @@ yy206:
BEGIN(INITIAL);
return T_CLOSE_TAG; /* implicit ';' at php-end tag */
}
-#line 3383 "Zend/zend_language_scanner.c"
-yy207:
- YYDEBUG(207, *YYCURSOR);
- yych = *++YYCURSOR;
- goto yy206;
+#line 3397 "Zend/zend_language_scanner.c"
yy208:
YYDEBUG(208, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == '\n') goto yy207;
- goto yy206;
+ goto yy207;
yy209:
YYDEBUG(209, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == '\n') goto yy208;
+ goto yy207;
+yy210:
+ YYDEBUG(210, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
- YYDEBUG(210, *YYCURSOR);
+ YYDEBUG(211, *YYCURSOR);
if (yych <= '^') {
if (yych <= '9') {
- if (yych >= '0') goto yy209;
+ if (yych >= '0') goto yy210;
} else {
- if (yych <= '@') goto yy211;
- if (yych <= 'Z') goto yy209;
+ if (yych <= '@') goto yy212;
+ if (yych <= 'Z') goto yy210;
}
} else {
if (yych <= '`') {
- if (yych <= '_') goto yy209;
+ if (yych <= '_') goto yy210;
} else {
- if (yych <= 'z') goto yy209;
- if (yych >= 0x7F) goto yy209;
+ if (yych <= 'z') goto yy210;
+ if (yych >= 0x7F) goto yy210;
}
}
-yy211:
- YYDEBUG(211, *YYCURSOR);
+yy212:
+ YYDEBUG(212, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1877 "Zend/zend_language_scanner.l"
+#line 1889 "Zend/zend_language_scanner.l"
{
zend_copy_value(zendlval, (yytext+1), (yyleng-1));
zendlval->type = IS_STRING;
return T_VARIABLE;
}
-#line 3423 "Zend/zend_language_scanner.c"
-yy212:
- YYDEBUG(212, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'R') goto yy213;
- if (yych != 'r') goto yy186;
+#line 3437 "Zend/zend_language_scanner.c"
yy213:
YYDEBUG(213, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'R') goto yy214;
+ if (yych != 'r') goto yy187;
+yy214:
+ YYDEBUG(214, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(214, *YYCURSOR);
+ YYDEBUG(215, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1431 "Zend/zend_language_scanner.l"
+#line 1442 "Zend/zend_language_scanner.l"
{
return T_LOGICAL_XOR;
}
-#line 3441 "Zend/zend_language_scanner.c"
-yy215:
- YYDEBUG(215, *YYCURSOR);
+#line 3455 "Zend/zend_language_scanner.c"
+yy216:
+ YYDEBUG(216, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(216, *YYCURSOR);
+ YYDEBUG(217, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1423 "Zend/zend_language_scanner.l"
+#line 1434 "Zend/zend_language_scanner.l"
{
return T_LOGICAL_OR;
}
-#line 3454 "Zend/zend_language_scanner.c"
-yy217:
- YYDEBUG(217, *YYCURSOR);
- ++YYCURSOR;
+#line 3468 "Zend/zend_language_scanner.c"
+yy218:
YYDEBUG(218, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(219, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1411 "Zend/zend_language_scanner.l"
+#line 1422 "Zend/zend_language_scanner.l"
{
return T_XOR_EQUAL;
}
-#line 3464 "Zend/zend_language_scanner.c"
-yy219:
- YYDEBUG(219, *YYCURSOR);
- ++YYCURSOR;
+#line 3478 "Zend/zend_language_scanner.c"
+yy220:
YYDEBUG(220, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(221, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1415 "Zend/zend_language_scanner.l"
+#line 1426 "Zend/zend_language_scanner.l"
{
return T_BOOLEAN_OR;
}
-#line 3474 "Zend/zend_language_scanner.c"
-yy221:
- YYDEBUG(221, *YYCURSOR);
- ++YYCURSOR;
+#line 3488 "Zend/zend_language_scanner.c"
+yy222:
YYDEBUG(222, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(223, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1407 "Zend/zend_language_scanner.l"
+#line 1418 "Zend/zend_language_scanner.l"
{
return T_OR_EQUAL;
}
-#line 3484 "Zend/zend_language_scanner.c"
-yy223:
- YYDEBUG(223, *YYCURSOR);
- ++YYCURSOR;
+#line 3498 "Zend/zend_language_scanner.c"
+yy224:
YYDEBUG(224, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(225, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1419 "Zend/zend_language_scanner.l"
+#line 1430 "Zend/zend_language_scanner.l"
{
return T_BOOLEAN_AND;
}
-#line 3494 "Zend/zend_language_scanner.c"
-yy225:
- YYDEBUG(225, *YYCURSOR);
- ++YYCURSOR;
+#line 3508 "Zend/zend_language_scanner.c"
+yy226:
YYDEBUG(226, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(227, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1403 "Zend/zend_language_scanner.l"
+#line 1414 "Zend/zend_language_scanner.l"
{
return T_AND_EQUAL;
}
-#line 3504 "Zend/zend_language_scanner.c"
-yy227:
- YYDEBUG(227, *YYCURSOR);
- ++YYCURSOR;
- if ((yych = *YYCURSOR) == '\n') goto yy231;
- if (yych == '\r') goto yy232;
+#line 3518 "Zend/zend_language_scanner.c"
yy228:
YYDEBUG(228, *YYCURSOR);
+ ++YYCURSOR;
+ if ((yych = *YYCURSOR) == '\n') goto yy232;
+ if (yych == '\r') goto yy233;
+yy229:
+ YYDEBUG(229, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1984 "Zend/zend_language_scanner.l"
+#line 1996 "Zend/zend_language_scanner.l"
{
if (CG(asp_tags)) {
BEGIN(INITIAL);
@@ -3522,61 +3536,61 @@ yy228:
return yytext[0];
}
}
-#line 3526 "Zend/zend_language_scanner.c"
-yy229:
- YYDEBUG(229, *YYCURSOR);
- ++YYCURSOR;
+#line 3540 "Zend/zend_language_scanner.c"
+yy230:
YYDEBUG(230, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(231, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1391 "Zend/zend_language_scanner.l"
+#line 1402 "Zend/zend_language_scanner.l"
{
return T_MOD_EQUAL;
}
-#line 3536 "Zend/zend_language_scanner.c"
-yy231:
- YYDEBUG(231, *YYCURSOR);
- yych = *++YYCURSOR;
- goto yy228;
+#line 3550 "Zend/zend_language_scanner.c"
yy232:
YYDEBUG(232, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == '\n') goto yy231;
- goto yy228;
+ goto yy229;
yy233:
YYDEBUG(233, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == '\n') goto yy232;
+ goto yy229;
+yy234:
+ YYDEBUG(234, *YYCURSOR);
yyaccept = 3;
YYMARKER = ++YYCURSOR;
YYFILL(3);
yych = *YYCURSOR;
- YYDEBUG(234, *YYCURSOR);
+ YYDEBUG(235, *YYCURSOR);
if (yych <= 'D') {
- if (yych <= '/') goto yy189;
- if (yych <= '9') goto yy233;
- goto yy189;
+ if (yych <= '/') goto yy190;
+ if (yych <= '9') goto yy234;
+ goto yy190;
} else {
- if (yych <= 'E') goto yy192;
- if (yych == 'e') goto yy192;
- goto yy189;
+ if (yych <= 'E') goto yy193;
+ if (yych == 'e') goto yy193;
+ goto yy190;
}
-yy235:
- YYDEBUG(235, *YYCURSOR);
- ++YYCURSOR;
+yy236:
YYDEBUG(236, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(237, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1387 "Zend/zend_language_scanner.l"
+#line 1398 "Zend/zend_language_scanner.l"
{
return T_CONCAT_EQUAL;
}
-#line 3571 "Zend/zend_language_scanner.c"
-yy237:
- YYDEBUG(237, *YYCURSOR);
- yyaccept = 4;
- yych = *(YYMARKER = ++YYCURSOR);
- if (yych == '*') goto yy242;
+#line 3585 "Zend/zend_language_scanner.c"
yy238:
YYDEBUG(238, *YYCURSOR);
+ yyaccept = 4;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if (yych == '*') goto yy243;
+yy239:
+ YYDEBUG(239, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1941 "Zend/zend_language_scanner.l"
+#line 1953 "Zend/zend_language_scanner.l"
{
int doc_com;
@@ -3610,316 +3624,313 @@ yy238:
return T_COMMENT;
}
-#line 3614 "Zend/zend_language_scanner.c"
-yy239:
- YYDEBUG(239, *YYCURSOR);
- yych = *++YYCURSOR;
- goto yy176;
+#line 3628 "Zend/zend_language_scanner.c"
yy240:
YYDEBUG(240, *YYCURSOR);
- ++YYCURSOR;
+ yych = *++YYCURSOR;
+ goto yy177;
+yy241:
YYDEBUG(241, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(242, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1383 "Zend/zend_language_scanner.l"
+#line 1394 "Zend/zend_language_scanner.l"
{
return T_DIV_EQUAL;
}
-#line 3628 "Zend/zend_language_scanner.c"
-yy242:
- YYDEBUG(242, *YYCURSOR);
+#line 3642 "Zend/zend_language_scanner.c"
+yy243:
+ YYDEBUG(243, *YYCURSOR);
yych = *++YYCURSOR;
if (yybm[0+yych] & 64) {
- goto yy243;
+ goto yy244;
}
- goto yy193;
-yy243:
- YYDEBUG(243, *YYCURSOR);
+ goto yy194;
+yy244:
+ YYDEBUG(244, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
- YYDEBUG(244, *YYCURSOR);
+ YYDEBUG(245, *YYCURSOR);
if (yybm[0+yych] & 64) {
- goto yy243;
+ goto yy244;
}
- goto yy238;
-yy245:
- YYDEBUG(245, *YYCURSOR);
- ++YYCURSOR;
+ goto yy239;
+yy246:
YYDEBUG(246, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(247, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1379 "Zend/zend_language_scanner.l"
+#line 1390 "Zend/zend_language_scanner.l"
{
return T_MUL_EQUAL;
}
-#line 3655 "Zend/zend_language_scanner.c"
-yy247:
- YYDEBUG(247, *YYCURSOR);
- ++YYCURSOR;
- if ((yych = *YYCURSOR) == '=') goto yy251;
+#line 3669 "Zend/zend_language_scanner.c"
+yy248:
YYDEBUG(248, *YYCURSOR);
+ ++YYCURSOR;
+ if ((yych = *YYCURSOR) == '=') goto yy252;
+ YYDEBUG(249, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1439 "Zend/zend_language_scanner.l"
+#line 1450 "Zend/zend_language_scanner.l"
{
return T_SR;
}
-#line 3666 "Zend/zend_language_scanner.c"
-yy249:
- YYDEBUG(249, *YYCURSOR);
- ++YYCURSOR;
+#line 3680 "Zend/zend_language_scanner.c"
+yy250:
YYDEBUG(250, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(251, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1367 "Zend/zend_language_scanner.l"
+#line 1378 "Zend/zend_language_scanner.l"
{
return T_IS_GREATER_OR_EQUAL;
}
-#line 3676 "Zend/zend_language_scanner.c"
-yy251:
- YYDEBUG(251, *YYCURSOR);
- ++YYCURSOR;
+#line 3690 "Zend/zend_language_scanner.c"
+yy252:
YYDEBUG(252, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(253, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1399 "Zend/zend_language_scanner.l"
+#line 1410 "Zend/zend_language_scanner.l"
{
return T_SR_EQUAL;
}
-#line 3686 "Zend/zend_language_scanner.c"
-yy253:
- YYDEBUG(253, *YYCURSOR);
- yyaccept = 5;
- yych = *(YYMARKER = ++YYCURSOR);
- if (yych <= ';') goto yy254;
- if (yych <= '<') goto yy269;
- if (yych <= '=') goto yy267;
+#line 3700 "Zend/zend_language_scanner.c"
yy254:
YYDEBUG(254, *YYCURSOR);
+ yyaccept = 5;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if (yych <= ';') goto yy255;
+ if (yych <= '<') goto yy270;
+ if (yych <= '=') goto yy268;
+yy255:
+ YYDEBUG(255, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1435 "Zend/zend_language_scanner.l"
+#line 1446 "Zend/zend_language_scanner.l"
{
return T_SL;
}
-#line 3701 "Zend/zend_language_scanner.c"
-yy255:
- YYDEBUG(255, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'S') goto yy260;
- if (yych == 's') goto yy260;
- goto yy193;
+#line 3715 "Zend/zend_language_scanner.c"
yy256:
YYDEBUG(256, *YYCURSOR);
- ++YYCURSOR;
+ yych = *++YYCURSOR;
+ if (yych == 'S') goto yy261;
+ if (yych == 's') goto yy261;
+ goto yy194;
+yy257:
YYDEBUG(257, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(258, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1363 "Zend/zend_language_scanner.l"
+#line 1374 "Zend/zend_language_scanner.l"
{
return T_IS_SMALLER_OR_EQUAL;
}
-#line 3717 "Zend/zend_language_scanner.c"
-yy258:
- YYDEBUG(258, *YYCURSOR);
- ++YYCURSOR;
+#line 3731 "Zend/zend_language_scanner.c"
yy259:
YYDEBUG(259, *YYCURSOR);
+ ++YYCURSOR;
+yy260:
+ YYDEBUG(260, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1359 "Zend/zend_language_scanner.l"
+#line 1370 "Zend/zend_language_scanner.l"
{
return T_IS_NOT_EQUAL;
}
-#line 3728 "Zend/zend_language_scanner.c"
-yy260:
- YYDEBUG(260, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'C') goto yy261;
- if (yych != 'c') goto yy193;
+#line 3742 "Zend/zend_language_scanner.c"
yy261:
YYDEBUG(261, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'R') goto yy262;
- if (yych != 'r') goto yy193;
+ if (yych == 'C') goto yy262;
+ if (yych != 'c') goto yy194;
yy262:
YYDEBUG(262, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'I') goto yy263;
- if (yych != 'i') goto yy193;
+ if (yych == 'R') goto yy263;
+ if (yych != 'r') goto yy194;
yy263:
YYDEBUG(263, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'P') goto yy264;
- if (yych != 'p') goto yy193;
+ if (yych == 'I') goto yy264;
+ if (yych != 'i') goto yy194;
yy264:
YYDEBUG(264, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'T') goto yy265;
- if (yych != 't') goto yy193;
+ if (yych == 'P') goto yy265;
+ if (yych != 'p') goto yy194;
yy265:
YYDEBUG(265, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'T') goto yy266;
+ if (yych != 't') goto yy194;
+yy266:
+ YYDEBUG(266, *YYCURSOR);
++YYCURSOR;
YYFILL(3);
yych = *YYCURSOR;
- YYDEBUG(266, *YYCURSOR);
+ YYDEBUG(267, *YYCURSOR);
if (yych <= '\r') {
- if (yych <= 0x08) goto yy193;
- if (yych <= '\n') goto yy265;
- if (yych <= '\f') goto yy193;
- goto yy265;
+ if (yych <= 0x08) goto yy194;
+ if (yych <= '\n') goto yy266;
+ if (yych <= '\f') goto yy194;
+ goto yy266;
} else {
if (yych <= ' ') {
- if (yych <= 0x1F) goto yy193;
- goto yy265;
+ if (yych <= 0x1F) goto yy194;
+ goto yy266;
} else {
- if (yych == '>') goto yy205;
- goto yy193;
+ if (yych == '>') goto yy206;
+ goto yy194;
}
}
-yy267:
- YYDEBUG(267, *YYCURSOR);
- ++YYCURSOR;
+yy268:
YYDEBUG(268, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(269, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1395 "Zend/zend_language_scanner.l"
+#line 1406 "Zend/zend_language_scanner.l"
{
return T_SL_EQUAL;
}
-#line 3783 "Zend/zend_language_scanner.c"
-yy269:
- YYDEBUG(269, *YYCURSOR);
+#line 3797 "Zend/zend_language_scanner.c"
+yy270:
+ YYDEBUG(270, *YYCURSOR);
++YYCURSOR;
YYFILL(2);
yych = *YYCURSOR;
- YYDEBUG(270, *YYCURSOR);
+ YYDEBUG(271, *YYCURSOR);
if (yybm[0+yych] & 128) {
- goto yy269;
+ goto yy270;
}
if (yych <= 'Z') {
if (yych <= '&') {
- if (yych == '"') goto yy274;
- goto yy193;
+ if (yych == '"') goto yy275;
+ goto yy194;
} else {
- if (yych <= '\'') goto yy273;
- if (yych <= '@') goto yy193;
+ if (yych <= '\'') goto yy274;
+ if (yych <= '@') goto yy194;
}
} else {
if (yych <= '`') {
- if (yych != '_') goto yy193;
+ if (yych != '_') goto yy194;
} else {
- if (yych <= 'z') goto yy271;
- if (yych <= '~') goto yy193;
+ if (yych <= 'z') goto yy272;
+ if (yych <= '~') goto yy194;
}
}
-yy271:
- YYDEBUG(271, *YYCURSOR);
+yy272:
+ YYDEBUG(272, *YYCURSOR);
++YYCURSOR;
YYFILL(2);
yych = *YYCURSOR;
- YYDEBUG(272, *YYCURSOR);
+ YYDEBUG(273, *YYCURSOR);
if (yych <= '@') {
if (yych <= '\f') {
- if (yych == '\n') goto yy278;
- goto yy193;
+ if (yych == '\n') goto yy279;
+ goto yy194;
} else {
- if (yych <= '\r') goto yy280;
- if (yych <= '/') goto yy193;
- if (yych <= '9') goto yy271;
- goto yy193;
+ if (yych <= '\r') goto yy281;
+ if (yych <= '/') goto yy194;
+ if (yych <= '9') goto yy272;
+ goto yy194;
}
} else {
if (yych <= '_') {
- if (yych <= 'Z') goto yy271;
- if (yych <= '^') goto yy193;
- goto yy271;
+ if (yych <= 'Z') goto yy272;
+ if (yych <= '^') goto yy194;
+ goto yy272;
} else {
- if (yych <= '`') goto yy193;
- if (yych <= 'z') goto yy271;
- if (yych <= '~') goto yy193;
- goto yy271;
+ if (yych <= '`') goto yy194;
+ if (yych <= 'z') goto yy272;
+ if (yych <= '~') goto yy194;
+ goto yy272;
}
}
-yy273:
- YYDEBUG(273, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == '\'') goto yy193;
- if (yych <= '/') goto yy282;
- if (yych <= '9') goto yy193;
- goto yy282;
yy274:
YYDEBUG(274, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == '"') goto yy193;
- if (yych <= '/') goto yy276;
- if (yych <= '9') goto yy193;
- goto yy276;
+ if (yych == '\'') goto yy194;
+ if (yych <= '/') goto yy283;
+ if (yych <= '9') goto yy194;
+ goto yy283;
yy275:
YYDEBUG(275, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == '"') goto yy194;
+ if (yych <= '/') goto yy277;
+ if (yych <= '9') goto yy194;
+ goto yy277;
+yy276:
+ YYDEBUG(276, *YYCURSOR);
++YYCURSOR;
YYFILL(3);
yych = *YYCURSOR;
-yy276:
- YYDEBUG(276, *YYCURSOR);
+yy277:
+ YYDEBUG(277, *YYCURSOR);
if (yych <= 'Z') {
if (yych <= '/') {
- if (yych != '"') goto yy193;
+ if (yych != '"') goto yy194;
} else {
- if (yych <= '9') goto yy275;
- if (yych <= '@') goto yy193;
- goto yy275;
+ if (yych <= '9') goto yy276;
+ if (yych <= '@') goto yy194;
+ goto yy276;
}
} else {
if (yych <= '`') {
- if (yych == '_') goto yy275;
- goto yy193;
+ if (yych == '_') goto yy276;
+ goto yy194;
} else {
- if (yych <= 'z') goto yy275;
- if (yych <= '~') goto yy193;
- goto yy275;
+ if (yych <= 'z') goto yy276;
+ if (yych <= '~') goto yy194;
+ goto yy276;
}
}
-yy277:
- YYDEBUG(277, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == '\n') goto yy278;
- if (yych == '\r') goto yy280;
- goto yy193;
yy278:
YYDEBUG(278, *YYCURSOR);
- ++YYCURSOR;
+ yych = *++YYCURSOR;
+ if (yych == '\n') goto yy279;
+ if (yych == '\r') goto yy281;
+ goto yy194;
yy279:
YYDEBUG(279, *YYCURSOR);
+ ++YYCURSOR;
+yy280:
+ YYDEBUG(280, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 2109 "Zend/zend_language_scanner.l"
+#line 2121 "Zend/zend_language_scanner.l"
{
char *s;
int bprefix = (yytext[0] != '<') ? 1 : 0;
-
- /* save old heredoc label */
- Z_STRVAL_P(zendlval) = CG(heredoc);
- Z_STRLEN_P(zendlval) = CG(heredoc_len);
+ zend_heredoc_label *heredoc_label = emalloc(sizeof(zend_heredoc_label));
CG(zend_lineno)++;
- CG(heredoc_len) = yyleng-bprefix-3-1-(yytext[yyleng-2]=='\r'?1:0);
+ heredoc_label->length = yyleng-bprefix-3-1-(yytext[yyleng-2]=='\r'?1:0);
s = yytext+bprefix+3;
while ((*s == ' ') || (*s == '\t')) {
s++;
- CG(heredoc_len)--;
+ heredoc_label->length--;
}
if (*s == '\'') {
s++;
- CG(heredoc_len) -= 2;
+ heredoc_label->length -= 2;
BEGIN(ST_NOWDOC);
} else {
if (*s == '"') {
s++;
- CG(heredoc_len) -= 2;
+ heredoc_label->length -= 2;
}
BEGIN(ST_HEREDOC);
}
- CG(heredoc) = estrndup(s, CG(heredoc_len));
+ heredoc_label->label = estrndup(s, heredoc_label->length);
/* Check for ending label on the next line */
- if (CG(heredoc_len) < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, s, CG(heredoc_len))) {
- YYCTYPE *end = YYCURSOR + CG(heredoc_len);
+ if (heredoc_label->length < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, s, heredoc_label->length)) {
+ YYCTYPE *end = YYCURSOR + heredoc_label->length;
if (*end == ';') {
end++;
@@ -3930,257 +3941,259 @@ yy279:
}
}
+ zend_ptr_stack_push(&SCNG(heredoc_label_stack), (void *) heredoc_label);
+
return T_START_HEREDOC;
}
-#line 3936 "Zend/zend_language_scanner.c"
-yy280:
- YYDEBUG(280, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == '\n') goto yy278;
- goto yy279;
+#line 3949 "Zend/zend_language_scanner.c"
yy281:
YYDEBUG(281, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == '\n') goto yy279;
+ goto yy280;
+yy282:
+ YYDEBUG(282, *YYCURSOR);
++YYCURSOR;
YYFILL(3);
yych = *YYCURSOR;
-yy282:
- YYDEBUG(282, *YYCURSOR);
+yy283:
+ YYDEBUG(283, *YYCURSOR);
if (yych <= 'Z') {
if (yych <= '/') {
- if (yych == '\'') goto yy277;
- goto yy193;
+ if (yych == '\'') goto yy278;
+ goto yy194;
} else {
- if (yych <= '9') goto yy281;
- if (yych <= '@') goto yy193;
- goto yy281;
+ if (yych <= '9') goto yy282;
+ if (yych <= '@') goto yy194;
+ goto yy282;
}
} else {
if (yych <= '`') {
- if (yych == '_') goto yy281;
- goto yy193;
+ if (yych == '_') goto yy282;
+ goto yy194;
} else {
- if (yych <= 'z') goto yy281;
- if (yych <= '~') goto yy193;
- goto yy281;
+ if (yych <= 'z') goto yy282;
+ if (yych <= '~') goto yy194;
+ goto yy282;
}
}
-yy283:
- YYDEBUG(283, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych != '=') goto yy259;
+yy284:
YYDEBUG(284, *YYCURSOR);
- ++YYCURSOR;
+ yych = *++YYCURSOR;
+ if (yych != '=') goto yy260;
YYDEBUG(285, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(286, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1351 "Zend/zend_language_scanner.l"
+#line 1362 "Zend/zend_language_scanner.l"
{
return T_IS_NOT_IDENTICAL;
}
-#line 3980 "Zend/zend_language_scanner.c"
-yy286:
- YYDEBUG(286, *YYCURSOR);
- ++YYCURSOR;
+#line 3993 "Zend/zend_language_scanner.c"
+yy287:
YYDEBUG(287, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(288, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1371 "Zend/zend_language_scanner.l"
+#line 1382 "Zend/zend_language_scanner.l"
{
return T_PLUS_EQUAL;
}
-#line 3990 "Zend/zend_language_scanner.c"
-yy288:
- YYDEBUG(288, *YYCURSOR);
- ++YYCURSOR;
+#line 4003 "Zend/zend_language_scanner.c"
+yy289:
YYDEBUG(289, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(290, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1339 "Zend/zend_language_scanner.l"
+#line 1350 "Zend/zend_language_scanner.l"
{
return T_INC;
}
-#line 4000 "Zend/zend_language_scanner.c"
-yy290:
- YYDEBUG(290, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'S') goto yy291;
- if (yych != 's') goto yy186;
+#line 4013 "Zend/zend_language_scanner.c"
yy291:
YYDEBUG(291, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'T') goto yy292;
- if (yych != 't') goto yy186;
+ if (yych == 'S') goto yy292;
+ if (yych != 's') goto yy187;
yy292:
YYDEBUG(292, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'T') goto yy293;
+ if (yych != 't') goto yy187;
+yy293:
+ YYDEBUG(293, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(293, *YYCURSOR);
+ YYDEBUG(294, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1327 "Zend/zend_language_scanner.l"
+#line 1338 "Zend/zend_language_scanner.l"
{
return T_LIST;
}
-#line 4023 "Zend/zend_language_scanner.c"
-yy294:
- YYDEBUG(294, *YYCURSOR);
- ++YYCURSOR;
- if ((yych = *YYCURSOR) == '=') goto yy298;
+#line 4036 "Zend/zend_language_scanner.c"
+yy295:
YYDEBUG(295, *YYCURSOR);
+ ++YYCURSOR;
+ if ((yych = *YYCURSOR) == '=') goto yy299;
+ YYDEBUG(296, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1355 "Zend/zend_language_scanner.l"
+#line 1366 "Zend/zend_language_scanner.l"
{
return T_IS_EQUAL;
}
-#line 4034 "Zend/zend_language_scanner.c"
-yy296:
- YYDEBUG(296, *YYCURSOR);
- ++YYCURSOR;
+#line 4047 "Zend/zend_language_scanner.c"
+yy297:
YYDEBUG(297, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(298, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1323 "Zend/zend_language_scanner.l"
+#line 1334 "Zend/zend_language_scanner.l"
{
return T_DOUBLE_ARROW;
}
-#line 4044 "Zend/zend_language_scanner.c"
-yy298:
- YYDEBUG(298, *YYCURSOR);
- ++YYCURSOR;
+#line 4057 "Zend/zend_language_scanner.c"
+yy299:
YYDEBUG(299, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(300, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1347 "Zend/zend_language_scanner.l"
+#line 1358 "Zend/zend_language_scanner.l"
{
return T_IS_IDENTICAL;
}
-#line 4054 "Zend/zend_language_scanner.c"
-yy300:
- YYDEBUG(300, *YYCURSOR);
+#line 4067 "Zend/zend_language_scanner.c"
+yy301:
+ YYDEBUG(301, *YYCURSOR);
yych = *++YYCURSOR;
YYDEBUG(-1, yych);
switch (yych) {
case 'C':
- case 'c': goto yy302;
+ case 'c': goto yy303;
case 'D':
- case 'd': goto yy307;
+ case 'd': goto yy308;
case 'F':
- case 'f': goto yy304;
+ case 'f': goto yy305;
case 'H':
- case 'h': goto yy301;
+ case 'h': goto yy302;
case 'L':
- case 'l': goto yy306;
+ case 'l': goto yy307;
case 'M':
- case 'm': goto yy305;
+ case 'm': goto yy306;
case 'N':
- case 'n': goto yy308;
+ case 'n': goto yy309;
case 'T':
- case 't': goto yy303;
- default: goto yy186;
+ case 't': goto yy304;
+ default: goto yy187;
}
-yy301:
- YYDEBUG(301, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'A') goto yy369;
- if (yych == 'a') goto yy369;
- goto yy186;
yy302:
YYDEBUG(302, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'L') goto yy362;
- if (yych == 'l') goto yy362;
- goto yy186;
+ if (yych == 'A') goto yy370;
+ if (yych == 'a') goto yy370;
+ goto yy187;
yy303:
YYDEBUG(303, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'R') goto yy355;
- if (yych == 'r') goto yy355;
- goto yy186;
+ if (yych == 'L') goto yy363;
+ if (yych == 'l') goto yy363;
+ goto yy187;
yy304:
YYDEBUG(304, *YYCURSOR);
yych = *++YYCURSOR;
+ if (yych == 'R') goto yy356;
+ if (yych == 'r') goto yy356;
+ goto yy187;
+yy305:
+ YYDEBUG(305, *YYCURSOR);
+ yych = *++YYCURSOR;
if (yych <= 'U') {
- if (yych == 'I') goto yy339;
- if (yych <= 'T') goto yy186;
- goto yy340;
+ if (yych == 'I') goto yy340;
+ if (yych <= 'T') goto yy187;
+ goto yy341;
} else {
if (yych <= 'i') {
- if (yych <= 'h') goto yy186;
- goto yy339;
+ if (yych <= 'h') goto yy187;
+ goto yy340;
} else {
- if (yych == 'u') goto yy340;
- goto yy186;
+ if (yych == 'u') goto yy341;
+ goto yy187;
}
}
-yy305:
- YYDEBUG(305, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'E') goto yy331;
- if (yych == 'e') goto yy331;
- goto yy186;
yy306:
YYDEBUG(306, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'I') goto yy325;
- if (yych == 'i') goto yy325;
- goto yy186;
+ if (yych == 'E') goto yy332;
+ if (yych == 'e') goto yy332;
+ goto yy187;
yy307:
YYDEBUG(307, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'I') goto yy320;
- if (yych == 'i') goto yy320;
- goto yy186;
+ if (yych == 'I') goto yy326;
+ if (yych == 'i') goto yy326;
+ goto yy187;
yy308:
YYDEBUG(308, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'A') goto yy309;
- if (yych != 'a') goto yy186;
+ if (yych == 'I') goto yy321;
+ if (yych == 'i') goto yy321;
+ goto yy187;
yy309:
YYDEBUG(309, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'M') goto yy310;
- if (yych != 'm') goto yy186;
+ if (yych == 'A') goto yy310;
+ if (yych != 'a') goto yy187;
yy310:
YYDEBUG(310, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy311;
- if (yych != 'e') goto yy186;
+ if (yych == 'M') goto yy311;
+ if (yych != 'm') goto yy187;
yy311:
YYDEBUG(311, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'S') goto yy312;
- if (yych != 's') goto yy186;
+ if (yych == 'E') goto yy312;
+ if (yych != 'e') goto yy187;
yy312:
YYDEBUG(312, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'P') goto yy313;
- if (yych != 'p') goto yy186;
+ if (yych == 'S') goto yy313;
+ if (yych != 's') goto yy187;
yy313:
YYDEBUG(313, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'A') goto yy314;
- if (yych != 'a') goto yy186;
+ if (yych == 'P') goto yy314;
+ if (yych != 'p') goto yy187;
yy314:
YYDEBUG(314, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'C') goto yy315;
- if (yych != 'c') goto yy186;
+ if (yych == 'A') goto yy315;
+ if (yych != 'a') goto yy187;
yy315:
YYDEBUG(315, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy316;
- if (yych != 'e') goto yy186;
+ if (yych == 'C') goto yy316;
+ if (yych != 'c') goto yy187;
yy316:
YYDEBUG(316, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych != '_') goto yy186;
+ if (yych == 'E') goto yy317;
+ if (yych != 'e') goto yy187;
+yy317:
YYDEBUG(317, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych != '_') goto yy186;
+ if (yych != '_') goto yy187;
YYDEBUG(318, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych != '_') goto yy187;
+ YYDEBUG(319, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(319, *YYCURSOR);
+ YYDEBUG(320, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1710 "Zend/zend_language_scanner.l"
+#line 1722 "Zend/zend_language_scanner.l"
{
if (CG(current_namespace)) {
*zendlval = *CG(current_namespace);
@@ -4190,27 +4203,27 @@ yy316:
}
return T_NS_C;
}
-#line 4194 "Zend/zend_language_scanner.c"
-yy320:
- YYDEBUG(320, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'R') goto yy321;
- if (yych != 'r') goto yy186;
+#line 4207 "Zend/zend_language_scanner.c"
yy321:
YYDEBUG(321, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych != '_') goto yy186;
+ if (yych == 'R') goto yy322;
+ if (yych != 'r') goto yy187;
+yy322:
YYDEBUG(322, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych != '_') goto yy186;
+ if (yych != '_') goto yy187;
YYDEBUG(323, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych != '_') goto yy187;
+ YYDEBUG(324, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(324, *YYCURSOR);
+ YYDEBUG(325, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1683 "Zend/zend_language_scanner.l"
+#line 1695 "Zend/zend_language_scanner.l"
{
char *filename = zend_get_compiled_filename(TSRMLS_C);
const size_t filename_len = strlen(filename);
@@ -4237,73 +4250,73 @@ yy321:
zendlval->type = IS_STRING;
return T_DIR;
}
-#line 4241 "Zend/zend_language_scanner.c"
-yy325:
- YYDEBUG(325, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'N') goto yy326;
- if (yych != 'n') goto yy186;
+#line 4254 "Zend/zend_language_scanner.c"
yy326:
YYDEBUG(326, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy327;
- if (yych != 'e') goto yy186;
+ if (yych == 'N') goto yy327;
+ if (yych != 'n') goto yy187;
yy327:
YYDEBUG(327, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych != '_') goto yy186;
+ if (yych == 'E') goto yy328;
+ if (yych != 'e') goto yy187;
+yy328:
YYDEBUG(328, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych != '_') goto yy186;
+ if (yych != '_') goto yy187;
YYDEBUG(329, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych != '_') goto yy187;
+ YYDEBUG(330, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(330, *YYCURSOR);
+ YYDEBUG(331, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1665 "Zend/zend_language_scanner.l"
+#line 1677 "Zend/zend_language_scanner.l"
{
zendlval->value.lval = CG(zend_lineno);
zendlval->type = IS_LONG;
return T_LINE;
}
-#line 4272 "Zend/zend_language_scanner.c"
-yy331:
- YYDEBUG(331, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'T') goto yy332;
- if (yych != 't') goto yy186;
+#line 4285 "Zend/zend_language_scanner.c"
yy332:
YYDEBUG(332, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'H') goto yy333;
- if (yych != 'h') goto yy186;
+ if (yych == 'T') goto yy333;
+ if (yych != 't') goto yy187;
yy333:
YYDEBUG(333, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'O') goto yy334;
- if (yych != 'o') goto yy186;
+ if (yych == 'H') goto yy334;
+ if (yych != 'h') goto yy187;
yy334:
YYDEBUG(334, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'D') goto yy335;
- if (yych != 'd') goto yy186;
+ if (yych == 'O') goto yy335;
+ if (yych != 'o') goto yy187;
yy335:
YYDEBUG(335, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych != '_') goto yy186;
+ if (yych == 'D') goto yy336;
+ if (yych != 'd') goto yy187;
+yy336:
YYDEBUG(336, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych != '_') goto yy186;
+ if (yych != '_') goto yy187;
YYDEBUG(337, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych != '_') goto yy187;
+ YYDEBUG(338, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(338, *YYCURSOR);
+ YYDEBUG(339, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1644 "Zend/zend_language_scanner.l"
+#line 1656 "Zend/zend_language_scanner.l"
{
const char *class_name = CG(active_class_entry) ? CG(active_class_entry)->name : NULL;
const char *func_name = CG(active_op_array)? CG(active_op_array)->function_name : NULL;
@@ -4324,58 +4337,58 @@ yy335:
zendlval->type = IS_STRING;
return T_METHOD_C;
}
-#line 4328 "Zend/zend_language_scanner.c"
-yy339:
- YYDEBUG(339, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'L') goto yy350;
- if (yych == 'l') goto yy350;
- goto yy186;
+#line 4341 "Zend/zend_language_scanner.c"
yy340:
YYDEBUG(340, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'N') goto yy341;
- if (yych != 'n') goto yy186;
+ if (yych == 'L') goto yy351;
+ if (yych == 'l') goto yy351;
+ goto yy187;
yy341:
YYDEBUG(341, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'C') goto yy342;
- if (yych != 'c') goto yy186;
+ if (yych == 'N') goto yy342;
+ if (yych != 'n') goto yy187;
yy342:
YYDEBUG(342, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'T') goto yy343;
- if (yych != 't') goto yy186;
+ if (yych == 'C') goto yy343;
+ if (yych != 'c') goto yy187;
yy343:
YYDEBUG(343, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'I') goto yy344;
- if (yych != 'i') goto yy186;
+ if (yych == 'T') goto yy344;
+ if (yych != 't') goto yy187;
yy344:
YYDEBUG(344, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'O') goto yy345;
- if (yych != 'o') goto yy186;
+ if (yych == 'I') goto yy345;
+ if (yych != 'i') goto yy187;
yy345:
YYDEBUG(345, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'N') goto yy346;
- if (yych != 'n') goto yy186;
+ if (yych == 'O') goto yy346;
+ if (yych != 'o') goto yy187;
yy346:
YYDEBUG(346, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych != '_') goto yy186;
+ if (yych == 'N') goto yy347;
+ if (yych != 'n') goto yy187;
+yy347:
YYDEBUG(347, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych != '_') goto yy186;
+ if (yych != '_') goto yy187;
YYDEBUG(348, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych != '_') goto yy187;
+ YYDEBUG(349, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(349, *YYCURSOR);
+ YYDEBUG(350, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1628 "Zend/zend_language_scanner.l"
+#line 1640 "Zend/zend_language_scanner.l"
{
const char *func_name = NULL;
@@ -4391,27 +4404,27 @@ yy346:
zendlval->type = IS_STRING;
return T_FUNC_C;
}
-#line 4395 "Zend/zend_language_scanner.c"
-yy350:
- YYDEBUG(350, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'E') goto yy351;
- if (yych != 'e') goto yy186;
+#line 4408 "Zend/zend_language_scanner.c"
yy351:
YYDEBUG(351, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych != '_') goto yy186;
+ if (yych == 'E') goto yy352;
+ if (yych != 'e') goto yy187;
+yy352:
YYDEBUG(352, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych != '_') goto yy186;
+ if (yych != '_') goto yy187;
YYDEBUG(353, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych != '_') goto yy187;
+ YYDEBUG(354, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(354, *YYCURSOR);
+ YYDEBUG(355, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1671 "Zend/zend_language_scanner.l"
+#line 1683 "Zend/zend_language_scanner.l"
{
char *filename = zend_get_compiled_filename(TSRMLS_C);
@@ -4423,37 +4436,37 @@ yy351:
zendlval->type = IS_STRING;
return T_FILE;
}
-#line 4427 "Zend/zend_language_scanner.c"
-yy355:
- YYDEBUG(355, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'A') goto yy356;
- if (yych != 'a') goto yy186;
+#line 4440 "Zend/zend_language_scanner.c"
yy356:
YYDEBUG(356, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'I') goto yy357;
- if (yych != 'i') goto yy186;
+ if (yych == 'A') goto yy357;
+ if (yych != 'a') goto yy187;
yy357:
YYDEBUG(357, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'T') goto yy358;
- if (yych != 't') goto yy186;
+ if (yych == 'I') goto yy358;
+ if (yych != 'i') goto yy187;
yy358:
YYDEBUG(358, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych != '_') goto yy186;
+ if (yych == 'T') goto yy359;
+ if (yych != 't') goto yy187;
+yy359:
YYDEBUG(359, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych != '_') goto yy186;
+ if (yych != '_') goto yy187;
YYDEBUG(360, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych != '_') goto yy187;
+ YYDEBUG(361, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(361, *YYCURSOR);
+ YYDEBUG(362, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1608 "Zend/zend_language_scanner.l"
+#line 1620 "Zend/zend_language_scanner.l"
{
const char *trait_name = NULL;
@@ -4473,37 +4486,37 @@ yy358:
return T_TRAIT_C;
}
-#line 4477 "Zend/zend_language_scanner.c"
-yy362:
- YYDEBUG(362, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'A') goto yy363;
- if (yych != 'a') goto yy186;
+#line 4490 "Zend/zend_language_scanner.c"
yy363:
YYDEBUG(363, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'S') goto yy364;
- if (yych != 's') goto yy186;
+ if (yych == 'A') goto yy364;
+ if (yych != 'a') goto yy187;
yy364:
YYDEBUG(364, *YYCURSOR);
yych = *++YYCURSOR;
if (yych == 'S') goto yy365;
- if (yych != 's') goto yy186;
+ if (yych != 's') goto yy187;
yy365:
YYDEBUG(365, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych != '_') goto yy186;
+ if (yych == 'S') goto yy366;
+ if (yych != 's') goto yy187;
+yy366:
YYDEBUG(366, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych != '_') goto yy186;
+ if (yych != '_') goto yy187;
YYDEBUG(367, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych != '_') goto yy187;
+ YYDEBUG(368, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(368, *YYCURSOR);
+ YYDEBUG(369, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1581 "Zend/zend_language_scanner.l"
+#line 1593 "Zend/zend_language_scanner.l"
{
const char *class_name = NULL;
@@ -4530,2648 +4543,2709 @@ yy365:
}
return T_CLASS_C;
}
-#line 4534 "Zend/zend_language_scanner.c"
-yy369:
- YYDEBUG(369, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'L') goto yy370;
- if (yych != 'l') goto yy186;
+#line 4547 "Zend/zend_language_scanner.c"
yy370:
YYDEBUG(370, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'T') goto yy371;
- if (yych != 't') goto yy186;
+ if (yych == 'L') goto yy371;
+ if (yych != 'l') goto yy187;
yy371:
YYDEBUG(371, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych != '_') goto yy186;
+ if (yych == 'T') goto yy372;
+ if (yych != 't') goto yy187;
+yy372:
YYDEBUG(372, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'C') goto yy373;
- if (yych != 'c') goto yy186;
-yy373:
+ if (yych != '_') goto yy187;
YYDEBUG(373, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'O') goto yy374;
- if (yych != 'o') goto yy186;
+ if (yych == 'C') goto yy374;
+ if (yych != 'c') goto yy187;
yy374:
YYDEBUG(374, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'M') goto yy375;
- if (yych != 'm') goto yy186;
+ if (yych == 'O') goto yy375;
+ if (yych != 'o') goto yy187;
yy375:
YYDEBUG(375, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'P') goto yy376;
- if (yych != 'p') goto yy186;
+ if (yych == 'M') goto yy376;
+ if (yych != 'm') goto yy187;
yy376:
YYDEBUG(376, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'I') goto yy377;
- if (yych != 'i') goto yy186;
+ if (yych == 'P') goto yy377;
+ if (yych != 'p') goto yy187;
yy377:
YYDEBUG(377, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'L') goto yy378;
- if (yych != 'l') goto yy186;
+ if (yych == 'I') goto yy378;
+ if (yych != 'i') goto yy187;
yy378:
YYDEBUG(378, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy379;
- if (yych != 'e') goto yy186;
+ if (yych == 'L') goto yy379;
+ if (yych != 'l') goto yy187;
yy379:
YYDEBUG(379, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'R') goto yy380;
- if (yych != 'r') goto yy186;
+ if (yych == 'E') goto yy380;
+ if (yych != 'e') goto yy187;
yy380:
YYDEBUG(380, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'R') goto yy381;
+ if (yych != 'r') goto yy187;
+yy381:
+ YYDEBUG(381, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(381, *YYCURSOR);
+ YYDEBUG(382, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1291 "Zend/zend_language_scanner.l"
+#line 1302 "Zend/zend_language_scanner.l"
{
return T_HALT_COMPILER;
}
-#line 4600 "Zend/zend_language_scanner.c"
-yy382:
- YYDEBUG(382, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'S') goto yy386;
- if (yych == 's') goto yy386;
- goto yy186;
+#line 4613 "Zend/zend_language_scanner.c"
yy383:
YYDEBUG(383, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy384;
- if (yych != 'e') goto yy186;
+ if (yych == 'S') goto yy387;
+ if (yych == 's') goto yy387;
+ goto yy187;
yy384:
YYDEBUG(384, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'E') goto yy385;
+ if (yych != 'e') goto yy187;
+yy385:
+ YYDEBUG(385, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(385, *YYCURSOR);
+ YYDEBUG(386, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1271 "Zend/zend_language_scanner.l"
+#line 1282 "Zend/zend_language_scanner.l"
{
return T_USE;
}
-#line 4624 "Zend/zend_language_scanner.c"
-yy386:
- YYDEBUG(386, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'E') goto yy387;
- if (yych != 'e') goto yy186;
+#line 4637 "Zend/zend_language_scanner.c"
yy387:
YYDEBUG(387, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'T') goto yy388;
- if (yych != 't') goto yy186;
+ if (yych == 'E') goto yy388;
+ if (yych != 'e') goto yy187;
yy388:
YYDEBUG(388, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'T') goto yy389;
+ if (yych != 't') goto yy187;
+yy389:
+ YYDEBUG(389, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(389, *YYCURSOR);
+ YYDEBUG(390, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1319 "Zend/zend_language_scanner.l"
+#line 1330 "Zend/zend_language_scanner.l"
{
return T_UNSET;
}
-#line 4647 "Zend/zend_language_scanner.c"
-yy390:
- YYDEBUG(390, *YYCURSOR);
+#line 4660 "Zend/zend_language_scanner.c"
+yy391:
+ YYDEBUG(391, *YYCURSOR);
++YYCURSOR;
YYFILL(7);
yych = *YYCURSOR;
-yy391:
- YYDEBUG(391, *YYCURSOR);
+yy392:
+ YYDEBUG(392, *YYCURSOR);
if (yych <= 'S') {
if (yych <= 'D') {
if (yych <= ' ') {
- if (yych == '\t') goto yy390;
- if (yych <= 0x1F) goto yy193;
- goto yy390;
+ if (yych == '\t') goto yy391;
+ if (yych <= 0x1F) goto yy194;
+ goto yy391;
} else {
if (yych <= 'A') {
- if (yych <= '@') goto yy193;
- goto yy395;
+ if (yych <= '@') goto yy194;
+ goto yy396;
} else {
- if (yych <= 'B') goto yy393;
- if (yych <= 'C') goto yy193;
- goto yy398;
+ if (yych <= 'B') goto yy394;
+ if (yych <= 'C') goto yy194;
+ goto yy399;
}
}
} else {
if (yych <= 'I') {
- if (yych == 'F') goto yy399;
- if (yych <= 'H') goto yy193;
- goto yy400;
+ if (yych == 'F') goto yy400;
+ if (yych <= 'H') goto yy194;
+ goto yy401;
} else {
if (yych <= 'O') {
- if (yych <= 'N') goto yy193;
- goto yy394;
+ if (yych <= 'N') goto yy194;
+ goto yy395;
} else {
- if (yych <= 'Q') goto yy193;
- if (yych <= 'R') goto yy397;
- goto yy396;
+ if (yych <= 'Q') goto yy194;
+ if (yych <= 'R') goto yy398;
+ goto yy397;
}
}
}
} else {
if (yych <= 'f') {
if (yych <= 'a') {
- if (yych == 'U') goto yy392;
- if (yych <= '`') goto yy193;
- goto yy395;
+ if (yych == 'U') goto yy393;
+ if (yych <= '`') goto yy194;
+ goto yy396;
} else {
if (yych <= 'c') {
- if (yych <= 'b') goto yy393;
- goto yy193;
+ if (yych <= 'b') goto yy394;
+ goto yy194;
} else {
- if (yych <= 'd') goto yy398;
- if (yych <= 'e') goto yy193;
- goto yy399;
+ if (yych <= 'd') goto yy399;
+ if (yych <= 'e') goto yy194;
+ goto yy400;
}
}
} else {
if (yych <= 'q') {
if (yych <= 'i') {
- if (yych <= 'h') goto yy193;
- goto yy400;
+ if (yych <= 'h') goto yy194;
+ goto yy401;
} else {
- if (yych == 'o') goto yy394;
- goto yy193;
+ if (yych == 'o') goto yy395;
+ goto yy194;
}
} else {
if (yych <= 's') {
- if (yych <= 'r') goto yy397;
- goto yy396;
+ if (yych <= 'r') goto yy398;
+ goto yy397;
} else {
- if (yych != 'u') goto yy193;
+ if (yych != 'u') goto yy194;
}
}
}
}
-yy392:
- YYDEBUG(392, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'N') goto yy459;
- if (yych == 'n') goto yy459;
- goto yy193;
yy393:
YYDEBUG(393, *YYCURSOR);
yych = *++YYCURSOR;
+ if (yych == 'N') goto yy460;
+ if (yych == 'n') goto yy460;
+ goto yy194;
+yy394:
+ YYDEBUG(394, *YYCURSOR);
+ yych = *++YYCURSOR;
if (yych <= 'O') {
- if (yych == 'I') goto yy446;
- if (yych <= 'N') goto yy193;
- goto yy447;
+ if (yych == 'I') goto yy447;
+ if (yych <= 'N') goto yy194;
+ goto yy448;
} else {
if (yych <= 'i') {
- if (yych <= 'h') goto yy193;
- goto yy446;
+ if (yych <= 'h') goto yy194;
+ goto yy447;
} else {
- if (yych == 'o') goto yy447;
- goto yy193;
+ if (yych == 'o') goto yy448;
+ goto yy194;
}
}
-yy394:
- YYDEBUG(394, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'B') goto yy438;
- if (yych == 'b') goto yy438;
- goto yy193;
yy395:
YYDEBUG(395, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'R') goto yy431;
- if (yych == 'r') goto yy431;
- goto yy193;
+ if (yych == 'B') goto yy439;
+ if (yych == 'b') goto yy439;
+ goto yy194;
yy396:
YYDEBUG(396, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'T') goto yy423;
- if (yych == 't') goto yy423;
- goto yy193;
+ if (yych == 'R') goto yy432;
+ if (yych == 'r') goto yy432;
+ goto yy194;
yy397:
YYDEBUG(397, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy421;
- if (yych == 'e') goto yy421;
- goto yy193;
+ if (yych == 'T') goto yy424;
+ if (yych == 't') goto yy424;
+ goto yy194;
yy398:
YYDEBUG(398, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'O') goto yy417;
- if (yych == 'o') goto yy417;
- goto yy193;
+ if (yych == 'E') goto yy422;
+ if (yych == 'e') goto yy422;
+ goto yy194;
yy399:
YYDEBUG(399, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'L') goto yy410;
- if (yych == 'l') goto yy410;
- goto yy193;
+ if (yych == 'O') goto yy418;
+ if (yych == 'o') goto yy418;
+ goto yy194;
yy400:
YYDEBUG(400, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'N') goto yy401;
- if (yych != 'n') goto yy193;
+ if (yych == 'L') goto yy411;
+ if (yych == 'l') goto yy411;
+ goto yy194;
yy401:
YYDEBUG(401, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'T') goto yy402;
- if (yych != 't') goto yy193;
+ if (yych == 'N') goto yy402;
+ if (yych != 'n') goto yy194;
yy402:
YYDEBUG(402, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy403;
- if (yych != 'e') goto yy405;
+ if (yych == 'T') goto yy403;
+ if (yych != 't') goto yy194;
yy403:
YYDEBUG(403, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'G') goto yy408;
- if (yych == 'g') goto yy408;
- goto yy193;
+ if (yych == 'E') goto yy404;
+ if (yych != 'e') goto yy406;
yy404:
YYDEBUG(404, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'G') goto yy409;
+ if (yych == 'g') goto yy409;
+ goto yy194;
+yy405:
+ YYDEBUG(405, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
-yy405:
- YYDEBUG(405, *YYCURSOR);
+yy406:
+ YYDEBUG(406, *YYCURSOR);
if (yych <= 0x1F) {
- if (yych == '\t') goto yy404;
- goto yy193;
+ if (yych == '\t') goto yy405;
+ goto yy194;
} else {
- if (yych <= ' ') goto yy404;
- if (yych != ')') goto yy193;
+ if (yych <= ' ') goto yy405;
+ if (yych != ')') goto yy194;
}
- YYDEBUG(406, *YYCURSOR);
- ++YYCURSOR;
YYDEBUG(407, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(408, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1219 "Zend/zend_language_scanner.l"
+#line 1230 "Zend/zend_language_scanner.l"
{
return T_INT_CAST;
}
-#line 4823 "Zend/zend_language_scanner.c"
-yy408:
- YYDEBUG(408, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'E') goto yy409;
- if (yych != 'e') goto yy193;
+#line 4836 "Zend/zend_language_scanner.c"
yy409:
YYDEBUG(409, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'R') goto yy404;
- if (yych == 'r') goto yy404;
- goto yy193;
+ if (yych == 'E') goto yy410;
+ if (yych != 'e') goto yy194;
yy410:
YYDEBUG(410, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'O') goto yy411;
- if (yych != 'o') goto yy193;
+ if (yych == 'R') goto yy405;
+ if (yych == 'r') goto yy405;
+ goto yy194;
yy411:
YYDEBUG(411, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'A') goto yy412;
- if (yych != 'a') goto yy193;
+ if (yych == 'O') goto yy412;
+ if (yych != 'o') goto yy194;
yy412:
YYDEBUG(412, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'T') goto yy413;
- if (yych != 't') goto yy193;
+ if (yych == 'A') goto yy413;
+ if (yych != 'a') goto yy194;
yy413:
YYDEBUG(413, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'T') goto yy414;
+ if (yych != 't') goto yy194;
+yy414:
+ YYDEBUG(414, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
- YYDEBUG(414, *YYCURSOR);
+ YYDEBUG(415, *YYCURSOR);
if (yych <= 0x1F) {
- if (yych == '\t') goto yy413;
- goto yy193;
+ if (yych == '\t') goto yy414;
+ goto yy194;
} else {
- if (yych <= ' ') goto yy413;
- if (yych != ')') goto yy193;
+ if (yych <= ' ') goto yy414;
+ if (yych != ')') goto yy194;
}
- YYDEBUG(415, *YYCURSOR);
- ++YYCURSOR;
YYDEBUG(416, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(417, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1223 "Zend/zend_language_scanner.l"
+#line 1234 "Zend/zend_language_scanner.l"
{
return T_DOUBLE_CAST;
}
-#line 4871 "Zend/zend_language_scanner.c"
-yy417:
- YYDEBUG(417, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'U') goto yy418;
- if (yych != 'u') goto yy193;
+#line 4884 "Zend/zend_language_scanner.c"
yy418:
YYDEBUG(418, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'B') goto yy419;
- if (yych != 'b') goto yy193;
+ if (yych == 'U') goto yy419;
+ if (yych != 'u') goto yy194;
yy419:
YYDEBUG(419, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'L') goto yy420;
- if (yych != 'l') goto yy193;
+ if (yych == 'B') goto yy420;
+ if (yych != 'b') goto yy194;
yy420:
YYDEBUG(420, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy413;
- if (yych == 'e') goto yy413;
- goto yy193;
+ if (yych == 'L') goto yy421;
+ if (yych != 'l') goto yy194;
yy421:
YYDEBUG(421, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'A') goto yy422;
- if (yych != 'a') goto yy193;
+ if (yych == 'E') goto yy414;
+ if (yych == 'e') goto yy414;
+ goto yy194;
yy422:
YYDEBUG(422, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'L') goto yy413;
- if (yych == 'l') goto yy413;
- goto yy193;
+ if (yych == 'A') goto yy423;
+ if (yych != 'a') goto yy194;
yy423:
YYDEBUG(423, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'R') goto yy424;
- if (yych != 'r') goto yy193;
+ if (yych == 'L') goto yy414;
+ if (yych == 'l') goto yy414;
+ goto yy194;
yy424:
YYDEBUG(424, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'I') goto yy425;
- if (yych != 'i') goto yy193;
+ if (yych == 'R') goto yy425;
+ if (yych != 'r') goto yy194;
yy425:
YYDEBUG(425, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'N') goto yy426;
- if (yych != 'n') goto yy193;
+ if (yych == 'I') goto yy426;
+ if (yych != 'i') goto yy194;
yy426:
YYDEBUG(426, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'G') goto yy427;
- if (yych != 'g') goto yy193;
+ if (yych == 'N') goto yy427;
+ if (yych != 'n') goto yy194;
yy427:
YYDEBUG(427, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'G') goto yy428;
+ if (yych != 'g') goto yy194;
+yy428:
+ YYDEBUG(428, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
- YYDEBUG(428, *YYCURSOR);
+ YYDEBUG(429, *YYCURSOR);
if (yych <= 0x1F) {
- if (yych == '\t') goto yy427;
- goto yy193;
+ if (yych == '\t') goto yy428;
+ goto yy194;
} else {
- if (yych <= ' ') goto yy427;
- if (yych != ')') goto yy193;
+ if (yych <= ' ') goto yy428;
+ if (yych != ')') goto yy194;
}
- YYDEBUG(429, *YYCURSOR);
- ++YYCURSOR;
YYDEBUG(430, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(431, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1227 "Zend/zend_language_scanner.l"
+#line 1238 "Zend/zend_language_scanner.l"
{
return T_STRING_CAST;
}
-#line 4945 "Zend/zend_language_scanner.c"
-yy431:
- YYDEBUG(431, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'R') goto yy432;
- if (yych != 'r') goto yy193;
+#line 4958 "Zend/zend_language_scanner.c"
yy432:
YYDEBUG(432, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'A') goto yy433;
- if (yych != 'a') goto yy193;
+ if (yych == 'R') goto yy433;
+ if (yych != 'r') goto yy194;
yy433:
YYDEBUG(433, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'Y') goto yy434;
- if (yych != 'y') goto yy193;
+ if (yych == 'A') goto yy434;
+ if (yych != 'a') goto yy194;
yy434:
YYDEBUG(434, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'Y') goto yy435;
+ if (yych != 'y') goto yy194;
+yy435:
+ YYDEBUG(435, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
- YYDEBUG(435, *YYCURSOR);
+ YYDEBUG(436, *YYCURSOR);
if (yych <= 0x1F) {
- if (yych == '\t') goto yy434;
- goto yy193;
+ if (yych == '\t') goto yy435;
+ goto yy194;
} else {
- if (yych <= ' ') goto yy434;
- if (yych != ')') goto yy193;
+ if (yych <= ' ') goto yy435;
+ if (yych != ')') goto yy194;
}
- YYDEBUG(436, *YYCURSOR);
- ++YYCURSOR;
YYDEBUG(437, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(438, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1231 "Zend/zend_language_scanner.l"
+#line 1242 "Zend/zend_language_scanner.l"
{
return T_ARRAY_CAST;
}
-#line 4982 "Zend/zend_language_scanner.c"
-yy438:
- YYDEBUG(438, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'J') goto yy439;
- if (yych != 'j') goto yy193;
+#line 4995 "Zend/zend_language_scanner.c"
yy439:
YYDEBUG(439, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy440;
- if (yych != 'e') goto yy193;
+ if (yych == 'J') goto yy440;
+ if (yych != 'j') goto yy194;
yy440:
YYDEBUG(440, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'C') goto yy441;
- if (yych != 'c') goto yy193;
+ if (yych == 'E') goto yy441;
+ if (yych != 'e') goto yy194;
yy441:
YYDEBUG(441, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'T') goto yy442;
- if (yych != 't') goto yy193;
+ if (yych == 'C') goto yy442;
+ if (yych != 'c') goto yy194;
yy442:
YYDEBUG(442, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'T') goto yy443;
+ if (yych != 't') goto yy194;
+yy443:
+ YYDEBUG(443, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
- YYDEBUG(443, *YYCURSOR);
+ YYDEBUG(444, *YYCURSOR);
if (yych <= 0x1F) {
- if (yych == '\t') goto yy442;
- goto yy193;
+ if (yych == '\t') goto yy443;
+ goto yy194;
} else {
- if (yych <= ' ') goto yy442;
- if (yych != ')') goto yy193;
+ if (yych <= ' ') goto yy443;
+ if (yych != ')') goto yy194;
}
- YYDEBUG(444, *YYCURSOR);
- ++YYCURSOR;
YYDEBUG(445, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(446, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1235 "Zend/zend_language_scanner.l"
+#line 1246 "Zend/zend_language_scanner.l"
{
return T_OBJECT_CAST;
}
-#line 5024 "Zend/zend_language_scanner.c"
-yy446:
- YYDEBUG(446, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'N') goto yy456;
- if (yych == 'n') goto yy456;
- goto yy193;
+#line 5037 "Zend/zend_language_scanner.c"
yy447:
YYDEBUG(447, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'O') goto yy448;
- if (yych != 'o') goto yy193;
+ if (yych == 'N') goto yy457;
+ if (yych == 'n') goto yy457;
+ goto yy194;
yy448:
YYDEBUG(448, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'L') goto yy449;
- if (yych != 'l') goto yy193;
+ if (yych == 'O') goto yy449;
+ if (yych != 'o') goto yy194;
yy449:
YYDEBUG(449, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy454;
- if (yych == 'e') goto yy454;
- goto yy451;
+ if (yych == 'L') goto yy450;
+ if (yych != 'l') goto yy194;
yy450:
YYDEBUG(450, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'E') goto yy455;
+ if (yych == 'e') goto yy455;
+ goto yy452;
+yy451:
+ YYDEBUG(451, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
-yy451:
- YYDEBUG(451, *YYCURSOR);
+yy452:
+ YYDEBUG(452, *YYCURSOR);
if (yych <= 0x1F) {
- if (yych == '\t') goto yy450;
- goto yy193;
+ if (yych == '\t') goto yy451;
+ goto yy194;
} else {
- if (yych <= ' ') goto yy450;
- if (yych != ')') goto yy193;
+ if (yych <= ' ') goto yy451;
+ if (yych != ')') goto yy194;
}
- YYDEBUG(452, *YYCURSOR);
- ++YYCURSOR;
YYDEBUG(453, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(454, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1239 "Zend/zend_language_scanner.l"
+#line 1250 "Zend/zend_language_scanner.l"
{
return T_BOOL_CAST;
}
-#line 5069 "Zend/zend_language_scanner.c"
-yy454:
- YYDEBUG(454, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'A') goto yy455;
- if (yych != 'a') goto yy193;
+#line 5082 "Zend/zend_language_scanner.c"
yy455:
YYDEBUG(455, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'N') goto yy450;
- if (yych == 'n') goto yy450;
- goto yy193;
+ if (yych == 'A') goto yy456;
+ if (yych != 'a') goto yy194;
yy456:
YYDEBUG(456, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'A') goto yy457;
- if (yych != 'a') goto yy193;
+ if (yych == 'N') goto yy451;
+ if (yych == 'n') goto yy451;
+ goto yy194;
yy457:
YYDEBUG(457, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'R') goto yy458;
- if (yych != 'r') goto yy193;
+ if (yych == 'A') goto yy458;
+ if (yych != 'a') goto yy194;
yy458:
YYDEBUG(458, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'Y') goto yy427;
- if (yych == 'y') goto yy427;
- goto yy193;
+ if (yych == 'R') goto yy459;
+ if (yych != 'r') goto yy194;
yy459:
YYDEBUG(459, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'S') goto yy460;
- if (yych != 's') goto yy193;
+ if (yych == 'Y') goto yy428;
+ if (yych == 'y') goto yy428;
+ goto yy194;
yy460:
YYDEBUG(460, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy461;
- if (yych != 'e') goto yy193;
+ if (yych == 'S') goto yy461;
+ if (yych != 's') goto yy194;
yy461:
YYDEBUG(461, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'T') goto yy462;
- if (yych != 't') goto yy193;
+ if (yych == 'E') goto yy462;
+ if (yych != 'e') goto yy194;
yy462:
YYDEBUG(462, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'T') goto yy463;
+ if (yych != 't') goto yy194;
+yy463:
+ YYDEBUG(463, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
- YYDEBUG(463, *YYCURSOR);
+ YYDEBUG(464, *YYCURSOR);
if (yych <= 0x1F) {
- if (yych == '\t') goto yy462;
- goto yy193;
+ if (yych == '\t') goto yy463;
+ goto yy194;
} else {
- if (yych <= ' ') goto yy462;
- if (yych != ')') goto yy193;
+ if (yych <= ' ') goto yy463;
+ if (yych != ')') goto yy194;
}
- YYDEBUG(464, *YYCURSOR);
- ++YYCURSOR;
YYDEBUG(465, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(466, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1243 "Zend/zend_language_scanner.l"
+#line 1254 "Zend/zend_language_scanner.l"
{
return T_UNSET_CAST;
}
-#line 5133 "Zend/zend_language_scanner.c"
-yy466:
- YYDEBUG(466, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'R') goto yy467;
- if (yych != 'r') goto yy186;
+#line 5146 "Zend/zend_language_scanner.c"
yy467:
YYDEBUG(467, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'R') goto yy468;
+ if (yych != 'r') goto yy187;
+yy468:
+ YYDEBUG(468, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(468, *YYCURSOR);
+ YYDEBUG(469, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1215 "Zend/zend_language_scanner.l"
+#line 1226 "Zend/zend_language_scanner.l"
{
return T_VAR;
}
-#line 5151 "Zend/zend_language_scanner.c"
-yy469:
- YYDEBUG(469, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'M') goto yy473;
- if (yych == 'm') goto yy473;
- goto yy186;
+#line 5164 "Zend/zend_language_scanner.c"
yy470:
YYDEBUG(470, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'W') goto yy471;
- if (yych != 'w') goto yy186;
+ if (yych == 'M') goto yy474;
+ if (yych == 'm') goto yy474;
+ goto yy187;
yy471:
YYDEBUG(471, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'W') goto yy472;
+ if (yych != 'w') goto yy187;
+yy472:
+ YYDEBUG(472, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(472, *YYCURSOR);
+ YYDEBUG(473, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1207 "Zend/zend_language_scanner.l"
+#line 1218 "Zend/zend_language_scanner.l"
{
return T_NEW;
}
-#line 5175 "Zend/zend_language_scanner.c"
-yy473:
- YYDEBUG(473, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'E') goto yy474;
- if (yych != 'e') goto yy186;
+#line 5188 "Zend/zend_language_scanner.c"
yy474:
YYDEBUG(474, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'S') goto yy475;
- if (yych != 's') goto yy186;
+ if (yych == 'E') goto yy475;
+ if (yych != 'e') goto yy187;
yy475:
YYDEBUG(475, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'P') goto yy476;
- if (yych != 'p') goto yy186;
+ if (yych == 'S') goto yy476;
+ if (yych != 's') goto yy187;
yy476:
YYDEBUG(476, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'A') goto yy477;
- if (yych != 'a') goto yy186;
+ if (yych == 'P') goto yy477;
+ if (yych != 'p') goto yy187;
yy477:
YYDEBUG(477, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'C') goto yy478;
- if (yych != 'c') goto yy186;
+ if (yych == 'A') goto yy478;
+ if (yych != 'a') goto yy187;
yy478:
YYDEBUG(478, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy479;
- if (yych != 'e') goto yy186;
+ if (yych == 'C') goto yy479;
+ if (yych != 'c') goto yy187;
yy479:
YYDEBUG(479, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'E') goto yy480;
+ if (yych != 'e') goto yy187;
+yy480:
+ YYDEBUG(480, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(480, *YYCURSOR);
+ YYDEBUG(481, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1267 "Zend/zend_language_scanner.l"
+#line 1278 "Zend/zend_language_scanner.l"
{
return T_NAMESPACE;
}
-#line 5218 "Zend/zend_language_scanner.c"
-yy481:
- YYDEBUG(481, *YYCURSOR);
- ++YYCURSOR;
+#line 5231 "Zend/zend_language_scanner.c"
+yy482:
YYDEBUG(482, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(483, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1199 "Zend/zend_language_scanner.l"
+#line 1210 "Zend/zend_language_scanner.l"
{
return T_PAAMAYIM_NEKUDOTAYIM;
}
-#line 5228 "Zend/zend_language_scanner.c"
-yy483:
- YYDEBUG(483, *YYCURSOR);
+#line 5241 "Zend/zend_language_scanner.c"
+yy484:
+ YYDEBUG(484, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
-yy484:
- YYDEBUG(484, *YYCURSOR);
+yy485:
+ YYDEBUG(485, *YYCURSOR);
if (yych <= '\f') {
- if (yych <= 0x08) goto yy140;
- if (yych <= '\n') goto yy483;
- goto yy140;
+ if (yych <= 0x08) goto yy141;
+ if (yych <= '\n') goto yy484;
+ goto yy141;
} else {
- if (yych <= '\r') goto yy483;
- if (yych == ' ') goto yy483;
- goto yy140;
+ if (yych <= '\r') goto yy484;
+ if (yych == ' ') goto yy484;
+ goto yy141;
}
-yy485:
- YYDEBUG(485, *YYCURSOR);
- ++YYCURSOR;
+yy486:
YYDEBUG(486, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(487, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1375 "Zend/zend_language_scanner.l"
+#line 1386 "Zend/zend_language_scanner.l"
{
return T_MINUS_EQUAL;
}
-#line 5254 "Zend/zend_language_scanner.c"
-yy487:
- YYDEBUG(487, *YYCURSOR);
- ++YYCURSOR;
+#line 5267 "Zend/zend_language_scanner.c"
+yy488:
YYDEBUG(488, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(489, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1343 "Zend/zend_language_scanner.l"
+#line 1354 "Zend/zend_language_scanner.l"
{
return T_DEC;
}
-#line 5264 "Zend/zend_language_scanner.c"
-yy489:
- YYDEBUG(489, *YYCURSOR);
- ++YYCURSOR;
+#line 5277 "Zend/zend_language_scanner.c"
+yy490:
YYDEBUG(490, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(491, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1169 "Zend/zend_language_scanner.l"
+#line 1180 "Zend/zend_language_scanner.l"
{
yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
return T_OBJECT_OPERATOR;
}
-#line 5275 "Zend/zend_language_scanner.c"
-yy491:
- YYDEBUG(491, *YYCURSOR);
+#line 5288 "Zend/zend_language_scanner.c"
+yy492:
+ YYDEBUG(492, *YYCURSOR);
yych = *++YYCURSOR;
if (yych <= 'O') {
- if (yych == 'I') goto yy498;
- if (yych <= 'N') goto yy186;
- goto yy499;
+ if (yych == 'I') goto yy499;
+ if (yych <= 'N') goto yy187;
+ goto yy500;
} else {
if (yych <= 'i') {
- if (yych <= 'h') goto yy186;
- goto yy498;
+ if (yych <= 'h') goto yy187;
+ goto yy499;
} else {
- if (yych == 'o') goto yy499;
- goto yy186;
+ if (yych == 'o') goto yy500;
+ goto yy187;
}
}
-yy492:
- YYDEBUG(492, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'B') goto yy493;
- if (yych != 'b') goto yy186;
yy493:
YYDEBUG(493, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'L') goto yy494;
- if (yych != 'l') goto yy186;
+ if (yych == 'B') goto yy494;
+ if (yych != 'b') goto yy187;
yy494:
YYDEBUG(494, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'I') goto yy495;
- if (yych != 'i') goto yy186;
+ if (yych == 'L') goto yy495;
+ if (yych != 'l') goto yy187;
yy495:
YYDEBUG(495, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'C') goto yy496;
- if (yych != 'c') goto yy186;
+ if (yych == 'I') goto yy496;
+ if (yych != 'i') goto yy187;
yy496:
YYDEBUG(496, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'C') goto yy497;
+ if (yych != 'c') goto yy187;
+yy497:
+ YYDEBUG(497, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(497, *YYCURSOR);
+ YYDEBUG(498, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1315 "Zend/zend_language_scanner.l"
+#line 1326 "Zend/zend_language_scanner.l"
{
return T_PUBLIC;
}
-#line 5324 "Zend/zend_language_scanner.c"
-yy498:
- YYDEBUG(498, *YYCURSOR);
+#line 5337 "Zend/zend_language_scanner.c"
+yy499:
+ YYDEBUG(499, *YYCURSOR);
yych = *++YYCURSOR;
if (yych <= 'V') {
- if (yych == 'N') goto yy507;
- if (yych <= 'U') goto yy186;
- goto yy508;
+ if (yych == 'N') goto yy508;
+ if (yych <= 'U') goto yy187;
+ goto yy509;
} else {
if (yych <= 'n') {
- if (yych <= 'm') goto yy186;
- goto yy507;
+ if (yych <= 'm') goto yy187;
+ goto yy508;
} else {
- if (yych == 'v') goto yy508;
- goto yy186;
+ if (yych == 'v') goto yy509;
+ goto yy187;
}
}
-yy499:
- YYDEBUG(499, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'T') goto yy500;
- if (yych != 't') goto yy186;
yy500:
YYDEBUG(500, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy501;
- if (yych != 'e') goto yy186;
+ if (yych == 'T') goto yy501;
+ if (yych != 't') goto yy187;
yy501:
YYDEBUG(501, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'C') goto yy502;
- if (yych != 'c') goto yy186;
+ if (yych == 'E') goto yy502;
+ if (yych != 'e') goto yy187;
yy502:
YYDEBUG(502, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'T') goto yy503;
- if (yych != 't') goto yy186;
+ if (yych == 'C') goto yy503;
+ if (yych != 'c') goto yy187;
yy503:
YYDEBUG(503, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy504;
- if (yych != 'e') goto yy186;
+ if (yych == 'T') goto yy504;
+ if (yych != 't') goto yy187;
yy504:
YYDEBUG(504, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'D') goto yy505;
- if (yych != 'd') goto yy186;
+ if (yych == 'E') goto yy505;
+ if (yych != 'e') goto yy187;
yy505:
YYDEBUG(505, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'D') goto yy506;
+ if (yych != 'd') goto yy187;
+yy506:
+ YYDEBUG(506, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(506, *YYCURSOR);
+ YYDEBUG(507, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1311 "Zend/zend_language_scanner.l"
+#line 1322 "Zend/zend_language_scanner.l"
{
return T_PROTECTED;
}
-#line 5383 "Zend/zend_language_scanner.c"
-yy507:
- YYDEBUG(507, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'T') goto yy513;
- if (yych == 't') goto yy513;
- goto yy186;
+#line 5396 "Zend/zend_language_scanner.c"
yy508:
YYDEBUG(508, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'A') goto yy509;
- if (yych != 'a') goto yy186;
+ if (yych == 'T') goto yy514;
+ if (yych == 't') goto yy514;
+ goto yy187;
yy509:
YYDEBUG(509, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'T') goto yy510;
- if (yych != 't') goto yy186;
+ if (yych == 'A') goto yy510;
+ if (yych != 'a') goto yy187;
yy510:
YYDEBUG(510, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy511;
- if (yych != 'e') goto yy186;
+ if (yych == 'T') goto yy511;
+ if (yych != 't') goto yy187;
yy511:
YYDEBUG(511, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'E') goto yy512;
+ if (yych != 'e') goto yy187;
+yy512:
+ YYDEBUG(512, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(512, *YYCURSOR);
+ YYDEBUG(513, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1307 "Zend/zend_language_scanner.l"
+#line 1318 "Zend/zend_language_scanner.l"
{
return T_PRIVATE;
}
-#line 5417 "Zend/zend_language_scanner.c"
-yy513:
- YYDEBUG(513, *YYCURSOR);
+#line 5430 "Zend/zend_language_scanner.c"
+yy514:
+ YYDEBUG(514, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(514, *YYCURSOR);
+ YYDEBUG(515, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1145 "Zend/zend_language_scanner.l"
+#line 1156 "Zend/zend_language_scanner.l"
{
return T_PRINT;
}
-#line 5430 "Zend/zend_language_scanner.c"
-yy515:
- YYDEBUG(515, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'O') goto yy520;
- if (yych == 'o') goto yy520;
- goto yy186;
+#line 5443 "Zend/zend_language_scanner.c"
yy516:
YYDEBUG(516, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'T') goto yy517;
- if (yych != 't') goto yy186;
+ if (yych == 'O') goto yy521;
+ if (yych == 'o') goto yy521;
+ goto yy187;
yy517:
YYDEBUG(517, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'O') goto yy518;
- if (yych != 'o') goto yy186;
+ if (yych == 'T') goto yy518;
+ if (yych != 't') goto yy187;
yy518:
YYDEBUG(518, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'O') goto yy519;
+ if (yych != 'o') goto yy187;
+yy519:
+ YYDEBUG(519, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(519, *YYCURSOR);
+ YYDEBUG(520, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1137 "Zend/zend_language_scanner.l"
+#line 1148 "Zend/zend_language_scanner.l"
{
return T_GOTO;
}
-#line 5459 "Zend/zend_language_scanner.c"
-yy520:
- YYDEBUG(520, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'B') goto yy521;
- if (yych != 'b') goto yy186;
+#line 5472 "Zend/zend_language_scanner.c"
yy521:
YYDEBUG(521, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'A') goto yy522;
- if (yych != 'a') goto yy186;
+ if (yych == 'B') goto yy522;
+ if (yych != 'b') goto yy187;
yy522:
YYDEBUG(522, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'L') goto yy523;
- if (yych != 'l') goto yy186;
+ if (yych == 'A') goto yy523;
+ if (yych != 'a') goto yy187;
yy523:
YYDEBUG(523, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'L') goto yy524;
+ if (yych != 'l') goto yy187;
+yy524:
+ YYDEBUG(524, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(524, *YYCURSOR);
+ YYDEBUG(525, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1279 "Zend/zend_language_scanner.l"
+#line 1290 "Zend/zend_language_scanner.l"
{
return T_GLOBAL;
}
-#line 5487 "Zend/zend_language_scanner.c"
-yy525:
- YYDEBUG(525, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == '<') goto yy533;
- goto yy193;
+#line 5500 "Zend/zend_language_scanner.c"
yy526:
YYDEBUG(526, *YYCURSOR);
yych = *++YYCURSOR;
- goto yy180;
+ if (yych == '<') goto yy534;
+ goto yy194;
yy527:
YYDEBUG(527, *YYCURSOR);
yych = *++YYCURSOR;
- goto yy178;
+ goto yy181;
yy528:
YYDEBUG(528, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy529;
- if (yych != 'e') goto yy186;
+ goto yy179;
yy529:
YYDEBUG(529, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'A') goto yy530;
- if (yych != 'a') goto yy186;
+ if (yych == 'E') goto yy530;
+ if (yych != 'e') goto yy187;
yy530:
YYDEBUG(530, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'K') goto yy531;
- if (yych != 'k') goto yy186;
+ if (yych == 'A') goto yy531;
+ if (yych != 'a') goto yy187;
yy531:
YYDEBUG(531, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'K') goto yy532;
+ if (yych != 'k') goto yy187;
+yy532:
+ YYDEBUG(532, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(532, *YYCURSOR);
+ YYDEBUG(533, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1129 "Zend/zend_language_scanner.l"
+#line 1140 "Zend/zend_language_scanner.l"
{
return T_BREAK;
}
-#line 5528 "Zend/zend_language_scanner.c"
-yy533:
- YYDEBUG(533, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == '<') goto yy269;
- goto yy193;
+#line 5541 "Zend/zend_language_scanner.c"
yy534:
YYDEBUG(534, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'A') goto yy541;
- if (yych == 'a') goto yy541;
- goto yy186;
+ if (yych == '<') goto yy270;
+ goto yy194;
yy535:
YYDEBUG(535, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'I') goto yy536;
- if (yych != 'i') goto yy186;
+ if (yych == 'A') goto yy542;
+ if (yych == 'a') goto yy542;
+ goto yy187;
yy536:
YYDEBUG(536, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'T') goto yy537;
- if (yych != 't') goto yy186;
+ if (yych == 'I') goto yy537;
+ if (yych != 'i') goto yy187;
yy537:
YYDEBUG(537, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'C') goto yy538;
- if (yych != 'c') goto yy186;
+ if (yych == 'T') goto yy538;
+ if (yych != 't') goto yy187;
yy538:
YYDEBUG(538, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'H') goto yy539;
- if (yych != 'h') goto yy186;
+ if (yych == 'C') goto yy539;
+ if (yych != 'c') goto yy187;
yy539:
YYDEBUG(539, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'H') goto yy540;
+ if (yych != 'h') goto yy187;
+yy540:
+ YYDEBUG(540, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(540, *YYCURSOR);
+ YYDEBUG(541, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1113 "Zend/zend_language_scanner.l"
+#line 1124 "Zend/zend_language_scanner.l"
{
return T_SWITCH;
}
-#line 5572 "Zend/zend_language_scanner.c"
-yy541:
- YYDEBUG(541, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'T') goto yy542;
- if (yych != 't') goto yy186;
+#line 5585 "Zend/zend_language_scanner.c"
yy542:
YYDEBUG(542, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'I') goto yy543;
- if (yych != 'i') goto yy186;
+ if (yych == 'T') goto yy543;
+ if (yych != 't') goto yy187;
yy543:
YYDEBUG(543, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'C') goto yy544;
- if (yych != 'c') goto yy186;
+ if (yych == 'I') goto yy544;
+ if (yych != 'i') goto yy187;
yy544:
YYDEBUG(544, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'C') goto yy545;
+ if (yych != 'c') goto yy187;
+yy545:
+ YYDEBUG(545, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(545, *YYCURSOR);
+ YYDEBUG(546, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1295 "Zend/zend_language_scanner.l"
+#line 1306 "Zend/zend_language_scanner.l"
{
return T_STATIC;
}
-#line 5600 "Zend/zend_language_scanner.c"
-yy546:
- YYDEBUG(546, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'S') goto yy557;
- if (yych == 's') goto yy557;
- goto yy186;
+#line 5613 "Zend/zend_language_scanner.c"
yy547:
YYDEBUG(547, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'D') goto yy555;
- if (yych == 'd') goto yy555;
- goto yy186;
+ if (yych == 'S') goto yy558;
+ if (yych == 's') goto yy558;
+ goto yy187;
yy548:
YYDEBUG(548, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'R') goto yy551;
- if (yych == 'r') goto yy551;
- goto yy186;
+ if (yych == 'D') goto yy556;
+ if (yych == 'd') goto yy556;
+ goto yy187;
yy549:
YYDEBUG(549, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'R') goto yy552;
+ if (yych == 'r') goto yy552;
+ goto yy187;
+yy550:
+ YYDEBUG(550, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(550, *YYCURSOR);
+ YYDEBUG(551, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1109 "Zend/zend_language_scanner.l"
+#line 1120 "Zend/zend_language_scanner.l"
{
return T_AS;
}
-#line 5631 "Zend/zend_language_scanner.c"
-yy551:
- YYDEBUG(551, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'A') goto yy552;
- if (yych != 'a') goto yy186;
+#line 5644 "Zend/zend_language_scanner.c"
yy552:
YYDEBUG(552, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'Y') goto yy553;
- if (yych != 'y') goto yy186;
+ if (yych == 'A') goto yy553;
+ if (yych != 'a') goto yy187;
yy553:
YYDEBUG(553, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'Y') goto yy554;
+ if (yych != 'y') goto yy187;
+yy554:
+ YYDEBUG(554, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(554, *YYCURSOR);
+ YYDEBUG(555, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1331 "Zend/zend_language_scanner.l"
+#line 1342 "Zend/zend_language_scanner.l"
{
return T_ARRAY;
}
-#line 5654 "Zend/zend_language_scanner.c"
-yy555:
- YYDEBUG(555, *YYCURSOR);
+#line 5667 "Zend/zend_language_scanner.c"
+yy556:
+ YYDEBUG(556, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(556, *YYCURSOR);
+ YYDEBUG(557, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1427 "Zend/zend_language_scanner.l"
+#line 1438 "Zend/zend_language_scanner.l"
{
return T_LOGICAL_AND;
}
-#line 5667 "Zend/zend_language_scanner.c"
-yy557:
- YYDEBUG(557, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'T') goto yy558;
- if (yych != 't') goto yy186;
+#line 5680 "Zend/zend_language_scanner.c"
yy558:
YYDEBUG(558, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'R') goto yy559;
- if (yych != 'r') goto yy186;
+ if (yych == 'T') goto yy559;
+ if (yych != 't') goto yy187;
yy559:
YYDEBUG(559, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'A') goto yy560;
- if (yych != 'a') goto yy186;
+ if (yych == 'R') goto yy560;
+ if (yych != 'r') goto yy187;
yy560:
YYDEBUG(560, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'C') goto yy561;
- if (yych != 'c') goto yy186;
+ if (yych == 'A') goto yy561;
+ if (yych != 'a') goto yy187;
yy561:
YYDEBUG(561, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'T') goto yy562;
- if (yych != 't') goto yy186;
+ if (yych == 'C') goto yy562;
+ if (yych != 'c') goto yy187;
yy562:
YYDEBUG(562, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'T') goto yy563;
+ if (yych != 't') goto yy187;
+yy563:
+ YYDEBUG(563, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(563, *YYCURSOR);
+ YYDEBUG(564, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1299 "Zend/zend_language_scanner.l"
+#line 1310 "Zend/zend_language_scanner.l"
{
return T_ABSTRACT;
}
-#line 5705 "Zend/zend_language_scanner.c"
-yy564:
- YYDEBUG(564, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'I') goto yy565;
- if (yych != 'i') goto yy186;
+#line 5718 "Zend/zend_language_scanner.c"
yy565:
YYDEBUG(565, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'L') goto yy566;
- if (yych != 'l') goto yy186;
+ if (yych == 'I') goto yy566;
+ if (yych != 'i') goto yy187;
yy566:
YYDEBUG(566, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy567;
- if (yych != 'e') goto yy186;
+ if (yych == 'L') goto yy567;
+ if (yych != 'l') goto yy187;
yy567:
YYDEBUG(567, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'E') goto yy568;
+ if (yych != 'e') goto yy187;
+yy568:
+ YYDEBUG(568, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(568, *YYCURSOR);
+ YYDEBUG(569, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1069 "Zend/zend_language_scanner.l"
+#line 1080 "Zend/zend_language_scanner.l"
{
return T_WHILE;
}
-#line 5733 "Zend/zend_language_scanner.c"
-yy569:
- YYDEBUG(569, *YYCURSOR);
+#line 5746 "Zend/zend_language_scanner.c"
+yy570:
+ YYDEBUG(570, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(570, *YYCURSOR);
+ YYDEBUG(571, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1053 "Zend/zend_language_scanner.l"
+#line 1064 "Zend/zend_language_scanner.l"
{
return T_IF;
}
-#line 5746 "Zend/zend_language_scanner.c"
-yy571:
- YYDEBUG(571, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'P') goto yy613;
- if (yych == 'p') goto yy613;
- goto yy186;
+#line 5759 "Zend/zend_language_scanner.c"
yy572:
YYDEBUG(572, *YYCURSOR);
yych = *++YYCURSOR;
+ if (yych == 'P') goto yy614;
+ if (yych == 'p') goto yy614;
+ goto yy187;
+yy573:
+ YYDEBUG(573, *YYCURSOR);
+ yych = *++YYCURSOR;
if (yych <= 'T') {
if (yych <= 'C') {
- if (yych <= 'B') goto yy186;
- goto yy580;
+ if (yych <= 'B') goto yy187;
+ goto yy581;
} else {
- if (yych <= 'R') goto yy186;
- if (yych <= 'S') goto yy578;
- goto yy579;
+ if (yych <= 'R') goto yy187;
+ if (yych <= 'S') goto yy579;
+ goto yy580;
}
} else {
if (yych <= 'r') {
- if (yych == 'c') goto yy580;
- goto yy186;
+ if (yych == 'c') goto yy581;
+ goto yy187;
} else {
- if (yych <= 's') goto yy578;
- if (yych <= 't') goto yy579;
- goto yy186;
+ if (yych <= 's') goto yy579;
+ if (yych <= 't') goto yy580;
+ goto yy187;
}
}
-yy573:
- YYDEBUG(573, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'S') goto yy574;
- if (yych != 's') goto yy186;
yy574:
YYDEBUG(574, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy575;
- if (yych != 'e') goto yy186;
+ if (yych == 'S') goto yy575;
+ if (yych != 's') goto yy187;
yy575:
YYDEBUG(575, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'T') goto yy576;
- if (yych != 't') goto yy186;
+ if (yych == 'E') goto yy576;
+ if (yych != 'e') goto yy187;
yy576:
YYDEBUG(576, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'T') goto yy577;
+ if (yych != 't') goto yy187;
+yy577:
+ YYDEBUG(577, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(577, *YYCURSOR);
+ YYDEBUG(578, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1283 "Zend/zend_language_scanner.l"
+#line 1294 "Zend/zend_language_scanner.l"
{
return T_ISSET;
}
-#line 5802 "Zend/zend_language_scanner.c"
-yy578:
- YYDEBUG(578, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'T') goto yy599;
- if (yych == 't') goto yy599;
- goto yy186;
+#line 5815 "Zend/zend_language_scanner.c"
yy579:
YYDEBUG(579, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy592;
- if (yych == 'e') goto yy592;
- goto yy186;
+ if (yych == 'T') goto yy600;
+ if (yych == 't') goto yy600;
+ goto yy187;
yy580:
YYDEBUG(580, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'L') goto yy581;
- if (yych != 'l') goto yy186;
+ if (yych == 'E') goto yy593;
+ if (yych == 'e') goto yy593;
+ goto yy187;
yy581:
YYDEBUG(581, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'U') goto yy582;
- if (yych != 'u') goto yy186;
+ if (yych == 'L') goto yy582;
+ if (yych != 'l') goto yy187;
yy582:
YYDEBUG(582, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'D') goto yy583;
- if (yych != 'd') goto yy186;
+ if (yych == 'U') goto yy583;
+ if (yych != 'u') goto yy187;
yy583:
YYDEBUG(583, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy584;
- if (yych != 'e') goto yy186;
+ if (yych == 'D') goto yy584;
+ if (yych != 'd') goto yy187;
yy584:
YYDEBUG(584, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'E') goto yy585;
+ if (yych != 'e') goto yy187;
+yy585:
+ YYDEBUG(585, *YYCURSOR);
++YYCURSOR;
if ((yych = *YYCURSOR) <= '^') {
if (yych <= '9') {
- if (yych >= '0') goto yy185;
+ if (yych >= '0') goto yy186;
} else {
- if (yych <= '@') goto yy585;
- if (yych <= 'Z') goto yy185;
+ if (yych <= '@') goto yy586;
+ if (yych <= 'Z') goto yy186;
}
} else {
if (yych <= '`') {
- if (yych <= '_') goto yy586;
+ if (yych <= '_') goto yy587;
} else {
- if (yych <= 'z') goto yy185;
- if (yych >= 0x7F) goto yy185;
+ if (yych <= 'z') goto yy186;
+ if (yych >= 0x7F) goto yy186;
}
}
-yy585:
- YYDEBUG(585, *YYCURSOR);
+yy586:
+ YYDEBUG(586, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1251 "Zend/zend_language_scanner.l"
+#line 1262 "Zend/zend_language_scanner.l"
{
return T_INCLUDE;
}
-#line 5860 "Zend/zend_language_scanner.c"
-yy586:
- YYDEBUG(586, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'O') goto yy587;
- if (yych != 'o') goto yy186;
+#line 5873 "Zend/zend_language_scanner.c"
yy587:
YYDEBUG(587, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'N') goto yy588;
- if (yych != 'n') goto yy186;
+ if (yych == 'O') goto yy588;
+ if (yych != 'o') goto yy187;
yy588:
YYDEBUG(588, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'C') goto yy589;
- if (yych != 'c') goto yy186;
+ if (yych == 'N') goto yy589;
+ if (yych != 'n') goto yy187;
yy589:
YYDEBUG(589, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy590;
- if (yych != 'e') goto yy186;
+ if (yych == 'C') goto yy590;
+ if (yych != 'c') goto yy187;
yy590:
YYDEBUG(590, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'E') goto yy591;
+ if (yych != 'e') goto yy187;
+yy591:
+ YYDEBUG(591, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(591, *YYCURSOR);
+ YYDEBUG(592, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1255 "Zend/zend_language_scanner.l"
+#line 1266 "Zend/zend_language_scanner.l"
{
return T_INCLUDE_ONCE;
}
-#line 5893 "Zend/zend_language_scanner.c"
-yy592:
- YYDEBUG(592, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'R') goto yy593;
- if (yych != 'r') goto yy186;
+#line 5906 "Zend/zend_language_scanner.c"
yy593:
YYDEBUG(593, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'F') goto yy594;
- if (yych != 'f') goto yy186;
+ if (yych == 'R') goto yy594;
+ if (yych != 'r') goto yy187;
yy594:
YYDEBUG(594, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'A') goto yy595;
- if (yych != 'a') goto yy186;
+ if (yych == 'F') goto yy595;
+ if (yych != 'f') goto yy187;
yy595:
YYDEBUG(595, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'C') goto yy596;
- if (yych != 'c') goto yy186;
+ if (yych == 'A') goto yy596;
+ if (yych != 'a') goto yy187;
yy596:
YYDEBUG(596, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy597;
- if (yych != 'e') goto yy186;
+ if (yych == 'C') goto yy597;
+ if (yych != 'c') goto yy187;
yy597:
YYDEBUG(597, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'E') goto yy598;
+ if (yych != 'e') goto yy187;
+yy598:
+ YYDEBUG(598, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(598, *YYCURSOR);
+ YYDEBUG(599, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1153 "Zend/zend_language_scanner.l"
+#line 1164 "Zend/zend_language_scanner.l"
{
return T_INTERFACE;
}
-#line 5931 "Zend/zend_language_scanner.c"
-yy599:
- YYDEBUG(599, *YYCURSOR);
+#line 5944 "Zend/zend_language_scanner.c"
+yy600:
+ YYDEBUG(600, *YYCURSOR);
yych = *++YYCURSOR;
if (yych <= 'E') {
- if (yych == 'A') goto yy600;
- if (yych <= 'D') goto yy186;
- goto yy601;
+ if (yych == 'A') goto yy601;
+ if (yych <= 'D') goto yy187;
+ goto yy602;
} else {
if (yych <= 'a') {
- if (yych <= '`') goto yy186;
+ if (yych <= '`') goto yy187;
} else {
- if (yych == 'e') goto yy601;
- goto yy186;
+ if (yych == 'e') goto yy602;
+ goto yy187;
}
}
-yy600:
- YYDEBUG(600, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'N') goto yy607;
- if (yych == 'n') goto yy607;
- goto yy186;
yy601:
YYDEBUG(601, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'A') goto yy602;
- if (yych != 'a') goto yy186;
+ if (yych == 'N') goto yy608;
+ if (yych == 'n') goto yy608;
+ goto yy187;
yy602:
YYDEBUG(602, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'D') goto yy603;
- if (yych != 'd') goto yy186;
+ if (yych == 'A') goto yy603;
+ if (yych != 'a') goto yy187;
yy603:
YYDEBUG(603, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'O') goto yy604;
- if (yych != 'o') goto yy186;
+ if (yych == 'D') goto yy604;
+ if (yych != 'd') goto yy187;
yy604:
YYDEBUG(604, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'F') goto yy605;
- if (yych != 'f') goto yy186;
+ if (yych == 'O') goto yy605;
+ if (yych != 'o') goto yy187;
yy605:
YYDEBUG(605, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'F') goto yy606;
+ if (yych != 'f') goto yy187;
+yy606:
+ YYDEBUG(606, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(606, *YYCURSOR);
+ YYDEBUG(607, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1275 "Zend/zend_language_scanner.l"
+#line 1286 "Zend/zend_language_scanner.l"
{
return T_INSTEADOF;
}
-#line 5985 "Zend/zend_language_scanner.c"
-yy607:
- YYDEBUG(607, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'C') goto yy608;
- if (yych != 'c') goto yy186;
+#line 5998 "Zend/zend_language_scanner.c"
yy608:
YYDEBUG(608, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy609;
- if (yych != 'e') goto yy186;
+ if (yych == 'C') goto yy609;
+ if (yych != 'c') goto yy187;
yy609:
YYDEBUG(609, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'O') goto yy610;
- if (yych != 'o') goto yy186;
+ if (yych == 'E') goto yy610;
+ if (yych != 'e') goto yy187;
yy610:
YYDEBUG(610, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'F') goto yy611;
- if (yych != 'f') goto yy186;
+ if (yych == 'O') goto yy611;
+ if (yych != 'o') goto yy187;
yy611:
YYDEBUG(611, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'F') goto yy612;
+ if (yych != 'f') goto yy187;
+yy612:
+ YYDEBUG(612, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(612, *YYCURSOR);
+ YYDEBUG(613, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1105 "Zend/zend_language_scanner.l"
+#line 1116 "Zend/zend_language_scanner.l"
{
return T_INSTANCEOF;
}
-#line 6018 "Zend/zend_language_scanner.c"
-yy613:
- YYDEBUG(613, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'L') goto yy614;
- if (yych != 'l') goto yy186;
+#line 6031 "Zend/zend_language_scanner.c"
yy614:
YYDEBUG(614, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy615;
- if (yych != 'e') goto yy186;
+ if (yych == 'L') goto yy615;
+ if (yych != 'l') goto yy187;
yy615:
YYDEBUG(615, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'M') goto yy616;
- if (yych != 'm') goto yy186;
+ if (yych == 'E') goto yy616;
+ if (yych != 'e') goto yy187;
yy616:
YYDEBUG(616, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy617;
- if (yych != 'e') goto yy186;
+ if (yych == 'M') goto yy617;
+ if (yych != 'm') goto yy187;
yy617:
YYDEBUG(617, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'N') goto yy618;
- if (yych != 'n') goto yy186;
+ if (yych == 'E') goto yy618;
+ if (yych != 'e') goto yy187;
yy618:
YYDEBUG(618, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'T') goto yy619;
- if (yych != 't') goto yy186;
+ if (yych == 'N') goto yy619;
+ if (yych != 'n') goto yy187;
yy619:
YYDEBUG(619, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'S') goto yy620;
- if (yych != 's') goto yy186;
+ if (yych == 'T') goto yy620;
+ if (yych != 't') goto yy187;
yy620:
YYDEBUG(620, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'S') goto yy621;
+ if (yych != 's') goto yy187;
+yy621:
+ YYDEBUG(621, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(621, *YYCURSOR);
+ YYDEBUG(622, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1165 "Zend/zend_language_scanner.l"
+#line 1176 "Zend/zend_language_scanner.l"
{
return T_IMPLEMENTS;
}
-#line 6066 "Zend/zend_language_scanner.c"
-yy622:
- YYDEBUG(622, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'R') goto yy630;
- if (yych == 'r') goto yy630;
- goto yy186;
+#line 6079 "Zend/zend_language_scanner.c"
yy623:
YYDEBUG(623, *YYCURSOR);
yych = *++YYCURSOR;
+ if (yych == 'R') goto yy631;
+ if (yych == 'r') goto yy631;
+ goto yy187;
+yy624:
+ YYDEBUG(624, *YYCURSOR);
+ yych = *++YYCURSOR;
if (yych <= 'Y') {
- if (yych == 'A') goto yy626;
- if (yych <= 'X') goto yy186;
+ if (yych == 'A') goto yy627;
+ if (yych <= 'X') goto yy187;
} else {
if (yych <= 'a') {
- if (yych <= '`') goto yy186;
- goto yy626;
+ if (yych <= '`') goto yy187;
+ goto yy627;
} else {
- if (yych != 'y') goto yy186;
+ if (yych != 'y') goto yy187;
}
}
- YYDEBUG(624, *YYCURSOR);
+ YYDEBUG(625, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(625, *YYCURSOR);
+ YYDEBUG(626, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1041 "Zend/zend_language_scanner.l"
+#line 1048 "Zend/zend_language_scanner.l"
{
return T_TRY;
}
-#line 6098 "Zend/zend_language_scanner.c"
-yy626:
- YYDEBUG(626, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'I') goto yy627;
- if (yych != 'i') goto yy186;
+#line 6111 "Zend/zend_language_scanner.c"
yy627:
YYDEBUG(627, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'T') goto yy628;
- if (yych != 't') goto yy186;
+ if (yych == 'I') goto yy628;
+ if (yych != 'i') goto yy187;
yy628:
YYDEBUG(628, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'T') goto yy629;
+ if (yych != 't') goto yy187;
+yy629:
+ YYDEBUG(629, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(629, *YYCURSOR);
+ YYDEBUG(630, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1157 "Zend/zend_language_scanner.l"
+#line 1168 "Zend/zend_language_scanner.l"
{
return T_TRAIT;
}
-#line 6121 "Zend/zend_language_scanner.c"
-yy630:
- YYDEBUG(630, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'O') goto yy631;
- if (yych != 'o') goto yy186;
+#line 6134 "Zend/zend_language_scanner.c"
yy631:
YYDEBUG(631, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'W') goto yy632;
- if (yych != 'w') goto yy186;
+ if (yych == 'O') goto yy632;
+ if (yych != 'o') goto yy187;
yy632:
YYDEBUG(632, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'W') goto yy633;
+ if (yych != 'w') goto yy187;
+yy633:
+ YYDEBUG(633, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(633, *YYCURSOR);
+ YYDEBUG(634, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1049 "Zend/zend_language_scanner.l"
+#line 1060 "Zend/zend_language_scanner.l"
{
return T_THROW;
}
-#line 6144 "Zend/zend_language_scanner.c"
-yy634:
- YYDEBUG(634, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych <= 'T') {
- if (yych == 'Q') goto yy636;
- if (yych <= 'S') goto yy186;
- } else {
- if (yych <= 'q') {
- if (yych <= 'p') goto yy186;
- goto yy636;
- } else {
- if (yych != 't') goto yy186;
- }
- }
+#line 6157 "Zend/zend_language_scanner.c"
+yy635:
YYDEBUG(635, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'U') goto yy648;
- if (yych == 'u') goto yy648;
- goto yy186;
+ if (yych == 'E') goto yy636;
+ if (yych != 'e') goto yy187;
yy636:
YYDEBUG(636, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'U') goto yy637;
- if (yych != 'u') goto yy186;
+ if (yych == 'L') goto yy637;
+ if (yych != 'l') goto yy187;
yy637:
YYDEBUG(637, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'I') goto yy638;
- if (yych != 'i') goto yy186;
+ if (yych == 'D') goto yy638;
+ if (yych != 'd') goto yy187;
yy638:
YYDEBUG(638, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'R') goto yy639;
- if (yych != 'r') goto yy186;
-yy639:
+ ++YYCURSOR;
+ if (yybm[0+(yych = *YYCURSOR)] & 4) {
+ goto yy186;
+ }
YYDEBUG(639, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'E') goto yy640;
- if (yych != 'e') goto yy186;
+ yyleng = YYCURSOR - SCNG(yy_text);
+#line 1044 "Zend/zend_language_scanner.l"
+ {
+ return T_YIELD;
+}
+#line 6185 "Zend/zend_language_scanner.c"
yy640:
YYDEBUG(640, *YYCURSOR);
- ++YYCURSOR;
- if ((yych = *YYCURSOR) <= '^') {
- if (yych <= '9') {
- if (yych >= '0') goto yy185;
- } else {
- if (yych <= '@') goto yy641;
- if (yych <= 'Z') goto yy185;
- }
+ yych = *++YYCURSOR;
+ if (yych <= 'T') {
+ if (yych == 'Q') goto yy642;
+ if (yych <= 'S') goto yy187;
} else {
- if (yych <= '`') {
- if (yych <= '_') goto yy642;
+ if (yych <= 'q') {
+ if (yych <= 'p') goto yy187;
+ goto yy642;
} else {
- if (yych <= 'z') goto yy185;
- if (yych >= 0x7F) goto yy185;
+ if (yych != 't') goto yy187;
}
}
-yy641:
YYDEBUG(641, *YYCURSOR);
- yyleng = YYCURSOR - SCNG(yy_text);
-#line 1259 "Zend/zend_language_scanner.l"
- {
- return T_REQUIRE;
-}
-#line 6209 "Zend/zend_language_scanner.c"
+ yych = *++YYCURSOR;
+ if (yych == 'U') goto yy654;
+ if (yych == 'u') goto yy654;
+ goto yy187;
yy642:
YYDEBUG(642, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'O') goto yy643;
- if (yych != 'o') goto yy186;
+ if (yych == 'U') goto yy643;
+ if (yych != 'u') goto yy187;
yy643:
YYDEBUG(643, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'N') goto yy644;
- if (yych != 'n') goto yy186;
+ if (yych == 'I') goto yy644;
+ if (yych != 'i') goto yy187;
yy644:
YYDEBUG(644, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'C') goto yy645;
- if (yych != 'c') goto yy186;
+ if (yych == 'R') goto yy645;
+ if (yych != 'r') goto yy187;
yy645:
YYDEBUG(645, *YYCURSOR);
yych = *++YYCURSOR;
if (yych == 'E') goto yy646;
- if (yych != 'e') goto yy186;
+ if (yych != 'e') goto yy187;
yy646:
YYDEBUG(646, *YYCURSOR);
++YYCURSOR;
- if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ if ((yych = *YYCURSOR) <= '^') {
+ if (yych <= '9') {
+ if (yych >= '0') goto yy186;
+ } else {
+ if (yych <= '@') goto yy647;
+ if (yych <= 'Z') goto yy186;
+ }
+ } else {
+ if (yych <= '`') {
+ if (yych <= '_') goto yy648;
+ } else {
+ if (yych <= 'z') goto yy186;
+ if (yych >= 0x7F) goto yy186;
+ }
}
+yy647:
YYDEBUG(647, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1263 "Zend/zend_language_scanner.l"
+#line 1270 "Zend/zend_language_scanner.l"
{
- return T_REQUIRE_ONCE;
+ return T_REQUIRE;
}
-#line 6242 "Zend/zend_language_scanner.c"
+#line 6250 "Zend/zend_language_scanner.c"
yy648:
YYDEBUG(648, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'R') goto yy649;
- if (yych != 'r') goto yy186;
+ if (yych == 'O') goto yy649;
+ if (yych != 'o') goto yy187;
yy649:
YYDEBUG(649, *YYCURSOR);
yych = *++YYCURSOR;
if (yych == 'N') goto yy650;
- if (yych != 'n') goto yy186;
+ if (yych != 'n') goto yy187;
yy650:
YYDEBUG(650, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'C') goto yy651;
+ if (yych != 'c') goto yy187;
+yy651:
+ YYDEBUG(651, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'E') goto yy652;
+ if (yych != 'e') goto yy187;
+yy652:
+ YYDEBUG(652, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(651, *YYCURSOR);
+ YYDEBUG(653, *YYCURSOR);
+ yyleng = YYCURSOR - SCNG(yy_text);
+#line 1274 "Zend/zend_language_scanner.l"
+ {
+ return T_REQUIRE_ONCE;
+}
+#line 6283 "Zend/zend_language_scanner.c"
+yy654:
+ YYDEBUG(654, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'R') goto yy655;
+ if (yych != 'r') goto yy187;
+yy655:
+ YYDEBUG(655, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'N') goto yy656;
+ if (yych != 'n') goto yy187;
+yy656:
+ YYDEBUG(656, *YYCURSOR);
+ ++YYCURSOR;
+ if (yybm[0+(yych = *YYCURSOR)] & 4) {
+ goto yy186;
+ }
+ YYDEBUG(657, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1037 "Zend/zend_language_scanner.l"
+#line 1040 "Zend/zend_language_scanner.l"
{
return T_RETURN;
}
-#line 6265 "Zend/zend_language_scanner.c"
-yy652:
- YYDEBUG(652, *YYCURSOR);
+#line 6306 "Zend/zend_language_scanner.c"
+yy658:
+ YYDEBUG(658, *YYCURSOR);
yych = *++YYCURSOR;
if (yych <= 'T') {
if (yych <= 'L') {
- if (yych <= 'K') goto yy186;
- goto yy675;
+ if (yych <= 'K') goto yy187;
+ goto yy681;
} else {
- if (yych <= 'R') goto yy186;
- if (yych <= 'S') goto yy674;
- goto yy673;
+ if (yych <= 'R') goto yy187;
+ if (yych <= 'S') goto yy680;
+ goto yy679;
}
} else {
if (yych <= 'r') {
- if (yych == 'l') goto yy675;
- goto yy186;
+ if (yych == 'l') goto yy681;
+ goto yy187;
} else {
- if (yych <= 's') goto yy674;
- if (yych <= 't') goto yy673;
- goto yy186;
+ if (yych <= 's') goto yy680;
+ if (yych <= 't') goto yy679;
+ goto yy187;
}
}
-yy653:
- YYDEBUG(653, *YYCURSOR);
+yy659:
+ YYDEBUG(659, *YYCURSOR);
yych = *++YYCURSOR;
if (yych <= 'O') {
- if (yych == 'A') goto yy665;
- if (yych <= 'N') goto yy186;
- goto yy666;
+ if (yych == 'A') goto yy671;
+ if (yych <= 'N') goto yy187;
+ goto yy672;
} else {
if (yych <= 'a') {
- if (yych <= '`') goto yy186;
- goto yy665;
+ if (yych <= '`') goto yy187;
+ goto yy671;
} else {
- if (yych == 'o') goto yy666;
- goto yy186;
+ if (yych == 'o') goto yy672;
+ goto yy187;
}
}
-yy654:
- YYDEBUG(654, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'N') goto yy655;
- if (yych != 'n') goto yy186;
-yy655:
- YYDEBUG(655, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych <= 'T') {
- if (yych <= 'R') goto yy186;
- if (yych >= 'T') goto yy657;
- } else {
- if (yych <= 'r') goto yy186;
- if (yych <= 's') goto yy656;
- if (yych <= 't') goto yy657;
- goto yy186;
- }
-yy656:
- YYDEBUG(656, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'T') goto yy663;
- if (yych == 't') goto yy663;
- goto yy186;
-yy657:
- YYDEBUG(657, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'I') goto yy658;
- if (yych != 'i') goto yy186;
-yy658:
- YYDEBUG(658, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'N') goto yy659;
- if (yych != 'n') goto yy186;
-yy659:
- YYDEBUG(659, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'U') goto yy660;
- if (yych != 'u') goto yy186;
yy660:
YYDEBUG(660, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy661;
- if (yych != 'e') goto yy186;
+ if (yych == 'N') goto yy661;
+ if (yych != 'n') goto yy187;
yy661:
YYDEBUG(661, *YYCURSOR);
- ++YYCURSOR;
- if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ yych = *++YYCURSOR;
+ if (yych <= 'T') {
+ if (yych <= 'R') goto yy187;
+ if (yych >= 'T') goto yy663;
+ } else {
+ if (yych <= 'r') goto yy187;
+ if (yych <= 's') goto yy662;
+ if (yych <= 't') goto yy663;
+ goto yy187;
}
+yy662:
YYDEBUG(662, *YYCURSOR);
- yyleng = YYCURSOR - SCNG(yy_text);
-#line 1133 "Zend/zend_language_scanner.l"
- {
- return T_CONTINUE;
-}
-#line 6359 "Zend/zend_language_scanner.c"
+ yych = *++YYCURSOR;
+ if (yych == 'T') goto yy669;
+ if (yych == 't') goto yy669;
+ goto yy187;
yy663:
YYDEBUG(663, *YYCURSOR);
- ++YYCURSOR;
- if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
- }
+ yych = *++YYCURSOR;
+ if (yych == 'I') goto yy664;
+ if (yych != 'i') goto yy187;
+yy664:
YYDEBUG(664, *YYCURSOR);
- yyleng = YYCURSOR - SCNG(yy_text);
-#line 1033 "Zend/zend_language_scanner.l"
- {
- return T_CONST;
-}
-#line 6372 "Zend/zend_language_scanner.c"
+ yych = *++YYCURSOR;
+ if (yych == 'N') goto yy665;
+ if (yych != 'n') goto yy187;
yy665:
YYDEBUG(665, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'S') goto yy670;
- if (yych == 's') goto yy670;
- goto yy186;
+ if (yych == 'U') goto yy666;
+ if (yych != 'u') goto yy187;
yy666:
YYDEBUG(666, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'N') goto yy667;
- if (yych != 'n') goto yy186;
+ if (yych == 'E') goto yy667;
+ if (yych != 'e') goto yy187;
yy667:
YYDEBUG(667, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'E') goto yy668;
- if (yych != 'e') goto yy186;
-yy668:
- YYDEBUG(668, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(669, *YYCURSOR);
+ YYDEBUG(668, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1211 "Zend/zend_language_scanner.l"
+#line 1144 "Zend/zend_language_scanner.l"
{
- return T_CLONE;
+ return T_CONTINUE;
}
-#line 6401 "Zend/zend_language_scanner.c"
-yy670:
- YYDEBUG(670, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'S') goto yy671;
- if (yych != 's') goto yy186;
-yy671:
- YYDEBUG(671, *YYCURSOR);
+#line 6400 "Zend/zend_language_scanner.c"
+yy669:
+ YYDEBUG(669, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(672, *YYCURSOR);
+ YYDEBUG(670, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1149 "Zend/zend_language_scanner.l"
+#line 1036 "Zend/zend_language_scanner.l"
{
- return T_CLASS;
+ return T_CONST;
}
-#line 6419 "Zend/zend_language_scanner.c"
+#line 6413 "Zend/zend_language_scanner.c"
+yy671:
+ YYDEBUG(671, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'S') goto yy676;
+ if (yych == 's') goto yy676;
+ goto yy187;
+yy672:
+ YYDEBUG(672, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'N') goto yy673;
+ if (yych != 'n') goto yy187;
yy673:
YYDEBUG(673, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'C') goto yy684;
- if (yych == 'c') goto yy684;
- goto yy186;
+ if (yych == 'E') goto yy674;
+ if (yych != 'e') goto yy187;
yy674:
YYDEBUG(674, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'E') goto yy682;
- if (yych == 'e') goto yy682;
- goto yy186;
-yy675:
+ ++YYCURSOR;
+ if (yybm[0+(yych = *YYCURSOR)] & 4) {
+ goto yy186;
+ }
YYDEBUG(675, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'L') goto yy676;
- if (yych != 'l') goto yy186;
+ yyleng = YYCURSOR - SCNG(yy_text);
+#line 1222 "Zend/zend_language_scanner.l"
+ {
+ return T_CLONE;
+}
+#line 6442 "Zend/zend_language_scanner.c"
yy676:
YYDEBUG(676, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'A') goto yy677;
- if (yych != 'a') goto yy186;
+ if (yych == 'S') goto yy677;
+ if (yych != 's') goto yy187;
yy677:
YYDEBUG(677, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'B') goto yy678;
- if (yych != 'b') goto yy186;
-yy678:
+ ++YYCURSOR;
+ if (yybm[0+(yych = *YYCURSOR)] & 4) {
+ goto yy186;
+ }
YYDEBUG(678, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'L') goto yy679;
- if (yych != 'l') goto yy186;
+ yyleng = YYCURSOR - SCNG(yy_text);
+#line 1160 "Zend/zend_language_scanner.l"
+ {
+ return T_CLASS;
+}
+#line 6460 "Zend/zend_language_scanner.c"
yy679:
YYDEBUG(679, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy680;
- if (yych != 'e') goto yy186;
+ if (yych == 'C') goto yy690;
+ if (yych == 'c') goto yy690;
+ goto yy187;
yy680:
YYDEBUG(680, *YYCURSOR);
- ++YYCURSOR;
- if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
- }
+ yych = *++YYCURSOR;
+ if (yych == 'E') goto yy688;
+ if (yych == 'e') goto yy688;
+ goto yy187;
+yy681:
YYDEBUG(681, *YYCURSOR);
- yyleng = YYCURSOR - SCNG(yy_text);
-#line 1335 "Zend/zend_language_scanner.l"
- {
- return T_CALLABLE;
-}
-#line 6469 "Zend/zend_language_scanner.c"
+ yych = *++YYCURSOR;
+ if (yych == 'L') goto yy682;
+ if (yych != 'l') goto yy187;
yy682:
YYDEBUG(682, *YYCURSOR);
- ++YYCURSOR;
- if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
- }
+ yych = *++YYCURSOR;
+ if (yych == 'A') goto yy683;
+ if (yych != 'a') goto yy187;
+yy683:
YYDEBUG(683, *YYCURSOR);
- yyleng = YYCURSOR - SCNG(yy_text);
-#line 1121 "Zend/zend_language_scanner.l"
- {
- return T_CASE;
-}
-#line 6482 "Zend/zend_language_scanner.c"
+ yych = *++YYCURSOR;
+ if (yych == 'B') goto yy684;
+ if (yych != 'b') goto yy187;
yy684:
YYDEBUG(684, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'H') goto yy685;
- if (yych != 'h') goto yy186;
+ if (yych == 'L') goto yy685;
+ if (yych != 'l') goto yy187;
yy685:
YYDEBUG(685, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'E') goto yy686;
+ if (yych != 'e') goto yy187;
+yy686:
+ YYDEBUG(686, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(686, *YYCURSOR);
+ YYDEBUG(687, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1045 "Zend/zend_language_scanner.l"
+#line 1346 "Zend/zend_language_scanner.l"
{
- return T_CATCH;
+ return T_CALLABLE;
}
-#line 6500 "Zend/zend_language_scanner.c"
-yy687:
- YYDEBUG(687, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'N') goto yy704;
- if (yych == 'n') goto yy704;
- goto yy186;
+#line 6510 "Zend/zend_language_scanner.c"
yy688:
YYDEBUG(688, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'R') goto yy697;
- if (yych == 'r') goto yy697;
- goto yy186;
-yy689:
+ ++YYCURSOR;
+ if (yybm[0+(yych = *YYCURSOR)] & 4) {
+ goto yy186;
+ }
YYDEBUG(689, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'N') goto yy690;
- if (yych != 'n') goto yy186;
+ yyleng = YYCURSOR - SCNG(yy_text);
+#line 1132 "Zend/zend_language_scanner.l"
+ {
+ return T_CASE;
+}
+#line 6523 "Zend/zend_language_scanner.c"
yy690:
YYDEBUG(690, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'C') goto yy691;
- if (yych != 'c') goto yy186;
+ if (yych == 'H') goto yy691;
+ if (yych != 'h') goto yy187;
yy691:
YYDEBUG(691, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'T') goto yy692;
- if (yych != 't') goto yy186;
-yy692:
+ ++YYCURSOR;
+ if (yybm[0+(yych = *YYCURSOR)] & 4) {
+ goto yy186;
+ }
YYDEBUG(692, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'I') goto yy693;
- if (yych != 'i') goto yy186;
+ yyleng = YYCURSOR - SCNG(yy_text);
+#line 1052 "Zend/zend_language_scanner.l"
+ {
+ return T_CATCH;
+}
+#line 6541 "Zend/zend_language_scanner.c"
yy693:
YYDEBUG(693, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'O') goto yy694;
- if (yych != 'o') goto yy186;
+ if (yych == 'N') goto yy710;
+ if (yych == 'n') goto yy710;
+ goto yy187;
yy694:
YYDEBUG(694, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'N') goto yy695;
- if (yych != 'n') goto yy186;
+ if (yych == 'R') goto yy703;
+ if (yych == 'r') goto yy703;
+ goto yy187;
yy695:
YYDEBUG(695, *YYCURSOR);
- ++YYCURSOR;
- if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
- }
+ yych = *++YYCURSOR;
+ if (yych == 'N') goto yy696;
+ if (yych != 'n') goto yy187;
+yy696:
YYDEBUG(696, *YYCURSOR);
- yyleng = YYCURSOR - SCNG(yy_text);
-#line 1029 "Zend/zend_language_scanner.l"
- {
- return T_FUNCTION;
-}
-#line 6555 "Zend/zend_language_scanner.c"
+ yych = *++YYCURSOR;
+ if (yych == 'C') goto yy697;
+ if (yych != 'c') goto yy187;
yy697:
YYDEBUG(697, *YYCURSOR);
- ++YYCURSOR;
- if ((yych = *YYCURSOR) <= '^') {
- if (yych <= '@') {
- if (yych <= '/') goto yy698;
- if (yych <= '9') goto yy185;
- } else {
- if (yych == 'E') goto yy699;
- if (yych <= 'Z') goto yy185;
- }
- } else {
- if (yych <= 'd') {
- if (yych != '`') goto yy185;
- } else {
- if (yych <= 'e') goto yy699;
- if (yych <= 'z') goto yy185;
- if (yych >= 0x7F) goto yy185;
- }
- }
+ yych = *++YYCURSOR;
+ if (yych == 'T') goto yy698;
+ if (yych != 't') goto yy187;
yy698:
YYDEBUG(698, *YYCURSOR);
- yyleng = YYCURSOR - SCNG(yy_text);
-#line 1081 "Zend/zend_language_scanner.l"
- {
- return T_FOR;
-}
-#line 6583 "Zend/zend_language_scanner.c"
+ yych = *++YYCURSOR;
+ if (yych == 'I') goto yy699;
+ if (yych != 'i') goto yy187;
yy699:
YYDEBUG(699, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'A') goto yy700;
- if (yych != 'a') goto yy186;
+ if (yych == 'O') goto yy700;
+ if (yych != 'o') goto yy187;
yy700:
YYDEBUG(700, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'C') goto yy701;
- if (yych != 'c') goto yy186;
+ if (yych == 'N') goto yy701;
+ if (yych != 'n') goto yy187;
yy701:
YYDEBUG(701, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'H') goto yy702;
- if (yych != 'h') goto yy186;
-yy702:
- YYDEBUG(702, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(703, *YYCURSOR);
+ YYDEBUG(702, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1089 "Zend/zend_language_scanner.l"
+#line 1032 "Zend/zend_language_scanner.l"
{
- return T_FOREACH;
+ return T_FUNCTION;
}
-#line 6611 "Zend/zend_language_scanner.c"
+#line 6596 "Zend/zend_language_scanner.c"
+yy703:
+ YYDEBUG(703, *YYCURSOR);
+ ++YYCURSOR;
+ if ((yych = *YYCURSOR) <= '^') {
+ if (yych <= '@') {
+ if (yych <= '/') goto yy704;
+ if (yych <= '9') goto yy186;
+ } else {
+ if (yych == 'E') goto yy705;
+ if (yych <= 'Z') goto yy186;
+ }
+ } else {
+ if (yych <= 'd') {
+ if (yych != '`') goto yy186;
+ } else {
+ if (yych <= 'e') goto yy705;
+ if (yych <= 'z') goto yy186;
+ if (yych >= 0x7F) goto yy186;
+ }
+ }
yy704:
YYDEBUG(704, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'A') goto yy705;
- if (yych != 'a') goto yy186;
+ yyleng = YYCURSOR - SCNG(yy_text);
+#line 1092 "Zend/zend_language_scanner.l"
+ {
+ return T_FOR;
+}
+#line 6624 "Zend/zend_language_scanner.c"
yy705:
YYDEBUG(705, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'L') goto yy706;
- if (yych != 'l') goto yy186;
+ if (yych == 'A') goto yy706;
+ if (yych != 'a') goto yy187;
yy706:
YYDEBUG(706, *YYCURSOR);
- ++YYCURSOR;
- if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
- }
+ yych = *++YYCURSOR;
+ if (yych == 'C') goto yy707;
+ if (yych != 'c') goto yy187;
+yy707:
YYDEBUG(707, *YYCURSOR);
- yyleng = YYCURSOR - SCNG(yy_text);
-#line 1303 "Zend/zend_language_scanner.l"
- {
- return T_FINAL;
-}
-#line 6634 "Zend/zend_language_scanner.c"
+ yych = *++YYCURSOR;
+ if (yych == 'H') goto yy708;
+ if (yych != 'h') goto yy187;
yy708:
YYDEBUG(708, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych <= 'F') {
- if (yych == 'C') goto yy714;
- if (yych <= 'E') goto yy186;
- goto yy715;
- } else {
- if (yych <= 'c') {
- if (yych <= 'b') goto yy186;
- goto yy714;
- } else {
- if (yych == 'f') goto yy715;
- goto yy186;
- }
- }
-yy709:
- YYDEBUG(709, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'E') goto yy712;
- if (yych == 'e') goto yy712;
- goto yy186;
-yy710:
- YYDEBUG(710, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(711, *YYCURSOR);
+ YYDEBUG(709, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1077 "Zend/zend_language_scanner.l"
+#line 1100 "Zend/zend_language_scanner.l"
{
- return T_DO;
+ return T_FOREACH;
}
-#line 6669 "Zend/zend_language_scanner.c"
+#line 6652 "Zend/zend_language_scanner.c"
+yy710:
+ YYDEBUG(710, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'A') goto yy711;
+ if (yych != 'a') goto yy187;
+yy711:
+ YYDEBUG(711, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'L') goto yy712;
+ if (yych != 'l') goto yy187;
yy712:
YYDEBUG(712, *YYCURSOR);
++YYCURSOR;
- if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ if ((yych = *YYCURSOR) <= '^') {
+ if (yych <= '@') {
+ if (yych <= '/') goto yy713;
+ if (yych <= '9') goto yy186;
+ } else {
+ if (yych == 'L') goto yy714;
+ if (yych <= 'Z') goto yy186;
+ }
+ } else {
+ if (yych <= 'k') {
+ if (yych != '`') goto yy186;
+ } else {
+ if (yych <= 'l') goto yy714;
+ if (yych <= 'z') goto yy186;
+ if (yych >= 0x7F) goto yy186;
+ }
}
+yy713:
YYDEBUG(713, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1025 "Zend/zend_language_scanner.l"
+#line 1314 "Zend/zend_language_scanner.l"
{
- return T_EXIT;
+ return T_FINAL;
}
-#line 6682 "Zend/zend_language_scanner.c"
+#line 6690 "Zend/zend_language_scanner.c"
yy714:
YYDEBUG(714, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'L') goto yy721;
- if (yych == 'l') goto yy721;
- goto yy186;
+ if (yych == 'Y') goto yy715;
+ if (yych != 'y') goto yy187;
yy715:
YYDEBUG(715, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'A') goto yy716;
- if (yych != 'a') goto yy186;
-yy716:
+ ++YYCURSOR;
+ if (yybm[0+(yych = *YYCURSOR)] & 4) {
+ goto yy186;
+ }
YYDEBUG(716, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'U') goto yy717;
- if (yych != 'u') goto yy186;
+ yyleng = YYCURSOR - SCNG(yy_text);
+#line 1056 "Zend/zend_language_scanner.l"
+ {
+ return T_FINALLY;
+}
+#line 6708 "Zend/zend_language_scanner.c"
yy717:
YYDEBUG(717, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'L') goto yy718;
- if (yych != 'l') goto yy186;
+ if (yych <= 'F') {
+ if (yych == 'C') goto yy723;
+ if (yych <= 'E') goto yy187;
+ goto yy724;
+ } else {
+ if (yych <= 'c') {
+ if (yych <= 'b') goto yy187;
+ goto yy723;
+ } else {
+ if (yych == 'f') goto yy724;
+ goto yy187;
+ }
+ }
yy718:
YYDEBUG(718, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'T') goto yy719;
- if (yych != 't') goto yy186;
+ if (yych == 'E') goto yy721;
+ if (yych == 'e') goto yy721;
+ goto yy187;
yy719:
YYDEBUG(719, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
YYDEBUG(720, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1125 "Zend/zend_language_scanner.l"
+#line 1088 "Zend/zend_language_scanner.l"
{
- return T_DEFAULT;
+ return T_DO;
}
-#line 6721 "Zend/zend_language_scanner.c"
+#line 6743 "Zend/zend_language_scanner.c"
yy721:
YYDEBUG(721, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'A') goto yy722;
- if (yych != 'a') goto yy186;
-yy722:
+ ++YYCURSOR;
+ if (yybm[0+(yych = *YYCURSOR)] & 4) {
+ goto yy186;
+ }
YYDEBUG(722, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'R') goto yy723;
- if (yych != 'r') goto yy186;
+ yyleng = YYCURSOR - SCNG(yy_text);
+#line 1028 "Zend/zend_language_scanner.l"
+ {
+ return T_EXIT;
+}
+#line 6756 "Zend/zend_language_scanner.c"
yy723:
YYDEBUG(723, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy724;
- if (yych != 'e') goto yy186;
+ if (yych == 'L') goto yy730;
+ if (yych == 'l') goto yy730;
+ goto yy187;
yy724:
YYDEBUG(724, *YYCURSOR);
- ++YYCURSOR;
- if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
- }
+ yych = *++YYCURSOR;
+ if (yych == 'A') goto yy725;
+ if (yych != 'a') goto yy187;
+yy725:
YYDEBUG(725, *YYCURSOR);
- yyleng = YYCURSOR - SCNG(yy_text);
-#line 1097 "Zend/zend_language_scanner.l"
- {
- return T_DECLARE;
-}
-#line 6749 "Zend/zend_language_scanner.c"
+ yych = *++YYCURSOR;
+ if (yych == 'U') goto yy726;
+ if (yych != 'u') goto yy187;
yy726:
YYDEBUG(726, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'H') goto yy788;
- if (yych == 'h') goto yy788;
- goto yy186;
+ if (yych == 'L') goto yy727;
+ if (yych != 'l') goto yy187;
yy727:
YYDEBUG(727, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'S') goto yy782;
- if (yych == 's') goto yy782;
- goto yy186;
+ if (yych == 'T') goto yy728;
+ if (yych != 't') goto yy187;
yy728:
YYDEBUG(728, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'P') goto yy778;
- if (yych == 'p') goto yy778;
- goto yy186;
-yy729:
+ ++YYCURSOR;
+ if (yybm[0+(yych = *YYCURSOR)] & 4) {
+ goto yy186;
+ }
YYDEBUG(729, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'D') goto yy744;
- if (yych == 'd') goto yy744;
- goto yy186;
+ yyleng = YYCURSOR - SCNG(yy_text);
+#line 1136 "Zend/zend_language_scanner.l"
+ {
+ return T_DEFAULT;
+}
+#line 6795 "Zend/zend_language_scanner.c"
yy730:
YYDEBUG(730, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'A') goto yy741;
- if (yych == 'a') goto yy741;
- goto yy186;
+ if (yych == 'A') goto yy731;
+ if (yych != 'a') goto yy187;
yy731:
YYDEBUG(731, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych <= 'T') {
- if (yych == 'I') goto yy732;
- if (yych <= 'S') goto yy186;
- goto yy733;
- } else {
- if (yych <= 'i') {
- if (yych <= 'h') goto yy186;
- } else {
- if (yych == 't') goto yy733;
- goto yy186;
- }
- }
+ if (yych == 'R') goto yy732;
+ if (yych != 'r') goto yy187;
yy732:
YYDEBUG(732, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'T') goto yy739;
- if (yych == 't') goto yy739;
- goto yy186;
+ if (yych == 'E') goto yy733;
+ if (yych != 'e') goto yy187;
yy733:
YYDEBUG(733, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'E') goto yy734;
- if (yych != 'e') goto yy186;
-yy734:
+ ++YYCURSOR;
+ if (yybm[0+(yych = *YYCURSOR)] & 4) {
+ goto yy186;
+ }
YYDEBUG(734, *YYCURSOR);
- yych = *++YYCURSOR;
- if (yych == 'N') goto yy735;
- if (yych != 'n') goto yy186;
+ yyleng = YYCURSOR - SCNG(yy_text);
+#line 1108 "Zend/zend_language_scanner.l"
+ {
+ return T_DECLARE;
+}
+#line 6823 "Zend/zend_language_scanner.c"
yy735:
YYDEBUG(735, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'D') goto yy736;
- if (yych != 'd') goto yy186;
+ if (yych == 'H') goto yy797;
+ if (yych == 'h') goto yy797;
+ goto yy187;
yy736:
YYDEBUG(736, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'S') goto yy737;
- if (yych != 's') goto yy186;
+ if (yych == 'S') goto yy791;
+ if (yych == 's') goto yy791;
+ goto yy187;
yy737:
YYDEBUG(737, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'P') goto yy787;
+ if (yych == 'p') goto yy787;
+ goto yy187;
+yy738:
+ YYDEBUG(738, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'D') goto yy753;
+ if (yych == 'd') goto yy753;
+ goto yy187;
+yy739:
+ YYDEBUG(739, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'A') goto yy750;
+ if (yych == 'a') goto yy750;
+ goto yy187;
+yy740:
+ YYDEBUG(740, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych <= 'T') {
+ if (yych == 'I') goto yy741;
+ if (yych <= 'S') goto yy187;
+ goto yy742;
+ } else {
+ if (yych <= 'i') {
+ if (yych <= 'h') goto yy187;
+ } else {
+ if (yych == 't') goto yy742;
+ goto yy187;
+ }
+ }
+yy741:
+ YYDEBUG(741, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'T') goto yy748;
+ if (yych == 't') goto yy748;
+ goto yy187;
+yy742:
+ YYDEBUG(742, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'E') goto yy743;
+ if (yych != 'e') goto yy187;
+yy743:
+ YYDEBUG(743, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'N') goto yy744;
+ if (yych != 'n') goto yy187;
+yy744:
+ YYDEBUG(744, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'D') goto yy745;
+ if (yych != 'd') goto yy187;
+yy745:
+ YYDEBUG(745, *YYCURSOR);
+ yych = *++YYCURSOR;
+ if (yych == 'S') goto yy746;
+ if (yych != 's') goto yy187;
+yy746:
+ YYDEBUG(746, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(738, *YYCURSOR);
+ YYDEBUG(747, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1161 "Zend/zend_language_scanner.l"
+#line 1172 "Zend/zend_language_scanner.l"
{
return T_EXTENDS;
}
-#line 6833 "Zend/zend_language_scanner.c"
-yy739:
- YYDEBUG(739, *YYCURSOR);
+#line 6907 "Zend/zend_language_scanner.c"
+yy748:
+ YYDEBUG(748, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(740, *YYCURSOR);
+ YYDEBUG(749, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1021 "Zend/zend_language_scanner.l"
+#line 1024 "Zend/zend_language_scanner.l"
{
return T_EXIT;
}
-#line 6846 "Zend/zend_language_scanner.c"
-yy741:
- YYDEBUG(741, *YYCURSOR);
+#line 6920 "Zend/zend_language_scanner.c"
+yy750:
+ YYDEBUG(750, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'L') goto yy742;
- if (yych != 'l') goto yy186;
-yy742:
- YYDEBUG(742, *YYCURSOR);
+ if (yych == 'L') goto yy751;
+ if (yych != 'l') goto yy187;
+yy751:
+ YYDEBUG(751, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(743, *YYCURSOR);
+ YYDEBUG(752, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1247 "Zend/zend_language_scanner.l"
+#line 1258 "Zend/zend_language_scanner.l"
{
return T_EVAL;
}
-#line 6864 "Zend/zend_language_scanner.c"
-yy744:
- YYDEBUG(744, *YYCURSOR);
+#line 6938 "Zend/zend_language_scanner.c"
+yy753:
+ YYDEBUG(753, *YYCURSOR);
yych = *++YYCURSOR;
YYDEBUG(-1, yych);
switch (yych) {
case 'D':
- case 'd': goto yy745;
+ case 'd': goto yy754;
case 'F':
- case 'f': goto yy746;
+ case 'f': goto yy755;
case 'I':
- case 'i': goto yy747;
+ case 'i': goto yy756;
case 'S':
- case 's': goto yy748;
+ case 's': goto yy757;
case 'W':
- case 'w': goto yy749;
- default: goto yy186;
+ case 'w': goto yy758;
+ default: goto yy187;
}
-yy745:
- YYDEBUG(745, *YYCURSOR);
+yy754:
+ YYDEBUG(754, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy771;
- if (yych == 'e') goto yy771;
- goto yy186;
-yy746:
- YYDEBUG(746, *YYCURSOR);
+ if (yych == 'E') goto yy780;
+ if (yych == 'e') goto yy780;
+ goto yy187;
+yy755:
+ YYDEBUG(755, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'O') goto yy763;
- if (yych == 'o') goto yy763;
- goto yy186;
-yy747:
- YYDEBUG(747, *YYCURSOR);
+ if (yych == 'O') goto yy772;
+ if (yych == 'o') goto yy772;
+ goto yy187;
+yy756:
+ YYDEBUG(756, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'F') goto yy761;
- if (yych == 'f') goto yy761;
- goto yy186;
-yy748:
- YYDEBUG(748, *YYCURSOR);
+ if (yych == 'F') goto yy770;
+ if (yych == 'f') goto yy770;
+ goto yy187;
+yy757:
+ YYDEBUG(757, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'W') goto yy755;
- if (yych == 'w') goto yy755;
- goto yy186;
-yy749:
- YYDEBUG(749, *YYCURSOR);
+ if (yych == 'W') goto yy764;
+ if (yych == 'w') goto yy764;
+ goto yy187;
+yy758:
+ YYDEBUG(758, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'H') goto yy750;
- if (yych != 'h') goto yy186;
-yy750:
- YYDEBUG(750, *YYCURSOR);
+ if (yych == 'H') goto yy759;
+ if (yych != 'h') goto yy187;
+yy759:
+ YYDEBUG(759, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'I') goto yy751;
- if (yych != 'i') goto yy186;
-yy751:
- YYDEBUG(751, *YYCURSOR);
+ if (yych == 'I') goto yy760;
+ if (yych != 'i') goto yy187;
+yy760:
+ YYDEBUG(760, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'L') goto yy752;
- if (yych != 'l') goto yy186;
-yy752:
- YYDEBUG(752, *YYCURSOR);
+ if (yych == 'L') goto yy761;
+ if (yych != 'l') goto yy187;
+yy761:
+ YYDEBUG(761, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy753;
- if (yych != 'e') goto yy186;
-yy753:
- YYDEBUG(753, *YYCURSOR);
+ if (yych == 'E') goto yy762;
+ if (yych != 'e') goto yy187;
+yy762:
+ YYDEBUG(762, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(754, *YYCURSOR);
+ YYDEBUG(763, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1073 "Zend/zend_language_scanner.l"
+#line 1084 "Zend/zend_language_scanner.l"
{
return T_ENDWHILE;
}
-#line 6938 "Zend/zend_language_scanner.c"
-yy755:
- YYDEBUG(755, *YYCURSOR);
+#line 7012 "Zend/zend_language_scanner.c"
+yy764:
+ YYDEBUG(764, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'I') goto yy756;
- if (yych != 'i') goto yy186;
-yy756:
- YYDEBUG(756, *YYCURSOR);
+ if (yych == 'I') goto yy765;
+ if (yych != 'i') goto yy187;
+yy765:
+ YYDEBUG(765, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'T') goto yy757;
- if (yych != 't') goto yy186;
-yy757:
- YYDEBUG(757, *YYCURSOR);
+ if (yych == 'T') goto yy766;
+ if (yych != 't') goto yy187;
+yy766:
+ YYDEBUG(766, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'C') goto yy758;
- if (yych != 'c') goto yy186;
-yy758:
- YYDEBUG(758, *YYCURSOR);
+ if (yych == 'C') goto yy767;
+ if (yych != 'c') goto yy187;
+yy767:
+ YYDEBUG(767, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'H') goto yy759;
- if (yych != 'h') goto yy186;
-yy759:
- YYDEBUG(759, *YYCURSOR);
+ if (yych == 'H') goto yy768;
+ if (yych != 'h') goto yy187;
+yy768:
+ YYDEBUG(768, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(760, *YYCURSOR);
+ YYDEBUG(769, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1117 "Zend/zend_language_scanner.l"
+#line 1128 "Zend/zend_language_scanner.l"
{
return T_ENDSWITCH;
}
-#line 6971 "Zend/zend_language_scanner.c"
-yy761:
- YYDEBUG(761, *YYCURSOR);
+#line 7045 "Zend/zend_language_scanner.c"
+yy770:
+ YYDEBUG(770, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(762, *YYCURSOR);
+ YYDEBUG(771, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1061 "Zend/zend_language_scanner.l"
+#line 1072 "Zend/zend_language_scanner.l"
{
return T_ENDIF;
}
-#line 6984 "Zend/zend_language_scanner.c"
-yy763:
- YYDEBUG(763, *YYCURSOR);
+#line 7058 "Zend/zend_language_scanner.c"
+yy772:
+ YYDEBUG(772, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'R') goto yy764;
- if (yych != 'r') goto yy186;
-yy764:
- YYDEBUG(764, *YYCURSOR);
+ if (yych == 'R') goto yy773;
+ if (yych != 'r') goto yy187;
+yy773:
+ YYDEBUG(773, *YYCURSOR);
++YYCURSOR;
if ((yych = *YYCURSOR) <= '^') {
if (yych <= '@') {
- if (yych <= '/') goto yy765;
- if (yych <= '9') goto yy185;
+ if (yych <= '/') goto yy774;
+ if (yych <= '9') goto yy186;
} else {
- if (yych == 'E') goto yy766;
- if (yych <= 'Z') goto yy185;
+ if (yych == 'E') goto yy775;
+ if (yych <= 'Z') goto yy186;
}
} else {
if (yych <= 'd') {
- if (yych != '`') goto yy185;
+ if (yych != '`') goto yy186;
} else {
- if (yych <= 'e') goto yy766;
- if (yych <= 'z') goto yy185;
- if (yych >= 0x7F) goto yy185;
+ if (yych <= 'e') goto yy775;
+ if (yych <= 'z') goto yy186;
+ if (yych >= 0x7F) goto yy186;
}
}
-yy765:
- YYDEBUG(765, *YYCURSOR);
+yy774:
+ YYDEBUG(774, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1085 "Zend/zend_language_scanner.l"
+#line 1096 "Zend/zend_language_scanner.l"
{
return T_ENDFOR;
}
-#line 7017 "Zend/zend_language_scanner.c"
-yy766:
- YYDEBUG(766, *YYCURSOR);
+#line 7091 "Zend/zend_language_scanner.c"
+yy775:
+ YYDEBUG(775, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'A') goto yy767;
- if (yych != 'a') goto yy186;
-yy767:
- YYDEBUG(767, *YYCURSOR);
+ if (yych == 'A') goto yy776;
+ if (yych != 'a') goto yy187;
+yy776:
+ YYDEBUG(776, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'C') goto yy768;
- if (yych != 'c') goto yy186;
-yy768:
- YYDEBUG(768, *YYCURSOR);
+ if (yych == 'C') goto yy777;
+ if (yych != 'c') goto yy187;
+yy777:
+ YYDEBUG(777, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'H') goto yy769;
- if (yych != 'h') goto yy186;
-yy769:
- YYDEBUG(769, *YYCURSOR);
+ if (yych == 'H') goto yy778;
+ if (yych != 'h') goto yy187;
+yy778:
+ YYDEBUG(778, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(770, *YYCURSOR);
+ YYDEBUG(779, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1093 "Zend/zend_language_scanner.l"
+#line 1104 "Zend/zend_language_scanner.l"
{
return T_ENDFOREACH;
}
-#line 7045 "Zend/zend_language_scanner.c"
-yy771:
- YYDEBUG(771, *YYCURSOR);
+#line 7119 "Zend/zend_language_scanner.c"
+yy780:
+ YYDEBUG(780, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'C') goto yy772;
- if (yych != 'c') goto yy186;
-yy772:
- YYDEBUG(772, *YYCURSOR);
+ if (yych == 'C') goto yy781;
+ if (yych != 'c') goto yy187;
+yy781:
+ YYDEBUG(781, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'L') goto yy773;
- if (yych != 'l') goto yy186;
-yy773:
- YYDEBUG(773, *YYCURSOR);
+ if (yych == 'L') goto yy782;
+ if (yych != 'l') goto yy187;
+yy782:
+ YYDEBUG(782, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'A') goto yy774;
- if (yych != 'a') goto yy186;
-yy774:
- YYDEBUG(774, *YYCURSOR);
+ if (yych == 'A') goto yy783;
+ if (yych != 'a') goto yy187;
+yy783:
+ YYDEBUG(783, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'R') goto yy775;
- if (yych != 'r') goto yy186;
-yy775:
- YYDEBUG(775, *YYCURSOR);
+ if (yych == 'R') goto yy784;
+ if (yych != 'r') goto yy187;
+yy784:
+ YYDEBUG(784, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy776;
- if (yych != 'e') goto yy186;
-yy776:
- YYDEBUG(776, *YYCURSOR);
+ if (yych == 'E') goto yy785;
+ if (yych != 'e') goto yy187;
+yy785:
+ YYDEBUG(785, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(777, *YYCURSOR);
+ YYDEBUG(786, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1101 "Zend/zend_language_scanner.l"
+#line 1112 "Zend/zend_language_scanner.l"
{
return T_ENDDECLARE;
}
-#line 7083 "Zend/zend_language_scanner.c"
-yy778:
- YYDEBUG(778, *YYCURSOR);
+#line 7157 "Zend/zend_language_scanner.c"
+yy787:
+ YYDEBUG(787, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'T') goto yy779;
- if (yych != 't') goto yy186;
-yy779:
- YYDEBUG(779, *YYCURSOR);
+ if (yych == 'T') goto yy788;
+ if (yych != 't') goto yy187;
+yy788:
+ YYDEBUG(788, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'Y') goto yy780;
- if (yych != 'y') goto yy186;
-yy780:
- YYDEBUG(780, *YYCURSOR);
+ if (yych == 'Y') goto yy789;
+ if (yych != 'y') goto yy187;
+yy789:
+ YYDEBUG(789, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(781, *YYCURSOR);
+ YYDEBUG(790, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1287 "Zend/zend_language_scanner.l"
+#line 1298 "Zend/zend_language_scanner.l"
{
return T_EMPTY;
}
-#line 7106 "Zend/zend_language_scanner.c"
-yy782:
- YYDEBUG(782, *YYCURSOR);
+#line 7180 "Zend/zend_language_scanner.c"
+yy791:
+ YYDEBUG(791, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'E') goto yy783;
- if (yych != 'e') goto yy186;
-yy783:
- YYDEBUG(783, *YYCURSOR);
+ if (yych == 'E') goto yy792;
+ if (yych != 'e') goto yy187;
+yy792:
+ YYDEBUG(792, *YYCURSOR);
++YYCURSOR;
if ((yych = *YYCURSOR) <= '^') {
if (yych <= '@') {
- if (yych <= '/') goto yy784;
- if (yych <= '9') goto yy185;
+ if (yych <= '/') goto yy793;
+ if (yych <= '9') goto yy186;
} else {
- if (yych == 'I') goto yy785;
- if (yych <= 'Z') goto yy185;
+ if (yych == 'I') goto yy794;
+ if (yych <= 'Z') goto yy186;
}
} else {
if (yych <= 'h') {
- if (yych != '`') goto yy185;
+ if (yych != '`') goto yy186;
} else {
- if (yych <= 'i') goto yy785;
- if (yych <= 'z') goto yy185;
- if (yych >= 0x7F) goto yy185;
+ if (yych <= 'i') goto yy794;
+ if (yych <= 'z') goto yy186;
+ if (yych >= 0x7F) goto yy186;
}
}
-yy784:
- YYDEBUG(784, *YYCURSOR);
+yy793:
+ YYDEBUG(793, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1065 "Zend/zend_language_scanner.l"
+#line 1076 "Zend/zend_language_scanner.l"
{
return T_ELSE;
}
-#line 7139 "Zend/zend_language_scanner.c"
-yy785:
- YYDEBUG(785, *YYCURSOR);
+#line 7213 "Zend/zend_language_scanner.c"
+yy794:
+ YYDEBUG(794, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'F') goto yy786;
- if (yych != 'f') goto yy186;
-yy786:
- YYDEBUG(786, *YYCURSOR);
+ if (yych == 'F') goto yy795;
+ if (yych != 'f') goto yy187;
+yy795:
+ YYDEBUG(795, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(787, *YYCURSOR);
+ YYDEBUG(796, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1057 "Zend/zend_language_scanner.l"
+#line 1068 "Zend/zend_language_scanner.l"
{
return T_ELSEIF;
}
-#line 7157 "Zend/zend_language_scanner.c"
-yy788:
- YYDEBUG(788, *YYCURSOR);
+#line 7231 "Zend/zend_language_scanner.c"
+yy797:
+ YYDEBUG(797, *YYCURSOR);
yych = *++YYCURSOR;
- if (yych == 'O') goto yy789;
- if (yych != 'o') goto yy186;
-yy789:
- YYDEBUG(789, *YYCURSOR);
+ if (yych == 'O') goto yy798;
+ if (yych != 'o') goto yy187;
+yy798:
+ YYDEBUG(798, *YYCURSOR);
++YYCURSOR;
if (yybm[0+(yych = *YYCURSOR)] & 4) {
- goto yy185;
+ goto yy186;
}
- YYDEBUG(790, *YYCURSOR);
+ YYDEBUG(799, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1141 "Zend/zend_language_scanner.l"
+#line 1152 "Zend/zend_language_scanner.l"
{
return T_ECHO;
}
-#line 7175 "Zend/zend_language_scanner.c"
+#line 7249 "Zend/zend_language_scanner.c"
}
/* *********************************** */
yyc_ST_LOOKING_FOR_PROPERTY:
@@ -7210,41 +7284,41 @@ yyc_ST_LOOKING_FOR_PROPERTY:
64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64,
};
- YYDEBUG(791, *YYCURSOR);
+ YYDEBUG(800, *YYCURSOR);
YYFILL(2);
yych = *YYCURSOR;
if (yych <= '-') {
if (yych <= '\r') {
- if (yych <= 0x08) goto yy799;
- if (yych <= '\n') goto yy793;
- if (yych <= '\f') goto yy799;
+ if (yych <= 0x08) goto yy808;
+ if (yych <= '\n') goto yy802;
+ if (yych <= '\f') goto yy808;
} else {
- if (yych == ' ') goto yy793;
- if (yych <= ',') goto yy799;
- goto yy795;
+ if (yych == ' ') goto yy802;
+ if (yych <= ',') goto yy808;
+ goto yy804;
}
} else {
if (yych <= '_') {
- if (yych <= '@') goto yy799;
- if (yych <= 'Z') goto yy797;
- if (yych <= '^') goto yy799;
- goto yy797;
+ if (yych <= '@') goto yy808;
+ if (yych <= 'Z') goto yy806;
+ if (yych <= '^') goto yy808;
+ goto yy806;
} else {
- if (yych <= '`') goto yy799;
- if (yych <= 'z') goto yy797;
- if (yych <= '~') goto yy799;
- goto yy797;
+ if (yych <= '`') goto yy808;
+ if (yych <= 'z') goto yy806;
+ if (yych <= '~') goto yy808;
+ goto yy806;
}
}
-yy793:
- YYDEBUG(793, *YYCURSOR);
+yy802:
+ YYDEBUG(802, *YYCURSOR);
++YYCURSOR;
yych = *YYCURSOR;
- goto yy805;
-yy794:
- YYDEBUG(794, *YYCURSOR);
+ goto yy814;
+yy803:
+ YYDEBUG(803, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1174 "Zend/zend_language_scanner.l"
+#line 1185 "Zend/zend_language_scanner.l"
{
zendlval->value.str.val = yytext; /* no copying - intentional */
zendlval->value.str.len = yyleng;
@@ -7252,73 +7326,73 @@ yy794:
HANDLE_NEWLINES(yytext, yyleng);
return T_WHITESPACE;
}
-#line 7256 "Zend/zend_language_scanner.c"
-yy795:
- YYDEBUG(795, *YYCURSOR);
+#line 7330 "Zend/zend_language_scanner.c"
+yy804:
+ YYDEBUG(804, *YYCURSOR);
++YYCURSOR;
- if ((yych = *YYCURSOR) == '>') goto yy802;
-yy796:
- YYDEBUG(796, *YYCURSOR);
+ if ((yych = *YYCURSOR) == '>') goto yy811;
+yy805:
+ YYDEBUG(805, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1193 "Zend/zend_language_scanner.l"
+#line 1204 "Zend/zend_language_scanner.l"
{
yyless(0);
yy_pop_state(TSRMLS_C);
goto restart;
}
-#line 7270 "Zend/zend_language_scanner.c"
-yy797:
- YYDEBUG(797, *YYCURSOR);
+#line 7344 "Zend/zend_language_scanner.c"
+yy806:
+ YYDEBUG(806, *YYCURSOR);
++YYCURSOR;
yych = *YYCURSOR;
- goto yy801;
-yy798:
- YYDEBUG(798, *YYCURSOR);
+ goto yy810;
+yy807:
+ YYDEBUG(807, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1186 "Zend/zend_language_scanner.l"
+#line 1197 "Zend/zend_language_scanner.l"
{
yy_pop_state(TSRMLS_C);
zend_copy_value(zendlval, yytext, yyleng);
zendlval->type = IS_STRING;
return T_STRING;
}
-#line 7286 "Zend/zend_language_scanner.c"
-yy799:
- YYDEBUG(799, *YYCURSOR);
+#line 7360 "Zend/zend_language_scanner.c"
+yy808:
+ YYDEBUG(808, *YYCURSOR);
yych = *++YYCURSOR;
- goto yy796;
-yy800:
- YYDEBUG(800, *YYCURSOR);
+ goto yy805;
+yy809:
+ YYDEBUG(809, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
-yy801:
- YYDEBUG(801, *YYCURSOR);
+yy810:
+ YYDEBUG(810, *YYCURSOR);
if (yybm[0+yych] & 64) {
- goto yy800;
+ goto yy809;
}
- goto yy798;
-yy802:
- YYDEBUG(802, *YYCURSOR);
+ goto yy807;
+yy811:
+ YYDEBUG(811, *YYCURSOR);
++YYCURSOR;
- YYDEBUG(803, *YYCURSOR);
+ YYDEBUG(812, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1182 "Zend/zend_language_scanner.l"
+#line 1193 "Zend/zend_language_scanner.l"
{
return T_OBJECT_OPERATOR;
}
-#line 7311 "Zend/zend_language_scanner.c"
-yy804:
- YYDEBUG(804, *YYCURSOR);
+#line 7385 "Zend/zend_language_scanner.c"
+yy813:
+ YYDEBUG(813, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
-yy805:
- YYDEBUG(805, *YYCURSOR);
+yy814:
+ YYDEBUG(814, *YYCURSOR);
if (yybm[0+yych] & 128) {
- goto yy804;
+ goto yy813;
}
- goto yy794;
+ goto yy803;
}
/* *********************************** */
yyc_ST_LOOKING_FOR_VARNAME:
@@ -7357,73 +7431,99 @@ yyc_ST_LOOKING_FOR_VARNAME:
128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128,
};
- YYDEBUG(806, *YYCURSOR);
+ YYDEBUG(815, *YYCURSOR);
YYFILL(2);
yych = *YYCURSOR;
if (yych <= '_') {
- if (yych <= '@') goto yy810;
- if (yych <= 'Z') goto yy808;
- if (yych <= '^') goto yy810;
+ if (yych <= '@') goto yy819;
+ if (yych <= 'Z') goto yy817;
+ if (yych <= '^') goto yy819;
} else {
- if (yych <= '`') goto yy810;
- if (yych <= 'z') goto yy808;
- if (yych <= '~') goto yy810;
+ if (yych <= '`') goto yy819;
+ if (yych <= 'z') goto yy817;
+ if (yych <= '~') goto yy819;
}
-yy808:
- YYDEBUG(808, *YYCURSOR);
- ++YYCURSOR;
- yych = *YYCURSOR;
- goto yy813;
-yy809:
- YYDEBUG(809, *YYCURSOR);
- yyleng = YYCURSOR - SCNG(yy_text);
-#line 1469 "Zend/zend_language_scanner.l"
- {
- zend_copy_value(zendlval, yytext, yyleng);
- zendlval->type = IS_STRING;
- yy_pop_state(TSRMLS_C);
- yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
- return T_STRING_VARNAME;
-}
-#line 7389 "Zend/zend_language_scanner.c"
-yy810:
- YYDEBUG(810, *YYCURSOR);
- ++YYCURSOR;
- YYDEBUG(811, *YYCURSOR);
+yy817:
+ YYDEBUG(817, *YYCURSOR);
+ yyaccept = 0;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if (yych <= '_') {
+ if (yych <= '@') {
+ if (yych <= '/') goto yy818;
+ if (yych <= '9') goto yy821;
+ } else {
+ if (yych <= '[') goto yy821;
+ if (yych >= '_') goto yy821;
+ }
+ } else {
+ if (yych <= '|') {
+ if (yych <= '`') goto yy818;
+ if (yych <= 'z') goto yy821;
+ } else {
+ if (yych != '~') goto yy821;
+ }
+ }
+yy818:
+ YYDEBUG(818, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1478 "Zend/zend_language_scanner.l"
+#line 1490 "Zend/zend_language_scanner.l"
{
yyless(0);
yy_pop_state(TSRMLS_C);
yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
goto restart;
}
-#line 7402 "Zend/zend_language_scanner.c"
-yy812:
- YYDEBUG(812, *YYCURSOR);
+#line 7477 "Zend/zend_language_scanner.c"
+yy819:
+ YYDEBUG(819, *YYCURSOR);
+ yych = *++YYCURSOR;
+ goto yy818;
+yy820:
+ YYDEBUG(820, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
-yy813:
- YYDEBUG(813, *YYCURSOR);
+yy821:
+ YYDEBUG(821, *YYCURSOR);
if (yybm[0+yych] & 128) {
- goto yy812;
+ goto yy820;
}
- goto yy809;
+ if (yych == '[') goto yy823;
+ if (yych == '}') goto yy823;
+ YYDEBUG(822, *YYCURSOR);
+ YYCURSOR = YYMARKER;
+ goto yy818;
+yy823:
+ YYDEBUG(823, *YYCURSOR);
+ ++YYCURSOR;
+ YYDEBUG(824, *YYCURSOR);
+ yyleng = YYCURSOR - SCNG(yy_text);
+#line 1480 "Zend/zend_language_scanner.l"
+ {
+ yyless(yyleng - 1);
+ zend_copy_value(zendlval, yytext, yyleng);
+ zendlval->type = IS_STRING;
+ yy_pop_state(TSRMLS_C);
+ yy_push_state(ST_IN_SCRIPTING TSRMLS_CC);
+ return T_STRING_VARNAME;
+}
+#line 7511 "Zend/zend_language_scanner.c"
}
/* *********************************** */
yyc_ST_NOWDOC:
- YYDEBUG(814, *YYCURSOR);
+ YYDEBUG(825, *YYCURSOR);
YYFILL(1);
yych = *YYCURSOR;
- YYDEBUG(816, *YYCURSOR);
+ YYDEBUG(827, *YYCURSOR);
++YYCURSOR;
- YYDEBUG(817, *YYCURSOR);
+ YYDEBUG(828, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 2360 "Zend/zend_language_scanner.l"
+#line 2374 "Zend/zend_language_scanner.l"
{
int newline = 0;
+ zend_heredoc_label *heredoc_label = zend_ptr_stack_top(&SCNG(heredoc_label_stack));
+
if (YYCURSOR > YYLIMIT) {
return 0;
}
@@ -7439,8 +7539,8 @@ yyc_ST_NOWDOC:
/* fall through */
case '\n':
/* Check for ending label on the next line */
- if (IS_LABEL_START(*YYCURSOR) && CG(heredoc_len) < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, CG(heredoc), CG(heredoc_len))) {
- YYCTYPE *end = YYCURSOR + CG(heredoc_len);
+ if (IS_LABEL_START(*YYCURSOR) && heredoc_label->length < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, heredoc_label->label, heredoc_label->length)) {
+ YYCTYPE *end = YYCURSOR + heredoc_label->length;
if (*end == ';') {
end++;
@@ -7475,7 +7575,7 @@ nowdoc_scan_done:
HANDLE_NEWLINES(yytext, yyleng - newline);
return T_ENCAPSED_AND_WHITESPACE;
}
-#line 7479 "Zend/zend_language_scanner.c"
+#line 7579 "Zend/zend_language_scanner.c"
/* *********************************** */
yyc_ST_VAR_OFFSET:
{
@@ -7513,76 +7613,76 @@ yyc_ST_VAR_OFFSET:
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
};
- YYDEBUG(818, *YYCURSOR);
+ YYDEBUG(829, *YYCURSOR);
YYFILL(3);
yych = *YYCURSOR;
if (yych <= '/') {
if (yych <= ' ') {
if (yych <= '\f') {
- if (yych <= 0x08) goto yy832;
- if (yych <= '\n') goto yy828;
- goto yy832;
+ if (yych <= 0x08) goto yy843;
+ if (yych <= '\n') goto yy839;
+ goto yy843;
} else {
- if (yych <= '\r') goto yy828;
- if (yych <= 0x1F) goto yy832;
- goto yy828;
+ if (yych <= '\r') goto yy839;
+ if (yych <= 0x1F) goto yy843;
+ goto yy839;
}
} else {
if (yych <= '$') {
- if (yych <= '"') goto yy827;
- if (yych <= '#') goto yy828;
- goto yy823;
+ if (yych <= '"') goto yy838;
+ if (yych <= '#') goto yy839;
+ goto yy834;
} else {
- if (yych == '\'') goto yy828;
- goto yy827;
+ if (yych == '\'') goto yy839;
+ goto yy838;
}
}
} else {
if (yych <= '\\') {
if (yych <= '@') {
- if (yych <= '0') goto yy820;
- if (yych <= '9') goto yy822;
- goto yy827;
+ if (yych <= '0') goto yy831;
+ if (yych <= '9') goto yy833;
+ goto yy838;
} else {
- if (yych <= 'Z') goto yy830;
- if (yych <= '[') goto yy827;
- goto yy828;
+ if (yych <= 'Z') goto yy841;
+ if (yych <= '[') goto yy838;
+ goto yy839;
}
} else {
if (yych <= '_') {
- if (yych <= ']') goto yy825;
- if (yych <= '^') goto yy827;
- goto yy830;
+ if (yych <= ']') goto yy836;
+ if (yych <= '^') goto yy838;
+ goto yy841;
} else {
- if (yych <= '`') goto yy827;
- if (yych <= 'z') goto yy830;
- if (yych <= '~') goto yy827;
- goto yy830;
+ if (yych <= '`') goto yy838;
+ if (yych <= 'z') goto yy841;
+ if (yych <= '~') goto yy838;
+ goto yy841;
}
}
}
-yy820:
- YYDEBUG(820, *YYCURSOR);
+yy831:
+ YYDEBUG(831, *YYCURSOR);
yyaccept = 0;
yych = *(YYMARKER = ++YYCURSOR);
if (yych <= 'W') {
if (yych <= '9') {
- if (yych >= '0') goto yy844;
+ if (yych >= '0') goto yy855;
} else {
- if (yych == 'B') goto yy841;
+ if (yych == 'B') goto yy852;
}
} else {
if (yych <= 'b') {
- if (yych <= 'X') goto yy843;
- if (yych >= 'b') goto yy841;
+ if (yych <= 'X') goto yy854;
+ if (yych >= 'b') goto yy852;
} else {
- if (yych == 'x') goto yy843;
+ if (yych == 'x') goto yy854;
}
}
-yy821:
- YYDEBUG(821, *YYCURSOR);
+yy832:
+ YYDEBUG(832, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1556 "Zend/zend_language_scanner.l"
+#line 1568 "Zend/zend_language_scanner.l"
{ /* Offset could be treated as a long */
if (yyleng < MAX_LENGTH_OF_LONG - 1 || (yyleng == MAX_LENGTH_OF_LONG - 1 && strcmp(yytext, long_min_digits) < 0)) {
zendlval->value.lval = strtol(yytext, NULL, 10);
@@ -7594,81 +7694,81 @@ yy821:
}
return T_NUM_STRING;
}
-#line 7598 "Zend/zend_language_scanner.c"
-yy822:
- YYDEBUG(822, *YYCURSOR);
+#line 7698 "Zend/zend_language_scanner.c"
+yy833:
+ YYDEBUG(833, *YYCURSOR);
yych = *++YYCURSOR;
- goto yy840;
-yy823:
- YYDEBUG(823, *YYCURSOR);
+ goto yy851;
+yy834:
+ YYDEBUG(834, *YYCURSOR);
++YYCURSOR;
if ((yych = *YYCURSOR) <= '_') {
- if (yych <= '@') goto yy824;
- if (yych <= 'Z') goto yy836;
- if (yych >= '_') goto yy836;
+ if (yych <= '@') goto yy835;
+ if (yych <= 'Z') goto yy847;
+ if (yych >= '_') goto yy847;
} else {
- if (yych <= '`') goto yy824;
- if (yych <= 'z') goto yy836;
- if (yych >= 0x7F) goto yy836;
+ if (yych <= '`') goto yy835;
+ if (yych <= 'z') goto yy847;
+ if (yych >= 0x7F) goto yy847;
}
-yy824:
- YYDEBUG(824, *YYCURSOR);
+yy835:
+ YYDEBUG(835, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1888 "Zend/zend_language_scanner.l"
+#line 1900 "Zend/zend_language_scanner.l"
{
/* Only '[' can be valid, but returning other tokens will allow a more explicit parse error */
return yytext[0];
}
-#line 7623 "Zend/zend_language_scanner.c"
-yy825:
- YYDEBUG(825, *YYCURSOR);
+#line 7723 "Zend/zend_language_scanner.c"
+yy836:
+ YYDEBUG(836, *YYCURSOR);
++YYCURSOR;
- YYDEBUG(826, *YYCURSOR);
+ YYDEBUG(837, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1883 "Zend/zend_language_scanner.l"
+#line 1895 "Zend/zend_language_scanner.l"
{
yy_pop_state(TSRMLS_C);
return ']';
}
-#line 7634 "Zend/zend_language_scanner.c"
-yy827:
- YYDEBUG(827, *YYCURSOR);
+#line 7734 "Zend/zend_language_scanner.c"
+yy838:
+ YYDEBUG(838, *YYCURSOR);
yych = *++YYCURSOR;
- goto yy824;
-yy828:
- YYDEBUG(828, *YYCURSOR);
+ goto yy835;
+yy839:
+ YYDEBUG(839, *YYCURSOR);
++YYCURSOR;
- YYDEBUG(829, *YYCURSOR);
+ YYDEBUG(840, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1893 "Zend/zend_language_scanner.l"
+#line 1905 "Zend/zend_language_scanner.l"
{
/* Invalid rule to return a more explicit parse error with proper line number */
yyless(0);
yy_pop_state(TSRMLS_C);
return T_ENCAPSED_AND_WHITESPACE;
}
-#line 7651 "Zend/zend_language_scanner.c"
-yy830:
- YYDEBUG(830, *YYCURSOR);
+#line 7751 "Zend/zend_language_scanner.c"
+yy841:
+ YYDEBUG(841, *YYCURSOR);
++YYCURSOR;
yych = *YYCURSOR;
- goto yy835;
-yy831:
- YYDEBUG(831, *YYCURSOR);
+ goto yy846;
+yy842:
+ YYDEBUG(842, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1900 "Zend/zend_language_scanner.l"
+#line 1912 "Zend/zend_language_scanner.l"
{
zend_copy_value(zendlval, yytext, yyleng);
zendlval->type = IS_STRING;
return T_STRING;
}
-#line 7666 "Zend/zend_language_scanner.c"
-yy832:
- YYDEBUG(832, *YYCURSOR);
+#line 7766 "Zend/zend_language_scanner.c"
+yy843:
+ YYDEBUG(843, *YYCURSOR);
++YYCURSOR;
- YYDEBUG(833, *YYCURSOR);
+ YYDEBUG(844, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 2416 "Zend/zend_language_scanner.l"
+#line 2432 "Zend/zend_language_scanner.l"
{
if (YYCURSOR > YYLIMIT) {
return 0;
@@ -7677,118 +7777,118 @@ yy832:
zend_error(E_COMPILE_WARNING,"Unexpected character in input: '%c' (ASCII=%d) state=%d", yytext[0], yytext[0], YYSTATE);
goto restart;
}
-#line 7681 "Zend/zend_language_scanner.c"
-yy834:
- YYDEBUG(834, *YYCURSOR);
+#line 7781 "Zend/zend_language_scanner.c"
+yy845:
+ YYDEBUG(845, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
-yy835:
- YYDEBUG(835, *YYCURSOR);
+yy846:
+ YYDEBUG(846, *YYCURSOR);
if (yybm[0+yych] & 16) {
- goto yy834;
+ goto yy845;
}
- goto yy831;
-yy836:
- YYDEBUG(836, *YYCURSOR);
+ goto yy842;
+yy847:
+ YYDEBUG(847, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
- YYDEBUG(837, *YYCURSOR);
+ YYDEBUG(848, *YYCURSOR);
if (yych <= '^') {
if (yych <= '9') {
- if (yych >= '0') goto yy836;
+ if (yych >= '0') goto yy847;
} else {
- if (yych <= '@') goto yy838;
- if (yych <= 'Z') goto yy836;
+ if (yych <= '@') goto yy849;
+ if (yych <= 'Z') goto yy847;
}
} else {
if (yych <= '`') {
- if (yych <= '_') goto yy836;
+ if (yych <= '_') goto yy847;
} else {
- if (yych <= 'z') goto yy836;
- if (yych >= 0x7F) goto yy836;
+ if (yych <= 'z') goto yy847;
+ if (yych >= 0x7F) goto yy847;
}
}
-yy838:
- YYDEBUG(838, *YYCURSOR);
+yy849:
+ YYDEBUG(849, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1877 "Zend/zend_language_scanner.l"
+#line 1889 "Zend/zend_language_scanner.l"
{
zend_copy_value(zendlval, (yytext+1), (yyleng-1));
zendlval->type = IS_STRING;
return T_VARIABLE;
}
-#line 7723 "Zend/zend_language_scanner.c"
-yy839:
- YYDEBUG(839, *YYCURSOR);
+#line 7823 "Zend/zend_language_scanner.c"
+yy850:
+ YYDEBUG(850, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
-yy840:
- YYDEBUG(840, *YYCURSOR);
+yy851:
+ YYDEBUG(851, *YYCURSOR);
if (yybm[0+yych] & 32) {
- goto yy839;
+ goto yy850;
}
- goto yy821;
-yy841:
- YYDEBUG(841, *YYCURSOR);
+ goto yy832;
+yy852:
+ YYDEBUG(852, *YYCURSOR);
yych = *++YYCURSOR;
if (yybm[0+yych] & 128) {
- goto yy849;
+ goto yy860;
}
-yy842:
- YYDEBUG(842, *YYCURSOR);
+yy853:
+ YYDEBUG(853, *YYCURSOR);
YYCURSOR = YYMARKER;
- goto yy821;
-yy843:
- YYDEBUG(843, *YYCURSOR);
+ goto yy832;
+yy854:
+ YYDEBUG(854, *YYCURSOR);
yych = *++YYCURSOR;
if (yybm[0+yych] & 64) {
- goto yy847;
+ goto yy858;
}
- goto yy842;
-yy844:
- YYDEBUG(844, *YYCURSOR);
+ goto yy853;
+yy855:
+ YYDEBUG(855, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
- YYDEBUG(845, *YYCURSOR);
- if (yych <= '/') goto yy846;
- if (yych <= '9') goto yy844;
-yy846:
- YYDEBUG(846, *YYCURSOR);
+ YYDEBUG(856, *YYCURSOR);
+ if (yych <= '/') goto yy857;
+ if (yych <= '9') goto yy855;
+yy857:
+ YYDEBUG(857, *YYCURSOR);
yyleng = YYCURSOR - SCNG(yy_text);
-#line 1568 "Zend/zend_language_scanner.l"
+#line 1580 "Zend/zend_language_scanner.l"
{ /* Offset must be treated as a string */
zendlval->value.str.val = (char *)estrndup(yytext, yyleng);
zendlval->value.str.len = yyleng;
zendlval->type = IS_STRING;
return T_NUM_STRING;
}
-#line 7770 "Zend/zend_language_scanner.c"
-yy847:
- YYDEBUG(847, *YYCURSOR);
+#line 7870 "Zend/zend_language_scanner.c"
+yy858:
+ YYDEBUG(858, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
- YYDEBUG(848, *YYCURSOR);
+ YYDEBUG(859, *YYCURSOR);
if (yybm[0+yych] & 64) {
- goto yy847;
+ goto yy858;
}
- goto yy846;
-yy849:
- YYDEBUG(849, *YYCURSOR);
+ goto yy857;
+yy860:
+ YYDEBUG(860, *YYCURSOR);
++YYCURSOR;
YYFILL(1);
yych = *YYCURSOR;
- YYDEBUG(850, *YYCURSOR);
+ YYDEBUG(861, *YYCURSOR);
if (yybm[0+yych] & 128) {
- goto yy849;
+ goto yy860;
}
- goto yy846;
+ goto yy857;
}
}
-#line 2425 "Zend/zend_language_scanner.l"
+#line 2441 "Zend/zend_language_scanner.l"
}
diff --git a/Zend/zend_language_scanner.h b/Zend/zend_language_scanner.h
index 62ad8ddf91..05345b2cc3 100644
--- a/Zend/zend_language_scanner.h
+++ b/Zend/zend_language_scanner.h
@@ -31,6 +31,7 @@ typedef struct _zend_lex_state {
unsigned char *yy_limit;
int yy_state;
zend_stack state_stack;
+ zend_ptr_stack heredoc_label_stack;
zend_file_handle *in;
uint lineno;
@@ -50,6 +51,10 @@ typedef struct _zend_lex_state {
const zend_encoding *script_encoding;
} zend_lex_state;
+typedef struct _zend_heredoc_label {
+ char *label;
+ int length;
+} zend_heredoc_label;
BEGIN_EXTERN_C()
int zend_compare_file_handles(zend_file_handle *fh1, zend_file_handle *fh2);
diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l
index 0300b3208b..a4b5b32d96 100644
--- a/Zend/zend_language_scanner.l
+++ b/Zend/zend_language_scanner.l
@@ -178,22 +178,23 @@ static void yy_scan_buffer(char *str, unsigned int len TSRMLS_DC)
void startup_scanner(TSRMLS_D)
{
CG(parse_error) = 0;
- CG(heredoc) = NULL;
- CG(heredoc_len) = 0;
CG(doc_comment) = NULL;
CG(doc_comment_len) = 0;
zend_stack_init(&SCNG(state_stack));
+ zend_ptr_stack_init(&SCNG(heredoc_label_stack));
+}
+
+static void heredoc_label_dtor(zend_heredoc_label *heredoc_label) {
+ efree(heredoc_label->label);
}
void shutdown_scanner(TSRMLS_D)
{
- if (CG(heredoc)) {
- efree(CG(heredoc));
- CG(heredoc_len)=0;
- }
CG(parse_error) = 0;
- zend_stack_destroy(&SCNG(state_stack));
RESET_DOC_COMMENT();
+ zend_stack_destroy(&SCNG(state_stack));
+ zend_ptr_stack_clean(&SCNG(heredoc_label_stack), (void (*)(void *)) &heredoc_label_dtor, 1);
+ zend_ptr_stack_destroy(&SCNG(heredoc_label_stack));
}
ZEND_API void zend_save_lexical_state(zend_lex_state *lex_state TSRMLS_DC)
@@ -208,6 +209,9 @@ ZEND_API void zend_save_lexical_state(zend_lex_state *lex_state TSRMLS_DC)
lex_state->state_stack = SCNG(state_stack);
zend_stack_init(&SCNG(state_stack));
+ lex_state->heredoc_label_stack = SCNG(heredoc_label_stack);
+ zend_ptr_stack_init(&SCNG(heredoc_label_stack));
+
lex_state->in = SCNG(yy_in);
lex_state->yy_state = YYSTATE;
lex_state->filename = zend_get_compiled_filename(TSRMLS_C);
@@ -234,6 +238,10 @@ ZEND_API void zend_restore_lexical_state(zend_lex_state *lex_state TSRMLS_DC)
zend_stack_destroy(&SCNG(state_stack));
SCNG(state_stack) = lex_state->state_stack;
+ zend_ptr_stack_clean(&SCNG(heredoc_label_stack), (void (*)(void *)) &heredoc_label_dtor, 1);
+ zend_ptr_stack_destroy(&SCNG(heredoc_label_stack));
+ SCNG(heredoc_label_stack) = lex_state->heredoc_label_stack;
+
SCNG(yy_in) = lex_state->in;
YYSETCONDITION(lex_state->yy_state);
CG(zend_lineno) = lex_state->lineno;
@@ -251,11 +259,6 @@ ZEND_API void zend_restore_lexical_state(zend_lex_state *lex_state TSRMLS_DC)
SCNG(output_filter) = lex_state->output_filter;
SCNG(script_encoding) = lex_state->script_encoding;
- if (CG(heredoc)) {
- efree(CG(heredoc));
- CG(heredoc) = NULL;
- CG(heredoc_len) = 0;
- }
RESET_DOC_COMMENT();
}
@@ -1038,6 +1041,10 @@ NEWLINE ("\r"|"\n"|"\r\n")
return T_RETURN;
}
+<ST_IN_SCRIPTING>"yield" {
+ return T_YIELD;
+}
+
<ST_IN_SCRIPTING>"try" {
return T_TRY;
}
@@ -1046,6 +1053,10 @@ NEWLINE ("\r"|"\n"|"\r\n")
return T_CATCH;
}
+<ST_IN_SCRIPTING>"finally" {
+ return T_FINALLY;
+}
+
<ST_IN_SCRIPTING>"throw" {
return T_THROW;
}
@@ -1466,7 +1477,8 @@ NEWLINE ("\r"|"\n"|"\r\n")
}
-<ST_LOOKING_FOR_VARNAME>{LABEL} {
+<ST_LOOKING_FOR_VARNAME>{LABEL}[[}] {
+ yyless(yyleng - 1);
zend_copy_value(zendlval, yytext, yyleng);
zendlval->type = IS_STRING;
yy_pop_state(TSRMLS_C);
@@ -2109,38 +2121,35 @@ inline_html:
<ST_IN_SCRIPTING>b?"<<<"{TABS_AND_SPACES}({LABEL}|([']{LABEL}['])|(["]{LABEL}["])){NEWLINE} {
char *s;
int bprefix = (yytext[0] != '<') ? 1 : 0;
-
- /* save old heredoc label */
- Z_STRVAL_P(zendlval) = CG(heredoc);
- Z_STRLEN_P(zendlval) = CG(heredoc_len);
+ zend_heredoc_label *heredoc_label = emalloc(sizeof(zend_heredoc_label));
CG(zend_lineno)++;
- CG(heredoc_len) = yyleng-bprefix-3-1-(yytext[yyleng-2]=='\r'?1:0);
+ heredoc_label->length = yyleng-bprefix-3-1-(yytext[yyleng-2]=='\r'?1:0);
s = yytext+bprefix+3;
while ((*s == ' ') || (*s == '\t')) {
s++;
- CG(heredoc_len)--;
+ heredoc_label->length--;
}
if (*s == '\'') {
s++;
- CG(heredoc_len) -= 2;
+ heredoc_label->length -= 2;
BEGIN(ST_NOWDOC);
} else {
if (*s == '"') {
s++;
- CG(heredoc_len) -= 2;
+ heredoc_label->length -= 2;
}
BEGIN(ST_HEREDOC);
}
- CG(heredoc) = estrndup(s, CG(heredoc_len));
+ heredoc_label->label = estrndup(s, heredoc_label->length);
/* Check for ending label on the next line */
- if (CG(heredoc_len) < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, s, CG(heredoc_len))) {
- YYCTYPE *end = YYCURSOR + CG(heredoc_len);
+ if (heredoc_label->length < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, s, heredoc_label->length)) {
+ YYCTYPE *end = YYCURSOR + heredoc_label->length;
if (*end == ';') {
end++;
@@ -2151,6 +2160,8 @@ inline_html:
}
}
+ zend_ptr_stack_push(&SCNG(heredoc_label_stack), (void *) heredoc_label);
+
return T_START_HEREDOC;
}
@@ -2162,13 +2173,14 @@ inline_html:
<ST_END_HEREDOC>{ANY_CHAR} {
- YYCURSOR += CG(heredoc_len) - 1;
- yyleng = CG(heredoc_len);
+ zend_heredoc_label *heredoc_label = zend_ptr_stack_pop(&SCNG(heredoc_label_stack));
+
+ YYCURSOR += heredoc_label->length - 1;
+ yyleng = heredoc_label->length;
+
+ heredoc_label_dtor(heredoc_label);
+ efree(heredoc_label);
- Z_STRVAL_P(zendlval) = CG(heredoc);
- Z_STRLEN_P(zendlval) = CG(heredoc_len);
- CG(heredoc) = NULL;
- CG(heredoc_len) = 0;
BEGIN(ST_IN_SCRIPTING);
return T_END_HEREDOC;
}
@@ -2288,6 +2300,8 @@ double_quotes_scan_done:
<ST_HEREDOC>{ANY_CHAR} {
int newline = 0;
+ zend_heredoc_label *heredoc_label = zend_ptr_stack_top(&SCNG(heredoc_label_stack));
+
if (YYCURSOR > YYLIMIT) {
return 0;
}
@@ -2303,8 +2317,8 @@ double_quotes_scan_done:
/* fall through */
case '\n':
/* Check for ending label on the next line */
- if (IS_LABEL_START(*YYCURSOR) && CG(heredoc_len) < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, CG(heredoc), CG(heredoc_len))) {
- YYCTYPE *end = YYCURSOR + CG(heredoc_len);
+ if (IS_LABEL_START(*YYCURSOR) && heredoc_label->length < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, heredoc_label->label, heredoc_label->length)) {
+ YYCTYPE *end = YYCURSOR + heredoc_label->length;
if (*end == ';') {
end++;
@@ -2360,6 +2374,8 @@ heredoc_scan_done:
<ST_NOWDOC>{ANY_CHAR} {
int newline = 0;
+ zend_heredoc_label *heredoc_label = zend_ptr_stack_top(&SCNG(heredoc_label_stack));
+
if (YYCURSOR > YYLIMIT) {
return 0;
}
@@ -2375,8 +2391,8 @@ heredoc_scan_done:
/* fall through */
case '\n':
/* Check for ending label on the next line */
- if (IS_LABEL_START(*YYCURSOR) && CG(heredoc_len) < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, CG(heredoc), CG(heredoc_len))) {
- YYCTYPE *end = YYCURSOR + CG(heredoc_len);
+ if (IS_LABEL_START(*YYCURSOR) && heredoc_label->length < YYLIMIT - YYCURSOR && !memcmp(YYCURSOR, heredoc_label->label, heredoc_label->length)) {
+ YYCTYPE *end = YYCURSOR + heredoc_label->length;
if (*end == ';') {
end++;
diff --git a/Zend/zend_language_scanner_defs.h b/Zend/zend_language_scanner_defs.h
index 5c30d3dd9b..70ce8b890c 100644
--- a/Zend/zend_language_scanner_defs.h
+++ b/Zend/zend_language_scanner_defs.h
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.13.5 on Sun Jun 16 14:52:22 2013 */
+/* Generated by re2c 0.13.5 on Sun Dec 22 13:03:33 2013 */
#line 3 "Zend/zend_language_scanner_defs.h"
enum YYCONDTYPE {
diff --git a/Zend/zend_llist.c b/Zend/zend_llist.c
index f8c20e7b76..ad74bd56cb 100644
--- a/Zend/zend_llist.c
+++ b/Zend/zend_llist.c
@@ -91,15 +91,13 @@ ZEND_API void zend_llist_prepend_element(zend_llist *l, void *element)
ZEND_API void zend_llist_del_element(zend_llist *l, void *element, int (*compare)(void *element1, void *element2))
{
zend_llist_element *current=l->head;
- zend_llist_element *next;
while (current) {
- next = current->next;
if (compare(current->data, element)) {
DEL_LLIST_ELEMENT(current, l);
break;
}
- current = next;
+ current = current->next;
}
}
diff --git a/Zend/zend_modules.h b/Zend/zend_modules.h
index 123fdf9f3e..18cf05cf31 100644
--- a/Zend/zend_modules.h
+++ b/Zend/zend_modules.h
@@ -33,7 +33,7 @@
#define ZEND_MODULE_INFO_FUNC_ARGS zend_module_entry *zend_module TSRMLS_DC
#define ZEND_MODULE_INFO_FUNC_ARGS_PASSTHRU zend_module TSRMLS_CC
-#define ZEND_MODULE_API_NO 20100525
+#define ZEND_MODULE_API_NO 20121212
#ifdef ZTS
#define USING_ZTS 1
#else
diff --git a/Zend/zend_multiply.h b/Zend/zend_multiply.h
index 5d03125b29..74dc7d1452 100644
--- a/Zend/zend_multiply.h
+++ b/Zend/zend_multiply.h
@@ -13,7 +13,7 @@
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Sascha Schumann <sascha@schumann.cx> |
- | Ard Biesheuvel <ard@ard.nu> |
+ | Ard Biesheuvel <ard.biesheuvel@linaro.org> |
+----------------------------------------------------------------------+
*/
@@ -43,6 +43,31 @@
else (lval) = __tmpvar; \
} while (0)
+#elif defined(__arm__) && defined(__GNUC__)
+
+#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \
+ long __tmpvar; \
+ __asm__("smull %0, %1, %2, %3\n" \
+ "sub %1, %1, %0, asr #31" \
+ : "=r"(__tmpvar), "=r"(usedval) \
+ : "r"(a), "r"(b)); \
+ if (usedval) (dval) = (double) (a) * (double) (b); \
+ else (lval) = __tmpvar; \
+} while (0)
+
+#elif defined(__aarch64__) && defined(__GNUC__)
+
+#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \
+ long __tmpvar; \
+ __asm__("mul %0, %2, %3\n" \
+ "smulh %1, %2, %3\n" \
+ "sub %1, %1, %0, asr #63\n" \
+ : "=X"(__tmpvar), "=X"(usedval) \
+ : "X"(a), "X"(b)); \
+ if (usedval) (dval) = (double) (a) * (double) (b); \
+ else (lval) = __tmpvar; \
+} while (0)
+
#elif SIZEOF_LONG == 4 && defined(HAVE_ZEND_LONG64)
#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \
@@ -58,15 +83,15 @@
#else
-#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \
- long __lres = (a) * (b); \
- long double __dres = (long double)(a) * (long double)(b); \
- long double __delta = (long double) __lres - __dres; \
- if ( ((usedval) = (( __dres + __delta ) != __dres))) { \
- (dval) = __dres; \
- } else { \
- (lval) = __lres; \
- } \
+#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \
+ long __lres = (a) * (b); \
+ long double __dres = (long double)(a) * (long double)(b); \
+ long double __delta = (long double) __lres - __dres; \
+ if ( ((usedval) = (( __dres + __delta ) != __dres))) { \
+ (dval) = __dres; \
+ } else { \
+ (lval) = __lres; \
+ } \
} while (0)
#endif
diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c
index 054c1bf553..093951eeca 100644
--- a/Zend/zend_object_handlers.c
+++ b/Zend/zend_object_handlers.c
@@ -363,9 +363,10 @@ ZEND_API int zend_check_property_access(zend_object *zobj, const char *prop_info
zend_property_info *property_info;
const char *class_name, *prop_name;
zval member;
+ int prop_name_len;
- zend_unmangle_property_name(prop_info_name, prop_info_name_len, &class_name, &prop_name);
- ZVAL_STRING(&member, prop_name, 0);
+ zend_unmangle_property_name_ex(prop_info_name, prop_info_name_len, &class_name, &prop_name, &prop_name_len);
+ ZVAL_STRINGL(&member, prop_name, prop_name_len, 0);
property_info = zend_get_property_info_quick(zobj->ce, &member, 1, NULL TSRMLS_CC);
if (!property_info) {
return FAILURE;
@@ -713,7 +714,7 @@ static int zend_std_has_dimension(zval *object, zval *offset, int check_empty TS
}
/* }}} */
-static zval **zend_std_get_property_ptr_ptr(zval *object, zval *member, const zend_literal *key TSRMLS_DC) /* {{{ */
+static zval **zend_std_get_property_ptr_ptr(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */
{
zend_object *zobj;
zval tmp_member;
@@ -753,7 +754,9 @@ static zval **zend_std_get_property_ptr_ptr(zval *object, zval *member, const ze
/* we don't have access controls - will just add it */
new_zval = &EG(uninitialized_zval);
-/* zend_error(E_NOTICE, "Undefined property: %s", Z_STRVAL_P(member)); */
+ if(UNEXPECTED(type == BP_VAR_RW || type == BP_VAR_R)) {
+ zend_error(E_NOTICE, "Undefined property: %s::$%s", zobj->ce->name, Z_STRVAL_P(member));
+ }
Z_ADDREF_P(new_zval);
if (EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0) &&
property_info->offset >= 0) {
diff --git a/Zend/zend_object_handlers.h b/Zend/zend_object_handlers.h
index cfc0933d22..715ba1ea65 100644
--- a/Zend/zend_object_handlers.h
+++ b/Zend/zend_object_handlers.h
@@ -50,7 +50,7 @@ typedef void (*zend_object_write_dimension_t)(zval *object, zval *offset, zval *
/* Used to create pointer to the property of the object, for future direct r/w access */
-typedef zval **(*zend_object_get_property_ptr_ptr_t)(zval *object, zval *member, const struct _zend_literal *key TSRMLS_DC);
+typedef zval **(*zend_object_get_property_ptr_ptr_t)(zval *object, zval *member, int type, const struct _zend_literal *key TSRMLS_DC);
/* Used to set object value. Can be used to override assignments and scalar
write ops (like ++, +=) on the object */
diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c
index 52b68a9191..025e8faa3c 100644
--- a/Zend/zend_opcode.c
+++ b/Zend/zend_opcode.c
@@ -70,6 +70,9 @@ void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_siz
op_array->T = 0;
+ op_array->nested_calls = 0;
+ op_array->used_stack = 0;
+
op_array->function_name = NULL;
op_array->filename = zend_get_compiled_filename(TSRMLS_C);
op_array->doc_comment = NULL;
@@ -87,6 +90,7 @@ void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_siz
op_array->static_variables = NULL;
op_array->last_try_catch = 0;
+ op_array->has_finally_block = 0;
op_array->this_var = -1;
@@ -480,6 +484,175 @@ static void zend_extension_op_array_handler(zend_extension *extension, zend_op_a
}
}
+static void zend_check_finally_breakout(zend_op_array *op_array, zend_uint op_num, zend_uint dst_num TSRMLS_DC)
+{
+ zend_uint i;
+
+ for (i = 0; i < op_array->last_try_catch; i++) {
+ if ((op_num < op_array->try_catch_array[i].finally_op ||
+ op_num >= op_array->try_catch_array[i].finally_end)
+ && (dst_num >= op_array->try_catch_array[i].finally_op &&
+ dst_num <= op_array->try_catch_array[i].finally_end)) {
+ CG(in_compilation) = 1;
+ CG(active_op_array) = op_array;
+ CG(zend_lineno) = op_array->opcodes[op_num].lineno;
+ zend_error_noreturn(E_COMPILE_ERROR, "jump into a finally block is disallowed");
+ } else if ((op_num >= op_array->try_catch_array[i].finally_op
+ && op_num <= op_array->try_catch_array[i].finally_end)
+ && (dst_num > op_array->try_catch_array[i].finally_end
+ || dst_num < op_array->try_catch_array[i].finally_op)) {
+ CG(in_compilation) = 1;
+ CG(active_op_array) = op_array;
+ CG(zend_lineno) = op_array->opcodes[op_num].lineno;
+ zend_error_noreturn(E_COMPILE_ERROR, "jump out of a finally block is disallowed");
+ }
+ }
+}
+
+static void zend_resolve_finally_call(zend_op_array *op_array, zend_uint op_num, zend_uint dst_num TSRMLS_DC)
+{
+ zend_uint start_op;
+ zend_op *opline;
+ zend_uint i = op_array->last_try_catch;
+
+ if (dst_num != (zend_uint)-1) {
+ zend_check_finally_breakout(op_array, op_num, dst_num TSRMLS_CC);
+ }
+
+ /* the backward order is mater */
+ while (i > 0) {
+ i--;
+ if (op_array->try_catch_array[i].finally_op &&
+ op_num >= op_array->try_catch_array[i].try_op &&
+ op_num < op_array->try_catch_array[i].finally_op - 1 &&
+ (dst_num < op_array->try_catch_array[i].try_op ||
+ dst_num > op_array->try_catch_array[i].finally_end)) {
+ /* we have a jump out of try block that needs executing finally */
+
+ /* generate a FAST_CALL to finally block */
+ start_op = get_next_op_number(op_array);
+
+ opline = get_next_op(op_array TSRMLS_CC);
+ opline->opcode = ZEND_FAST_CALL;
+ SET_UNUSED(opline->op1);
+ SET_UNUSED(opline->op2);
+ opline->op1.opline_num = op_array->try_catch_array[i].finally_op;
+ if (op_array->try_catch_array[i].catch_op) {
+ opline->extended_value = 1;
+ opline->op2.opline_num = op_array->try_catch_array[i].catch_op;
+ }
+
+ /* generate a sequence of FAST_CALL to upward finally block */
+ while (i > 0) {
+ i--;
+ if (op_array->try_catch_array[i].finally_op &&
+ op_num >= op_array->try_catch_array[i].try_op &&
+ op_num < op_array->try_catch_array[i].finally_op - 1 &&
+ (dst_num < op_array->try_catch_array[i].try_op ||
+ dst_num > op_array->try_catch_array[i].finally_end)) {
+
+ opline = get_next_op(op_array TSRMLS_CC);
+ opline->opcode = ZEND_FAST_CALL;
+ SET_UNUSED(opline->op1);
+ SET_UNUSED(opline->op2);
+ opline->op1.opline_num = op_array->try_catch_array[i].finally_op;
+ }
+ }
+
+ /* Finish the sequence with original opcode */
+ opline = get_next_op(op_array TSRMLS_CC);
+ *opline = op_array->opcodes[op_num];
+
+ /* Replace original opcode with jump to this sequence */
+ opline = op_array->opcodes + op_num;
+ opline->opcode = ZEND_JMP;
+ SET_UNUSED(opline->op1);
+ SET_UNUSED(opline->op2);
+ opline->op1.opline_num = start_op;
+
+ break;
+ }
+ }
+}
+
+static void zend_resolve_finally_ret(zend_op_array *op_array, zend_uint op_num TSRMLS_DC)
+{
+ int i;
+ zend_uint catch_op_num = 0, finally_op_num = 0;
+
+ for (i = 0; i < op_array->last_try_catch; i++) {
+ if (op_array->try_catch_array[i].try_op > op_num) {
+ break;
+ }
+ if (op_num < op_array->try_catch_array[i].finally_op) {
+ finally_op_num = op_array->try_catch_array[i].finally_op;
+ }
+ if (op_num < op_array->try_catch_array[i].catch_op) {
+ catch_op_num = op_array->try_catch_array[i].catch_op;
+ }
+ }
+
+ if (finally_op_num && (!catch_op_num || catch_op_num >= finally_op_num)) {
+ /* in case of unhandled exception return to upward finally block */
+ op_array->opcodes[op_num].extended_value = ZEND_FAST_RET_TO_FINALLY;
+ op_array->opcodes[op_num].op2.opline_num = finally_op_num;
+ } else if (catch_op_num) {
+ /* in case of unhandled exception return to upward catch block */
+ op_array->opcodes[op_num].extended_value = ZEND_FAST_RET_TO_CATCH;
+ op_array->opcodes[op_num].op2.opline_num = catch_op_num;
+ }
+}
+
+static void zend_resolve_finally_calls(zend_op_array *op_array TSRMLS_DC)
+{
+ zend_uint i;
+ zend_op *opline;
+
+ for (i = 0; i < op_array->last; i++) {
+ opline = op_array->opcodes + i;
+ switch (opline->opcode) {
+ case ZEND_RETURN:
+ case ZEND_RETURN_BY_REF:
+ case ZEND_GENERATOR_RETURN:
+ zend_resolve_finally_call(op_array, i, (zend_uint)-1 TSRMLS_CC);
+ break;
+ case ZEND_BRK:
+ case ZEND_CONT:
+ {
+ int nest_levels, array_offset;
+ zend_brk_cont_element *jmp_to;
+
+ nest_levels = Z_LVAL(op_array->literals[opline->op2.constant].constant);
+ array_offset = opline->op1.opline_num;
+ do {
+ jmp_to = &op_array->brk_cont_array[array_offset];
+ if (nest_levels > 1) {
+ array_offset = jmp_to->parent;
+ }
+ } while (--nest_levels > 0);
+ zend_resolve_finally_call(op_array, i, opline->opcode == ZEND_BRK ? jmp_to->brk : jmp_to->cont TSRMLS_CC);
+ break;
+ }
+ case ZEND_GOTO:
+ if (Z_TYPE(op_array->literals[opline->op2.constant].constant) != IS_LONG) {
+ zend_uint num = opline->op2.constant;
+ opline->op2.zv = &op_array->literals[opline->op2.constant].constant;
+ zend_resolve_goto_label(op_array, opline, 1 TSRMLS_CC);
+ opline->op2.constant = num;
+ }
+ /* break omitted intentionally */
+ case ZEND_JMP:
+ zend_resolve_finally_call(op_array, i, opline->op1.opline_num TSRMLS_CC);
+ break;
+ case ZEND_FAST_RET:
+ zend_resolve_finally_ret(op_array, i TSRMLS_CC);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
ZEND_API int pass_two(zend_op_array *op_array TSRMLS_DC)
{
zend_op *opline, *end;
@@ -487,6 +660,9 @@ ZEND_API int pass_two(zend_op_array *op_array TSRMLS_DC)
if (op_array->type!=ZEND_USER_FUNCTION && op_array->type!=ZEND_EVAL_CODE) {
return 0;
}
+ if (op_array->has_finally_block) {
+ zend_resolve_finally_calls(op_array TSRMLS_CC);
+ }
if (CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO) {
zend_update_extended_info(op_array TSRMLS_CC);
}
@@ -523,6 +699,7 @@ ZEND_API int pass_two(zend_op_array *op_array TSRMLS_DC)
}
/* break omitted intentionally */
case ZEND_JMP:
+ case ZEND_FAST_CALL:
opline->op1.jmp_addr = &op_array->opcodes[opline->op1.opline_num];
break;
case ZEND_JMPZ:
@@ -533,6 +710,17 @@ ZEND_API int pass_two(zend_op_array *op_array TSRMLS_DC)
case ZEND_JMP_SET_VAR:
opline->op2.jmp_addr = &op_array->opcodes[opline->op2.opline_num];
break;
+ case ZEND_RETURN:
+ case ZEND_RETURN_BY_REF:
+ if (op_array->fn_flags & ZEND_ACC_GENERATOR) {
+ if (opline->op1_type != IS_CONST || Z_TYPE_P(opline->op1.zv) != IS_NULL) {
+ CG(zend_lineno) = opline->lineno;
+ zend_error(E_COMPILE_ERROR, "Generators cannot return values using \"return\"");
+ }
+
+ opline->opcode = ZEND_GENERATOR_RETURN;
+ }
+ break;
}
ZEND_VM_SET_OPCODE_HANDLER(opline);
opline++;
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
index a791a36d78..683ab3c5cf 100644
--- a/Zend/zend_operators.c
+++ b/Zend/zend_operators.c
@@ -42,6 +42,43 @@ static _locale_t current_locale = NULL;
#define TYPE_PAIR(t1,t2) (((t1) << 4) | (t2))
+static const unsigned char tolower_map[256] = {
+0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
+0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
+0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+0x40,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
+0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x5b,0x5c,0x5d,0x5e,0x5f,
+0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
+0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,
+0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,
+0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,
+0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,
+0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf,
+0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,
+0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf,
+0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,
+0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
+};
+
+#define zend_tolower_ascii(c) (tolower_map[(unsigned char)(c)])
+
+/**
+ * Functions using locale lowercase:
+ zend_binary_strncasecmp_l
+ zend_binary_strcasecmp_l
+ zend_binary_zval_strcasecmp
+ zend_binary_zval_strncasecmp
+ string_compare_function_ex
+ string_case_compare_function
+ * Functions using ascii lowercase:
+ zend_str_tolower_copy
+ zend_str_tolower_dup
+ zend_str_tolower
+ zend_binary_strcasecmp
+ zend_binary_strncasecmp
+ */
+
ZEND_API int zend_atoi(const char *str, int str_len) /* {{{ */
{
int retval;
@@ -535,6 +572,24 @@ ZEND_API void convert_to_boolean(zval *op) /* {{{ */
}
/* }}} */
+ZEND_API void _convert_to_cstring(zval *op ZEND_FILE_LINE_DC) /* {{{ */
+{
+ double dval;
+ switch (Z_TYPE_P(op)) {
+ case IS_DOUBLE: {
+ TSRMLS_FETCH();
+ dval = Z_DVAL_P(op);
+ Z_STRLEN_P(op) = zend_spprintf(&Z_STRVAL_P(op), 0, "%.*H", (int) EG(precision), dval);
+ /* %H already handles removing trailing zeros from the fractional part, yay */
+ break;
+ }
+ default:
+ _convert_to_string(op ZEND_FILE_LINE_CC);
+ }
+ Z_TYPE_P(op) = IS_STRING;
+}
+/* }}} */
+
ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC) /* {{{ */
{
long lval;
@@ -1911,7 +1966,7 @@ ZEND_API char *zend_str_tolower_copy(char *dest, const char *source, unsigned in
register unsigned char *end = str + length;
while (str < end) {
- *result++ = zend_tolower((int)*str++);
+ *result++ = zend_tolower_ascii(*str++);
}
*result = '\0';
@@ -1931,7 +1986,7 @@ ZEND_API void zend_str_tolower(char *str, unsigned int length) /* {{{ */
register unsigned char *end = p + length;
while (p < end) {
- *p = zend_tolower((int)*p);
+ *p = zend_tolower_ascii(*p);
p++;
}
}
@@ -1980,6 +2035,49 @@ ZEND_API int zend_binary_strcasecmp(const char *s1, uint len1, const char *s2, u
len = MIN(len1, len2);
while (len--) {
+ c1 = zend_tolower_ascii(*(unsigned char *)s1++);
+ c2 = zend_tolower_ascii(*(unsigned char *)s2++);
+ if (c1 != c2) {
+ return c1 - c2;
+ }
+ }
+
+ return len1 - len2;
+}
+/* }}} */
+
+ZEND_API int zend_binary_strncasecmp(const char *s1, uint len1, const char *s2, uint len2, uint length) /* {{{ */
+{
+ int len;
+ int c1, c2;
+
+ if (s1 == s2) {
+ return 0;
+ }
+ len = MIN(length, MIN(len1, len2));
+ while (len--) {
+ c1 = zend_tolower_ascii(*(unsigned char *)s1++);
+ c2 = zend_tolower_ascii(*(unsigned char *)s2++);
+ if (c1 != c2) {
+ return c1 - c2;
+ }
+ }
+
+ return MIN(length, len1) - MIN(length, len2);
+}
+/* }}} */
+
+ZEND_API int zend_binary_strcasecmp_l(const char *s1, uint len1, const char *s2, uint len2) /* {{{ */
+{
+ int len;
+ int c1, c2;
+
+ if (s1 == s2) {
+ return 0;
+ }
+
+ len = MIN(len1, len2);
+ while (len--) {
c1 = zend_tolower((int)*(unsigned char *)s1++);
c2 = zend_tolower((int)*(unsigned char *)s2++);
if (c1 != c2) {
@@ -1991,7 +2089,7 @@ ZEND_API int zend_binary_strcasecmp(const char *s1, uint len1, const char *s2, u
}
/* }}} */
-ZEND_API int zend_binary_strncasecmp(const char *s1, uint len1, const char *s2, uint len2, uint length) /* {{{ */
+ZEND_API int zend_binary_strncasecmp_l(const char *s1, uint len1, const char *s2, uint len2, uint length) /* {{{ */
{
int len;
int c1, c2;
@@ -2026,13 +2124,13 @@ ZEND_API int zend_binary_zval_strncmp(zval *s1, zval *s2, zval *s3) /* {{{ */
ZEND_API int zend_binary_zval_strcasecmp(zval *s1, zval *s2) /* {{{ */
{
- return zend_binary_strcasecmp(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2));
+ return zend_binary_strcasecmp_l(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2));
}
/* }}} */
ZEND_API int zend_binary_zval_strncasecmp(zval *s1, zval *s2, zval *s3) /* {{{ */
{
- return zend_binary_strncasecmp(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2), Z_LVAL_P(s3));
+ return zend_binary_strncasecmp_l(Z_STRVAL_P(s1), Z_STRLEN_P(s1), Z_STRVAL_P(s2), Z_STRLEN_P(s2), Z_LVAL_P(s3));
}
/* }}} */
@@ -2040,8 +2138,8 @@ ZEND_API void zendi_smart_strcmp(zval *result, zval *s1, zval *s2) /* {{{ */
{
int ret1, ret2;
int oflow1, oflow2;
- long lval1, lval2;
- double dval1, dval2;
+ long lval1 = 0, lval2 = 0;
+ double dval1 = 0.0, dval2 = 0.0;
if ((ret1=is_numeric_string_ex(Z_STRVAL_P(s1), Z_STRLEN_P(s1), &lval1, &dval1, 0, &oflow1)) &&
(ret2=is_numeric_string_ex(Z_STRVAL_P(s2), Z_STRLEN_P(s2), &lval2, &dval2, 0, &oflow2))) {
@@ -2067,7 +2165,7 @@ ZEND_API void zendi_smart_strcmp(zval *result, zval *s1, zval *s2) /* {{{ */
} else if (ret2!=IS_DOUBLE) {
if (oflow1) {
ZVAL_LONG(result, oflow1);
- return;
+ return;
}
dval2 = (double) lval2;
} else if (dval1 == dval2 && !zend_finite(dval1)) {
diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h
index 94cb924f5a..976cf33ca0 100644
--- a/Zend/zend_operators.h
+++ b/Zend/zend_operators.h
@@ -26,6 +26,10 @@
#include <math.h>
#include <assert.h>
+#ifdef __GNUC__
+#include <stddef.h>
+#endif
+
#ifdef HAVE_IEEEFP_H
#include <ieeefp.h>
#endif
@@ -68,22 +72,40 @@ END_EXTERN_C()
#if ZEND_DVAL_TO_LVAL_CAST_OK
# define zend_dval_to_lval(d) ((long) (d))
-#elif SIZEOF_LONG == 4 && defined(HAVE_ZEND_LONG64)
+#elif SIZEOF_LONG == 4
static zend_always_inline long zend_dval_to_lval(double d)
{
if (d > LONG_MAX || d < LONG_MIN) {
- return (long)(unsigned long)(zend_long64) d;
+ double two_pow_32 = pow(2., 32.),
+ dmod;
+
+ dmod = fmod(d, two_pow_32);
+ if (dmod < 0) {
+ /* we're going to make this number positive; call ceil()
+ * to simulate rounding towards 0 of the negative number */
+ dmod = ceil(dmod) + two_pow_32;
+ }
+ return (long)(unsigned long)dmod;
}
- return (long) d;
+ return (long)d;
}
#else
static zend_always_inline long zend_dval_to_lval(double d)
{
/* >= as (double)LONG_MAX is outside signed range */
- if (d >= LONG_MAX) {
- return (long)(unsigned long) d;
+ if (d >= LONG_MAX || d < LONG_MIN) {
+ double two_pow_64 = pow(2., 64.),
+ dmod;
+
+ dmod = fmod(d, two_pow_64);
+ if (dmod < 0) {
+ /* no need to call ceil; original double must have had no
+ * fractional part, hence dmod does not have one either */
+ dmod += two_pow_64;
+ }
+ return (long)(unsigned long)dmod;
}
- return (long) d;
+ return (long)d;
}
#endif
/* }}} */
@@ -110,7 +132,7 @@ static inline zend_uchar is_numeric_string_ex(const char *str, int length, long
{
const char *ptr;
int base = 10, digits = 0, dp_or_e = 0;
- double local_dval;
+ double local_dval = 0.0;
zend_uchar type;
if (!length) {
@@ -302,6 +324,7 @@ ZEND_API int increment_function(zval *op1);
ZEND_API int decrement_function(zval *op2);
ZEND_API void convert_scalar_to_number(zval *op TSRMLS_DC);
+ZEND_API void _convert_to_cstring(zval *op ZEND_FILE_LINE_DC);
ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC);
ZEND_API void convert_to_long(zval *op);
ZEND_API void convert_to_double(zval *op);
@@ -315,6 +338,7 @@ ZEND_API void multi_convert_to_double_ex(int argc, ...);
ZEND_API void multi_convert_to_string_ex(int argc, ...);
ZEND_API int add_char_to_string(zval *result, const zval *op1, const zval *op2);
ZEND_API int add_string_to_string(zval *result, const zval *op1, const zval *op2);
+#define convert_to_cstring(op) if ((op)->type != IS_STRING) { _convert_to_cstring((op) ZEND_FILE_LINE_CC); }
#define convert_to_string(op) if ((op)->type != IS_STRING) { _convert_to_string((op) ZEND_FILE_LINE_CC); }
ZEND_API double zend_string_to_double(const char *number, zend_uint length);
@@ -341,6 +365,7 @@ ZEND_API int zend_binary_strcmp(const char *s1, uint len1, const char *s2, uint
ZEND_API int zend_binary_strncmp(const char *s1, uint len1, const char *s2, uint len2, uint length);
ZEND_API int zend_binary_strcasecmp(const char *s1, uint len1, const char *s2, uint len2);
ZEND_API int zend_binary_strncasecmp(const char *s1, uint len1, const char *s2, uint len2, uint length);
+ZEND_API int zend_binary_strncasecmp_l(const char *s1, uint len1, const char *s2, uint len2, uint length);
ZEND_API void zendi_smart_strcmp(zval *result, zval *s1, zval *s2);
ZEND_API void zend_compare_symbol_tables(zval *result, HashTable *ht1, HashTable *ht2 TSRMLS_DC);
@@ -474,6 +499,10 @@ ZEND_API void zend_update_current_locale(void);
#define zend_update_current_locale()
#endif
+/* The offset in bytes between the value and type fields of a zval */
+#define ZVAL_OFFSETOF_TYPE \
+ (offsetof(zval,type) - offsetof(zval,value))
+
static zend_always_inline int fast_increment_function(zval *op1)
{
if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
@@ -483,20 +512,26 @@ static zend_always_inline int fast_increment_function(zval *op1)
"jno 0f\n\t"
"movl $0x0, (%0)\n\t"
"movl $0x41e00000, 0x4(%0)\n\t"
- "movb $0x2,0xc(%0)\n"
+ "movb %1, %c2(%0)\n"
"0:"
:
- : "r"(op1));
+ : "r"(&op1->value),
+ "n"(IS_DOUBLE),
+ "n"(ZVAL_OFFSETOF_TYPE)
+ : "cc");
#elif defined(__GNUC__) && defined(__x86_64__)
__asm__(
"incq (%0)\n\t"
"jno 0f\n\t"
"movl $0x0, (%0)\n\t"
"movl $0x43e00000, 0x4(%0)\n\t"
- "movb $0x2,0x14(%0)\n"
+ "movb %1, %c2(%0)\n"
"0:"
:
- : "r"(op1));
+ : "r"(&op1->value),
+ "n"(IS_DOUBLE),
+ "n"(ZVAL_OFFSETOF_TYPE)
+ : "cc");
#else
if (UNEXPECTED(Z_LVAL_P(op1) == LONG_MAX)) {
/* switch to double */
@@ -520,20 +555,26 @@ static zend_always_inline int fast_decrement_function(zval *op1)
"jno 0f\n\t"
"movl $0x00200000, (%0)\n\t"
"movl $0xc1e00000, 0x4(%0)\n\t"
- "movb $0x2,0xc(%0)\n"
+ "movb %1,%c2(%0)\n"
"0:"
:
- : "r"(op1));
+ : "r"(&op1->value),
+ "n"(IS_DOUBLE),
+ "n"(ZVAL_OFFSETOF_TYPE)
+ : "cc");
#elif defined(__GNUC__) && defined(__x86_64__)
__asm__(
"decq (%0)\n\t"
"jno 0f\n\t"
"movl $0x00000000, (%0)\n\t"
"movl $0xc3e00000, 0x4(%0)\n\t"
- "movb $0x2,0x14(%0)\n"
+ "movb %1,%c2(%0)\n"
"0:"
:
- : "r"(op1));
+ : "r"(&op1->value),
+ "n"(IS_DOUBLE),
+ "n"(ZVAL_OFFSETOF_TYPE)
+ : "cc");
#else
if (UNEXPECTED(Z_LVAL_P(op1) == LONG_MIN)) {
/* switch to double */
@@ -558,40 +599,46 @@ static zend_always_inline int fast_add_function(zval *result, zval *op1, zval *o
"addl (%2), %%eax\n\t"
"jo 0f\n\t"
"movl %%eax, (%0)\n\t"
- "movb $0x1,0xc(%0)\n\t"
+ "movb %3, %c5(%0)\n\t"
"jmp 1f\n"
"0:\n\t"
"fildl (%1)\n\t"
"fildl (%2)\n\t"
"faddp %%st, %%st(1)\n\t"
- "movb $0x2,0xc(%0)\n\t"
+ "movb %4, %c5(%0)\n\t"
"fstpl (%0)\n"
"1:"
:
- : "r"(result),
- "r"(op1),
- "r"(op2)
- : "eax");
+ : "r"(&result->value),
+ "r"(&op1->value),
+ "r"(&op2->value),
+ "n"(IS_LONG),
+ "n"(IS_DOUBLE),
+ "n"(ZVAL_OFFSETOF_TYPE)
+ : "eax","cc");
#elif defined(__GNUC__) && defined(__x86_64__)
__asm__(
"movq (%1), %%rax\n\t"
"addq (%2), %%rax\n\t"
"jo 0f\n\t"
"movq %%rax, (%0)\n\t"
- "movb $0x1,0x14(%0)\n\t"
+ "movb %3, %c5(%0)\n\t"
"jmp 1f\n"
"0:\n\t"
"fildq (%1)\n\t"
"fildq (%2)\n\t"
"faddp %%st, %%st(1)\n\t"
- "movb $0x2,0x14(%0)\n\t"
+ "movb %4, %c5(%0)\n\t"
"fstpl (%0)\n"
"1:"
:
- : "r"(result),
- "r"(op1),
- "r"(op2)
- : "rax");
+ : "r"(&result->value),
+ "r"(&op1->value),
+ "r"(&op2->value),
+ "n"(IS_LONG),
+ "n"(IS_DOUBLE),
+ "n"(ZVAL_OFFSETOF_TYPE)
+ : "rax","cc");
#else
/*
* 'result' may alias with op1 or op2, so we need to
@@ -638,7 +685,7 @@ static zend_always_inline int fast_sub_function(zval *result, zval *op1, zval *o
"subl (%2), %%eax\n\t"
"jo 0f\n\t"
"movl %%eax, (%0)\n\t"
- "movb $0x1,0xc(%0)\n\t"
+ "movb %3, %c5(%0)\n\t"
"jmp 1f\n"
"0:\n\t"
"fildl (%2)\n\t"
@@ -648,21 +695,24 @@ static zend_always_inline int fast_sub_function(zval *result, zval *op1, zval *o
#else
"fsubp %%st, %%st(1)\n\t"
#endif
- "movb $0x2,0xc(%0)\n\t"
+ "movb %4, %c5(%0)\n\t"
"fstpl (%0)\n"
"1:"
:
- : "r"(result),
- "r"(op1),
- "r"(op2)
- : "eax");
+ : "r"(&result->value),
+ "r"(&op1->value),
+ "r"(&op2->value),
+ "n"(IS_LONG),
+ "n"(IS_DOUBLE),
+ "n"(ZVAL_OFFSETOF_TYPE)
+ : "eax","cc");
#elif defined(__GNUC__) && defined(__x86_64__)
__asm__(
"movq (%1), %%rax\n\t"
"subq (%2), %%rax\n\t"
"jo 0f\n\t"
"movq %%rax, (%0)\n\t"
- "movb $0x1,0x14(%0)\n\t"
+ "movb %3, %c5(%0)\n\t"
"jmp 1f\n"
"0:\n\t"
"fildq (%2)\n\t"
@@ -672,14 +722,17 @@ static zend_always_inline int fast_sub_function(zval *result, zval *op1, zval *o
#else
"fsubp %%st, %%st(1)\n\t"
#endif
- "movb $0x2,0x14(%0)\n\t"
+ "movb %4, %c5(%0)\n\t"
"fstpl (%0)\n"
"1:"
:
- : "r"(result),
- "r"(op1),
- "r"(op2)
- : "rax");
+ : "r"(&result->value),
+ "r"(&op1->value),
+ "r"(&op2->value),
+ "n"(IS_LONG),
+ "n"(IS_DOUBLE),
+ "n"(ZVAL_OFFSETOF_TYPE)
+ : "rax","cc");
#else
Z_LVAL_P(result) = Z_LVAL_P(op1) - Z_LVAL_P(op2);
diff --git a/Zend/zend_ptr_stack.c b/Zend/zend_ptr_stack.c
index acdb800ca7..bb85a2cc26 100644
--- a/Zend/zend_ptr_stack.c
+++ b/Zend/zend_ptr_stack.c
@@ -110,7 +110,6 @@ ZEND_API int zend_ptr_stack_num_elements(zend_ptr_stack *stack)
{
return stack->top;
}
-
/*
* Local variables:
* tab-width: 4
diff --git a/Zend/zend_ptr_stack.h b/Zend/zend_ptr_stack.h
index 455aa63b4c..ecd7b7042a 100644
--- a/Zend/zend_ptr_stack.h
+++ b/Zend/zend_ptr_stack.h
@@ -111,6 +111,11 @@ static zend_always_inline void *zend_ptr_stack_pop(zend_ptr_stack *stack)
return *(--stack->top_element);
}
+static inline void *zend_ptr_stack_top(zend_ptr_stack *stack)
+{
+ return stack->elements[stack->top - 1];
+}
+
#endif /* ZEND_PTR_STACK_H */
/*
diff --git a/Zend/zend_qsort.c b/Zend/zend_qsort.c
index b5799897dd..ea577e1c07 100644
--- a/Zend/zend_qsort.c
+++ b/Zend/zend_qsort.c
@@ -19,6 +19,7 @@
/* $Id$ */
#include "zend.h"
+#include "zend_qsort.h"
#include <limits.h>
@@ -53,7 +54,7 @@ static void _zend_qsort_swap(void *a, void *b, size_t siz)
}
}
-ZEND_API void zend_qsort(void *base, size_t nmemb, size_t siz, compare_func_t compare TSRMLS_DC)
+ZEND_API void zend_qsort_r(void *base, size_t nmemb, size_t siz, compare_r_func_t compare, void *arg TSRMLS_DC)
{
void *begin_stack[QSORT_STACK_SIZE];
void *end_stack[QSORT_STACK_SIZE];
@@ -80,10 +81,10 @@ ZEND_API void zend_qsort(void *base, size_t nmemb, size_t siz, compare_func_t co
seg2 = end;
while (1) {
- for (; seg1 < seg2 && compare(begin, seg1 TSRMLS_CC) > 0;
+ for (; seg1 < seg2 && compare(begin, seg1 TSRMLS_CC, arg) > 0;
seg1 += siz);
- for (; seg2 >= seg1 && compare(seg2, begin TSRMLS_CC) > 0;
+ for (; seg2 >= seg1 && compare(seg2, begin TSRMLS_CC, arg) > 0;
seg2 -= siz);
if (seg1 >= seg2)
@@ -117,6 +118,11 @@ ZEND_API void zend_qsort(void *base, size_t nmemb, size_t siz, compare_func_t co
}
}
+ZEND_API void zend_qsort(void *base, size_t nmemb, size_t siz, compare_func_t compare TSRMLS_DC)
+{
+ zend_qsort_r(base, nmemb, siz, (compare_r_func_t)compare, NULL TSRMLS_CC);
+}
+
/*
* Local Variables:
* c-basic-offset: 4
diff --git a/Zend/zend_qsort.h b/Zend/zend_qsort.h
index 747e98823f..c61a85d18e 100644
--- a/Zend/zend_qsort.h
+++ b/Zend/zend_qsort.h
@@ -22,7 +22,9 @@
#define ZEND_QSORT_H
BEGIN_EXTERN_C()
+typedef int (*compare_r_func_t)(const void *, const void * TSRMLS_DC, void *);
ZEND_API void zend_qsort(void *base, size_t nmemb, size_t siz, compare_func_t compare TSRMLS_DC);
+ZEND_API void zend_qsort_r(void *base, size_t nmemb, size_t siz, compare_r_func_t compare, void *arg TSRMLS_DC);
END_EXTERN_C()
#endif /* ZEND_QSORT_H */
diff --git a/Zend/zend_signal.c b/Zend/zend_signal.c
index f61ae0b176..6105fb1119 100644
--- a/Zend/zend_signal.c
+++ b/Zend/zend_signal.c
@@ -215,7 +215,7 @@ ZEND_API int zend_sigaction(int signo, const struct sigaction *act, struct sigac
sa.sa_mask = global_sigmask;
if (sigaction(signo, &sa, NULL) < 0) {
- zend_error(E_WARNING, "Error installing signal handler for %d", signo);
+ zend_error(E_ERROR, "Error installing signal handler for %d", signo);
}
/* unsure this signal is not blocked */
@@ -267,7 +267,7 @@ static int zend_signal_register(int signo, void (*handler)(int, siginfo_t*, void
sa.sa_mask = global_sigmask;
if (sigaction(signo, &sa, NULL) < 0) {
- zend_error(E_WARNING, "Error installing signal handler for %d", signo);
+ zend_error(E_ERROR, "Error installing signal handler for %d", signo);
}
return SUCCESS;
diff --git a/Zend/zend_types.h b/Zend/zend_types.h
index d896159247..e5d5bbb500 100644
--- a/Zend/zend_types.h
+++ b/Zend/zend_types.h
@@ -52,6 +52,7 @@ typedef unsigned long zend_uintptr_t;
typedef unsigned int zend_object_handle;
typedef struct _zend_object_handlers zend_object_handlers;
+typedef struct _zval_struct zval;
typedef struct _zend_object_value {
zend_object_handle handle;
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index ab33468205..03cc9c45a0 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -334,7 +334,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMP|VAR
zval **object_ptr = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW);
zval *object;
zval *property = GET_OP2_ZVAL_PTR(BP_VAR_R);
- zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
+ zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
int have_get_ptr = 0;
if (OP1_TYPE == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -363,7 +363,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMP|VAR
/* here property is a string */
if (opline->extended_value == ZEND_ASSIGN_OBJ
&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -465,8 +465,8 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_helper, VAR|UNUSED|CV, CONST|TMP|VAR|UNU
zval *dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, OP2_TYPE, BP_VAR_RW TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
}
}
break;
@@ -625,7 +625,7 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR|
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -726,7 +726,7 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
have_get_ptr = 1;
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -1149,7 +1149,7 @@ ZEND_VM_HANDLER(92, ZEND_FETCH_FUNC_ARG, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
USE_OPLINE
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type,
- ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R);
+ ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R);
}
ZEND_VM_HANDLER(95, ZEND_FETCH_UNSET, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
@@ -1162,7 +1162,7 @@ ZEND_VM_HANDLER(89, ZEND_FETCH_IS, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_fetch_var_address_helper, type, BP_VAR_IS);
}
-ZEND_VM_HANDLER(81, ZEND_FETCH_DIM_R, VAR|CV, CONST|TMP|VAR|CV)
+ZEND_VM_HANDLER(81, ZEND_FETCH_DIM_R, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
@@ -1259,7 +1259,7 @@ ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
SAVE_OPLINE();
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
zval **container = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
@@ -1311,6 +1311,7 @@ ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET, VAR|CV, CONST|TMP|VAR|CV)
FREE_OP1_VAR_PTR();
if (UNEXPECTED(EX_T(opline->result.var).var.ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
+ ZEND_VM_NEXT_OPCODE();
} else {
zend_free_op free_res;
zval **retval_ptr = EX_T(opline->result.var).var.ptr_ptr;
@@ -1384,11 +1385,6 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
SAVE_OPLINE();
property = GET_OP2_ZVAL_PTR(BP_VAR_R);
- if (OP1_TYPE == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
- PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
- EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr;
- }
-
if (IS_OP2_TMP_FREE()) {
MAKE_REAL_ZVAL_PTR(property);
}
@@ -1500,7 +1496,7 @@ ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
{
USE_OPLINE
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
/* Behave like FETCH_OBJ_W */
zend_free_op free_op1, free_op2;
zval *property;
@@ -1617,7 +1613,7 @@ ZEND_VM_HANDLER(136, ZEND_ASSIGN_OBJ, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
if (OP1_TYPE == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_OBJ, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (IS_OP2_TMP_FREE()) {
zval_ptr_dtor(&property_name);
} else {
@@ -1649,7 +1645,7 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
if (IS_OP2_TMP_FREE()) {
MAKE_REAL_ZVAL_PTR(property_name);
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_DIM, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (IS_OP2_TMP_FREE()) {
zval_ptr_dtor(&property_name);
} else {
@@ -1664,8 +1660,8 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), object_ptr, dim, OP2_TYPE, BP_VAR_W TSRMLS_CC);
FREE_OP2();
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
if (RETURN_VALUE_USED(opline)) {
@@ -1821,6 +1817,270 @@ ZEND_VM_HANDLER(39, ZEND_ASSIGN_REF, VAR|CV, VAR|CV)
ZEND_VM_NEXT_OPCODE();
}
+ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
+{
+ zend_bool nested = EX(nested);
+ zend_op_array *op_array = EX(op_array);
+
+ EG(current_execute_data) = EX(prev_execute_data);
+ EG(opline_ptr) = NULL;
+ if (!EG(active_symbol_table)) {
+ i_free_compiled_variables(execute_data);
+ }
+
+ zend_vm_stack_free((char*)execute_data - (ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * op_array->T) TSRMLS_CC);
+
+ if ((op_array->fn_flags & ZEND_ACC_CLOSURE) && op_array->prototype) {
+ zval_ptr_dtor((zval**)&op_array->prototype);
+ }
+
+ if (nested) {
+ execute_data = EG(current_execute_data);
+ }
+ if (nested) {
+ USE_OPLINE
+
+ LOAD_REGS();
+ LOAD_OPLINE();
+ if (UNEXPECTED(opline->opcode == ZEND_INCLUDE_OR_EVAL)) {
+
+ EX(function_state).function = (zend_function *) EX(op_array);
+ EX(function_state).arguments = NULL;
+
+ EG(opline_ptr) = &EX(opline);
+ EG(active_op_array) = EX(op_array);
+ EG(return_value_ptr_ptr) = EX(original_return_value);
+ destroy_op_array(op_array TSRMLS_CC);
+ efree(op_array);
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ zend_throw_exception_internal(NULL TSRMLS_CC);
+ HANDLE_EXCEPTION_LEAVE();
+ }
+
+ ZEND_VM_INC_OPCODE();
+ ZEND_VM_LEAVE();
+ } else {
+ EG(opline_ptr) = &EX(opline);
+ EG(active_op_array) = EX(op_array);
+ EG(return_value_ptr_ptr) = EX(original_return_value);
+ if (EG(active_symbol_table)) {
+ zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC);
+ }
+ EG(active_symbol_table) = EX(symbol_table);
+
+ EX(function_state).function = (zend_function *) EX(op_array);
+ EX(function_state).arguments = NULL;
+
+ if (EG(This)) {
+ if (UNEXPECTED(EG(exception) != NULL) && EX(call)->is_ctor_call) {
+ if (EX(call)->is_ctor_result_used) {
+ Z_DELREF_P(EG(This));
+ }
+ if (Z_REFCOUNT_P(EG(This)) == 1) {
+ zend_object_store_ctor_failed(EG(This) TSRMLS_CC);
+ }
+ }
+ zval_ptr_dtor(&EG(This));
+ }
+ EG(This) = EX(current_this);
+ EG(scope) = EX(current_scope);
+ EG(called_scope) = EX(current_called_scope);
+
+ EX(call)--;
+
+ zend_vm_stack_clear_multiple(1 TSRMLS_CC);
+
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ zend_throw_exception_internal(NULL TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline) && EX_T(opline->result.var).var.ptr) {
+ zval_ptr_dtor(&EX_T(opline->result.var).var.ptr);
+ }
+ HANDLE_EXCEPTION_LEAVE();
+ }
+
+ ZEND_VM_INC_OPCODE();
+ ZEND_VM_LEAVE();
+ }
+ }
+ ZEND_VM_RETURN();
+}
+
+ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
+{
+ USE_OPLINE
+ zend_bool should_change_scope = 0;
+ zend_function *fbc = EX(function_state).function;
+
+ SAVE_OPLINE();
+ EX(object) = EX(call)->object;
+ if (UNEXPECTED((fbc->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) != 0)) {
+ if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_ABSTRACT) != 0)) {
+ zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", fbc->common.scope->name, fbc->common.function_name);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE(); /* Never reached */
+ }
+ if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
+ zend_error(E_DEPRECATED, "Function %s%s%s() is deprecated",
+ fbc->common.scope ? fbc->common.scope->name : "",
+ fbc->common.scope ? "::" : "",
+ fbc->common.function_name);
+ }
+ }
+ if (fbc->common.scope &&
+ !(fbc->common.fn_flags & ZEND_ACC_STATIC) &&
+ !EX(object)) {
+
+ if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ /* FIXME: output identifiers properly */
+ zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically", fbc->common.scope->name, fbc->common.function_name);
+ } else {
+ /* FIXME: output identifiers properly */
+ /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically", fbc->common.scope->name, fbc->common.function_name);
+ }
+ }
+
+ if (fbc->type == ZEND_USER_FUNCTION || fbc->common.scope) {
+ should_change_scope = 1;
+ EX(current_this) = EG(This);
+ EX(current_scope) = EG(scope);
+ EX(current_called_scope) = EG(called_scope);
+ EG(This) = EX(object);
+ EG(scope) = (fbc->type == ZEND_USER_FUNCTION || !EX(object)) ? fbc->common.scope : NULL;
+ EG(called_scope) = EX(call)->called_scope;
+ }
+
+ EX(function_state).arguments = zend_vm_stack_top(TSRMLS_C);
+ zend_vm_stack_push((void*)(zend_uintptr_t)opline->extended_value TSRMLS_CC);
+ LOAD_OPLINE();
+
+ if (fbc->type == ZEND_INTERNAL_FUNCTION) {
+ if (fbc->common.arg_info) {
+ zend_uint i=0;
+ zval **p = (zval**)EX(function_state).arguments;
+ ulong arg_count = opline->extended_value;
+
+ while (arg_count>0) {
+ zend_verify_arg_type(fbc, ++i, *(p-arg_count), 0 TSRMLS_CC);
+ arg_count--;
+ }
+ }
+
+ if (EXPECTED(EG(exception) == NULL)) {
+ temp_variable *ret = &EX_T(opline->result.var);
+
+ MAKE_STD_ZVAL(ret->var.ptr);
+ ZVAL_NULL(ret->var.ptr);
+ ret->var.ptr_ptr = &ret->var.ptr;
+ ret->var.fcall_returned_reference = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0;
+
+ if (!zend_execute_internal) {
+ /* saves one function call if zend_execute_internal is not used */
+ fbc->internal_function.handler(opline->extended_value, ret->var.ptr, (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ? &ret->var.ptr : NULL, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
+ } else {
+ zend_execute_internal(execute_data, NULL, RETURN_VALUE_USED(opline) TSRMLS_CC);
+ }
+
+ if (!RETURN_VALUE_USED(opline)) {
+ zval_ptr_dtor(&ret->var.ptr);
+ }
+ } else if (RETURN_VALUE_USED(opline)) {
+ EX_T(opline->result.var).var.ptr = NULL;
+ }
+ } else if (fbc->type == ZEND_USER_FUNCTION) {
+ EX(original_return_value) = EG(return_value_ptr_ptr);
+ EG(active_symbol_table) = NULL;
+ EG(active_op_array) = &fbc->op_array;
+ EG(return_value_ptr_ptr) = NULL;
+ if (RETURN_VALUE_USED(opline)) {
+ temp_variable *ret = &EX_T(opline->result.var);
+
+ ret->var.ptr = NULL;
+ EG(return_value_ptr_ptr) = &ret->var.ptr;
+ ret->var.ptr_ptr = &ret->var.ptr;
+ ret->var.fcall_returned_reference = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0;
+ }
+
+ if (UNEXPECTED((EG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0)) {
+ if (RETURN_VALUE_USED(opline)) {
+ EX_T(opline->result.var).var.ptr = zend_generator_create_zval(EG(active_op_array) TSRMLS_CC);
+ }
+ } else if (EXPECTED(zend_execute_ex == execute_ex)) {
+ if (EXPECTED(EG(exception) == NULL)) {
+ ZEND_VM_ENTER();
+ }
+ } else {
+ zend_execute(EG(active_op_array) TSRMLS_CC);
+ }
+
+ EG(opline_ptr) = &EX(opline);
+ EG(active_op_array) = EX(op_array);
+ EG(return_value_ptr_ptr) = EX(original_return_value);
+ if (EG(active_symbol_table)) {
+ zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC);
+ }
+ EG(active_symbol_table) = EX(symbol_table);
+ } else { /* ZEND_OVERLOADED_FUNCTION */
+ MAKE_STD_ZVAL(EX_T(opline->result.var).var.ptr);
+ ZVAL_NULL(EX_T(opline->result.var).var.ptr);
+
+ /* Not sure what should be done here if it's a static method */
+ if (EXPECTED(EX(object) != NULL)) {
+ Z_OBJ_HT_P(EX(object))->call_method(fbc->common.function_name, opline->extended_value, EX_T(opline->result.var).var.ptr, &EX_T(opline->result.var).var.ptr, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
+ } else {
+ zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
+ }
+
+ if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
+ efree((char*)fbc->common.function_name);
+ }
+ efree(fbc);
+
+ if (!RETURN_VALUE_USED(opline)) {
+ zval_ptr_dtor(&EX_T(opline->result.var).var.ptr);
+ } else {
+ Z_UNSET_ISREF_P(EX_T(opline->result.var).var.ptr);
+ Z_SET_REFCOUNT_P(EX_T(opline->result.var).var.ptr, 1);
+ EX_T(opline->result.var).var.fcall_returned_reference = 0;
+ EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr;
+ }
+ }
+
+ EX(function_state).function = (zend_function *) EX(op_array);
+ EX(function_state).arguments = NULL;
+
+ if (should_change_scope) {
+ if (EG(This)) {
+ if (UNEXPECTED(EG(exception) != NULL) && EX(call)->is_ctor_call) {
+ if (EX(call)->is_ctor_result_used) {
+ Z_DELREF_P(EG(This));
+ }
+ if (Z_REFCOUNT_P(EG(This)) == 1) {
+ zend_object_store_ctor_failed(EG(This) TSRMLS_CC);
+ }
+ }
+ zval_ptr_dtor(&EG(This));
+ }
+ EG(This) = EX(current_this);
+ EG(scope) = EX(current_scope);
+ EG(called_scope) = EX(current_called_scope);
+ }
+
+ EX(call)--;
+
+ zend_vm_stack_clear_multiple(1 TSRMLS_CC);
+
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ zend_throw_exception_internal(NULL TSRMLS_CC);
+ if (RETURN_VALUE_USED(opline) && EX_T(opline->result.var).var.ptr) {
+ zval_ptr_dtor(&EX_T(opline->result.var).var.ptr);
+ }
+ HANDLE_EXCEPTION();
+ }
+
+ ZEND_VM_NEXT_OPCODE();
+}
+
ZEND_VM_HANDLER(42, ZEND_JMP, ANY, ANY)
{
USE_OPLINE
@@ -1829,7 +2089,7 @@ ZEND_VM_HANDLER(42, ZEND_JMP, ANY, ANY)
printf("Jumping to %d\n", opline->op1.opline_num);
#endif
ZEND_VM_SET_OPCODE(opline->op1.jmp_addr);
- ZEND_VM_CONTINUE(); /* CHECK_ME */
+ ZEND_VM_CONTINUE();
}
ZEND_VM_HANDLER(43, ZEND_JMPZ, CONST|TMP|VAR|CV, ANY)
@@ -2114,7 +2374,9 @@ ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, ANY, CONST|TMP|VAR|UNUSED|CV)
USE_OPLINE
SAVE_OPLINE();
- EG(exception) = NULL;
+ if (EG(exception)) {
+ zend_exception_save(TSRMLS_C);
+ }
if (OP2_TYPE == IS_UNUSED) {
EX_T(opline->result.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC);
CHECK_EXCEPTION();
@@ -2135,6 +2397,9 @@ ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, ANY, CONST|TMP|VAR|UNUSED|CV)
} else if (Z_TYPE_P(class_name) == IS_STRING) {
EX_T(opline->result.var).class_entry = zend_fetch_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), opline->extended_value TSRMLS_CC);
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string");
}
@@ -2151,63 +2416,72 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV)
char *function_name_strval;
int function_name_strlen;
zend_free_op free_op1, free_op2;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
function_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
if (OP2_TYPE != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_R);
+ call->object = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_R);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (OP2_TYPE != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((OP2_TYPE == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((OP2_TYPE == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (OP2_TYPE == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ FREE_OP2();
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
FREE_OP2();
FREE_OP1_IF_VAR();
@@ -2221,9 +2495,9 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMP|VAR|UNUS
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (OP1_TYPE == IS_CONST) {
/* no function found. try a static method in class */
@@ -2239,24 +2513,24 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMP|VAR|UNUS
}
CACHE_PTR(opline->op1.literal->cache_slot, ce);
}
- EX(called_scope) = ce;
+ call->called_scope = ce;
} else {
ce = EX_T(opline->op1.var).class_entry;
if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
- EX(called_scope) = EG(called_scope);
+ call->called_scope = EG(called_scope);
} else {
- EX(called_scope) = ce;
+ call->called_scope = ce;
}
}
if (OP1_TYPE == IS_CONST &&
OP2_TYPE == IS_CONST &&
CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
} else if (OP1_TYPE != IS_CONST &&
OP2_TYPE == IS_CONST &&
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
/* do nothing */
} else if (OP2_TYPE != IS_UNUSED) {
char *function_name_strval = NULL;
@@ -2270,6 +2544,9 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMP|VAR|UNUS
function_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Function name must be a string");
} else {
function_name_strval = Z_STRVAL_P(function_name);
@@ -2279,20 +2556,20 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMP|VAR|UNUS
if (function_name_strval) {
if (ce->get_static_method) {
- EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
+ call->fbc = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
} else {
- EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((OP2_TYPE == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ call->fbc = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((OP2_TYPE == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
}
- if (UNEXPECTED(EX(fbc) == NULL)) {
+ if (UNEXPECTED(call->fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
}
if (OP2_TYPE == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
if (OP1_TYPE == IS_CONST) {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
} else {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, EX(fbc));
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, call->fbc);
}
}
}
@@ -2306,29 +2583,31 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMP|VAR|UNUS
if (EG(This) && Z_OBJCE_P(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name);
}
- EX(fbc) = ce->constructor;
+ call->fbc = ce->constructor;
}
- if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
- EX(object) = NULL;
+ if (call->fbc->common.fn_flags & ZEND_ACC_STATIC) {
+ call->object = NULL;
} else {
if (EG(This) &&
Z_OBJ_HT_P(EG(This))->get_class_entry &&
!instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
- if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
} else {
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
}
}
- if ((EX(object) = EG(This))) {
- Z_ADDREF_P(EX(object));
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if ((call->object = EG(This))) {
+ Z_ADDREF_P(call->object);
+ call->called_scope = Z_OBJCE_P(call->object);
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -2338,19 +2617,22 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV)
{
USE_OPLINE
zval *function_name;
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
+ call_slot *call = EX(call_slots) + opline->result.num;
if (OP2_TYPE == IS_CONST) {
function_name = (zval*)(opline->op2.literal+1);
if (CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
- } else if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &EX(fbc)) == FAILURE)) {
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
+ } else if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &call->fbc) == FAILURE)) {
SAVE_OPLINE();
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
} else {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
}
- EX(object) = NULL;
+ call->object = NULL;
+ call->called_scope = NULL;
+ call->is_ctor_call = 0;
+ EX(call) = call;
/*CHECK_EXCEPTION();*/
ZEND_VM_NEXT_OPCODE();
} else {
@@ -2370,28 +2652,33 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV)
} else {
lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen);
}
- if (UNEXPECTED(zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &EX(fbc)) == FAILURE)) {
+ if (UNEXPECTED(zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &call->fbc) == FAILURE)) {
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
}
efree(lcname);
FREE_OP2();
- EX(object) = NULL;
+ call->object = NULL;
+ call->called_scope = NULL;
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else if (OP2_TYPE != IS_CONST && OP2_TYPE != IS_TMP_VAR &&
EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) &&
Z_OBJ_HANDLER_P(function_name, get_closure) &&
- Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &EX(called_scope), &EX(fbc), &EX(object) TSRMLS_CC) == SUCCESS) {
- if (EX(object)) {
- Z_ADDREF_P(EX(object));
+ Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &call->called_scope, &call->fbc, &call->object TSRMLS_CC) == SUCCESS) {
+ if (call->object) {
+ Z_ADDREF_P(call->object);
}
if (OP2_TYPE == IS_VAR && OP2_FREE &&
- EX(fbc)->common.fn_flags & ZEND_ACC_CLOSURE) {
+ call->fbc->common.fn_flags & ZEND_ACC_CLOSURE) {
/* Delay closure destruction until its invocation */
- EX(fbc)->common.prototype = (zend_function*)function_name;
+ call->fbc->common.prototype = (zend_function*)function_name;
} else {
FREE_OP2();
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else if (OP2_TYPE != IS_CONST &&
@@ -2418,52 +2705,56 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV)
if (Z_TYPE_PP(obj) == IS_STRING) {
ce = zend_fetch_class_by_name(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj), NULL, 0 TSRMLS_CC);
- if (UNEXPECTED(EG(exception) != NULL)) {
- HANDLE_EXCEPTION();
- }
if (UNEXPECTED(ce == NULL)) {
- zend_error_noreturn(E_ERROR, "Class '%s' not found", Z_STRVAL_PP(obj));
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
- EX(called_scope) = ce;
- EX(object) = NULL;
+ call->called_scope = ce;
+ call->object = NULL;
if (ce->get_static_method) {
- EX(fbc) = ce->get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method) TSRMLS_CC);
+ call->fbc = ce->get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method) TSRMLS_CC);
} else {
- EX(fbc) = zend_std_get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
+ call->fbc = zend_std_get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
}
} else {
- EX(object) = *obj;
- ce = EX(called_scope) = Z_OBJCE_PP(obj);
+ call->object = *obj;
+ ce = call->called_scope = Z_OBJCE_PP(obj);
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), Z_STRVAL_PP(method));
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), Z_STRVAL_PP(method));
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
}
- if (UNEXPECTED(EX(fbc) == NULL)) {
+ if (UNEXPECTED(call->fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, Z_STRVAL_PP(method));
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
FREE_OP2();
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Function name must be a string");
+ ZEND_VM_NEXT_OPCODE(); /* Never reached */
}
}
}
@@ -2473,328 +2764,33 @@ ZEND_VM_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST)
{
USE_OPLINE
zend_literal *func_name;
-
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
+ call_slot *call = EX(call_slots) + opline->result.num;
func_name = opline->op2.literal + 1;
if (CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
- } else if (zend_hash_quick_find(EG(function_table), Z_STRVAL(func_name->constant), Z_STRLEN(func_name->constant)+1, func_name->hash_value, (void **) &EX(fbc))==FAILURE) {
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
+ } else if (zend_hash_quick_find(EG(function_table), Z_STRVAL(func_name->constant), Z_STRLEN(func_name->constant)+1, func_name->hash_value, (void **) &call->fbc)==FAILURE) {
func_name++;
- if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL(func_name->constant), Z_STRLEN(func_name->constant)+1, func_name->hash_value, (void **) &EX(fbc))==FAILURE)) {
+ if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL(func_name->constant), Z_STRLEN(func_name->constant)+1, func_name->hash_value, (void **) &call->fbc)==FAILURE)) {
SAVE_OPLINE();
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
} else {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
}
} else {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
- }
-
- EX(object) = NULL;
- ZEND_VM_NEXT_OPCODE();
-}
-
-ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
-{
- zend_bool nested;
- zend_op_array *op_array = EX(op_array);
-
- EG(current_execute_data) = EX(prev_execute_data);
- EG(opline_ptr) = NULL;
- if (!EG(active_symbol_table)) {
- zval ***cv = EX_CVs();
- zval ***end = cv + op_array->last_var;
- while (cv != end) {
- if (*cv) {
- zval_ptr_dtor(*cv);
- }
- cv++;
- }
- }
-
- if ((op_array->fn_flags & ZEND_ACC_CLOSURE) && op_array->prototype) {
- zval_ptr_dtor((zval**)&op_array->prototype);
- }
-
- nested = EX(nested);
-
- zend_vm_stack_free(execute_data TSRMLS_CC);
-
- if (nested) {
- execute_data = EG(current_execute_data);
- }
- if (nested) {
- USE_OPLINE
-
- LOAD_REGS();
- LOAD_OPLINE();
- if (UNEXPECTED(opline->opcode == ZEND_INCLUDE_OR_EVAL)) {
-
- EX(function_state).function = (zend_function *) EX(op_array);
- EX(function_state).arguments = NULL;
- EX(object) = EX(current_object);
-
- EG(opline_ptr) = &EX(opline);
- EG(active_op_array) = EX(op_array);
- EG(return_value_ptr_ptr) = EX(original_return_value);
- destroy_op_array(op_array TSRMLS_CC);
- efree(op_array);
- if (UNEXPECTED(EG(exception) != NULL)) {
- zend_throw_exception_internal(NULL TSRMLS_CC);
- HANDLE_EXCEPTION_LEAVE();
- } else if (RETURN_VALUE_USED(opline)) {
- if (!EX_T(opline->result.var).var.ptr) { /* there was no return statement */
- zval *retval;
-
- ALLOC_ZVAL(retval);
- ZVAL_BOOL(retval, 1);
- INIT_PZVAL(retval);
- EX_T(opline->result.var).var.ptr = retval;
- }
- }
-
- ZEND_VM_INC_OPCODE();
- ZEND_VM_LEAVE();
- } else {
-
- EG(opline_ptr) = &EX(opline);
- EG(active_op_array) = EX(op_array);
- EG(return_value_ptr_ptr) = EX(original_return_value);
- if (EG(active_symbol_table)) {
- if (EG(symtable_cache_ptr)>=EG(symtable_cache_limit)) {
- zend_hash_destroy(EG(active_symbol_table));
- FREE_HASHTABLE(EG(active_symbol_table));
- } else {
- /* clean before putting into the cache, since clean
- could call dtors, which could use cached hash */
- zend_hash_clean(EG(active_symbol_table));
- *(++EG(symtable_cache_ptr)) = EG(active_symbol_table);
- }
- }
- EG(active_symbol_table) = EX(symbol_table);
-
- EX(function_state).function = (zend_function *) EX(op_array);
- EX(function_state).arguments = NULL;
-
- if (EG(This)) {
- if (UNEXPECTED(EG(exception) != NULL) && IS_CTOR_CALL(EX(called_scope))) {
- if (IS_CTOR_USED(EX(called_scope))) {
- Z_DELREF_P(EG(This));
- }
- if (Z_REFCOUNT_P(EG(This)) == 1) {
- zend_object_store_ctor_failed(EG(This) TSRMLS_CC);
- }
- }
- zval_ptr_dtor(&EG(This));
- }
- EG(This) = EX(current_this);
- EG(scope) = EX(current_scope);
- EG(called_scope) = EX(current_called_scope);
-
- EX(object) = EX(current_object);
- EX(called_scope) = DECODE_CTOR(EX(called_scope));
-
- zend_vm_stack_clear_multiple(TSRMLS_C);
-
- if (UNEXPECTED(EG(exception) != NULL)) {
- zend_throw_exception_internal(NULL TSRMLS_CC);
- if (RETURN_VALUE_USED(opline) && EX_T(opline->result.var).var.ptr) {
- zval_ptr_dtor(&EX_T(opline->result.var).var.ptr);
- }
- HANDLE_EXCEPTION_LEAVE();
- }
-
- ZEND_VM_INC_OPCODE();
- ZEND_VM_LEAVE();
- }
- }
- ZEND_VM_RETURN();
-}
-
-ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
-{
- USE_OPLINE
- zend_bool should_change_scope = 0;
- zend_function *fbc = EX(function_state).function;
-
- SAVE_OPLINE();
- if (UNEXPECTED((fbc->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) != 0)) {
- if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_ABSTRACT) != 0)) {
- zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", fbc->common.scope->name, fbc->common.function_name);
- CHECK_EXCEPTION();
- ZEND_VM_NEXT_OPCODE(); /* Never reached */
- }
- if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) {
- zend_error(E_DEPRECATED, "Function %s%s%s() is deprecated",
- fbc->common.scope ? fbc->common.scope->name : "",
- fbc->common.scope ? "::" : "",
- fbc->common.function_name);
- }
- }
- if (fbc->common.scope &&
- !(fbc->common.fn_flags & ZEND_ACC_STATIC) &&
- !EX(object)) {
-
- if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- /* FIXME: output identifiers properly */
- zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically", fbc->common.scope->name, fbc->common.function_name);
- } else {
- /* FIXME: output identifiers properly */
- /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically", fbc->common.scope->name, fbc->common.function_name);
- }
- }
-
- if (fbc->type == ZEND_USER_FUNCTION || fbc->common.scope) {
- should_change_scope = 1;
- EX(current_this) = EG(This);
- EX(current_scope) = EG(scope);
- EX(current_called_scope) = EG(called_scope);
- EG(This) = EX(object);
- EG(scope) = (fbc->type == ZEND_USER_FUNCTION || !EX(object)) ? fbc->common.scope : NULL;
- EG(called_scope) = EX(called_scope);
- }
-
- zend_arg_types_stack_3_pop(&EG(arg_types_stack), &EX(called_scope), &EX(current_object), &EX(fbc));
- EX(function_state).arguments = zend_vm_stack_push_args(opline->extended_value TSRMLS_CC);
- LOAD_OPLINE();
-
- if (fbc->type == ZEND_INTERNAL_FUNCTION) {
- temp_variable *ret = &EX_T(opline->result.var);
-
- if (fbc->common.arg_info) {
- zend_uint i=0;
- zval **p = (zval**)EX(function_state).arguments;
- ulong arg_count = opline->extended_value;
-
- while (arg_count>0) {
- zend_verify_arg_type(fbc, ++i, *(p-arg_count), 0 TSRMLS_CC);
- arg_count--;
- }
- }
-
- if (EXPECTED(EG(exception) == NULL)) {
- MAKE_STD_ZVAL(ret->var.ptr);
- ZVAL_NULL(ret->var.ptr);
- ret->var.ptr_ptr = &ret->var.ptr;
- ret->var.fcall_returned_reference = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0;
-
- if (!zend_execute_internal) {
- /* saves one function call if zend_execute_internal is not used */
- fbc->internal_function.handler(opline->extended_value, ret->var.ptr, (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ? &ret->var.ptr : NULL, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
- } else {
- zend_execute_internal(EXECUTE_DATA, RETURN_VALUE_USED(opline) TSRMLS_CC);
- }
-
- if (!RETURN_VALUE_USED(opline)) {
- zval_ptr_dtor(&ret->var.ptr);
- }
- } else if (RETURN_VALUE_USED(opline)) {
- EX_T(opline->result.var).var.ptr = NULL;
- }
- } else if (fbc->type == ZEND_USER_FUNCTION) {
- EX(original_return_value) = EG(return_value_ptr_ptr);
- EG(active_symbol_table) = NULL;
- EG(active_op_array) = &fbc->op_array;
- EG(return_value_ptr_ptr) = NULL;
- if (RETURN_VALUE_USED(opline)) {
- temp_variable *ret = &EX_T(opline->result.var);
-
- ret->var.ptr = NULL;
- EG(return_value_ptr_ptr) = &ret->var.ptr;
- ret->var.ptr_ptr = &ret->var.ptr;
- ret->var.fcall_returned_reference = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0;
- }
-
- if (EXPECTED(zend_execute == execute)) {
- if (EXPECTED(EG(exception) == NULL)) {
- ZEND_VM_ENTER();
- }
- } else {
- zend_execute(EG(active_op_array) TSRMLS_CC);
- }
-
- EG(opline_ptr) = &EX(opline);
- EG(active_op_array) = EX(op_array);
- EG(return_value_ptr_ptr) = EX(original_return_value);
- if (EG(active_symbol_table)) {
- if (EG(symtable_cache_ptr)>=EG(symtable_cache_limit)) {
- zend_hash_destroy(EG(active_symbol_table));
- FREE_HASHTABLE(EG(active_symbol_table));
- } else {
- /* clean before putting into the cache, since clean
- could call dtors, which could use cached hash */
- zend_hash_clean(EG(active_symbol_table));
- *(++EG(symtable_cache_ptr)) = EG(active_symbol_table);
- }
- }
- EG(active_symbol_table) = EX(symbol_table);
- } else { /* ZEND_OVERLOADED_FUNCTION */
- MAKE_STD_ZVAL(EX_T(opline->result.var).var.ptr);
- ZVAL_NULL(EX_T(opline->result.var).var.ptr);
-
- /* Not sure what should be done here if it's a static method */
- if (EXPECTED(EX(object) != NULL)) {
- Z_OBJ_HT_P(EX(object))->call_method(fbc->common.function_name, opline->extended_value, EX_T(opline->result.var).var.ptr, &EX_T(opline->result.var).var.ptr, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
- } else {
- zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
- }
-
- if (fbc->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) {
- efree((char*)fbc->common.function_name);
- }
- efree(fbc);
-
- if (!RETURN_VALUE_USED(opline)) {
- zval_ptr_dtor(&EX_T(opline->result.var).var.ptr);
- } else {
- Z_UNSET_ISREF_P(EX_T(opline->result.var).var.ptr);
- Z_SET_REFCOUNT_P(EX_T(opline->result.var).var.ptr, 1);
- EX_T(opline->result.var).var.fcall_returned_reference = 0;
- EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr;
- }
- }
-
- EX(function_state).function = (zend_function *) EX(op_array);
- EX(function_state).arguments = NULL;
-
- if (should_change_scope) {
- if (EG(This)) {
- if (UNEXPECTED(EG(exception) != NULL) && IS_CTOR_CALL(EX(called_scope))) {
- if (IS_CTOR_USED(EX(called_scope))) {
- Z_DELREF_P(EG(This));
- }
- if (Z_REFCOUNT_P(EG(This)) == 1) {
- zend_object_store_ctor_failed(EG(This) TSRMLS_CC);
- }
- }
- zval_ptr_dtor(&EG(This));
- }
- EG(This) = EX(current_this);
- EG(scope) = EX(current_scope);
- EG(called_scope) = EX(current_called_scope);
- }
-
- EX(object) = EX(current_object);
- EX(called_scope) = DECODE_CTOR(EX(called_scope));
-
- zend_vm_stack_clear_multiple(TSRMLS_C);
-
- if (UNEXPECTED(EG(exception) != NULL)) {
- zend_throw_exception_internal(NULL TSRMLS_CC);
- if (RETURN_VALUE_USED(opline) && EX_T(opline->result.var).var.ptr) {
- zval_ptr_dtor(&EX_T(opline->result.var).var.ptr);
- }
- HANDLE_EXCEPTION();
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
}
+ call->object = NULL;
+ call->called_scope = NULL;
+ call->is_ctor_call = 0;
+ EX(call) = call;
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(61, ZEND_DO_FCALL_BY_NAME, ANY, ANY)
{
- EX(function_state).function = EX(fbc);
+ EX(function_state).function = EX(call)->fbc;
ZEND_VM_DISPATCH_TO_HELPER(zend_do_fcall_common_helper);
}
@@ -2803,8 +2799,7 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, CONST, ANY)
USE_OPLINE
zend_free_op free_op1;
zval *fname = GET_OP1_ZVAL_PTR(BP_VAR_R);
-
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
+ call_slot *call = EX(call_slots) + opline->op2.num;
if (CACHED_PTR(opline->op1.literal->cache_slot)) {
EX(function_state).function = CACHED_PTR(opline->op1.literal->cache_slot);
@@ -2814,7 +2809,11 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, CONST, ANY)
} else {
CACHE_PTR(opline->op1.literal->cache_slot, EX(function_state).function);
}
- EX(object) = NULL;
+ call->fbc = EX(function_state).function;
+ call->object = NULL;
+ call->called_scope = NULL;
+ call->is_ctor_call = 0;
+ EX(call) = call;
FREE_OP1();
@@ -2834,14 +2833,17 @@ ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY)
if (OP1_TYPE == IS_TMP_VAR) {
FREE_OP1();
}
- } else if (!IS_OP1_TMP_FREE()) { /* Not a temp var */
+ } else {
if (OP1_TYPE == IS_CONST ||
- (PZVAL_IS_REF(retval_ptr) && Z_REFCOUNT_P(retval_ptr) > 0)) {
+ OP1_TYPE == IS_TMP_VAR ||
+ PZVAL_IS_REF(retval_ptr)) {
zval *ret;
ALLOC_ZVAL(ret);
INIT_PZVAL_COPY(ret, retval_ptr);
- zval_copy_ctor(ret);
+ if (OP1_TYPE != IS_TMP_VAR) {
+ zval_copy_ctor(ret);
+ }
*EG(return_value_ptr_ptr) = ret;
} else if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) &&
retval_ptr == &EG(uninitialized_zval)) {
@@ -2853,12 +2855,6 @@ ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY)
*EG(return_value_ptr_ptr) = retval_ptr;
Z_ADDREF_P(retval_ptr);
}
- } else {
- zval *ret;
-
- ALLOC_ZVAL(ret);
- INIT_PZVAL_COPY(ret, retval_ptr);
- *EG(return_value_ptr_ptr) = ret;
}
FREE_OP1_IF_VAR();
ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
@@ -2935,6 +2931,18 @@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY)
ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
}
+ZEND_VM_HANDLER(161, ZEND_GENERATOR_RETURN, ANY, ANY)
+{
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ /* Close the generator to free up resources */
+ zend_generator_close(generator, 1 TSRMLS_CC);
+
+ /* Pass execution back to handling code */
+ ZEND_VM_RETURN();
+}
+
ZEND_VM_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY)
{
USE_OPLINE
@@ -2946,8 +2954,12 @@ ZEND_VM_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY)
value = GET_OP1_ZVAL_PTR(BP_VAR_R);
if (OP1_TYPE == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Can only throw objects");
}
+
zend_exception_save(TSRMLS_C);
/* Not sure if a complete copy is what we want here */
ALLOC_ZVAL(exception);
@@ -3006,7 +3018,7 @@ ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV)
if (EX_CV(opline->op2.var)) {
zval_ptr_dtor(EX_CV(opline->op2.var));
}
- EX_CV(opline->op2.var) = (zval**)EX_CVs() + (EX(op_array)->last_var + opline->op2.var);
+ EX_CV(opline->op2.var) = (zval**)EX_CV_NUM(execute_data, EX(op_array)->last_var + opline->op2.var);
*EX_CV(opline->op2.var) = EG(exception);
} else {
zend_compiled_variable *cv = &CV_DEF_OF(opline->op2.var);
@@ -3028,7 +3040,7 @@ ZEND_VM_HANDLER(65, ZEND_SEND_VAL, CONST|TMP, ANY)
SAVE_OPLINE();
if (opline->extended_value==ZEND_DO_FCALL_BY_NAME
- && ARG_MUST_BE_SENT_BY_REF(EX(fbc), opline->op2.opline_num)) {
+ && ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) {
zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.opline_num);
}
{
@@ -3089,7 +3101,7 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY)
if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) {
ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper);
}
- } else if (!ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.opline_num)) {
+ } else if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) {
ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper);
}
@@ -3115,7 +3127,7 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY)
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.opline_num)) {
+ !ARG_MAY_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) {
zend_error(E_STRICT, "Only variables should be passed by reference");
}
ALLOC_ZVAL(valptr);
@@ -3153,7 +3165,7 @@ ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, ANY)
if (opline->extended_value == ZEND_DO_FCALL_BY_NAME &&
EX(function_state).function->type == ZEND_INTERNAL_FUNCTION &&
- !ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.opline_num)) {
+ !ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) {
ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper);
}
@@ -3172,7 +3184,7 @@ ZEND_VM_HANDLER(66, ZEND_SEND_VAR, VAR|CV, ANY)
USE_OPLINE
if ((opline->extended_value == ZEND_DO_FCALL_BY_NAME)
- && ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.opline_num)) {
+ && ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) {
ZEND_VM_DISPATCH_TO_HANDLER(ZEND_SEND_REF);
}
SAVE_OPLINE();
@@ -3210,7 +3222,7 @@ ZEND_VM_HANDLER(63, ZEND_RECV, ANY, ANY)
zval **var_ptr;
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param, opline->extended_value TSRMLS_CC);
- var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->result.var TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
Z_DELREF_PP(var_ptr);
*var_ptr = *param;
Z_ADDREF_PP(var_ptr);
@@ -3246,7 +3258,7 @@ ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST)
}
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value, opline->extended_value TSRMLS_CC);
- var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->result.var TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
zval_ptr_dtor(var_ptr);
*var_ptr = assignment_value;
@@ -3276,7 +3288,7 @@ ZEND_VM_HANDLER(50, ZEND_BRK, ANY, CONST)
SAVE_OPLINE();
el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->op1.opline_num,
- EX(op_array), EX_Ts() TSRMLS_CC);
+ EX(op_array), execute_data TSRMLS_CC);
ZEND_VM_JMP(EX(op_array)->opcodes + el->brk);
}
@@ -3287,7 +3299,7 @@ ZEND_VM_HANDLER(51, ZEND_CONT, ANY, CONST)
SAVE_OPLINE();
el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->op1.opline_num,
- EX(op_array), EX_Ts() TSRMLS_CC);
+ EX(op_array), execute_data TSRMLS_CC);
ZEND_VM_JMP(EX(op_array)->opcodes + el->cont);
}
@@ -3299,7 +3311,7 @@ ZEND_VM_HANDLER(100, ZEND_GOTO, ANY, CONST)
SAVE_OPLINE();
el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->extended_value,
- EX(op_array), EX_Ts() TSRMLS_CC);
+ EX(op_array), execute_data TSRMLS_CC);
brk_opline = EX(op_array)->opcodes + el->brk;
@@ -3376,17 +3388,20 @@ ZEND_VM_HANDLER(68, ZEND_NEW, ANY, ANY)
}
ZEND_VM_JMP(EX(op_array)->opcodes + opline->op2.opline_num);
} else {
+ call_slot *call = EX(call_slots) + opline->extended_value;
+
if (RETURN_VALUE_USED(opline)) {
PZVAL_LOCK(object_zval);
AI_SET_PTR(&EX_T(opline->result.var), object_zval);
}
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), ENCODE_CTOR(EX(called_scope), RETURN_VALUE_USED(opline)));
-
/* We are not handling overloaded classes right now */
- EX(object) = object_zval;
- EX(fbc) = constructor;
- EX(called_scope) = EX_T(opline->op1.var).class_entry;
+ call->fbc = constructor;
+ call->object = object_zval;
+ call->called_scope = EX_T(opline->op1.var).class_entry;
+ call->is_ctor_call = 1;
+ call->is_ctor_result_used = RETURN_VALUE_USED(opline);
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -3407,6 +3422,9 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMP|VAR|UNUSED|CV, ANY)
if (OP1_TYPE == IS_CONST ||
UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "__clone method called on non-object");
}
@@ -3541,6 +3559,9 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST)
}
ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value);
zval_copy_ctor(&EX_T(opline->result.var).tmp_var);
+ } else if (Z_STRLEN_P(opline->op2.zv) == sizeof("class")-1 && strcmp(Z_STRVAL_P(opline->op2.zv), "class") == 0) {
+ /* "class" is assigned as a case-sensitive keyword from zend_do_resolve_class_name */
+ ZVAL_STRINGL(&EX_T(opline->result.var).tmp_var, ce->name, ce->name_length, 1);
} else {
zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(opline->op2.zv));
}
@@ -3715,7 +3736,7 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMP|VAR|CV, ANY)
zend_op_array *new_op_array=NULL;
zend_free_op free_op1;
zval *inc_filename;
- zval *tmp_inc_filename = NULL;
+ zval *tmp_inc_filename = NULL;
zend_bool failure_retval=0;
SAVE_OPLINE();
@@ -3807,8 +3828,6 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMP|VAR|CV, ANY)
EG(return_value_ptr_ptr) = NULL;
}
- EX(current_object) = EX(object);
-
EX(function_state).function = (zend_function *) new_op_array;
EX(object) = NULL;
@@ -3816,14 +3835,13 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMP|VAR|CV, ANY)
zend_rebuild_symbol_table(TSRMLS_C);
}
- if (EXPECTED(zend_execute == execute)) {
+ if (EXPECTED(zend_execute_ex == execute_ex)) {
ZEND_VM_ENTER();
} else {
zend_execute(new_op_array TSRMLS_CC);
}
EX(function_state).function = (zend_function *) EX(op_array);
- EX(object) = EX(current_object);
EG(opline_ptr) = &EX(opline);
EG(active_op_array) = EX(op_array);
@@ -3833,15 +3851,6 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMP|VAR|CV, ANY)
if (UNEXPECTED(EG(exception) != NULL)) {
zend_throw_exception_internal(NULL TSRMLS_CC);
HANDLE_EXCEPTION();
- } else if (RETURN_VALUE_USED(opline)) {
- if (!EX_T(opline->result.var).var.ptr) { /* there was no return statement */
- zval *retval;
-
- ALLOC_ZVAL(retval);
- ZVAL_BOOL(retval, 1);
- INIT_PZVAL(retval);
- EX_T(opline->result.var).var.ptr = retval;
- }
}
} else if (RETURN_VALUE_USED(opline)) {
@@ -3920,7 +3929,7 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
ulong hash_value = zend_inline_hash_func(varname->value.str.val, varname->value.str.len+1);
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
- zend_delete_variable(EXECUTE_DATA, target_symbol_table, varname->value.str.val, varname->value.str.len+1, hash_value TSRMLS_CC);
+ zend_delete_variable(execute_data, target_symbol_table, varname->value.str.val, varname->value.str.len+1, hash_value TSRMLS_CC);
}
if (OP1_TYPE != IS_CONST && varname == &tmp) {
@@ -4193,7 +4202,7 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
zend_uchar key_type;
key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 0, NULL);
- if (key_type != HASH_KEY_NON_EXISTANT &&
+ if (key_type != HASH_KEY_NON_EXISTENT &&
(key_type == HASH_KEY_IS_LONG ||
zend_check_property_access(zobj, str_key, str_key_len-1 TSRMLS_CC) == SUCCESS)) {
break;
@@ -4223,13 +4232,13 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
zend_free_op free_op1;
zval *array = EX_T(opline->op1.var).fe.ptr;
zval **value;
- char *str_key;
- uint str_key_len;
- ulong int_key;
HashTable *fe_ht;
zend_object_iterator *iter = NULL;
- int key_type = 0;
- zend_bool use_key = (zend_bool)(opline->extended_value & ZEND_FE_FETCH_WITH_KEY);
+
+ zval *key = NULL;
+ if (opline->extended_value & ZEND_FE_FETCH_WITH_KEY) {
+ key = &EX_T((opline+1)->result.var).tmp_var;
+ }
SAVE_OPLINE();
@@ -4240,8 +4249,11 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num);
case ZEND_ITER_PLAIN_OBJECT: {
- const char *class_name, *prop_name;
zend_object *zobj = zend_objects_get_address(array TSRMLS_CC);
+ int key_type;
+ char *str_key;
+ zend_uint str_key_len;
+ zend_ulong int_key;
fe_ht = Z_OBJPROP_P(array);
zend_hash_set_pointer(fe_ht, &EX_T(opline->op1.var).fe.fe_pos);
@@ -4253,16 +4265,23 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 0, NULL);
zend_hash_move_forward(fe_ht);
- } while (key_type == HASH_KEY_NON_EXISTANT ||
- (key_type != HASH_KEY_IS_LONG &&
- zend_check_property_access(zobj, str_key, str_key_len-1 TSRMLS_CC) != SUCCESS));
- zend_hash_get_pointer(fe_ht, &EX_T(opline->op1.var).fe.fe_pos);
- if (use_key && key_type != HASH_KEY_IS_LONG) {
- zend_unmangle_property_name(str_key, str_key_len-1, &class_name, &prop_name);
- str_key_len = strlen(prop_name);
- str_key = estrndup(prop_name, str_key_len);
- str_key_len++;
+ } while (key_type != HASH_KEY_IS_LONG &&
+ zend_check_property_access(zobj, str_key, str_key_len - 1 TSRMLS_CC) != SUCCESS);
+
+ if (key) {
+ if (key_type == HASH_KEY_IS_LONG) {
+ ZVAL_LONG(key, int_key);
+ } else {
+ const char *class_name, *prop_name;
+ int prop_name_len;
+ zend_unmangle_property_name_ex(
+ str_key, str_key_len - 1, &class_name, &prop_name, &prop_name_len
+ );
+ ZVAL_STRINGL(key, prop_name, prop_name_len, 1);
+ }
}
+
+ zend_hash_get_pointer(fe_ht, &EX_T(opline->op1.var).fe.fe_pos);
break;
}
@@ -4273,8 +4292,8 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
/* reached end of iteration */
ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num);
}
- if (use_key) {
- key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 1, NULL);
+ if (key) {
+ zend_hash_get_current_key_zval(fe_ht, key);
}
zend_hash_move_forward(fe_ht);
zend_hash_get_pointer(fe_ht, &EX_T(opline->op1.var).fe.fe_pos);
@@ -4309,16 +4328,15 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
/* failure in get_current_data */
ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num);
}
- if (use_key) {
+ if (key) {
if (iter->funcs->get_current_key) {
- key_type = iter->funcs->get_current_key(iter, &str_key, &str_key_len, &int_key TSRMLS_CC);
+ iter->funcs->get_current_key(iter, key TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
zval_ptr_dtor(&array);
HANDLE_EXCEPTION();
}
} else {
- key_type = HASH_KEY_IS_LONG;
- int_key = iter->index;
+ ZVAL_LONG(key, iter->index);
}
}
break;
@@ -4334,26 +4352,6 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
AI_SET_PTR(&EX_T(opline->result.var), *value);
}
- if (use_key) {
- zval *key = &EX_T((opline+1)->result.var).tmp_var;
-
- switch (key_type) {
- case HASH_KEY_IS_STRING:
- Z_STRVAL_P(key) = (char*)str_key;
- Z_STRLEN_P(key) = str_key_len-1;
- Z_TYPE_P(key) = IS_STRING;
- break;
- case HASH_KEY_IS_LONG:
- Z_LVAL_P(key) = int_key;
- Z_TYPE_P(key) = IS_LONG;
- break;
- default:
- case HASH_KEY_NON_EXISTANT:
- ZVAL_NULL(key);
- break;
- }
- }
-
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
ZEND_VM_NEXT_OPCODE();
@@ -4448,22 +4446,22 @@ ZEND_VM_HELPER_EX(zend_isset_isempty_dim_prop_obj_handler, VAR|UNUSED|CV, CONST|
{
USE_OPLINE
zend_free_op free_op1, free_op2;
- zval **container;
+ zval *container;
zval **value = NULL;
int result = 0;
ulong hval;
zval *offset;
SAVE_OPLINE();
- container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_IS);
+ container = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_IS);
offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
- if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
+ if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) {
HashTable *ht;
int isset = 0;
- ht = Z_ARRVAL_PP(container);
+ ht = Z_ARRVAL_P(container);
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
@@ -4482,9 +4480,7 @@ ZEND_VM_C_LABEL(num_index_prop):
if (OP2_TYPE == IS_CONST) {
hval = Z_HASH_P(offset);
} else {
- if (!prop_dim) {
- ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, ZEND_VM_C_GOTO(num_index_prop));
- }
+ ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, ZEND_VM_C_GOTO(num_index_prop));
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
@@ -4519,20 +4515,20 @@ ZEND_VM_C_LABEL(num_index_prop):
}
}
FREE_OP2();
- } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ } else if (Z_TYPE_P(container) == IS_OBJECT) {
if (IS_OP2_TMP_FREE()) {
MAKE_REAL_ZVAL_PTR(offset);
}
if (prop_dim) {
- if (Z_OBJ_HT_P(*container)->has_property) {
- result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_property) {
+ result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((OP2_TYPE == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check property of non-object");
result = 0;
}
} else {
- if (Z_OBJ_HT_P(*container)->has_dimension) {
- result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_dimension) {
+ result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
result = 0;
@@ -4543,7 +4539,7 @@ ZEND_VM_C_LABEL(num_index_prop):
} else {
FREE_OP2();
}
- } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
+ } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */
zval tmp;
if (Z_TYPE_P(offset) != IS_LONG) {
@@ -4561,11 +4557,11 @@ ZEND_VM_C_LABEL(num_index_prop):
}
if (Z_TYPE_P(offset) == IS_LONG) {
if (opline->extended_value & ZEND_ISSET) {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) {
result = 1;
}
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') {
result = 1;
}
}
@@ -4997,13 +4993,15 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
{
zend_uint op_num = EG(opline_before_exception)-EG(active_op_array)->opcodes;
int i;
- zend_uint catch_op_num = 0;
- int catched = 0;
- zval restored_error_reporting;
+ zend_uint catch_op_num = 0, finally_op_num = 0;
+ void **stack_frame;
- void **stack_frame = (void**)(((char*)EX_Ts()) +
- (ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * EX(op_array)->T));
+ /* Figure out where the next stack frame (which maybe contains pushed
+ * arguments that have to be dtor'ed) starts */
+ stack_frame = zend_vm_stack_frame_base(execute_data);
+ /* If the exception was thrown during a function call there might be
+ * arguments pushed to the stack that have to be dtor'ed. */
while (zend_vm_stack_top(TSRMLS_C) != stack_frame) {
zval *stack_zval_p = zend_vm_stack_pop(TSRMLS_C);
zval_ptr_dtor(&stack_zval_p);
@@ -5013,27 +5011,32 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
/* further blocks will not be relevant... */
break;
- } else if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
+ }
+ if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
catch_op_num = EX(op_array)->try_catch_array[i].catch_op;
- catched = 1;
+ }
+ if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) {
+ finally_op_num = EX(op_array)->try_catch_array[i].finally_op;
}
}
- while (EX(fbc)) {
- EX(called_scope) = (zend_class_entry*)zend_ptr_stack_pop(&EG(arg_types_stack));
- if (EX(object)) {
- if (IS_CTOR_CALL(EX(called_scope))) {
- if (IS_CTOR_USED(EX(called_scope))) {
- Z_DELREF_P(EX(object));
- }
- if (Z_REFCOUNT_P(EX(object)) == 1) {
- zend_object_store_ctor_failed(EX(object) TSRMLS_CC);
+ if (EX(call) >= EX(call_slots)) {
+ call_slot *call = EX(call);
+ do {
+ if (call->object) {
+ if (call->is_ctor_call) {
+ if (call->is_ctor_result_used) {
+ Z_DELREF_P(call->object);
+ }
+ if (Z_REFCOUNT_P(call->object) == 1) {
+ zend_object_store_ctor_failed(call->object TSRMLS_CC);
+ }
}
+ zval_ptr_dtor(&call->object);
}
- zval_ptr_dtor(&EX(object));
- }
- EX(called_scope) = DECODE_CTOR(EX(called_scope));
- zend_arg_types_stack_2_pop(&EG(arg_types_stack), &EX(object), &EX(fbc));
+ call--;
+ } while (call >= EX(call_slots));
+ EX(call) = NULL;
}
for (i=0; i<EX(op_array)->last_brk_cont; i++) {
@@ -5043,7 +5046,7 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
/* further blocks will not be relevant... */
break;
} else if (op_num < EX(op_array)->brk_cont_array[i].brk) {
- if (!catched ||
+ if (!catch_op_num ||
catch_op_num >= EX(op_array)->brk_cont_array[i].brk) {
zend_op *brk_opline = &EX(op_array)->opcodes[EX(op_array)->brk_cont_array[i].brk];
@@ -5065,6 +5068,8 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
/* restore previous error_reporting value */
if (!EG(error_reporting) && EX(old_error_reporting) != NULL && Z_LVAL_P(EX(old_error_reporting)) != 0) {
+ zval restored_error_reporting;
+
Z_TYPE(restored_error_reporting) = IS_LONG;
Z_LVAL(restored_error_reporting) = Z_LVAL_P(EX(old_error_reporting));
convert_to_string(&restored_error_reporting);
@@ -5073,12 +5078,21 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
}
EX(old_error_reporting) = NULL;
- if (!catched) {
- ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
- } else {
+ if (finally_op_num && (!catch_op_num || catch_op_num >= finally_op_num)) {
+ zend_exception_save(TSRMLS_C);
+ EX(fast_ret) = NULL;
+ ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+ ZEND_VM_CONTINUE();
+ } else if (catch_op_num) {
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
- ZEND_VM_CONTINUE();
- }
+ ZEND_VM_CONTINUE();
+ } else {
+ if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0)) {
+ ZEND_VM_DISPATCH_TO_HANDLER(ZEND_GENERATOR_RETURN);
+ } else {
+ ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
+ }
+ }
}
ZEND_VM_HANDLER(146, ZEND_VERIFY_ABSTRACT_CLASS, ANY, ANY)
@@ -5104,7 +5118,11 @@ ZEND_VM_HANDLER(150, ZEND_USER_OPCODE, ANY, ANY)
case ZEND_USER_OPCODE_CONTINUE:
ZEND_VM_CONTINUE();
case ZEND_USER_OPCODE_RETURN:
- ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
+ if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0)) {
+ ZEND_VM_DISPATCH_TO_HANDLER(ZEND_GENERATOR_RETURN);
+ } else {
+ ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
+ }
case ZEND_USER_OPCODE_ENTER:
ZEND_VM_ENTER();
case ZEND_USER_OPCODE_LEAVE:
@@ -5169,7 +5187,7 @@ ZEND_VM_HANDLER(153, ZEND_DECLARE_LAMBDA_FUNCTION, CONST, UNUSED)
zend_error_noreturn(E_ERROR, "Base lambda function for closure not found");
}
- zend_create_closure(&EX_T(opline->result.var).tmp_var, op_array, EG(scope), EG(This) TSRMLS_CC);
+ zend_create_closure(&EX_T(opline->result.var).tmp_var, (zend_function *) op_array, EG(scope), EG(This) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -5183,8 +5201,8 @@ ZEND_VM_HANDLER(156, ZEND_SEPARATE, VAR, UNUSED)
SAVE_OPLINE();
var_ptr = EX_T(opline->op1.var).var.ptr;
if (Z_TYPE_P(var_ptr) != IS_OBJECT &&
- !PZVAL_IS_REF(var_ptr) &&
- Z_REFCOUNT_P(var_ptr) > 1) {
+ !PZVAL_IS_REF(var_ptr) &&
+ Z_REFCOUNT_P(var_ptr) > 1) {
Z_DELREF_P(var_ptr);
ALLOC_ZVAL(new_zv);
@@ -5196,4 +5214,216 @@ ZEND_VM_HANDLER(156, ZEND_SEPARATE, VAR, UNUSED)
ZEND_VM_NEXT_OPCODE();
}
+ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSED)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (OP1_TYPE != IS_UNUSED) {
+ zend_free_op free_op1;
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = GET_OP1_ZVAL_PTR(BP_VAR_R);
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!IS_OP1_TMP_FREE()) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_W);
+
+ if (OP1_TYPE == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* If a function call result is yielded and the function did
+ * not return by reference we throw a notice. */
+ if (OP1_TYPE == IS_VAR && !Z_ISREF_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ FREE_OP1_IF_VAR();
+ }
+ } else {
+ zval *value = GET_OP1_ZVAL_PTR(BP_VAR_R);
+
+ /* Consts, temporary variables and references need copying */
+ if (OP1_TYPE == IS_CONST || OP1_TYPE == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!IS_OP1_TMP_FREE()) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ FREE_OP1_IF_VAR();
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (OP2_TYPE != IS_UNUSED) {
+ zend_free_op free_op2;
+ zval *key = GET_OP2_ZVAL_PTR(BP_VAR_R);
+
+ /* Consts, temporary variables and references need copying */
+ if (OP2_TYPE == IS_CONST || OP2_TYPE == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!IS_OP2_TMP_FREE()) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ FREE_OP2_IF_VAR();
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
+ZEND_VM_HANDLER(159, ZEND_DISCARD_EXCEPTION, ANY, ANY)
+{
+ if (EG(prev_exception) != NULL) {
+ /* discard the previously thrown exception */
+ zval_ptr_dtor(&EG(prev_exception));
+ EG(prev_exception) = NULL;
+ }
+
+ ZEND_VM_NEXT_OPCODE();
+}
+
+ZEND_VM_HANDLER(162, ZEND_FAST_CALL, ANY, ANY)
+{
+ USE_OPLINE
+
+ if (opline->extended_value &&
+ UNEXPECTED(EG(prev_exception) != NULL)) {
+ /* in case of unhandled exception jump to catch block instead of finally */
+ ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.opline_num]);
+ ZEND_VM_CONTINUE();
+ }
+ EX(fast_ret) = opline + 1;
+ ZEND_VM_SET_OPCODE(opline->op1.jmp_addr);
+ ZEND_VM_CONTINUE();
+}
+
+ZEND_VM_HANDLER(163, ZEND_FAST_RET, ANY, ANY)
+{
+ if (EX(fast_ret)) {
+ ZEND_VM_SET_OPCODE(EX(fast_ret));
+ ZEND_VM_CONTINUE();
+ } else {
+ /* special case for unhandled exceptions */
+ USE_OPLINE
+
+ if (opline->extended_value == ZEND_FAST_RET_TO_FINALLY) {
+ ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.opline_num]);
+ ZEND_VM_CONTINUE();
+ } else if (opline->extended_value == ZEND_FAST_RET_TO_CATCH) {
+ zend_exception_restore(TSRMLS_C);
+ ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.opline_num]);
+ ZEND_VM_CONTINUE();
+ } else if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0)) {
+ zend_exception_restore(TSRMLS_C);
+ ZEND_VM_DISPATCH_TO_HANDLER(ZEND_GENERATOR_RETURN);
+ } else {
+ zend_exception_restore(TSRMLS_C);
+ ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
+ }
+ }
+}
+
ZEND_VM_EXPORT_HELPER(zend_do_fcall, zend_do_fcall_common_helper)
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index fa997b287e..511a40b37e 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -20,6 +20,13 @@
#ifdef ZEND_WIN32
# pragma warning(once : 4101)
+# pragma warning(once : 6235)
+# pragma warning(once : 6237)
+# pragma warning(once : 6239)
+# pragma warning(once : 6240)
+# pragma warning(once : 6285)
+# pragma warning(once : 6286)
+# pragma warning(once : 6326)
#endif
static user_opcode_handler_t zend_user_opcode_handlers[256] = {
(user_opcode_handler_t)NULL,
@@ -326,79 +333,25 @@ static opcode_handler_t zend_vm_get_opcode_handler(zend_uchar opcode, zend_op* o
#define ZEND_VM_DISPATCH(opcode, opline) return zend_vm_get_opcode_handler(opcode, opline)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
#define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL execute_data TSRMLS_CC
-#undef EX
-#define EX(element) execute_data->element
-#undef EX_CV
-#define EX_CV(var) EX(CVs)[var]
-#undef EX_CVs
-#define EX_CVs() EX(CVs)
-#undef EX_T
-#define EX_T(offset) (*(temp_variable *)((char *) EX(Ts) + offset))
-#undef EX_Ts
-#define EX_Ts() EX(Ts)
-
-
-ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)
+ZEND_API void execute_ex(zend_execute_data *execute_data TSRMLS_DC)
{
DCL_OPLINE
- zend_execute_data *execute_data;
- zend_bool nested = 0;
- zend_bool original_in_execution = EG(in_execution);
+ zend_bool original_in_execution;
- if (EG(exception)) {
- return;
- }
+ original_in_execution = EG(in_execution);
EG(in_execution) = 1;
+ if (0) {
zend_vm_enter:
- /* Initialize execute_data */
- execute_data = (zend_execute_data *)zend_vm_stack_alloc(
- 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 + ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data)));
- memset(EX(CVs), 0, sizeof(zval**) * op_array->last_var);
- 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;
- EX(old_error_reporting) = NULL;
- EX(op_array) = op_array;
- EX(symbol_table) = EG(active_symbol_table);
- EX(prev_execute_data) = EG(current_execute_data);
- EG(current_execute_data) = execute_data;
- EX(nested) = nested;
- nested = 1;
-
- LOAD_REGS();
-
- if (!op_array->run_time_cache && op_array->last_cache_slot) {
- op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*));
+ execute_data = i_create_execute_data_from_op_array(EG(active_op_array), 1 TSRMLS_CC);
}
- if (op_array->this_var != -1 && EG(This)) {
- Z_ADDREF_P(EG(This)); /* For $this pointer */
- if (!EG(active_symbol_table)) {
- EX_CV(op_array->this_var) = (zval**)EX_CVs() + (op_array->last_var + op_array->this_var);
- *EX_CV(op_array->this_var) = EG(This);
- } else {
- if (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), (void**)&EX_CV(op_array->this_var))==FAILURE) {
- Z_DELREF_P(EG(This));
- }
- }
- }
-
- EX(opline) = UNEXPECTED((op_array->fn_flags & ZEND_ACC_INTERACTIVE) != 0) && EG(start_op) ? EG(start_op) : op_array->opcodes;
- EG(opline_ptr) = &EX(opline);
+ LOAD_REGS();
LOAD_OPLINE();
- EX(function_state).function = (zend_function *) op_array;
- EX(function_state).arguments = NULL;
-
while (1) {
int ret;
#ifdef ZEND_WIN32
@@ -413,10 +366,11 @@ zend_vm_enter:
EG(in_execution) = original_in_execution;
return;
case 2:
- op_array = EG(active_op_array);
goto zend_vm_enter;
+ break;
case 3:
execute_data = EG(current_execute_data);
+ break;
default:
break;
}
@@ -426,59 +380,31 @@ zend_vm_enter:
zend_error_noreturn(E_ERROR, "Arrived at end of main loop which shouldn't happen");
}
-static int ZEND_FASTCALL ZEND_JMP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+ZEND_API void zend_execute(zend_op_array *op_array TSRMLS_DC)
{
- USE_OPLINE
-
-#if DEBUG_ZEND>=2
- printf("Jumping to %d\n", opline->op1.opline_num);
-#endif
- ZEND_VM_SET_OPCODE(opline->op1.jmp_addr);
- ZEND_VM_CONTINUE(); /* CHECK_ME */
-}
-
-static int ZEND_FASTCALL ZEND_INIT_STRING_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
-{
- USE_OPLINE
- zval *tmp = &EX_T(opline->result.var).tmp_var;
-
- SAVE_OPLINE();
- tmp->value.str.val = emalloc(1);
- tmp->value.str.val[0] = 0;
- tmp->value.str.len = 0;
- Z_SET_REFCOUNT_P(tmp, 1);
- tmp->type = IS_STRING;
- Z_UNSET_ISREF_P(tmp);
- /*CHECK_EXCEPTION();*/
- ZEND_VM_NEXT_OPCODE();
+ if (EG(exception)) {
+ return;
+ }
+ zend_execute_ex(i_create_execute_data_from_op_array(op_array, 0 TSRMLS_CC) TSRMLS_CC);
}
static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
{
- zend_bool nested;
+ zend_bool nested = EX(nested);
zend_op_array *op_array = EX(op_array);
EG(current_execute_data) = EX(prev_execute_data);
EG(opline_ptr) = NULL;
if (!EG(active_symbol_table)) {
- zval ***cv = EX_CVs();
- zval ***end = cv + op_array->last_var;
- while (cv != end) {
- if (*cv) {
- zval_ptr_dtor(*cv);
- }
- cv++;
- }
+ i_free_compiled_variables(execute_data);
}
+ zend_vm_stack_free((char*)execute_data - (ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * op_array->T) TSRMLS_CC);
+
if ((op_array->fn_flags & ZEND_ACC_CLOSURE) && op_array->prototype) {
zval_ptr_dtor((zval**)&op_array->prototype);
}
- nested = EX(nested);
-
- zend_vm_stack_free(execute_data TSRMLS_CC);
-
if (nested) {
execute_data = EG(current_execute_data);
}
@@ -491,7 +417,6 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
EX(function_state).function = (zend_function *) EX(op_array);
EX(function_state).arguments = NULL;
- EX(object) = EX(current_object);
EG(opline_ptr) = &EX(opline);
EG(active_op_array) = EX(op_array);
@@ -501,34 +426,16 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
if (UNEXPECTED(EG(exception) != NULL)) {
zend_throw_exception_internal(NULL TSRMLS_CC);
HANDLE_EXCEPTION_LEAVE();
- } else if (RETURN_VALUE_USED(opline)) {
- if (!EX_T(opline->result.var).var.ptr) { /* there was no return statement */
- zval *retval;
-
- ALLOC_ZVAL(retval);
- ZVAL_BOOL(retval, 1);
- INIT_PZVAL(retval);
- EX_T(opline->result.var).var.ptr = retval;
- }
}
ZEND_VM_INC_OPCODE();
ZEND_VM_LEAVE();
} else {
-
EG(opline_ptr) = &EX(opline);
EG(active_op_array) = EX(op_array);
EG(return_value_ptr_ptr) = EX(original_return_value);
if (EG(active_symbol_table)) {
- if (EG(symtable_cache_ptr)>=EG(symtable_cache_limit)) {
- zend_hash_destroy(EG(active_symbol_table));
- FREE_HASHTABLE(EG(active_symbol_table));
- } else {
- /* clean before putting into the cache, since clean
- could call dtors, which could use cached hash */
- zend_hash_clean(EG(active_symbol_table));
- *(++EG(symtable_cache_ptr)) = EG(active_symbol_table);
- }
+ zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC);
}
EG(active_symbol_table) = EX(symbol_table);
@@ -536,8 +443,8 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
EX(function_state).arguments = NULL;
if (EG(This)) {
- if (UNEXPECTED(EG(exception) != NULL) && IS_CTOR_CALL(EX(called_scope))) {
- if (IS_CTOR_USED(EX(called_scope))) {
+ if (UNEXPECTED(EG(exception) != NULL) && EX(call)->is_ctor_call) {
+ if (EX(call)->is_ctor_result_used) {
Z_DELREF_P(EG(This));
}
if (Z_REFCOUNT_P(EG(This)) == 1) {
@@ -550,10 +457,9 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
EG(scope) = EX(current_scope);
EG(called_scope) = EX(current_called_scope);
- EX(object) = EX(current_object);
- EX(called_scope) = DECODE_CTOR(EX(called_scope));
+ EX(call)--;
- zend_vm_stack_clear_multiple(TSRMLS_C);
+ zend_vm_stack_clear_multiple(1 TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
zend_throw_exception_internal(NULL TSRMLS_CC);
@@ -577,6 +483,7 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
zend_function *fbc = EX(function_state).function;
SAVE_OPLINE();
+ EX(object) = EX(call)->object;
if (UNEXPECTED((fbc->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) != 0)) {
if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_ABSTRACT) != 0)) {
zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", fbc->common.scope->name, fbc->common.function_name);
@@ -611,16 +518,14 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
EX(current_called_scope) = EG(called_scope);
EG(This) = EX(object);
EG(scope) = (fbc->type == ZEND_USER_FUNCTION || !EX(object)) ? fbc->common.scope : NULL;
- EG(called_scope) = EX(called_scope);
+ EG(called_scope) = EX(call)->called_scope;
}
- zend_arg_types_stack_3_pop(&EG(arg_types_stack), &EX(called_scope), &EX(current_object), &EX(fbc));
- EX(function_state).arguments = zend_vm_stack_push_args(opline->extended_value TSRMLS_CC);
+ EX(function_state).arguments = zend_vm_stack_top(TSRMLS_C);
+ zend_vm_stack_push((void*)(zend_uintptr_t)opline->extended_value TSRMLS_CC);
LOAD_OPLINE();
if (fbc->type == ZEND_INTERNAL_FUNCTION) {
- temp_variable *ret = &EX_T(opline->result.var);
-
if (fbc->common.arg_info) {
zend_uint i=0;
zval **p = (zval**)EX(function_state).arguments;
@@ -633,6 +538,8 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
}
if (EXPECTED(EG(exception) == NULL)) {
+ temp_variable *ret = &EX_T(opline->result.var);
+
MAKE_STD_ZVAL(ret->var.ptr);
ZVAL_NULL(ret->var.ptr);
ret->var.ptr_ptr = &ret->var.ptr;
@@ -642,7 +549,7 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
/* saves one function call if zend_execute_internal is not used */
fbc->internal_function.handler(opline->extended_value, ret->var.ptr, (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ? &ret->var.ptr : NULL, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
} else {
- zend_execute_internal(execute_data, RETURN_VALUE_USED(opline) TSRMLS_CC);
+ zend_execute_internal(execute_data, NULL, RETURN_VALUE_USED(opline) TSRMLS_CC);
}
if (!RETURN_VALUE_USED(opline)) {
@@ -665,7 +572,11 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
ret->var.fcall_returned_reference = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0;
}
- if (EXPECTED(zend_execute == execute)) {
+ if (UNEXPECTED((EG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0)) {
+ if (RETURN_VALUE_USED(opline)) {
+ EX_T(opline->result.var).var.ptr = zend_generator_create_zval(EG(active_op_array) TSRMLS_CC);
+ }
+ } else if (EXPECTED(zend_execute_ex == execute_ex)) {
if (EXPECTED(EG(exception) == NULL)) {
ZEND_VM_ENTER();
}
@@ -677,22 +588,14 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
EG(active_op_array) = EX(op_array);
EG(return_value_ptr_ptr) = EX(original_return_value);
if (EG(active_symbol_table)) {
- if (EG(symtable_cache_ptr)>=EG(symtable_cache_limit)) {
- zend_hash_destroy(EG(active_symbol_table));
- FREE_HASHTABLE(EG(active_symbol_table));
- } else {
- /* clean before putting into the cache, since clean
- could call dtors, which could use cached hash */
- zend_hash_clean(EG(active_symbol_table));
- *(++EG(symtable_cache_ptr)) = EG(active_symbol_table);
- }
+ zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC);
}
EG(active_symbol_table) = EX(symbol_table);
} else { /* ZEND_OVERLOADED_FUNCTION */
MAKE_STD_ZVAL(EX_T(opline->result.var).var.ptr);
ZVAL_NULL(EX_T(opline->result.var).var.ptr);
- /* Not sure what should be done here if it's a static method */
+ /* Not sure what should be done here if it's a static method */
if (EXPECTED(EX(object) != NULL)) {
Z_OBJ_HT_P(EX(object))->call_method(fbc->common.function_name, opline->extended_value, EX_T(opline->result.var).var.ptr, &EX_T(opline->result.var).var.ptr, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
} else {
@@ -719,8 +622,8 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
if (should_change_scope) {
if (EG(This)) {
- if (UNEXPECTED(EG(exception) != NULL) && IS_CTOR_CALL(EX(called_scope))) {
- if (IS_CTOR_USED(EX(called_scope))) {
+ if (UNEXPECTED(EG(exception) != NULL) && EX(call)->is_ctor_call) {
+ if (EX(call)->is_ctor_result_used) {
Z_DELREF_P(EG(This));
}
if (Z_REFCOUNT_P(EG(This)) == 1) {
@@ -734,10 +637,9 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
EG(called_scope) = EX(current_called_scope);
}
- EX(object) = EX(current_object);
- EX(called_scope) = DECODE_CTOR(EX(called_scope));
+ EX(call)--;
- zend_vm_stack_clear_multiple(TSRMLS_C);
+ zend_vm_stack_clear_multiple(1 TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
zend_throw_exception_internal(NULL TSRMLS_CC);
@@ -750,12 +652,51 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_JMP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+#if DEBUG_ZEND>=2
+ printf("Jumping to %d\n", opline->op1.opline_num);
+#endif
+ ZEND_VM_SET_OPCODE(opline->op1.jmp_addr);
+ ZEND_VM_CONTINUE();
+}
+
+static int ZEND_FASTCALL ZEND_INIT_STRING_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zval *tmp = &EX_T(opline->result.var).tmp_var;
+
+ SAVE_OPLINE();
+ tmp->value.str.val = emalloc(1);
+ tmp->value.str.val[0] = 0;
+ tmp->value.str.len = 0;
+ Z_SET_REFCOUNT_P(tmp, 1);
+ tmp->type = IS_STRING;
+ Z_UNSET_ISREF_P(tmp);
+ /*CHECK_EXCEPTION();*/
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
- EX(function_state).function = EX(fbc);
+ EX(function_state).function = EX(call)->fbc;
return zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_GENERATOR_RETURN_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ /* Close the generator to free up resources */
+ zend_generator_close(generator, 1 TSRMLS_CC);
+
+ /* Pass execution back to handling code */
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -787,7 +728,7 @@ static int ZEND_FASTCALL ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zval **var_ptr;
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param, opline->extended_value TSRMLS_CC);
- var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->result.var TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
Z_DELREF_PP(var_ptr);
*var_ptr = *param;
Z_ADDREF_PP(var_ptr);
@@ -827,17 +768,20 @@ static int ZEND_FASTCALL ZEND_NEW_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
}
ZEND_VM_JMP(EX(op_array)->opcodes + opline->op2.opline_num);
} else {
+ call_slot *call = EX(call_slots) + opline->extended_value;
+
if (RETURN_VALUE_USED(opline)) {
PZVAL_LOCK(object_zval);
AI_SET_PTR(&EX_T(opline->result.var), object_zval);
}
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), ENCODE_CTOR(EX(called_scope), RETURN_VALUE_USED(opline)));
-
/* We are not handling overloaded classes right now */
- EX(object) = object_zval;
- EX(fbc) = constructor;
- EX(called_scope) = EX_T(opline->op1.var).class_entry;
+ call->fbc = constructor;
+ call->object = object_zval;
+ call->called_scope = EX_T(opline->op1.var).class_entry;
+ call->is_ctor_call = 1;
+ call->is_ctor_result_used = RETURN_VALUE_USED(opline);
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -1037,13 +981,15 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
{
zend_uint op_num = EG(opline_before_exception)-EG(active_op_array)->opcodes;
int i;
- zend_uint catch_op_num = 0;
- int catched = 0;
- zval restored_error_reporting;
+ zend_uint catch_op_num = 0, finally_op_num = 0;
+ void **stack_frame;
- void **stack_frame = (void**)(((char*)EX_Ts()) +
- (ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * EX(op_array)->T));
+ /* Figure out where the next stack frame (which maybe contains pushed
+ * arguments that have to be dtor'ed) starts */
+ stack_frame = zend_vm_stack_frame_base(execute_data);
+ /* If the exception was thrown during a function call there might be
+ * arguments pushed to the stack that have to be dtor'ed. */
while (zend_vm_stack_top(TSRMLS_C) != stack_frame) {
zval *stack_zval_p = zend_vm_stack_pop(TSRMLS_C);
zval_ptr_dtor(&stack_zval_p);
@@ -1053,27 +999,32 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
if (EG(active_op_array)->try_catch_array[i].try_op > op_num) {
/* further blocks will not be relevant... */
break;
- } else if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
+ }
+ if (op_num < EG(active_op_array)->try_catch_array[i].catch_op) {
catch_op_num = EX(op_array)->try_catch_array[i].catch_op;
- catched = 1;
+ }
+ if (op_num < EG(active_op_array)->try_catch_array[i].finally_op) {
+ finally_op_num = EX(op_array)->try_catch_array[i].finally_op;
}
}
- while (EX(fbc)) {
- EX(called_scope) = (zend_class_entry*)zend_ptr_stack_pop(&EG(arg_types_stack));
- if (EX(object)) {
- if (IS_CTOR_CALL(EX(called_scope))) {
- if (IS_CTOR_USED(EX(called_scope))) {
- Z_DELREF_P(EX(object));
- }
- if (Z_REFCOUNT_P(EX(object)) == 1) {
- zend_object_store_ctor_failed(EX(object) TSRMLS_CC);
+ if (EX(call) >= EX(call_slots)) {
+ call_slot *call = EX(call);
+ do {
+ if (call->object) {
+ if (call->is_ctor_call) {
+ if (call->is_ctor_result_used) {
+ Z_DELREF_P(call->object);
+ }
+ if (Z_REFCOUNT_P(call->object) == 1) {
+ zend_object_store_ctor_failed(call->object TSRMLS_CC);
+ }
}
+ zval_ptr_dtor(&call->object);
}
- zval_ptr_dtor(&EX(object));
- }
- EX(called_scope) = DECODE_CTOR(EX(called_scope));
- zend_arg_types_stack_2_pop(&EG(arg_types_stack), &EX(object), &EX(fbc));
+ call--;
+ } while (call >= EX(call_slots));
+ EX(call) = NULL;
}
for (i=0; i<EX(op_array)->last_brk_cont; i++) {
@@ -1083,7 +1034,7 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
/* further blocks will not be relevant... */
break;
} else if (op_num < EX(op_array)->brk_cont_array[i].brk) {
- if (!catched ||
+ if (!catch_op_num ||
catch_op_num >= EX(op_array)->brk_cont_array[i].brk) {
zend_op *brk_opline = &EX(op_array)->opcodes[EX(op_array)->brk_cont_array[i].brk];
@@ -1105,6 +1056,8 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
/* restore previous error_reporting value */
if (!EG(error_reporting) && EX(old_error_reporting) != NULL && Z_LVAL_P(EX(old_error_reporting)) != 0) {
+ zval restored_error_reporting;
+
Z_TYPE(restored_error_reporting) = IS_LONG;
Z_LVAL(restored_error_reporting) = Z_LVAL_P(EX(old_error_reporting));
convert_to_string(&restored_error_reporting);
@@ -1113,12 +1066,21 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
}
EX(old_error_reporting) = NULL;
- if (!catched) {
- return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
- } else {
+ if (finally_op_num && (!catch_op_num || catch_op_num >= finally_op_num)) {
+ zend_exception_save(TSRMLS_C);
+ EX(fast_ret) = NULL;
+ ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+ ZEND_VM_CONTINUE();
+ } else if (catch_op_num) {
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
- ZEND_VM_CONTINUE();
- }
+ ZEND_VM_CONTINUE();
+ } else {
+ if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0)) {
+ return ZEND_GENERATOR_RETURN_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ } else {
+ return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ }
+ }
}
static int ZEND_FASTCALL ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -1144,7 +1106,11 @@ static int ZEND_FASTCALL ZEND_USER_OPCODE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS
case ZEND_USER_OPCODE_CONTINUE:
ZEND_VM_CONTINUE();
case ZEND_USER_OPCODE_RETURN:
- return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0)) {
+ return ZEND_GENERATOR_RETURN_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ } else {
+ return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ }
case ZEND_USER_OPCODE_ENTER:
ZEND_VM_ENTER();
case ZEND_USER_OPCODE_LEAVE:
@@ -1156,12 +1122,66 @@ static int ZEND_FASTCALL ZEND_USER_OPCODE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS
}
}
+static int ZEND_FASTCALL ZEND_DISCARD_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ if (EG(prev_exception) != NULL) {
+ /* discard the previously thrown exception */
+ zval_ptr_dtor(&EG(prev_exception));
+ EG(prev_exception) = NULL;
+ }
+
+ ZEND_VM_NEXT_OPCODE();
+}
+
+static int ZEND_FASTCALL ZEND_FAST_CALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ if (opline->extended_value &&
+ UNEXPECTED(EG(prev_exception) != NULL)) {
+ /* in case of unhandled exception jump to catch block instead of finally */
+ ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.opline_num]);
+ ZEND_VM_CONTINUE();
+ }
+ EX(fast_ret) = opline + 1;
+ ZEND_VM_SET_OPCODE(opline->op1.jmp_addr);
+ ZEND_VM_CONTINUE();
+}
+
+static int ZEND_FASTCALL ZEND_FAST_RET_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ if (EX(fast_ret)) {
+ ZEND_VM_SET_OPCODE(EX(fast_ret));
+ ZEND_VM_CONTINUE();
+ } else {
+ /* special case for unhandled exceptions */
+ USE_OPLINE
+
+ if (opline->extended_value == ZEND_FAST_RET_TO_FINALLY) {
+ ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.opline_num]);
+ ZEND_VM_CONTINUE();
+ } else if (opline->extended_value == ZEND_FAST_RET_TO_CATCH) {
+ zend_exception_restore(TSRMLS_C);
+ ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.opline_num]);
+ ZEND_VM_CONTINUE();
+ } else if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) != 0)) {
+ zend_exception_restore(TSRMLS_C);
+ return ZEND_GENERATOR_RETURN_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ } else {
+ zend_exception_restore(TSRMLS_C);
+ return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ }
+ }
+}
+
static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
SAVE_OPLINE();
- EG(exception) = NULL;
+ if (EG(exception)) {
+ zend_exception_save(TSRMLS_C);
+ }
if (IS_CONST == IS_UNUSED) {
EX_T(opline->result.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC);
CHECK_EXCEPTION();
@@ -1182,6 +1202,9 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLE
} else if (Z_TYPE_P(class_name) == IS_STRING) {
EX_T(opline->result.var).class_entry = zend_fetch_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), opline->extended_value TSRMLS_CC);
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string");
}
@@ -1194,19 +1217,22 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE
{
USE_OPLINE
zval *function_name;
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
+ call_slot *call = EX(call_slots) + opline->result.num;
if (IS_CONST == IS_CONST) {
function_name = (zval*)(opline->op2.literal+1);
if (CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
- } else if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &EX(fbc)) == FAILURE)) {
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
+ } else if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &call->fbc) == FAILURE)) {
SAVE_OPLINE();
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
} else {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
}
- EX(object) = NULL;
+ call->object = NULL;
+ call->called_scope = NULL;
+ call->is_ctor_call = 0;
+ EX(call) = call;
/*CHECK_EXCEPTION();*/
ZEND_VM_NEXT_OPCODE();
} else {
@@ -1226,28 +1252,33 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE
} else {
lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen);
}
- if (UNEXPECTED(zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &EX(fbc)) == FAILURE)) {
+ if (UNEXPECTED(zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &call->fbc) == FAILURE)) {
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
}
efree(lcname);
- EX(object) = NULL;
+ call->object = NULL;
+ call->called_scope = NULL;
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else if (IS_CONST != IS_CONST && IS_CONST != IS_TMP_VAR &&
EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) &&
Z_OBJ_HANDLER_P(function_name, get_closure) &&
- Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &EX(called_scope), &EX(fbc), &EX(object) TSRMLS_CC) == SUCCESS) {
- if (EX(object)) {
- Z_ADDREF_P(EX(object));
+ Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &call->called_scope, &call->fbc, &call->object TSRMLS_CC) == SUCCESS) {
+ if (call->object) {
+ Z_ADDREF_P(call->object);
}
if (IS_CONST == IS_VAR && 0 &&
- EX(fbc)->common.fn_flags & ZEND_ACC_CLOSURE) {
+ call->fbc->common.fn_flags & ZEND_ACC_CLOSURE) {
/* Delay closure destruction until its invocation */
- EX(fbc)->common.prototype = (zend_function*)function_name;
+ call->fbc->common.prototype = (zend_function*)function_name;
} else {
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else if (IS_CONST != IS_CONST &&
@@ -1274,52 +1305,56 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE
if (Z_TYPE_PP(obj) == IS_STRING) {
ce = zend_fetch_class_by_name(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj), NULL, 0 TSRMLS_CC);
- if (UNEXPECTED(EG(exception) != NULL)) {
- HANDLE_EXCEPTION();
- }
if (UNEXPECTED(ce == NULL)) {
- zend_error_noreturn(E_ERROR, "Class '%s' not found", Z_STRVAL_PP(obj));
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
- EX(called_scope) = ce;
- EX(object) = NULL;
+ call->called_scope = ce;
+ call->object = NULL;
if (ce->get_static_method) {
- EX(fbc) = ce->get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method) TSRMLS_CC);
+ call->fbc = ce->get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method) TSRMLS_CC);
} else {
- EX(fbc) = zend_std_get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
+ call->fbc = zend_std_get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
}
} else {
- EX(object) = *obj;
- ce = EX(called_scope) = Z_OBJCE_PP(obj);
+ call->object = *obj;
+ ce = call->called_scope = Z_OBJCE_PP(obj);
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), Z_STRVAL_PP(method));
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), Z_STRVAL_PP(method));
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
}
- if (UNEXPECTED(EX(fbc) == NULL)) {
+ if (UNEXPECTED(call->fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, Z_STRVAL_PP(method));
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Function name must be a string");
+ ZEND_VM_NEXT_OPCODE(); /* Never reached */
}
}
}
@@ -1329,25 +1364,27 @@ static int ZEND_FASTCALL ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPC
{
USE_OPLINE
zend_literal *func_name;
-
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
+ call_slot *call = EX(call_slots) + opline->result.num;
func_name = opline->op2.literal + 1;
if (CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
- } else if (zend_hash_quick_find(EG(function_table), Z_STRVAL(func_name->constant), Z_STRLEN(func_name->constant)+1, func_name->hash_value, (void **) &EX(fbc))==FAILURE) {
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
+ } else if (zend_hash_quick_find(EG(function_table), Z_STRVAL(func_name->constant), Z_STRLEN(func_name->constant)+1, func_name->hash_value, (void **) &call->fbc)==FAILURE) {
func_name++;
- if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL(func_name->constant), Z_STRLEN(func_name->constant)+1, func_name->hash_value, (void **) &EX(fbc))==FAILURE)) {
+ if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL(func_name->constant), Z_STRLEN(func_name->constant)+1, func_name->hash_value, (void **) &call->fbc)==FAILURE)) {
SAVE_OPLINE();
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
} else {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
}
} else {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
}
- EX(object) = NULL;
+ call->object = NULL;
+ call->called_scope = NULL;
+ call->is_ctor_call = 0;
+ EX(call) = call;
ZEND_VM_NEXT_OPCODE();
}
@@ -1377,7 +1414,7 @@ static int ZEND_FASTCALL ZEND_RECV_INIT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_
}
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value, opline->extended_value TSRMLS_CC);
- var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->result.var TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
zval_ptr_dtor(var_ptr);
*var_ptr = assignment_value;
@@ -1392,7 +1429,7 @@ static int ZEND_FASTCALL ZEND_BRK_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->op1.opline_num,
- EX(op_array), EX_Ts() TSRMLS_CC);
+ EX(op_array), execute_data TSRMLS_CC);
ZEND_VM_JMP(EX(op_array)->opcodes + el->brk);
}
@@ -1403,7 +1440,7 @@ static int ZEND_FASTCALL ZEND_CONT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->op1.opline_num,
- EX(op_array), EX_Ts() TSRMLS_CC);
+ EX(op_array), execute_data TSRMLS_CC);
ZEND_VM_JMP(EX(op_array)->opcodes + el->cont);
}
@@ -1415,7 +1452,7 @@ static int ZEND_FASTCALL ZEND_GOTO_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->extended_value,
- EX(op_array), EX_Ts() TSRMLS_CC);
+ EX(op_array), execute_data TSRMLS_CC);
brk_opline = EX(op_array)->opcodes + el->brk;
@@ -1466,14 +1503,16 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_
USE_OPLINE
SAVE_OPLINE();
- EG(exception) = NULL;
+ if (EG(exception)) {
+ zend_exception_save(TSRMLS_C);
+ }
if (IS_TMP_VAR == IS_UNUSED) {
EX_T(opline->result.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else {
zend_free_op free_op2;
- zval *class_name = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *class_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_TMP_VAR == IS_CONST) {
if (CACHED_PTR(opline->op2.literal->cache_slot)) {
@@ -1487,6 +1526,9 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_
} else if (Z_TYPE_P(class_name) == IS_STRING) {
EX_T(opline->result.var).class_entry = zend_fetch_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), opline->extended_value TSRMLS_CC);
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string");
}
@@ -1500,19 +1542,22 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H
{
USE_OPLINE
zval *function_name;
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
+ call_slot *call = EX(call_slots) + opline->result.num;
if (IS_TMP_VAR == IS_CONST) {
function_name = (zval*)(opline->op2.literal+1);
if (CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
- } else if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &EX(fbc)) == FAILURE)) {
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
+ } else if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &call->fbc) == FAILURE)) {
SAVE_OPLINE();
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
} else {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
}
- EX(object) = NULL;
+ call->object = NULL;
+ call->called_scope = NULL;
+ call->is_ctor_call = 0;
+ EX(call) = call;
/*CHECK_EXCEPTION();*/
ZEND_VM_NEXT_OPCODE();
} else {
@@ -1521,7 +1566,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H
zend_free_op free_op2;
SAVE_OPLINE();
- function_name = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ function_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
function_name_strval = Z_STRVAL_P(function_name);
@@ -1532,28 +1577,33 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H
} else {
lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen);
}
- if (UNEXPECTED(zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &EX(fbc)) == FAILURE)) {
+ if (UNEXPECTED(zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &call->fbc) == FAILURE)) {
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
}
efree(lcname);
zval_dtor(free_op2.var);
- EX(object) = NULL;
+ call->object = NULL;
+ call->called_scope = NULL;
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else if (IS_TMP_VAR != IS_CONST && IS_TMP_VAR != IS_TMP_VAR &&
EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) &&
Z_OBJ_HANDLER_P(function_name, get_closure) &&
- Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &EX(called_scope), &EX(fbc), &EX(object) TSRMLS_CC) == SUCCESS) {
- if (EX(object)) {
- Z_ADDREF_P(EX(object));
+ Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &call->called_scope, &call->fbc, &call->object TSRMLS_CC) == SUCCESS) {
+ if (call->object) {
+ Z_ADDREF_P(call->object);
}
if (IS_TMP_VAR == IS_VAR && 1 &&
- EX(fbc)->common.fn_flags & ZEND_ACC_CLOSURE) {
+ call->fbc->common.fn_flags & ZEND_ACC_CLOSURE) {
/* Delay closure destruction until its invocation */
- EX(fbc)->common.prototype = (zend_function*)function_name;
+ call->fbc->common.prototype = (zend_function*)function_name;
} else {
zval_dtor(free_op2.var);
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else if (IS_TMP_VAR != IS_CONST &&
@@ -1580,52 +1630,56 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H
if (Z_TYPE_PP(obj) == IS_STRING) {
ce = zend_fetch_class_by_name(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj), NULL, 0 TSRMLS_CC);
- if (UNEXPECTED(EG(exception) != NULL)) {
- HANDLE_EXCEPTION();
- }
if (UNEXPECTED(ce == NULL)) {
- zend_error_noreturn(E_ERROR, "Class '%s' not found", Z_STRVAL_PP(obj));
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
- EX(called_scope) = ce;
- EX(object) = NULL;
+ call->called_scope = ce;
+ call->object = NULL;
if (ce->get_static_method) {
- EX(fbc) = ce->get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method) TSRMLS_CC);
+ call->fbc = ce->get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method) TSRMLS_CC);
} else {
- EX(fbc) = zend_std_get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
+ call->fbc = zend_std_get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
}
} else {
- EX(object) = *obj;
- ce = EX(called_scope) = Z_OBJCE_PP(obj);
+ call->object = *obj;
+ ce = call->called_scope = Z_OBJCE_PP(obj);
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), Z_STRVAL_PP(method));
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), Z_STRVAL_PP(method));
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
}
- if (UNEXPECTED(EX(fbc) == NULL)) {
+ if (UNEXPECTED(call->fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, Z_STRVAL_PP(method));
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Function name must be a string");
+ ZEND_VM_NEXT_OPCODE(); /* Never reached */
}
}
}
@@ -1636,14 +1690,16 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_
USE_OPLINE
SAVE_OPLINE();
- EG(exception) = NULL;
+ if (EG(exception)) {
+ zend_exception_save(TSRMLS_C);
+ }
if (IS_VAR == IS_UNUSED) {
EX_T(opline->result.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else {
zend_free_op free_op2;
- zval *class_name = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *class_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_VAR == IS_CONST) {
if (CACHED_PTR(opline->op2.literal->cache_slot)) {
@@ -1657,6 +1713,9 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_
} else if (Z_TYPE_P(class_name) == IS_STRING) {
EX_T(opline->result.var).class_entry = zend_fetch_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), opline->extended_value TSRMLS_CC);
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string");
}
@@ -1670,19 +1729,22 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H
{
USE_OPLINE
zval *function_name;
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
+ call_slot *call = EX(call_slots) + opline->result.num;
if (IS_VAR == IS_CONST) {
function_name = (zval*)(opline->op2.literal+1);
if (CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
- } else if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &EX(fbc)) == FAILURE)) {
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
+ } else if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &call->fbc) == FAILURE)) {
SAVE_OPLINE();
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
} else {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
}
- EX(object) = NULL;
+ call->object = NULL;
+ call->called_scope = NULL;
+ call->is_ctor_call = 0;
+ EX(call) = call;
/*CHECK_EXCEPTION();*/
ZEND_VM_NEXT_OPCODE();
} else {
@@ -1691,7 +1753,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H
zend_free_op free_op2;
SAVE_OPLINE();
- function_name = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
function_name_strval = Z_STRVAL_P(function_name);
@@ -1702,28 +1764,33 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H
} else {
lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen);
}
- if (UNEXPECTED(zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &EX(fbc)) == FAILURE)) {
+ if (UNEXPECTED(zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &call->fbc) == FAILURE)) {
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
}
efree(lcname);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
- EX(object) = NULL;
+ call->object = NULL;
+ call->called_scope = NULL;
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else if (IS_VAR != IS_CONST && IS_VAR != IS_TMP_VAR &&
EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) &&
Z_OBJ_HANDLER_P(function_name, get_closure) &&
- Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &EX(called_scope), &EX(fbc), &EX(object) TSRMLS_CC) == SUCCESS) {
- if (EX(object)) {
- Z_ADDREF_P(EX(object));
+ Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &call->called_scope, &call->fbc, &call->object TSRMLS_CC) == SUCCESS) {
+ if (call->object) {
+ Z_ADDREF_P(call->object);
}
if (IS_VAR == IS_VAR && (free_op2.var != NULL) &&
- EX(fbc)->common.fn_flags & ZEND_ACC_CLOSURE) {
+ call->fbc->common.fn_flags & ZEND_ACC_CLOSURE) {
/* Delay closure destruction until its invocation */
- EX(fbc)->common.prototype = (zend_function*)function_name;
+ call->fbc->common.prototype = (zend_function*)function_name;
} else {
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else if (IS_VAR != IS_CONST &&
@@ -1750,52 +1817,56 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H
if (Z_TYPE_PP(obj) == IS_STRING) {
ce = zend_fetch_class_by_name(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj), NULL, 0 TSRMLS_CC);
- if (UNEXPECTED(EG(exception) != NULL)) {
- HANDLE_EXCEPTION();
- }
if (UNEXPECTED(ce == NULL)) {
- zend_error_noreturn(E_ERROR, "Class '%s' not found", Z_STRVAL_PP(obj));
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
- EX(called_scope) = ce;
- EX(object) = NULL;
+ call->called_scope = ce;
+ call->object = NULL;
if (ce->get_static_method) {
- EX(fbc) = ce->get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method) TSRMLS_CC);
+ call->fbc = ce->get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method) TSRMLS_CC);
} else {
- EX(fbc) = zend_std_get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
+ call->fbc = zend_std_get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
}
} else {
- EX(object) = *obj;
- ce = EX(called_scope) = Z_OBJCE_PP(obj);
+ call->object = *obj;
+ ce = call->called_scope = Z_OBJCE_PP(obj);
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), Z_STRVAL_PP(method));
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), Z_STRVAL_PP(method));
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
}
- if (UNEXPECTED(EX(fbc) == NULL)) {
+ if (UNEXPECTED(call->fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, Z_STRVAL_PP(method));
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Function name must be a string");
+ ZEND_VM_NEXT_OPCODE(); /* Never reached */
}
}
}
@@ -1806,7 +1877,9 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDL
USE_OPLINE
SAVE_OPLINE();
- EG(exception) = NULL;
+ if (EG(exception)) {
+ zend_exception_save(TSRMLS_C);
+ }
if (IS_UNUSED == IS_UNUSED) {
EX_T(opline->result.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC);
CHECK_EXCEPTION();
@@ -1827,6 +1900,9 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDL
} else if (Z_TYPE_P(class_name) == IS_STRING) {
EX_T(opline->result.var).class_entry = zend_fetch_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), opline->extended_value TSRMLS_CC);
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string");
}
@@ -1840,14 +1916,16 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_A
USE_OPLINE
SAVE_OPLINE();
- EG(exception) = NULL;
+ if (EG(exception)) {
+ zend_exception_save(TSRMLS_C);
+ }
if (IS_CV == IS_UNUSED) {
EX_T(opline->result.var).class_entry = zend_fetch_class(NULL, 0, opline->extended_value TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else {
- zval *class_name = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ zval *class_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_CV == IS_CONST) {
if (CACHED_PTR(opline->op2.literal->cache_slot)) {
@@ -1861,6 +1939,9 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_A
} else if (Z_TYPE_P(class_name) == IS_STRING) {
EX_T(opline->result.var).class_entry = zend_fetch_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), opline->extended_value TSRMLS_CC);
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string");
}
@@ -1873,19 +1954,22 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA
{
USE_OPLINE
zval *function_name;
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
+ call_slot *call = EX(call_slots) + opline->result.num;
if (IS_CV == IS_CONST) {
function_name = (zval*)(opline->op2.literal+1);
if (CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
- } else if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &EX(fbc)) == FAILURE)) {
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
+ } else if (UNEXPECTED(zend_hash_quick_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name)+1, Z_HASH_P(function_name), (void **) &call->fbc) == FAILURE)) {
SAVE_OPLINE();
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
} else {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
}
- EX(object) = NULL;
+ call->object = NULL;
+ call->called_scope = NULL;
+ call->is_ctor_call = 0;
+ EX(call) = call;
/*CHECK_EXCEPTION();*/
ZEND_VM_NEXT_OPCODE();
} else {
@@ -1894,7 +1978,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA
SAVE_OPLINE();
- function_name = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) {
function_name_strval = Z_STRVAL_P(function_name);
@@ -1905,28 +1989,33 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA
} else {
lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen);
}
- if (UNEXPECTED(zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &EX(fbc)) == FAILURE)) {
+ if (UNEXPECTED(zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &call->fbc) == FAILURE)) {
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval);
}
efree(lcname);
- EX(object) = NULL;
+ call->object = NULL;
+ call->called_scope = NULL;
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else if (IS_CV != IS_CONST && IS_CV != IS_TMP_VAR &&
EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) &&
Z_OBJ_HANDLER_P(function_name, get_closure) &&
- Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &EX(called_scope), &EX(fbc), &EX(object) TSRMLS_CC) == SUCCESS) {
- if (EX(object)) {
- Z_ADDREF_P(EX(object));
+ Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &call->called_scope, &call->fbc, &call->object TSRMLS_CC) == SUCCESS) {
+ if (call->object) {
+ Z_ADDREF_P(call->object);
}
if (IS_CV == IS_VAR && 0 &&
- EX(fbc)->common.fn_flags & ZEND_ACC_CLOSURE) {
+ call->fbc->common.fn_flags & ZEND_ACC_CLOSURE) {
/* Delay closure destruction until its invocation */
- EX(fbc)->common.prototype = (zend_function*)function_name;
+ call->fbc->common.prototype = (zend_function*)function_name;
} else {
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else if (IS_CV != IS_CONST &&
@@ -1953,52 +2042,56 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA
if (Z_TYPE_PP(obj) == IS_STRING) {
ce = zend_fetch_class_by_name(Z_STRVAL_PP(obj), Z_STRLEN_PP(obj), NULL, 0 TSRMLS_CC);
- if (UNEXPECTED(EG(exception) != NULL)) {
- HANDLE_EXCEPTION();
- }
if (UNEXPECTED(ce == NULL)) {
- zend_error_noreturn(E_ERROR, "Class '%s' not found", Z_STRVAL_PP(obj));
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
- EX(called_scope) = ce;
- EX(object) = NULL;
+ call->called_scope = ce;
+ call->object = NULL;
if (ce->get_static_method) {
- EX(fbc) = ce->get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method) TSRMLS_CC);
+ call->fbc = ce->get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method) TSRMLS_CC);
} else {
- EX(fbc) = zend_std_get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
+ call->fbc = zend_std_get_static_method(ce, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
}
} else {
- EX(object) = *obj;
- ce = EX(called_scope) = Z_OBJCE_PP(obj);
+ call->object = *obj;
+ ce = call->called_scope = Z_OBJCE_PP(obj);
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), Z_STRVAL_PP(method));
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, Z_STRVAL_PP(method), Z_STRLEN_PP(method), NULL TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), Z_STRVAL_PP(method));
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
}
- if (UNEXPECTED(EX(fbc) == NULL)) {
+ if (UNEXPECTED(call->fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, Z_STRVAL_PP(method));
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Function name must be a string");
+ ZEND_VM_NEXT_OPCODE(); /* Never reached */
}
}
}
@@ -2217,8 +2310,7 @@ static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
USE_OPLINE
zval *fname = opline->op1.zv;
-
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
+ call_slot *call = EX(call_slots) + opline->op2.num;
if (CACHED_PTR(opline->op1.literal->cache_slot)) {
EX(function_state).function = CACHED_PTR(opline->op1.literal->cache_slot);
@@ -2228,7 +2320,11 @@ static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
} else {
CACHE_PTR(opline->op1.literal->cache_slot, EX(function_state).function);
}
- EX(object) = NULL;
+ call->fbc = EX(function_state).function;
+ call->object = NULL;
+ call->called_scope = NULL;
+ call->is_ctor_call = 0;
+ EX(call) = call;
return zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
@@ -2246,14 +2342,17 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
if (IS_CONST == IS_TMP_VAR) {
}
- } else if (!0) { /* Not a temp var */
+ } else {
if (IS_CONST == IS_CONST ||
- (PZVAL_IS_REF(retval_ptr) && Z_REFCOUNT_P(retval_ptr) > 0)) {
+ IS_CONST == IS_TMP_VAR ||
+ PZVAL_IS_REF(retval_ptr)) {
zval *ret;
ALLOC_ZVAL(ret);
INIT_PZVAL_COPY(ret, retval_ptr);
- zval_copy_ctor(ret);
+ if (IS_CONST != IS_TMP_VAR) {
+ zval_copy_ctor(ret);
+ }
*EG(return_value_ptr_ptr) = ret;
} else if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) &&
retval_ptr == &EG(uninitialized_zval)) {
@@ -2265,12 +2364,6 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
*EG(return_value_ptr_ptr) = retval_ptr;
Z_ADDREF_P(retval_ptr);
}
- } else {
- zval *ret;
-
- ALLOC_ZVAL(ret);
- INIT_PZVAL_COPY(ret, retval_ptr);
- *EG(return_value_ptr_ptr) = ret;
}
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -2357,8 +2450,12 @@ static int ZEND_FASTCALL ZEND_THROW_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS
value = opline->op1.zv;
if (IS_CONST == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Can only throw objects");
}
+
zend_exception_save(TSRMLS_C);
/* Not sure if a complete copy is what we want here */
ALLOC_ZVAL(exception);
@@ -2379,7 +2476,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
if (opline->extended_value==ZEND_DO_FCALL_BY_NAME
- && ARG_MUST_BE_SENT_BY_REF(EX(fbc), opline->op2.opline_num)) {
+ && ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) {
zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.opline_num);
}
{
@@ -2429,6 +2526,9 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS
if (IS_CONST == IS_CONST ||
UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "__clone method called on non-object");
}
@@ -2543,7 +2643,7 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HA
zend_op_array *new_op_array=NULL;
zval *inc_filename;
- zval *tmp_inc_filename = NULL;
+ zval *tmp_inc_filename = NULL;
zend_bool failure_retval=0;
SAVE_OPLINE();
@@ -2635,8 +2735,6 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HA
EG(return_value_ptr_ptr) = NULL;
}
- EX(current_object) = EX(object);
-
EX(function_state).function = (zend_function *) new_op_array;
EX(object) = NULL;
@@ -2644,14 +2742,13 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HA
zend_rebuild_symbol_table(TSRMLS_C);
}
- if (EXPECTED(zend_execute == execute)) {
+ if (EXPECTED(zend_execute_ex == execute_ex)) {
ZEND_VM_ENTER();
} else {
zend_execute(new_op_array TSRMLS_CC);
}
EX(function_state).function = (zend_function *) EX(op_array);
- EX(object) = EX(current_object);
EG(opline_ptr) = &EX(opline);
EG(active_op_array) = EX(op_array);
@@ -2661,15 +2758,6 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HA
if (UNEXPECTED(EG(exception) != NULL)) {
zend_throw_exception_internal(NULL TSRMLS_CC);
HANDLE_EXCEPTION();
- } else if (RETURN_VALUE_USED(opline)) {
- if (!EX_T(opline->result.var).var.ptr) { /* there was no return statement */
- zval *retval;
-
- ALLOC_ZVAL(retval);
- ZVAL_BOOL(retval, 1);
- INIT_PZVAL(retval);
- EX_T(opline->result.var).var.ptr = retval;
- }
}
} else if (RETURN_VALUE_USED(opline)) {
@@ -2802,7 +2890,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
zend_uchar key_type;
key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 0, NULL);
- if (key_type != HASH_KEY_NON_EXISTANT &&
+ if (key_type != HASH_KEY_NON_EXISTENT &&
(key_type == HASH_KEY_IS_LONG ||
zend_check_property_access(zobj, str_key, str_key_len-1 TSRMLS_CC) == SUCCESS)) {
break;
@@ -3378,7 +3466,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_CONST_CONST_HANDLER(ZEND_OPCO
{
USE_OPLINE
- return zend_fetch_var_address_helper_SPEC_CONST_CONST(ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ return zend_fetch_var_address_helper_SPEC_CONST_CONST(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -3391,6 +3479,25 @@ static int ZEND_FASTCALL ZEND_FETCH_IS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HAN
return zend_fetch_var_address_helper_SPEC_CONST_CONST(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ zval *container;
+
+ SAVE_OPLINE();
+
+ if (IS_CONST == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
+ PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
+ }
+ container = opline->op1.zv;
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC);
+
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_FETCH_DIM_TMP_VAR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -3420,9 +3527,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER(
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (IS_CONST == IS_CONST) {
/* no function found. try a static method in class */
@@ -3438,24 +3545,24 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER(
}
CACHE_PTR(opline->op1.literal->cache_slot, ce);
}
- EX(called_scope) = ce;
+ call->called_scope = ce;
} else {
ce = EX_T(opline->op1.var).class_entry;
if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
- EX(called_scope) = EG(called_scope);
+ call->called_scope = EG(called_scope);
} else {
- EX(called_scope) = ce;
+ call->called_scope = ce;
}
}
if (IS_CONST == IS_CONST &&
IS_CONST == IS_CONST &&
CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
} else if (IS_CONST != IS_CONST &&
IS_CONST == IS_CONST &&
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
/* do nothing */
} else if (IS_CONST != IS_UNUSED) {
char *function_name_strval = NULL;
@@ -3469,6 +3576,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER(
function_name = opline->op2.zv;
if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Function name must be a string");
} else {
function_name_strval = Z_STRVAL_P(function_name);
@@ -3478,20 +3588,20 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER(
if (function_name_strval) {
if (ce->get_static_method) {
- EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
+ call->fbc = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
} else {
- EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_CONST == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ call->fbc = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_CONST == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
}
- if (UNEXPECTED(EX(fbc) == NULL)) {
+ if (UNEXPECTED(call->fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
}
if (IS_CONST == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
if (IS_CONST == IS_CONST) {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
} else {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, EX(fbc));
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, call->fbc);
}
}
}
@@ -3505,29 +3615,31 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER(
if (EG(This) && Z_OBJCE_P(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name);
}
- EX(fbc) = ce->constructor;
+ call->fbc = ce->constructor;
}
- if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
- EX(object) = NULL;
+ if (call->fbc->common.fn_flags & ZEND_ACC_STATIC) {
+ call->object = NULL;
} else {
if (EG(This) &&
Z_OBJ_HT_P(EG(This))->get_class_entry &&
!instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
- if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
} else {
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
}
}
- if ((EX(object) = EG(This))) {
- Z_ADDREF_P(EX(object));
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if ((call->object = EG(This))) {
+ Z_ADDREF_P(call->object);
+ call->called_scope = Z_OBJCE_P(call->object);
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -3635,6 +3747,9 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCO
}
ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value);
zval_copy_ctor(&EX_T(opline->result.var).tmp_var);
+ } else if (Z_STRLEN_P(opline->op2.zv) == sizeof("class")-1 && strcmp(Z_STRVAL_P(opline->op2.zv), "class") == 0) {
+ /* "class" is assigned as a case-sensitive keyword from zend_do_resolve_class_name */
+ ZVAL_STRINGL(&EX_T(opline->result.var).tmp_var, ce->name, ce->name_length, 1);
} else {
zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(opline->op2.zv));
}
@@ -3947,6 +4062,163 @@ static int ZEND_FASTCALL ZEND_DECLARE_CONST_SPEC_CONST_CONST_HANDLER(ZEND_OPCOD
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_CONST != IS_UNUSED) {
+
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = opline->op1.zv;
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = NULL;
+
+ if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* If a function call result is yielded and the function did
+ * not return by reference we throw a notice. */
+ if (IS_CONST == IS_VAR && !Z_ISREF_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = opline->op1.zv;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_CONST != IS_UNUSED) {
+
+ zval *key = opline->op2.zv;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_ADD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -3955,7 +4227,7 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_add_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -3970,7 +4242,7 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_sub_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -3985,7 +4257,7 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_mul_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -4000,7 +4272,7 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_div_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -4015,7 +4287,7 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_mod_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -4030,7 +4302,7 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
shift_left_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -4045,7 +4317,7 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
shift_right_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -4060,7 +4332,7 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
concat_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -4075,7 +4347,7 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_H
SAVE_OPLINE();
is_identical_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -4091,7 +4363,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CONST_TMP_HANDLER(ZEND_OPCO
SAVE_OPLINE();
is_identical_function(result,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
Z_LVAL_P(result) = !Z_LVAL_P(result);
zval_dtor(free_op2.var);
@@ -4108,7 +4380,7 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDL
SAVE_OPLINE();
ZVAL_BOOL(result, fast_equal_function(result,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -4124,7 +4396,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_H
SAVE_OPLINE();
ZVAL_BOOL(result, fast_not_equal_function(result,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -4140,7 +4412,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HAN
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_function(result,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -4156,7 +4428,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMP_HANDLER(ZEND_O
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -4171,7 +4443,7 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
bitwise_or_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -4186,7 +4458,7 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
bitwise_and_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -4201,7 +4473,7 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
bitwise_xor_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -4216,21 +4488,40 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDL
SAVE_OPLINE();
boolean_xor_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zend_free_op free_op2;
+ zval *container;
+
+ SAVE_OPLINE();
+
+ if (IS_CONST == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
+ PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
+ }
+ container = opline->op1.zv;
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
+ zval_dtor(free_op2.var);
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (IS_CONST == IS_CONST) {
/* no function found. try a static method in class */
@@ -4246,24 +4537,24 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZE
}
CACHE_PTR(opline->op1.literal->cache_slot, ce);
}
- EX(called_scope) = ce;
+ call->called_scope = ce;
} else {
ce = EX_T(opline->op1.var).class_entry;
if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
- EX(called_scope) = EG(called_scope);
+ call->called_scope = EG(called_scope);
} else {
- EX(called_scope) = ce;
+ call->called_scope = ce;
}
}
if (IS_CONST == IS_CONST &&
IS_TMP_VAR == IS_CONST &&
CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
} else if (IS_CONST != IS_CONST &&
IS_TMP_VAR == IS_CONST &&
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
/* do nothing */
} else if (IS_TMP_VAR != IS_UNUSED) {
char *function_name_strval = NULL;
@@ -4274,9 +4565,12 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZE
function_name_strval = Z_STRVAL_P(opline->op2.zv);
function_name_strlen = Z_STRLEN_P(opline->op2.zv);
} else {
- function_name = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ function_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Function name must be a string");
} else {
function_name_strval = Z_STRVAL_P(function_name);
@@ -4286,20 +4580,20 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZE
if (function_name_strval) {
if (ce->get_static_method) {
- EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
+ call->fbc = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
} else {
- EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_TMP_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ call->fbc = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_TMP_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
}
- if (UNEXPECTED(EX(fbc) == NULL)) {
+ if (UNEXPECTED(call->fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
}
if (IS_TMP_VAR == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
if (IS_CONST == IS_CONST) {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
} else {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, EX(fbc));
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, call->fbc);
}
}
}
@@ -4313,29 +4607,31 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZE
if (EG(This) && Z_OBJCE_P(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name);
}
- EX(fbc) = ce->constructor;
+ call->fbc = ce->constructor;
}
- if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
- EX(object) = NULL;
+ if (call->fbc->common.fn_flags & ZEND_ACC_STATIC) {
+ call->object = NULL;
} else {
if (EG(This) &&
Z_OBJ_HT_P(EG(This))->get_class_entry &&
!instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
- if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
} else {
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
}
}
- if ((EX(object) = EG(This))) {
- Z_ADDREF_P(EX(object));
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if ((call->object = EG(This))) {
+ Z_ADDREF_P(call->object);
+ call->called_scope = Z_OBJCE_P(call->object);
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -4352,7 +4648,7 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_A
}
is_equal_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -4397,7 +4693,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_HANDLER(ZEND_OPC
if (IS_TMP_VAR != IS_UNUSED) {
zend_free_op free_op2;
- zval *offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
ulong hval;
switch (Z_TYPE_P(offset)) {
@@ -4459,6 +4755,163 @@ static int ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HAN
}
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_CONST != IS_UNUSED) {
+
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = opline->op1.zv;
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = NULL;
+
+ if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* If a function call result is yielded and the function did
+ * not return by reference we throw a notice. */
+ if (IS_CONST == IS_VAR && !Z_ISREF_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = opline->op1.zv;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_TMP_VAR != IS_UNUSED) {
+ zend_free_op free_op2;
+ zval *key = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!1) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_ADD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -4467,7 +4920,7 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_add_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4482,7 +4935,7 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_sub_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4497,7 +4950,7 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_mul_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4512,7 +4965,7 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_div_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4527,7 +4980,7 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_mod_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4542,7 +4995,7 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
shift_left_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4557,7 +5010,7 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
shift_right_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4572,7 +5025,7 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
concat_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4587,7 +5040,7 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_H
SAVE_OPLINE();
is_identical_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4603,7 +5056,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCO
SAVE_OPLINE();
is_identical_function(result,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
Z_LVAL_P(result) = !Z_LVAL_P(result);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
@@ -4620,7 +5073,7 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDL
SAVE_OPLINE();
ZVAL_BOOL(result, fast_equal_function(result,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4636,7 +5089,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_H
SAVE_OPLINE();
ZVAL_BOOL(result, fast_not_equal_function(result,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4652,7 +5105,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HAN
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_function(result,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4668,7 +5121,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_VAR_HANDLER(ZEND_O
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4683,7 +5136,7 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
bitwise_or_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4698,7 +5151,7 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
bitwise_and_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4713,7 +5166,7 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
bitwise_xor_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4728,7 +5181,7 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDL
SAVE_OPLINE();
boolean_xor_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -4886,7 +5339,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE
{
USE_OPLINE
- return zend_fetch_var_address_helper_SPEC_CONST_VAR(ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ return zend_fetch_var_address_helper_SPEC_CONST_VAR(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -4899,14 +5352,33 @@ static int ZEND_FASTCALL ZEND_FETCH_IS_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDL
return zend_fetch_var_address_helper_SPEC_CONST_VAR(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zend_free_op free_op2;
+ zval *container;
+
+ SAVE_OPLINE();
+
+ if (IS_CONST == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
+ PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
+ }
+ container = opline->op1.zv;
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
+ if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (IS_CONST == IS_CONST) {
/* no function found. try a static method in class */
@@ -4922,24 +5394,24 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_VAR_HANDLER(ZE
}
CACHE_PTR(opline->op1.literal->cache_slot, ce);
}
- EX(called_scope) = ce;
+ call->called_scope = ce;
} else {
ce = EX_T(opline->op1.var).class_entry;
if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
- EX(called_scope) = EG(called_scope);
+ call->called_scope = EG(called_scope);
} else {
- EX(called_scope) = ce;
+ call->called_scope = ce;
}
}
if (IS_CONST == IS_CONST &&
IS_VAR == IS_CONST &&
CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
} else if (IS_CONST != IS_CONST &&
IS_VAR == IS_CONST &&
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
/* do nothing */
} else if (IS_VAR != IS_UNUSED) {
char *function_name_strval = NULL;
@@ -4950,9 +5422,12 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_VAR_HANDLER(ZE
function_name_strval = Z_STRVAL_P(opline->op2.zv);
function_name_strlen = Z_STRLEN_P(opline->op2.zv);
} else {
- function_name = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Function name must be a string");
} else {
function_name_strval = Z_STRVAL_P(function_name);
@@ -4962,20 +5437,20 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_VAR_HANDLER(ZE
if (function_name_strval) {
if (ce->get_static_method) {
- EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
+ call->fbc = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
} else {
- EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ call->fbc = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
}
- if (UNEXPECTED(EX(fbc) == NULL)) {
+ if (UNEXPECTED(call->fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
}
if (IS_VAR == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
if (IS_CONST == IS_CONST) {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
} else {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, EX(fbc));
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, call->fbc);
}
}
}
@@ -4989,29 +5464,31 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_VAR_HANDLER(ZE
if (EG(This) && Z_OBJCE_P(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name);
}
- EX(fbc) = ce->constructor;
+ call->fbc = ce->constructor;
}
- if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
- EX(object) = NULL;
+ if (call->fbc->common.fn_flags & ZEND_ACC_STATIC) {
+ call->object = NULL;
} else {
if (EG(This) &&
Z_OBJ_HT_P(EG(This))->get_class_entry &&
!instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
- if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
} else {
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
}
}
- if ((EX(object) = EG(This))) {
- Z_ADDREF_P(EX(object));
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if ((call->object = EG(This))) {
+ Z_ADDREF_P(call->object);
+ call->called_scope = Z_OBJCE_P(call->object);
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -5028,7 +5505,7 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_A
}
is_equal_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -5073,7 +5550,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_VAR_HANDLER(ZEND_OPC
if (IS_VAR != IS_UNUSED) {
zend_free_op free_op2;
- zval *offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
ulong hval;
switch (Z_TYPE_P(offset)) {
@@ -5298,6 +5775,164 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_VAR_HANDLER(ZEND_OPC
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_CONST != IS_UNUSED) {
+
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = opline->op1.zv;
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = NULL;
+
+ if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* If a function call result is yielded and the function did
+ * not return by reference we throw a notice. */
+ if (IS_CONST == IS_VAR && !Z_ISREF_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = opline->op1.zv;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_VAR != IS_UNUSED) {
+ zend_free_op free_op2;
+ zval *key = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_UNUSED(int type, ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -5449,7 +6084,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_CONST_UNUSED_HANDLER(ZEND_OPC
{
USE_OPLINE
- return zend_fetch_var_address_helper_SPEC_CONST_UNUSED(ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ return zend_fetch_var_address_helper_SPEC_CONST_UNUSED(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -5467,9 +6102,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (IS_CONST == IS_CONST) {
/* no function found. try a static method in class */
@@ -5485,24 +6120,24 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER
}
CACHE_PTR(opline->op1.literal->cache_slot, ce);
}
- EX(called_scope) = ce;
+ call->called_scope = ce;
} else {
ce = EX_T(opline->op1.var).class_entry;
if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
- EX(called_scope) = EG(called_scope);
+ call->called_scope = EG(called_scope);
} else {
- EX(called_scope) = ce;
+ call->called_scope = ce;
}
}
if (IS_CONST == IS_CONST &&
IS_UNUSED == IS_CONST &&
CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
} else if (IS_CONST != IS_CONST &&
IS_UNUSED == IS_CONST &&
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
/* do nothing */
} else if (IS_UNUSED != IS_UNUSED) {
char *function_name_strval = NULL;
@@ -5516,6 +6151,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER
function_name = NULL;
if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Function name must be a string");
} else {
function_name_strval = Z_STRVAL_P(function_name);
@@ -5525,20 +6163,20 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER
if (function_name_strval) {
if (ce->get_static_method) {
- EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
+ call->fbc = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
} else {
- EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_UNUSED == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ call->fbc = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_UNUSED == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
}
- if (UNEXPECTED(EX(fbc) == NULL)) {
+ if (UNEXPECTED(call->fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
}
if (IS_UNUSED == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
if (IS_CONST == IS_CONST) {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
} else {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, EX(fbc));
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, call->fbc);
}
}
}
@@ -5552,29 +6190,31 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER
if (EG(This) && Z_OBJCE_P(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name);
}
- EX(fbc) = ce->constructor;
+ call->fbc = ce->constructor;
}
- if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
- EX(object) = NULL;
+ if (call->fbc->common.fn_flags & ZEND_ACC_STATIC) {
+ call->object = NULL;
} else {
if (EG(This) &&
Z_OBJ_HT_P(EG(This))->get_class_entry &&
!instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
- if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
} else {
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
}
}
- if ((EX(object) = EG(This))) {
- Z_ADDREF_P(EX(object));
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if ((call->object = EG(This))) {
+ Z_ADDREF_P(call->object);
+ call->called_scope = Z_OBJCE_P(call->object);
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -5855,12 +6495,169 @@ static int ZEND_FASTCALL ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_UNUSED_HANDLER
zend_error_noreturn(E_ERROR, "Base lambda function for closure not found");
}
- zend_create_closure(&EX_T(opline->result.var).tmp_var, op_array, EG(scope), EG(This) TSRMLS_CC);
+ zend_create_closure(&EX_T(opline->result.var).tmp_var, (zend_function *) op_array, EG(scope), EG(This) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_CONST != IS_UNUSED) {
+
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = opline->op1.zv;
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = NULL;
+
+ if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* If a function call result is yielded and the function did
+ * not return by reference we throw a notice. */
+ if (IS_CONST == IS_VAR && !Z_ISREF_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = opline->op1.zv;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_UNUSED != IS_UNUSED) {
+
+ zval *key = NULL;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_ADD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -5869,7 +6666,7 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
fast_add_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -5884,7 +6681,7 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
fast_sub_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -5899,7 +6696,7 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
fast_mul_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -5914,7 +6711,7 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
fast_div_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -5929,7 +6726,7 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
fast_mod_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -5944,7 +6741,7 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
shift_left_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -5959,7 +6756,7 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
shift_right_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -5974,7 +6771,7 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
concat_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -5989,7 +6786,7 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HA
SAVE_OPLINE();
is_identical_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -6005,7 +6802,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CV_HANDLER(ZEND_OPCOD
SAVE_OPLINE();
is_identical_function(result,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
Z_LVAL_P(result) = !Z_LVAL_P(result);
@@ -6022,7 +6819,7 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLE
SAVE_OPLINE();
ZVAL_BOOL(result, fast_equal_function(result,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC));
CHECK_EXCEPTION();
@@ -6038,7 +6835,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HA
SAVE_OPLINE();
ZVAL_BOOL(result, fast_not_equal_function(result,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC));
CHECK_EXCEPTION();
@@ -6054,7 +6851,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HAND
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_function(result,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC));
CHECK_EXCEPTION();
@@ -6070,7 +6867,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_CV_HANDLER(ZEND_OP
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC));
CHECK_EXCEPTION();
@@ -6085,7 +6882,7 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
bitwise_or_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -6100,7 +6897,7 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
bitwise_and_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -6115,7 +6912,7 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
bitwise_xor_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -6130,7 +6927,26 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLE
SAVE_OPLINE();
boolean_xor_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
+
+
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
+static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ zval *container;
+
+ SAVE_OPLINE();
+
+ if (IS_CONST == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
+ PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
+ }
+ container = opline->op1.zv;
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
CHECK_EXCEPTION();
@@ -6142,9 +6958,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEN
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (IS_CONST == IS_CONST) {
/* no function found. try a static method in class */
@@ -6160,24 +6976,24 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEN
}
CACHE_PTR(opline->op1.literal->cache_slot, ce);
}
- EX(called_scope) = ce;
+ call->called_scope = ce;
} else {
ce = EX_T(opline->op1.var).class_entry;
if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
- EX(called_scope) = EG(called_scope);
+ call->called_scope = EG(called_scope);
} else {
- EX(called_scope) = ce;
+ call->called_scope = ce;
}
}
if (IS_CONST == IS_CONST &&
IS_CV == IS_CONST &&
CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
} else if (IS_CONST != IS_CONST &&
IS_CV == IS_CONST &&
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
/* do nothing */
} else if (IS_CV != IS_UNUSED) {
char *function_name_strval = NULL;
@@ -6188,9 +7004,12 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEN
function_name_strval = Z_STRVAL_P(opline->op2.zv);
function_name_strlen = Z_STRLEN_P(opline->op2.zv);
} else {
- function_name = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Function name must be a string");
} else {
function_name_strval = Z_STRVAL_P(function_name);
@@ -6200,20 +7019,20 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEN
if (function_name_strval) {
if (ce->get_static_method) {
- EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
+ call->fbc = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
} else {
- EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_CV == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ call->fbc = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_CV == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
}
- if (UNEXPECTED(EX(fbc) == NULL)) {
+ if (UNEXPECTED(call->fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
}
if (IS_CV == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
if (IS_CONST == IS_CONST) {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
} else {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, EX(fbc));
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, call->fbc);
}
}
}
@@ -6227,29 +7046,31 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEN
if (EG(This) && Z_OBJCE_P(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name);
}
- EX(fbc) = ce->constructor;
+ call->fbc = ce->constructor;
}
- if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
- EX(object) = NULL;
+ if (call->fbc->common.fn_flags & ZEND_ACC_STATIC) {
+ call->object = NULL;
} else {
if (EG(This) &&
Z_OBJ_HT_P(EG(This))->get_class_entry &&
!instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
- if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
} else {
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
}
}
- if ((EX(object) = EG(This))) {
- Z_ADDREF_P(EX(object));
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if ((call->object = EG(This))) {
+ Z_ADDREF_P(call->object);
+ call->called_scope = Z_OBJCE_P(call->object);
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -6299,7 +7120,7 @@ static int ZEND_FASTCALL ZEND_CATCH_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_A
if (EX_CV(opline->op2.var)) {
zval_ptr_dtor(EX_CV(opline->op2.var));
}
- EX_CV(opline->op2.var) = (zval**)EX_CVs() + (EX(op_array)->last_var + opline->op2.var);
+ EX_CV(opline->op2.var) = (zval**)EX_CV_NUM(execute_data, EX(op_array)->last_var + opline->op2.var);
*EX_CV(opline->op2.var) = EG(exception);
} else {
zend_compiled_variable *cv = &CV_DEF_OF(opline->op2.var);
@@ -6326,7 +7147,7 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_AR
}
is_equal_function(&EX_T(opline->result.var).tmp_var,
opline->op1.zv,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -6370,7 +7191,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(ZEND_OPCO
if (IS_CV != IS_UNUSED) {
- zval *offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ zval *offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
ulong hval;
switch (Z_TYPE_P(offset)) {
@@ -6432,6 +7253,163 @@ static int ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HAND
}
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_CONST != IS_UNUSED) {
+
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = opline->op1.zv;
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = NULL;
+
+ if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* If a function call result is yielded and the function did
+ * not return by reference we throw a notice. */
+ if (IS_CONST == IS_VAR && !Z_ISREF_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = opline->op1.zv;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_CV != IS_UNUSED) {
+
+ zval *key = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_BW_NOT_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -6439,7 +7417,7 @@ static int ZEND_FASTCALL ZEND_BW_NOT_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
bitwise_not_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -6452,7 +7430,7 @@ static int ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
boolean_not_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -6465,7 +7443,7 @@ static int ZEND_FASTCALL ZEND_ECHO_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zval *z;
SAVE_OPLINE();
- z = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ z = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR == IS_TMP_VAR && Z_TYPE_P(z) == IS_OBJECT) {
INIT_PZVAL(z);
@@ -6493,7 +7471,7 @@ static int ZEND_FASTCALL ZEND_JMPZ_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
int ret;
SAVE_OPLINE();
- val = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ val = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
ret = Z_LVAL_P(val);
@@ -6523,7 +7501,7 @@ static int ZEND_FASTCALL ZEND_JMPNZ_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
int ret;
SAVE_OPLINE();
- val = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ val = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
ret = Z_LVAL_P(val);
@@ -6553,7 +7531,7 @@ static int ZEND_FASTCALL ZEND_JMPZNZ_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
int retval;
SAVE_OPLINE();
- val = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ val = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
retval = Z_LVAL_P(val);
@@ -6587,7 +7565,7 @@ static int ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS
int retval;
SAVE_OPLINE();
- val = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ val = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
retval = Z_LVAL_P(val);
@@ -6618,7 +7596,7 @@ static int ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
int retval;
SAVE_OPLINE();
- val = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ val = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
retval = Z_LVAL_P(val);
@@ -6662,20 +7640,23 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zend_free_op free_op1;
SAVE_OPLINE();
- retval_ptr = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ retval_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (!EG(return_value_ptr_ptr)) {
if (IS_TMP_VAR == IS_TMP_VAR) {
zval_dtor(free_op1.var);
}
- } else if (!1) { /* Not a temp var */
+ } else {
if (IS_TMP_VAR == IS_CONST ||
- (PZVAL_IS_REF(retval_ptr) && Z_REFCOUNT_P(retval_ptr) > 0)) {
+ IS_TMP_VAR == IS_TMP_VAR ||
+ PZVAL_IS_REF(retval_ptr)) {
zval *ret;
ALLOC_ZVAL(ret);
INIT_PZVAL_COPY(ret, retval_ptr);
- zval_copy_ctor(ret);
+ if (IS_TMP_VAR != IS_TMP_VAR) {
+ zval_copy_ctor(ret);
+ }
*EG(return_value_ptr_ptr) = ret;
} else if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) &&
retval_ptr == &EG(uninitialized_zval)) {
@@ -6687,12 +7668,6 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
*EG(return_value_ptr_ptr) = retval_ptr;
Z_ADDREF_P(retval_ptr);
}
- } else {
- zval *ret;
-
- ALLOC_ZVAL(ret);
- INIT_PZVAL_COPY(ret, retval_ptr);
- *EG(return_value_ptr_ptr) = ret;
}
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -6712,7 +7687,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLE
/* Not supposed to happen, but we'll allow it */
zend_error(E_NOTICE, "Only variable references should be returned by reference");
- retval_ptr = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ retval_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (!EG(return_value_ptr_ptr)) {
if (IS_TMP_VAR == IS_TMP_VAR) {
zval_dtor(free_op1.var);
@@ -6776,11 +7751,15 @@ static int ZEND_FASTCALL ZEND_THROW_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zend_free_op free_op1;
SAVE_OPLINE();
- value = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Can only throw objects");
}
+
zend_exception_save(TSRMLS_C);
/* Not sure if a complete copy is what we want here */
ALLOC_ZVAL(exception);
@@ -6801,7 +7780,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
if (opline->extended_value==ZEND_DO_FCALL_BY_NAME
- && ARG_MUST_BE_SENT_BY_REF(EX(fbc), opline->op2.opline_num)) {
+ && ARG_MUST_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) {
zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.opline_num);
}
{
@@ -6809,7 +7788,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
zval *value;
zend_free_op free_op1;
- value = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
ALLOC_ZVAL(valptr);
INIT_PZVAL_COPY(valptr, value);
@@ -6831,7 +7810,7 @@ static int ZEND_FASTCALL ZEND_BOOL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
/* PHP 3.0 returned "" for false and 1 for true, here we use 0 and 1 for now */
- ZVAL_BOOL(retval, i_zend_is_true(_get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC)));
+ ZVAL_BOOL(retval, i_zend_is_true(_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC)));
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -6848,10 +7827,13 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zend_object_clone_obj_t clone_call;
SAVE_OPLINE();
- obj = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ obj = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR == IS_CONST ||
UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "__clone method called on non-object");
}
@@ -6909,7 +7891,7 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zval *result = &EX_T(opline->result.var).tmp_var;
SAVE_OPLINE();
- expr = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ expr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (opline->extended_value != IS_STRING) {
ZVAL_COPY_VALUE(result, expr);
@@ -6966,11 +7948,11 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HAND
zend_op_array *new_op_array=NULL;
zend_free_op free_op1;
zval *inc_filename;
- zval *tmp_inc_filename = NULL;
+ zval *tmp_inc_filename = NULL;
zend_bool failure_retval=0;
SAVE_OPLINE();
- inc_filename = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ inc_filename = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (inc_filename->type!=IS_STRING) {
MAKE_STD_ZVAL(tmp_inc_filename);
@@ -7058,8 +8040,6 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HAND
EG(return_value_ptr_ptr) = NULL;
}
- EX(current_object) = EX(object);
-
EX(function_state).function = (zend_function *) new_op_array;
EX(object) = NULL;
@@ -7067,14 +8047,13 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HAND
zend_rebuild_symbol_table(TSRMLS_C);
}
- if (EXPECTED(zend_execute == execute)) {
+ if (EXPECTED(zend_execute_ex == execute_ex)) {
ZEND_VM_ENTER();
} else {
zend_execute(new_op_array TSRMLS_CC);
}
EX(function_state).function = (zend_function *) EX(op_array);
- EX(object) = EX(current_object);
EG(opline_ptr) = &EX(opline);
EG(active_op_array) = EX(op_array);
@@ -7084,15 +8063,6 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HAND
if (UNEXPECTED(EG(exception) != NULL)) {
zend_throw_exception_internal(NULL TSRMLS_CC);
HANDLE_EXCEPTION();
- } else if (RETURN_VALUE_USED(opline)) {
- if (!EX_T(opline->result.var).var.ptr) { /* there was no return statement */
- zval *retval;
-
- ALLOC_ZVAL(retval);
- ZVAL_BOOL(retval, 1);
- INIT_PZVAL(retval);
- EX_T(opline->result.var).var.ptr = retval;
- }
}
} else if (RETURN_VALUE_USED(opline)) {
@@ -7147,7 +8117,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
Z_ADDREF_P(array_ptr);
}
} else {
- array_ptr = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ array_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (1) { /* IS_TMP_VAR */
zval *tmp;
@@ -7225,7 +8195,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
zend_uchar key_type;
key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 0, NULL);
- if (key_type != HASH_KEY_NON_EXISTANT &&
+ if (key_type != HASH_KEY_NON_EXISTENT &&
(key_type == HASH_KEY_IS_LONG ||
zend_check_property_access(zobj, str_key, str_key_len-1 TSRMLS_CC) == SUCCESS)) {
break;
@@ -7256,7 +8226,7 @@ static int ZEND_FASTCALL ZEND_EXIT_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
if (IS_TMP_VAR != IS_UNUSED) {
zend_free_op free_op1;
- zval *ptr = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval *ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (Z_TYPE_P(ptr) == IS_LONG) {
EG(exit_status) = Z_LVAL_P(ptr);
@@ -7306,7 +8276,7 @@ static int ZEND_FASTCALL ZEND_JMP_SET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS
zval *value;
SAVE_OPLINE();
- value = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (i_zend_is_true(value)) {
ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, value);
@@ -7332,7 +8302,7 @@ static int ZEND_FASTCALL ZEND_JMP_SET_VAR_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_
zval *value, *ret;
SAVE_OPLINE();
- value = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (i_zend_is_true(value)) {
if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
@@ -7367,7 +8337,7 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
zval *value;
SAVE_OPLINE();
- value = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, value);
if (!1) {
@@ -7385,7 +8355,7 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_VAR_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLE
zval *value, *ret;
SAVE_OPLINE();
- value = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
Z_ADDREF_P(value);
@@ -7413,7 +8383,7 @@ static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_A
zend_bool result;
SAVE_OPLINE();
- expr = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ expr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (Z_TYPE_P(expr) == IS_OBJECT && Z_OBJ_HT_P(expr)->get_class_entry) {
result = instanceof_function(Z_OBJCE_P(expr), EX_T(opline->op2.var).class_entry TSRMLS_CC);
@@ -7433,7 +8403,7 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_add_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
zval_dtor(free_op1.var);
@@ -7448,7 +8418,7 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_sub_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
zval_dtor(free_op1.var);
@@ -7463,7 +8433,7 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_mul_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
zval_dtor(free_op1.var);
@@ -7478,7 +8448,7 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_div_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
zval_dtor(free_op1.var);
@@ -7493,7 +8463,7 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_mod_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
zval_dtor(free_op1.var);
@@ -7508,7 +8478,7 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
shift_left_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
zval_dtor(free_op1.var);
@@ -7523,7 +8493,7 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
shift_right_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
zval_dtor(free_op1.var);
@@ -7538,7 +8508,7 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
concat_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
zval_dtor(free_op1.var);
@@ -7553,7 +8523,7 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_H
SAVE_OPLINE();
is_identical_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
zval_dtor(free_op1.var);
@@ -7569,7 +8539,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCO
SAVE_OPLINE();
is_identical_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
Z_LVAL_P(result) = !Z_LVAL_P(result);
zval_dtor(free_op1.var);
@@ -7586,7 +8556,7 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDL
SAVE_OPLINE();
ZVAL_BOOL(result, fast_equal_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC));
zval_dtor(free_op1.var);
@@ -7602,7 +8572,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_H
SAVE_OPLINE();
ZVAL_BOOL(result, fast_not_equal_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC));
zval_dtor(free_op1.var);
@@ -7618,7 +8588,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HAN
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC));
zval_dtor(free_op1.var);
@@ -7634,7 +8604,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMP_CONST_HANDLER(ZEND_O
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC));
zval_dtor(free_op1.var);
@@ -7649,7 +8619,7 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
bitwise_or_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
zval_dtor(free_op1.var);
@@ -7664,7 +8634,7 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
bitwise_and_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
zval_dtor(free_op1.var);
@@ -7679,7 +8649,7 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
bitwise_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
zval_dtor(free_op1.var);
@@ -7694,7 +8664,7 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDL
SAVE_OPLINE();
boolean_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
zval_dtor(free_op1.var);
@@ -7713,7 +8683,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_CONST(int type,
ulong hash_value;
SAVE_OPLINE();
- varname = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR != IS_CONST && UNEXPECTED(Z_TYPE_P(varname) != IS_STRING)) {
ZVAL_COPY_VALUE(&tmp_varname, varname);
@@ -7853,7 +8823,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE
{
USE_OPLINE
- return zend_fetch_var_address_helper_SPEC_TMP_CONST(ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ return zend_fetch_var_address_helper_SPEC_TMP_CONST(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -7866,6 +8836,25 @@ static int ZEND_FASTCALL ZEND_FETCH_IS_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDL
return zend_fetch_var_address_helper_SPEC_TMP_CONST(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zend_free_op free_op1;
+ zval *container;
+
+ SAVE_OPLINE();
+
+ if (IS_TMP_VAR == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
+ PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
+ }
+ container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC);
+
+ zval_dtor(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_FETCH_DIM_TMP_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -7873,7 +8862,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_TMP_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPC
zval *container;
SAVE_OPLINE();
- container = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_ARRAY)) {
PZVAL_LOCK(&EG(uninitialized_zval));
@@ -7943,63 +8932,72 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST_HANDLER(ZEND_OPCO
char *function_name_strval;
int function_name_strlen;
zend_free_op free_op1;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
function_name = opline->op2.zv;
if (IS_CONST != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ call->object = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (IS_CONST != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((IS_CONST == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_CONST == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (IS_CONST == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
@@ -8016,7 +9014,7 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
is_equal_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
CHECK_EXCEPTION();
@@ -8040,7 +9038,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPC
expr_ptr = *expr_ptr_ptr;
Z_ADDREF_P(expr_ptr);
} else {
- expr_ptr=_get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ expr_ptr=_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (1) { /* temporary variable */
zval *new_expr;
@@ -8147,7 +9145,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HAND
ZEND_VM_NEXT_OPCODE();
}
- varname = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -8225,7 +9223,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPC
} else {
HashTable *target_symbol_table;
zend_free_op free_op1;
- zval tmp, *varname = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval tmp, *varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -8286,6 +9284,163 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPC
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_TMP_VAR != IS_UNUSED) {
+ zend_free_op free_op1;
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!1) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = NULL;
+
+ if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* If a function call result is yielded and the function did
+ * not return by reference we throw a notice. */
+ if (IS_TMP_VAR == IS_VAR && !Z_ISREF_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!1) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_CONST != IS_UNUSED) {
+
+ zval *key = opline->op2.zv;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_ADD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -8293,8 +9448,8 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_add_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8308,8 +9463,8 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_sub_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8323,8 +9478,8 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_mul_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8338,8 +9493,8 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_div_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8353,8 +9508,8 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_mod_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8368,8 +9523,8 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_left_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8383,8 +9538,8 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_right_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8398,8 +9553,8 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
concat_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8413,8 +9568,8 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HAN
SAVE_OPLINE();
is_identical_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8429,8 +9584,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE
SAVE_OPLINE();
is_identical_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
Z_LVAL_P(result) = !Z_LVAL_P(result);
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
@@ -8446,8 +9601,8 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
ZVAL_BOOL(result, fast_equal_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8462,8 +9617,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HAN
SAVE_OPLINE();
ZVAL_BOOL(result, fast_not_equal_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8478,8 +9633,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDL
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8494,8 +9649,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMP_TMP_HANDLER(ZEND_OPC
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8509,8 +9664,8 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
bitwise_or_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8524,8 +9679,8 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
bitwise_and_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8539,8 +9694,8 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
bitwise_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8554,14 +9709,33 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
boolean_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zend_free_op free_op1, free_op2;
+ zval *container;
+
+ SAVE_OPLINE();
+
+ if (IS_TMP_VAR == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
+ PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
+ }
+ container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
+ zval_dtor(free_op2.var);
+ zval_dtor(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -8572,7 +9746,7 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_
int use_copy = 0;
SAVE_OPLINE();
- var = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ var = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_TMP_VAR == IS_UNUSED) {
/* Initialize for erealloc in add_string_to_string */
@@ -8614,63 +9788,72 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE
char *function_name_strval;
int function_name_strlen;
zend_free_op free_op1, free_op2;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
- function_name = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ function_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_TMP_VAR != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ call->object = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (IS_TMP_VAR != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((IS_TMP_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_TMP_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (IS_TMP_VAR == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ zval_dtor(free_op2.var);
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
zval_dtor(free_op2.var);
@@ -8688,8 +9871,8 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
is_equal_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -8713,7 +9896,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_HANDLER(ZEND_OPCOD
expr_ptr = *expr_ptr_ptr;
Z_ADDREF_P(expr_ptr);
} else {
- expr_ptr=_get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ expr_ptr=_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (1) { /* temporary variable */
zval *new_expr;
@@ -8734,7 +9917,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_HANDLER(ZEND_OPCOD
if (IS_TMP_VAR != IS_UNUSED) {
zend_free_op free_op2;
- zval *offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
ulong hval;
switch (Z_TYPE_P(offset)) {
@@ -8796,6 +9979,163 @@ static int ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDL
}
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_TMP_VAR != IS_UNUSED) {
+ zend_free_op free_op1;
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!1) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = NULL;
+
+ if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* If a function call result is yielded and the function did
+ * not return by reference we throw a notice. */
+ if (IS_TMP_VAR == IS_VAR && !Z_ISREF_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!1) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_TMP_VAR != IS_UNUSED) {
+ zend_free_op free_op2;
+ zval *key = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!1) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_ADD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -8803,8 +10143,8 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_add_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -8818,8 +10158,8 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_sub_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -8833,8 +10173,8 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_mul_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -8848,8 +10188,8 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_div_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -8863,8 +10203,8 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_mod_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -8878,8 +10218,8 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_left_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -8893,8 +10233,8 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_right_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -8908,8 +10248,8 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
concat_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -8923,8 +10263,8 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HAN
SAVE_OPLINE();
is_identical_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -8939,8 +10279,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE
SAVE_OPLINE();
is_identical_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
Z_LVAL_P(result) = !Z_LVAL_P(result);
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
@@ -8956,8 +10296,8 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
ZVAL_BOOL(result, fast_equal_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -8972,8 +10312,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HAN
SAVE_OPLINE();
ZVAL_BOOL(result, fast_not_equal_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -8988,8 +10328,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDL
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -9004,8 +10344,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMP_VAR_HANDLER(ZEND_OPC
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -9019,8 +10359,8 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
bitwise_or_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -9034,8 +10374,8 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
bitwise_and_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -9049,8 +10389,8 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
bitwise_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -9064,8 +10404,8 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
boolean_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -9083,7 +10423,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_VAR(int type, ZE
ulong hash_value;
SAVE_OPLINE();
- varname = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR != IS_CONST && UNEXPECTED(Z_TYPE_P(varname) != IS_STRING)) {
ZVAL_COPY_VALUE(&tmp_varname, varname);
@@ -9223,7 +10563,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_H
{
USE_OPLINE
- return zend_fetch_var_address_helper_SPEC_TMP_VAR(ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ return zend_fetch_var_address_helper_SPEC_TMP_VAR(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -9236,6 +10576,25 @@ static int ZEND_FASTCALL ZEND_FETCH_IS_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER
return zend_fetch_var_address_helper_SPEC_TMP_VAR(BP_VAR_IS, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zend_free_op free_op1, free_op2;
+ zval *container;
+
+ SAVE_OPLINE();
+
+ if (IS_TMP_VAR == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
+ PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
+ }
+ container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
+ if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+ zval_dtor(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -9246,7 +10605,7 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_
int use_copy = 0;
SAVE_OPLINE();
- var = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ var = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_TMP_VAR == IS_UNUSED) {
/* Initialize for erealloc in add_string_to_string */
@@ -9288,63 +10647,72 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE
char *function_name_strval;
int function_name_strlen;
zend_free_op free_op1, free_op2;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
- function_name = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_VAR != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ call->object = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (IS_VAR != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((IS_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (IS_VAR == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
@@ -9362,8 +10730,8 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
is_equal_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -9387,7 +10755,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_VAR_HANDLER(ZEND_OPCOD
expr_ptr = *expr_ptr_ptr;
Z_ADDREF_P(expr_ptr);
} else {
- expr_ptr=_get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ expr_ptr=_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (1) { /* temporary variable */
zval *new_expr;
@@ -9408,7 +10776,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_VAR_HANDLER(ZEND_OPCOD
if (IS_VAR != IS_UNUSED) {
zend_free_op free_op2;
- zval *offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
ulong hval;
switch (Z_TYPE_P(offset)) {
@@ -9494,7 +10862,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLE
ZEND_VM_NEXT_OPCODE();
}
- varname = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -9572,7 +10940,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCOD
} else {
HashTable *target_symbol_table;
zend_free_op free_op1;
- zval tmp, *varname = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval tmp, *varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -9633,6 +11001,164 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCOD
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_TMP_VAR != IS_UNUSED) {
+ zend_free_op free_op1;
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!1) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = NULL;
+
+ if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* If a function call result is yielded and the function did
+ * not return by reference we throw a notice. */
+ if (IS_TMP_VAR == IS_VAR && !Z_ISREF_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!1) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_VAR != IS_UNUSED) {
+ zend_free_op free_op2;
+ zval *key = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_UNUSED(int type, ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -9644,7 +11170,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_UNUSED(int type,
ulong hash_value;
SAVE_OPLINE();
- varname = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR != IS_CONST && UNEXPECTED(Z_TYPE_P(varname) != IS_STRING)) {
ZVAL_COPY_VALUE(&tmp_varname, varname);
@@ -9784,7 +11310,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCOD
{
USE_OPLINE
- return zend_fetch_var_address_helper_SPEC_TMP_UNUSED(ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ return zend_fetch_var_address_helper_SPEC_TMP_UNUSED(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -9814,7 +11340,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OP
expr_ptr = *expr_ptr_ptr;
Z_ADDREF_P(expr_ptr);
} else {
- expr_ptr=_get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ expr_ptr=_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (1) { /* temporary variable */
zval *new_expr;
@@ -9921,7 +11447,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HAN
ZEND_VM_NEXT_OPCODE();
}
- varname = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -9999,7 +11525,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_UNUSED_HANDLER(ZEND_OP
} else {
HashTable *target_symbol_table;
zend_free_op free_op1;
- zval tmp, *varname = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval tmp, *varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_TMP_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -10060,6 +11586,163 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_UNUSED_HANDLER(ZEND_OP
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_TMP_VAR != IS_UNUSED) {
+ zend_free_op free_op1;
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!1) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = NULL;
+
+ if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* If a function call result is yielded and the function did
+ * not return by reference we throw a notice. */
+ if (IS_TMP_VAR == IS_VAR && !Z_ISREF_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!1) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_UNUSED != IS_UNUSED) {
+
+ zval *key = NULL;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_ADD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -10067,8 +11750,8 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_add_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -10082,8 +11765,8 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_sub_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -10097,8 +11780,8 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_mul_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -10112,8 +11795,8 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_div_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -10127,8 +11810,8 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_mod_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -10142,8 +11825,8 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_left_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -10157,8 +11840,8 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_right_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -10172,8 +11855,8 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
concat_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -10187,8 +11870,8 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HAND
SAVE_OPLINE();
is_identical_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -10203,8 +11886,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_
SAVE_OPLINE();
is_identical_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
Z_LVAL_P(result) = !Z_LVAL_P(result);
zval_dtor(free_op1.var);
@@ -10220,8 +11903,8 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
ZVAL_BOOL(result, fast_equal_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -10236,8 +11919,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HAND
SAVE_OPLINE();
ZVAL_BOOL(result, fast_not_equal_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -10252,8 +11935,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLE
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -10268,8 +11951,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMP_CV_HANDLER(ZEND_OPCO
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -10283,8 +11966,8 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
bitwise_or_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -10298,8 +11981,8 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
bitwise_and_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -10313,8 +11996,8 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
bitwise_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -10328,14 +12011,33 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
boolean_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zend_free_op free_op1;
+ zval *container;
+
+ SAVE_OPLINE();
+
+ if (IS_TMP_VAR == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
+ PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
+ }
+ container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
+
+ zval_dtor(free_op1.var);
+ CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
+}
+
static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -10346,7 +12048,7 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_A
int use_copy = 0;
SAVE_OPLINE();
- var = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ var = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_TMP_VAR == IS_UNUSED) {
/* Initialize for erealloc in add_string_to_string */
@@ -10387,63 +12089,72 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_
char *function_name_strval;
int function_name_strlen;
zend_free_op free_op1;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
- function_name = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_CV != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ call->object = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (IS_CV != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((IS_CV == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_CV == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (IS_CV == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
@@ -10460,8 +12171,8 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
is_equal_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -10484,7 +12195,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE
expr_ptr = *expr_ptr_ptr;
Z_ADDREF_P(expr_ptr);
} else {
- expr_ptr=_get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ expr_ptr=_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (1) { /* temporary variable */
zval *new_expr;
@@ -10505,7 +12216,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE
if (IS_CV != IS_UNUSED) {
- zval *offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ zval *offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
ulong hval;
switch (Z_TYPE_P(offset)) {
@@ -10567,6 +12278,163 @@ static int ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLE
}
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_TMP_VAR != IS_UNUSED) {
+ zend_free_op free_op1;
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!1) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = NULL;
+
+ if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* If a function call result is yielded and the function did
+ * not return by reference we throw a notice. */
+ if (IS_TMP_VAR == IS_VAR && !Z_ISREF_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!1) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_CV != IS_UNUSED) {
+
+ zval *key = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_BW_NOT_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -10574,7 +12442,7 @@ static int ZEND_FASTCALL ZEND_BW_NOT_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
bitwise_not_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -10587,7 +12455,7 @@ static int ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
boolean_not_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -10600,7 +12468,7 @@ static int ZEND_FASTCALL ZEND_PRE_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
zval **var_ptr;
SAVE_OPLINE();
- var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
@@ -10647,7 +12515,7 @@ static int ZEND_FASTCALL ZEND_PRE_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
zval **var_ptr;
SAVE_OPLINE();
- var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
@@ -10694,7 +12562,7 @@ static int ZEND_FASTCALL ZEND_POST_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
zval **var_ptr, *retval;
SAVE_OPLINE();
- var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
@@ -10737,7 +12605,7 @@ static int ZEND_FASTCALL ZEND_POST_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
zval **var_ptr, *retval;
SAVE_OPLINE();
- var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
@@ -10780,7 +12648,7 @@ static int ZEND_FASTCALL ZEND_ECHO_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zval *z;
SAVE_OPLINE();
- z = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ z = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_TMP_VAR && Z_TYPE_P(z) == IS_OBJECT) {
INIT_PZVAL(z);
@@ -10808,7 +12676,7 @@ static int ZEND_FASTCALL ZEND_JMPZ_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
int ret;
SAVE_OPLINE();
- val = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ val = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
ret = Z_LVAL_P(val);
@@ -10838,7 +12706,7 @@ static int ZEND_FASTCALL ZEND_JMPNZ_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
int ret;
SAVE_OPLINE();
- val = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ val = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
ret = Z_LVAL_P(val);
@@ -10868,7 +12736,7 @@ static int ZEND_FASTCALL ZEND_JMPZNZ_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
int retval;
SAVE_OPLINE();
- val = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ val = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
retval = Z_LVAL_P(val);
@@ -10902,7 +12770,7 @@ static int ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
int retval;
SAVE_OPLINE();
- val = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ val = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
retval = Z_LVAL_P(val);
@@ -10933,7 +12801,7 @@ static int ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
int retval;
SAVE_OPLINE();
- val = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ val = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
retval = Z_LVAL_P(val);
@@ -10977,20 +12845,23 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zend_free_op free_op1;
SAVE_OPLINE();
- retval_ptr = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ retval_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (!EG(return_value_ptr_ptr)) {
if (IS_VAR == IS_TMP_VAR) {
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
}
- } else if (!0) { /* Not a temp var */
+ } else {
if (IS_VAR == IS_CONST ||
- (PZVAL_IS_REF(retval_ptr) && Z_REFCOUNT_P(retval_ptr) > 0)) {
+ IS_VAR == IS_TMP_VAR ||
+ PZVAL_IS_REF(retval_ptr)) {
zval *ret;
ALLOC_ZVAL(ret);
INIT_PZVAL_COPY(ret, retval_ptr);
- zval_copy_ctor(ret);
+ if (IS_VAR != IS_TMP_VAR) {
+ zval_copy_ctor(ret);
+ }
*EG(return_value_ptr_ptr) = ret;
} else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) &&
retval_ptr == &EG(uninitialized_zval)) {
@@ -11002,12 +12873,6 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
*EG(return_value_ptr_ptr) = retval_ptr;
Z_ADDREF_P(retval_ptr);
}
- } else {
- zval *ret;
-
- ALLOC_ZVAL(ret);
- INIT_PZVAL_COPY(ret, retval_ptr);
- *EG(return_value_ptr_ptr) = ret;
}
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -11027,7 +12892,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE
/* Not supposed to happen, but we'll allow it */
zend_error(E_NOTICE, "Only variable references should be returned by reference");
- retval_ptr = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ retval_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (!EG(return_value_ptr_ptr)) {
if (IS_VAR == IS_TMP_VAR) {
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -11049,7 +12914,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE
break;
}
- retval_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ retval_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(retval_ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
@@ -11092,11 +12957,15 @@ static int ZEND_FASTCALL ZEND_THROW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zend_free_op free_op1;
SAVE_OPLINE();
- value = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Can only throw objects");
}
+
zend_exception_save(TSRMLS_C);
/* Not sure if a complete copy is what we want here */
ALLOC_ZVAL(exception);
@@ -11116,7 +12985,7 @@ static int ZEND_FASTCALL zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_AR
USE_OPLINE
zval *varptr;
zend_free_op free_op1;
- varptr = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (varptr == &EG(uninitialized_zval)) {
ALLOC_ZVAL(varptr);
@@ -11150,7 +13019,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND
if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) {
return zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
- } else if (!ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.opline_num)) {
+ } else if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) {
return zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
@@ -11161,7 +13030,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND
varptr = EX_T(opline->op1.var).var.ptr;
PZVAL_UNLOCK_EX(varptr, &free_op1, 0);
} else {
- varptr = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
}
if ((!(opline->extended_value & ZEND_ARG_SEND_FUNCTION) ||
EX_T(opline->op1.var).var.fcall_returned_reference) &&
@@ -11176,7 +13045,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND
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.opline_num)) {
+ !ARG_MAY_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) {
zend_error(E_STRICT, "Only variables should be passed by reference");
}
ALLOC_ZVAL(valptr);
@@ -11199,7 +13068,7 @@ static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
zval *varptr;
SAVE_OPLINE();
- varptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ varptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(varptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Only variables can be passed by reference");
@@ -11214,7 +13083,7 @@ static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
if (opline->extended_value == ZEND_DO_FCALL_BY_NAME &&
EX(function_state).function->type == ZEND_INTERNAL_FUNCTION &&
- !ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.opline_num)) {
+ !ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) {
return zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
@@ -11233,7 +13102,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
USE_OPLINE
if ((opline->extended_value == ZEND_DO_FCALL_BY_NAME)
- && ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.opline_num)) {
+ && ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) {
return ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
SAVE_OPLINE();
@@ -11248,7 +13117,7 @@ static int ZEND_FASTCALL ZEND_BOOL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
/* PHP 3.0 returned "" for false and 1 for true, here we use 0 and 1 for now */
- ZVAL_BOOL(retval, i_zend_is_true(_get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC)));
+ ZVAL_BOOL(retval, i_zend_is_true(_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC)));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -11275,10 +13144,13 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zend_object_clone_obj_t clone_call;
SAVE_OPLINE();
- obj = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ obj = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_CONST ||
UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "__clone method called on non-object");
}
@@ -11336,7 +13208,7 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zval *result = &EX_T(opline->result.var).tmp_var;
SAVE_OPLINE();
- expr = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ expr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (opline->extended_value != IS_STRING) {
ZVAL_COPY_VALUE(result, expr);
@@ -11393,11 +13265,11 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND
zend_op_array *new_op_array=NULL;
zend_free_op free_op1;
zval *inc_filename;
- zval *tmp_inc_filename = NULL;
+ zval *tmp_inc_filename = NULL;
zend_bool failure_retval=0;
SAVE_OPLINE();
- inc_filename = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ inc_filename = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (inc_filename->type!=IS_STRING) {
MAKE_STD_ZVAL(tmp_inc_filename);
@@ -11485,8 +13357,6 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND
EG(return_value_ptr_ptr) = NULL;
}
- EX(current_object) = EX(object);
-
EX(function_state).function = (zend_function *) new_op_array;
EX(object) = NULL;
@@ -11494,14 +13364,13 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND
zend_rebuild_symbol_table(TSRMLS_C);
}
- if (EXPECTED(zend_execute == execute)) {
+ if (EXPECTED(zend_execute_ex == execute_ex)) {
ZEND_VM_ENTER();
} else {
zend_execute(new_op_array TSRMLS_CC);
}
EX(function_state).function = (zend_function *) EX(op_array);
- EX(object) = EX(current_object);
EG(opline_ptr) = &EX(opline);
EG(active_op_array) = EX(op_array);
@@ -11511,15 +13380,6 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND
if (UNEXPECTED(EG(exception) != NULL)) {
zend_throw_exception_internal(NULL TSRMLS_CC);
HANDLE_EXCEPTION();
- } else if (RETURN_VALUE_USED(opline)) {
- if (!EX_T(opline->result.var).var.ptr) { /* there was no return statement */
- zval *retval;
-
- ALLOC_ZVAL(retval);
- ZVAL_BOOL(retval, 1);
- INIT_PZVAL(retval);
- EX_T(opline->result.var).var.ptr = retval;
- }
}
} else if (RETURN_VALUE_USED(opline)) {
@@ -11547,7 +13407,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) &&
(opline->extended_value & ZEND_FE_RESET_VARIABLE)) {
- array_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ array_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (array_ptr_ptr == NULL || array_ptr_ptr == &EG(uninitialized_zval_ptr)) {
MAKE_STD_ZVAL(array_ptr);
ZVAL_NULL(array_ptr);
@@ -11574,7 +13434,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
Z_ADDREF_P(array_ptr);
}
} else {
- array_ptr = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ array_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (0) { /* IS_TMP_VAR */
zval *tmp;
@@ -11652,7 +13512,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
zend_uchar key_type;
key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 0, NULL);
- if (key_type != HASH_KEY_NON_EXISTANT &&
+ if (key_type != HASH_KEY_NON_EXISTENT &&
(key_type == HASH_KEY_IS_LONG ||
zend_check_property_access(zobj, str_key, str_key_len-1 TSRMLS_CC) == SUCCESS)) {
break;
@@ -11682,13 +13542,13 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
zval *array = EX_T(opline->op1.var).fe.ptr;
zval **value;
- char *str_key;
- uint str_key_len;
- ulong int_key;
HashTable *fe_ht;
zend_object_iterator *iter = NULL;
- int key_type = 0;
- zend_bool use_key = (zend_bool)(opline->extended_value & ZEND_FE_FETCH_WITH_KEY);
+
+ zval *key = NULL;
+ if (opline->extended_value & ZEND_FE_FETCH_WITH_KEY) {
+ key = &EX_T((opline+1)->result.var).tmp_var;
+ }
SAVE_OPLINE();
@@ -11699,8 +13559,11 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num);
case ZEND_ITER_PLAIN_OBJECT: {
- const char *class_name, *prop_name;
zend_object *zobj = zend_objects_get_address(array TSRMLS_CC);
+ int key_type;
+ char *str_key;
+ zend_uint str_key_len;
+ zend_ulong int_key;
fe_ht = Z_OBJPROP_P(array);
zend_hash_set_pointer(fe_ht, &EX_T(opline->op1.var).fe.fe_pos);
@@ -11712,16 +13575,23 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 0, NULL);
zend_hash_move_forward(fe_ht);
- } while (key_type == HASH_KEY_NON_EXISTANT ||
- (key_type != HASH_KEY_IS_LONG &&
- zend_check_property_access(zobj, str_key, str_key_len-1 TSRMLS_CC) != SUCCESS));
- zend_hash_get_pointer(fe_ht, &EX_T(opline->op1.var).fe.fe_pos);
- if (use_key && key_type != HASH_KEY_IS_LONG) {
- zend_unmangle_property_name(str_key, str_key_len-1, &class_name, &prop_name);
- str_key_len = strlen(prop_name);
- str_key = estrndup(prop_name, str_key_len);
- str_key_len++;
+ } while (key_type != HASH_KEY_IS_LONG &&
+ zend_check_property_access(zobj, str_key, str_key_len - 1 TSRMLS_CC) != SUCCESS);
+
+ if (key) {
+ if (key_type == HASH_KEY_IS_LONG) {
+ ZVAL_LONG(key, int_key);
+ } else {
+ const char *class_name, *prop_name;
+ int prop_name_len;
+ zend_unmangle_property_name_ex(
+ str_key, str_key_len - 1, &class_name, &prop_name, &prop_name_len
+ );
+ ZVAL_STRINGL(key, prop_name, prop_name_len, 1);
+ }
}
+
+ zend_hash_get_pointer(fe_ht, &EX_T(opline->op1.var).fe.fe_pos);
break;
}
@@ -11732,8 +13602,8 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
/* reached end of iteration */
ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num);
}
- if (use_key) {
- key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 1, NULL);
+ if (key) {
+ zend_hash_get_current_key_zval(fe_ht, key);
}
zend_hash_move_forward(fe_ht);
zend_hash_get_pointer(fe_ht, &EX_T(opline->op1.var).fe.fe_pos);
@@ -11768,16 +13638,15 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
/* failure in get_current_data */
ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num);
}
- if (use_key) {
+ if (key) {
if (iter->funcs->get_current_key) {
- key_type = iter->funcs->get_current_key(iter, &str_key, &str_key_len, &int_key TSRMLS_CC);
+ iter->funcs->get_current_key(iter, key TSRMLS_CC);
if (UNEXPECTED(EG(exception) != NULL)) {
zval_ptr_dtor(&array);
HANDLE_EXCEPTION();
}
} else {
- key_type = HASH_KEY_IS_LONG;
- int_key = iter->index;
+ ZVAL_LONG(key, iter->index);
}
}
break;
@@ -11793,26 +13662,6 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
AI_SET_PTR(&EX_T(opline->result.var), *value);
}
- if (use_key) {
- zval *key = &EX_T((opline+1)->result.var).tmp_var;
-
- switch (key_type) {
- case HASH_KEY_IS_STRING:
- Z_STRVAL_P(key) = (char*)str_key;
- Z_STRLEN_P(key) = str_key_len-1;
- Z_TYPE_P(key) = IS_STRING;
- break;
- case HASH_KEY_IS_LONG:
- Z_LVAL_P(key) = int_key;
- Z_TYPE_P(key) = IS_LONG;
- break;
- default:
- case HASH_KEY_NON_EXISTANT:
- ZVAL_NULL(key);
- break;
- }
- }
-
CHECK_EXCEPTION();
ZEND_VM_INC_OPCODE();
ZEND_VM_NEXT_OPCODE();
@@ -11826,7 +13675,7 @@ static int ZEND_FASTCALL ZEND_EXIT_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
if (IS_VAR != IS_UNUSED) {
zend_free_op free_op1;
- zval *ptr = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval *ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (Z_TYPE_P(ptr) == IS_LONG) {
EG(exit_status) = Z_LVAL_P(ptr);
@@ -11847,7 +13696,7 @@ static int ZEND_FASTCALL ZEND_JMP_SET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
zval *value;
SAVE_OPLINE();
- value = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (i_zend_is_true(value)) {
ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, value);
@@ -11873,7 +13722,7 @@ static int ZEND_FASTCALL ZEND_JMP_SET_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_
zval *value, *ret;
SAVE_OPLINE();
- value = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (i_zend_is_true(value)) {
if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
@@ -11908,7 +13757,7 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
zval *value;
SAVE_OPLINE();
- value = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, value);
if (!0) {
@@ -11926,7 +13775,7 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE
zval *value, *ret;
SAVE_OPLINE();
- value = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
Z_ADDREF_P(value);
@@ -11955,7 +13804,7 @@ static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_A
zend_bool result;
SAVE_OPLINE();
- expr = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ expr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (Z_TYPE_P(expr) == IS_OBJECT && Z_OBJ_HT_P(expr)->get_class_entry) {
result = instanceof_function(Z_OBJCE_P(expr), EX_T(opline->op2.var).class_entry TSRMLS_CC);
@@ -11975,7 +13824,7 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_add_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -11990,7 +13839,7 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_sub_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12005,7 +13854,7 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_mul_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12020,7 +13869,7 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_div_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12035,7 +13884,7 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
fast_mod_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12050,7 +13899,7 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
shift_left_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12065,7 +13914,7 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
shift_right_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12080,7 +13929,7 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
concat_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12095,7 +13944,7 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H
SAVE_OPLINE();
is_identical_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12111,7 +13960,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCO
SAVE_OPLINE();
is_identical_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
Z_LVAL_P(result) = !Z_LVAL_P(result);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12128,7 +13977,7 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDL
SAVE_OPLINE();
ZVAL_BOOL(result, fast_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12144,7 +13993,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H
SAVE_OPLINE();
ZVAL_BOOL(result, fast_not_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12160,7 +14009,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12176,7 +14025,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_VAR_CONST_HANDLER(ZEND_O
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12191,7 +14040,7 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
bitwise_or_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12206,7 +14055,7 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
bitwise_and_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12221,7 +14070,7 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
bitwise_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12236,7 +14085,7 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDL
SAVE_OPLINE();
boolean_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12248,10 +14097,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b
{
USE_OPLINE
zend_free_op free_op1, free_op_data1;
- zval **object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval **object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zval *object;
zval *property = opline->op2.zv;
- zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
+ zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
int have_get_ptr = 0;
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -12280,7 +14129,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b
/* here property is a string */
if (opline->extended_value == ZEND_ASSIGN_OBJ
&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -12369,7 +14218,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CONST(int (*binar
return zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval **container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
@@ -12382,14 +14231,14 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CONST(int (*binar
zval *dim = opline->op2.zv;
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, IS_CONST, BP_VAR_RW TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
}
}
break;
default:
value = opline->op2.zv;
- var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
/* do nothing */
break;
}
@@ -12511,7 +14360,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CONST(incdec_t
int have_get_ptr = 0;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
property = opline->op2.zv;
retval = &EX_T(opline->result.var).var.ptr;
@@ -12541,7 +14390,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CONST(incdec_t
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -12615,7 +14464,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CONST(incdec_
int have_get_ptr = 0;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
property = opline->op2.zv;
retval = &EX_T(opline->result.var).tmp_var;
@@ -12642,7 +14491,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CONST(incdec_
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
have_get_ptr = 1;
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -12717,7 +14566,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_CONST(int type,
ulong hash_value;
SAVE_OPLINE();
- varname = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR != IS_CONST && UNEXPECTED(Z_TYPE_P(varname) != IS_STRING)) {
ZVAL_COPY_VALUE(&tmp_varname, varname);
@@ -12857,7 +14706,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE
{
USE_OPLINE
- return zend_fetch_var_address_helper_SPEC_VAR_CONST(ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ return zend_fetch_var_address_helper_SPEC_VAR_CONST(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -12881,7 +14730,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA
if (IS_VAR == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12896,7 +14745,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
@@ -12930,7 +14779,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
@@ -12952,7 +14801,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H
zval *container;
SAVE_OPLINE();
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_IS TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -12967,8 +14816,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OP
SAVE_OPLINE();
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
- zval **container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ zval **container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
@@ -12985,7 +14834,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OP
if (IS_CONST == IS_UNUSED) {
zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
}
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -13001,7 +14850,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCOD
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -13019,6 +14868,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCOD
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (UNEXPECTED(EX_T(opline->result.var).var.ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
+ ZEND_VM_NEXT_OPCODE();
} else {
zend_free_op free_res;
zval **retval_ptr = EX_T(opline->result.var).var.ptr_ptr;
@@ -13043,7 +14893,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_CONST(
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
offset = opline->op2.zv;
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
@@ -13092,15 +14942,10 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA
SAVE_OPLINE();
property = opline->op2.zv;
- if (IS_VAR == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
- PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
- EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr;
- }
-
if (0) {
MAKE_REAL_ZVAL_PTR(property);
}
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
@@ -13140,7 +14985,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H
SAVE_OPLINE();
property = opline->op2.zv;
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
@@ -13171,7 +15016,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
offset = opline->op2.zv;
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
@@ -13208,7 +15053,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OP
{
USE_OPLINE
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
/* Behave like FETCH_OBJ_W */
zend_free_op free_op1;
zval *property;
@@ -13216,7 +15061,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OP
SAVE_OPLINE();
property = opline->op2.zv;
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
@@ -13249,7 +15094,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCOD
zval *property;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
property = opline->op2.zv;
if (IS_VAR == IS_CV) {
@@ -13292,7 +15137,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN
zval *property_name;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
property_name = opline->op2.zv;
if (0) {
@@ -13301,7 +15146,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_OBJ, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -13321,7 +15166,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN
zval **object_ptr;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
@@ -13333,7 +15178,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN
if (0) {
MAKE_REAL_ZVAL_PTR(property_name);
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_DIM, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -13347,8 +15192,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), object_ptr, dim, IS_CONST, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
if (RETURN_VALUE_USED(opline)) {
@@ -13403,7 +15248,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
value = opline->op2.zv;
- variable_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T(opline->op1.var), value, IS_CONST TSRMLS_CC)) {
@@ -13456,63 +15301,72 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZEND_OPCO
char *function_name_strval;
int function_name_strlen;
zend_free_op free_op1;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
function_name = opline->op2.zv;
if (IS_CONST != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ call->object = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (IS_CONST != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((IS_CONST == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_CONST == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (IS_CONST == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -13525,9 +15379,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZE
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (IS_VAR == IS_CONST) {
/* no function found. try a static method in class */
@@ -13543,24 +15397,24 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZE
}
CACHE_PTR(opline->op1.literal->cache_slot, ce);
}
- EX(called_scope) = ce;
+ call->called_scope = ce;
} else {
ce = EX_T(opline->op1.var).class_entry;
if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
- EX(called_scope) = EG(called_scope);
+ call->called_scope = EG(called_scope);
} else {
- EX(called_scope) = ce;
+ call->called_scope = ce;
}
}
if (IS_VAR == IS_CONST &&
IS_CONST == IS_CONST &&
CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
} else if (IS_VAR != IS_CONST &&
IS_CONST == IS_CONST &&
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
/* do nothing */
} else if (IS_CONST != IS_UNUSED) {
char *function_name_strval = NULL;
@@ -13574,6 +15428,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZE
function_name = opline->op2.zv;
if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Function name must be a string");
} else {
function_name_strval = Z_STRVAL_P(function_name);
@@ -13583,20 +15440,20 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZE
if (function_name_strval) {
if (ce->get_static_method) {
- EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
+ call->fbc = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
} else {
- EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_CONST == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ call->fbc = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_CONST == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
}
- if (UNEXPECTED(EX(fbc) == NULL)) {
+ if (UNEXPECTED(call->fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
}
if (IS_CONST == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
if (IS_VAR == IS_CONST) {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
} else {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, EX(fbc));
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, call->fbc);
}
}
}
@@ -13610,29 +15467,31 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZE
if (EG(This) && Z_OBJCE_P(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name);
}
- EX(fbc) = ce->constructor;
+ call->fbc = ce->constructor;
}
- if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
- EX(object) = NULL;
+ if (call->fbc->common.fn_flags & ZEND_ACC_STATIC) {
+ call->object = NULL;
} else {
if (EG(This) &&
Z_OBJ_HT_P(EG(This))->get_class_entry &&
!instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
- if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
} else {
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
}
}
- if ((EX(object) = EG(This))) {
- Z_ADDREF_P(EX(object));
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if ((call->object = EG(This))) {
+ Z_ADDREF_P(call->object);
+ call->called_scope = Z_OBJCE_P(call->object);
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -13648,7 +15507,7 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
is_equal_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
CHECK_EXCEPTION();
@@ -13740,6 +15599,9 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE
}
ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value);
zval_copy_ctor(&EX_T(opline->result.var).tmp_var);
+ } else if (Z_STRLEN_P(opline->op2.zv) == sizeof("class")-1 && strcmp(Z_STRVAL_P(opline->op2.zv), "class") == 0) {
+ /* "class" is assigned as a case-sensitive keyword from zend_do_resolve_class_name */
+ ZVAL_STRINGL(&EX_T(opline->result.var).tmp_var, ce->name, ce->name_length, 1);
} else {
zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(opline->op2.zv));
}
@@ -13757,7 +15619,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPC
SAVE_OPLINE();
if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && opline->extended_value) {
- zval **expr_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval **expr_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(expr_ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets");
@@ -13766,7 +15628,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPC
expr_ptr = *expr_ptr_ptr;
Z_ADDREF_P(expr_ptr);
} else {
- expr_ptr=_get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ expr_ptr=_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (0) { /* temporary variable */
zval *new_expr;
@@ -13873,7 +15735,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND
ZEND_VM_NEXT_OPCODE();
}
- varname = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -13936,7 +15798,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND
ulong hval;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
@@ -14035,7 +15897,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
offset = opline->op2.zv;
if (IS_VAR != IS_VAR || container) {
@@ -14092,7 +15954,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPC
} else {
HashTable *target_symbol_table;
zend_free_op free_op1;
- zval tmp, *varname = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval tmp, *varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -14157,22 +16019,22 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CONST(
{
USE_OPLINE
zend_free_op free_op1;
- zval **container;
+ zval *container;
zval **value = NULL;
int result = 0;
ulong hval;
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
offset = opline->op2.zv;
- if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
+ if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) {
HashTable *ht;
int isset = 0;
- ht = Z_ARRVAL_PP(container);
+ ht = Z_ARRVAL_P(container);
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
@@ -14191,9 +16053,7 @@ num_index_prop:
if (IS_CONST == IS_CONST) {
hval = Z_HASH_P(offset);
} else {
- if (!prop_dim) {
- ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
- }
+ ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
@@ -14228,20 +16088,20 @@ num_index_prop:
}
}
- } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ } else if (Z_TYPE_P(container) == IS_OBJECT) {
if (0) {
MAKE_REAL_ZVAL_PTR(offset);
}
if (prop_dim) {
- if (Z_OBJ_HT_P(*container)->has_property) {
- result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_property) {
+ result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check property of non-object");
result = 0;
}
} else {
- if (Z_OBJ_HT_P(*container)->has_dimension) {
- result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_dimension) {
+ result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
result = 0;
@@ -14252,7 +16112,7 @@ num_index_prop:
} else {
}
- } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
+ } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */
zval tmp;
if (Z_TYPE_P(offset) != IS_LONG) {
@@ -14270,11 +16130,11 @@ num_index_prop:
}
if (Z_TYPE_P(offset) == IS_LONG) {
if (opline->extended_value & ZEND_ISSET) {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) {
result = 1;
}
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') {
result = 1;
}
}
@@ -14307,6 +16167,165 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_CONST_HANDLER(ZEN
return zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CONST(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_VAR != IS_UNUSED) {
+ zend_free_op free_op1;
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* If a function call result is yielded and the function did
+ * not return by reference we throw a notice. */
+ if (IS_VAR == IS_VAR && !Z_ISREF_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+ }
+ } else {
+ zval *value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_CONST != IS_UNUSED) {
+
+ zval *key = opline->op2.zv;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_ADD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -14314,8 +16333,8 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_add_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14329,8 +16348,8 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_sub_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14344,8 +16363,8 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_mul_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14359,8 +16378,8 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_div_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14374,8 +16393,8 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_mod_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14389,8 +16408,8 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_left_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14404,8 +16423,8 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_right_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14419,8 +16438,8 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
concat_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14434,8 +16453,8 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN
SAVE_OPLINE();
is_identical_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14450,8 +16469,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE
SAVE_OPLINE();
is_identical_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
Z_LVAL_P(result) = !Z_LVAL_P(result);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
@@ -14467,8 +16486,8 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
ZVAL_BOOL(result, fast_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14483,8 +16502,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN
SAVE_OPLINE();
ZVAL_BOOL(result, fast_not_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14499,8 +16518,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14515,8 +16534,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_VAR_TMP_HANDLER(ZEND_OPC
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14530,8 +16549,8 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
bitwise_or_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14545,8 +16564,8 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
bitwise_and_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14560,8 +16579,8 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
bitwise_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14575,8 +16594,8 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
boolean_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -14587,10 +16606,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin
{
USE_OPLINE
zend_free_op free_op1, free_op2, free_op_data1;
- zval **object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval **object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zval *object;
- zval *property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
+ zval *property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
int have_get_ptr = 0;
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -14619,7 +16638,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin
/* here property is a string */
if (opline->extended_value == ZEND_ASSIGN_OBJ
&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -14708,7 +16727,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_TMP(int (*binary_
return zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval **container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
@@ -14718,17 +16737,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_TMP(int (*binary_
}
return zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
- zval *dim = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, IS_TMP_VAR, BP_VAR_RW TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
}
}
break;
default:
- value = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
/* do nothing */
break;
}
@@ -14851,8 +16870,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMP(incdec_t i
int have_get_ptr = 0;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
retval = &EX_T(opline->result.var).var.ptr;
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -14881,7 +16900,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMP(incdec_t i
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -14955,8 +16974,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMP(incdec_t
int have_get_ptr = 0;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
retval = &EX_T(opline->result.var).tmp_var;
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -14982,7 +17001,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMP(incdec_t
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
have_get_ptr = 1;
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -15057,8 +17076,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND
if (IS_VAR == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
zval_dtor(free_op2.var);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -15072,12 +17091,12 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_W TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_W TSRMLS_CC);
zval_dtor(free_op2.var);
if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -15106,12 +17125,12 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_RW TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_RW TSRMLS_CC);
zval_dtor(free_op2.var);
if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -15128,8 +17147,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN
zval *container;
SAVE_OPLINE();
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_IS TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_IS TSRMLS_CC);
zval_dtor(free_op2.var);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -15143,13 +17162,13 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCO
SAVE_OPLINE();
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
- zval **container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ zval **container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_W TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_W TSRMLS_CC);
if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
}
@@ -15161,8 +17180,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCO
if (IS_TMP_VAR == IS_UNUSED) {
zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
}
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
zval_dtor(free_op2.var);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
}
@@ -15177,7 +17196,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -15187,7 +17206,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_UNSET TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_UNSET TSRMLS_CC);
zval_dtor(free_op2.var);
if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -15195,6 +17214,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (UNEXPECTED(EX_T(opline->result.var).var.ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
+ ZEND_VM_NEXT_OPCODE();
} else {
zend_free_op free_res;
zval **retval_ptr = EX_T(opline->result.var).var.ptr_ptr;
@@ -15219,8 +17239,8 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_TMP(ZE
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -15266,17 +17286,12 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
-
- if (IS_VAR == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
- PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
- EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr;
- }
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (1) {
MAKE_REAL_ZVAL_PTR(property);
}
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
@@ -15315,8 +17330,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (1) {
MAKE_REAL_ZVAL_PTR(property);
@@ -15347,8 +17362,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -15384,15 +17399,15 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCO
{
USE_OPLINE
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
/* Behave like FETCH_OBJ_W */
zend_free_op free_op1, free_op2;
zval *property;
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (1) {
MAKE_REAL_ZVAL_PTR(property);
@@ -15425,8 +17440,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_
zval *property;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_VAR == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -15468,8 +17483,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL
zval *property_name;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- property_name = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (1) {
MAKE_REAL_ZVAL_PTR(property_name);
@@ -15477,7 +17492,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_OBJ, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (1) {
zval_ptr_dtor(&property_name);
} else {
@@ -15497,19 +17512,19 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL
zval **object_ptr;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
zend_free_op free_op2;
- zval *property_name = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (1) {
MAKE_REAL_ZVAL_PTR(property_name);
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_DIM, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (1) {
zval_ptr_dtor(&property_name);
} else {
@@ -15518,14 +17533,14 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL
} else {
zend_free_op free_op2, free_op_data1, free_op_data2;
zval *value;
- zval *dim = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval **variable_ptr_ptr;
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), object_ptr, dim, IS_TMP_VAR, BP_VAR_W TSRMLS_CC);
zval_dtor(free_op2.var);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
if (RETURN_VALUE_USED(opline)) {
@@ -15579,8 +17594,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_A
zval **variable_ptr_ptr;
SAVE_OPLINE();
- value = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- variable_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T(opline->op1.var), value, IS_TMP_VAR TSRMLS_CC)) {
@@ -15633,63 +17648,72 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE
char *function_name_strval;
int function_name_strlen;
zend_free_op free_op1, free_op2;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
- function_name = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ function_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_TMP_VAR != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ call->object = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (IS_TMP_VAR != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((IS_TMP_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_TMP_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (IS_TMP_VAR == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ zval_dtor(free_op2.var);
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
zval_dtor(free_op2.var);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -15703,9 +17727,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (IS_VAR == IS_CONST) {
/* no function found. try a static method in class */
@@ -15721,24 +17745,24 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND
}
CACHE_PTR(opline->op1.literal->cache_slot, ce);
}
- EX(called_scope) = ce;
+ call->called_scope = ce;
} else {
ce = EX_T(opline->op1.var).class_entry;
if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
- EX(called_scope) = EG(called_scope);
+ call->called_scope = EG(called_scope);
} else {
- EX(called_scope) = ce;
+ call->called_scope = ce;
}
}
if (IS_VAR == IS_CONST &&
IS_TMP_VAR == IS_CONST &&
CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
} else if (IS_VAR != IS_CONST &&
IS_TMP_VAR == IS_CONST &&
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
/* do nothing */
} else if (IS_TMP_VAR != IS_UNUSED) {
char *function_name_strval = NULL;
@@ -15749,9 +17773,12 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND
function_name_strval = Z_STRVAL_P(opline->op2.zv);
function_name_strlen = Z_STRLEN_P(opline->op2.zv);
} else {
- function_name = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ function_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Function name must be a string");
} else {
function_name_strval = Z_STRVAL_P(function_name);
@@ -15761,20 +17788,20 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND
if (function_name_strval) {
if (ce->get_static_method) {
- EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
+ call->fbc = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
} else {
- EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_TMP_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ call->fbc = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_TMP_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
}
- if (UNEXPECTED(EX(fbc) == NULL)) {
+ if (UNEXPECTED(call->fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
}
if (IS_TMP_VAR == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
if (IS_VAR == IS_CONST) {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
} else {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, EX(fbc));
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, call->fbc);
}
}
}
@@ -15788,29 +17815,31 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND
if (EG(This) && Z_OBJCE_P(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name);
}
- EX(fbc) = ce->constructor;
+ call->fbc = ce->constructor;
}
- if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
- EX(object) = NULL;
+ if (call->fbc->common.fn_flags & ZEND_ACC_STATIC) {
+ call->object = NULL;
} else {
if (EG(This) &&
Z_OBJ_HT_P(EG(This))->get_class_entry &&
!instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
- if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
} else {
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
}
}
- if ((EX(object) = EG(This))) {
- Z_ADDREF_P(EX(object));
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if ((call->object = EG(This))) {
+ Z_ADDREF_P(call->object);
+ call->called_scope = Z_OBJCE_P(call->object);
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -15826,8 +17855,8 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
is_equal_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -15842,7 +17871,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER(ZEND_OPCOD
SAVE_OPLINE();
if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && opline->extended_value) {
- zval **expr_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval **expr_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(expr_ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets");
@@ -15851,7 +17880,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER(ZEND_OPCOD
expr_ptr = *expr_ptr_ptr;
Z_ADDREF_P(expr_ptr);
} else {
- expr_ptr=_get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ expr_ptr=_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (0) { /* temporary variable */
zval *new_expr;
@@ -15872,7 +17901,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER(ZEND_OPCOD
if (IS_TMP_VAR != IS_UNUSED) {
zend_free_op free_op2;
- zval *offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
ulong hval;
switch (Z_TYPE_P(offset)) {
@@ -15943,11 +17972,11 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLE
ulong hval;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
- offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_VAR != IS_VAR || container) {
switch (Z_TYPE_PP(container)) {
@@ -16042,8 +18071,8 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLE
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_VAR != IS_VAR || container) {
if (IS_VAR == IS_CV && container != &EG(uninitialized_zval_ptr)) {
@@ -16079,22 +18108,22 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_TMP(in
{
USE_OPLINE
zend_free_op free_op1, free_op2;
- zval **container;
+ zval *container;
zval **value = NULL;
int result = 0;
ulong hval;
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
+ if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) {
HashTable *ht;
int isset = 0;
- ht = Z_ARRVAL_PP(container);
+ ht = Z_ARRVAL_P(container);
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
@@ -16113,9 +18142,7 @@ num_index_prop:
if (IS_TMP_VAR == IS_CONST) {
hval = Z_HASH_P(offset);
} else {
- if (!prop_dim) {
- ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
- }
+ ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
@@ -16150,20 +18177,20 @@ num_index_prop:
}
}
zval_dtor(free_op2.var);
- } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ } else if (Z_TYPE_P(container) == IS_OBJECT) {
if (1) {
MAKE_REAL_ZVAL_PTR(offset);
}
if (prop_dim) {
- if (Z_OBJ_HT_P(*container)->has_property) {
- result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_property) {
+ result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check property of non-object");
result = 0;
}
} else {
- if (Z_OBJ_HT_P(*container)->has_dimension) {
- result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_dimension) {
+ result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
result = 0;
@@ -16174,7 +18201,7 @@ num_index_prop:
} else {
zval_dtor(free_op2.var);
}
- } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
+ } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */
zval tmp;
if (Z_TYPE_P(offset) != IS_LONG) {
@@ -16192,11 +18219,11 @@ num_index_prop:
}
if (Z_TYPE_P(offset) == IS_LONG) {
if (opline->extended_value & ZEND_ISSET) {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) {
result = 1;
}
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') {
result = 1;
}
}
@@ -16229,6 +18256,165 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_
return zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_TMP(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_VAR != IS_UNUSED) {
+ zend_free_op free_op1;
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* If a function call result is yielded and the function did
+ * not return by reference we throw a notice. */
+ if (IS_VAR == IS_VAR && !Z_ISREF_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+ }
+ } else {
+ zval *value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_TMP_VAR != IS_UNUSED) {
+ zend_free_op free_op2;
+ zval *key = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!1) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_ADD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -16236,8 +18422,8 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_add_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16251,8 +18437,8 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_sub_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16266,8 +18452,8 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_mul_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16281,8 +18467,8 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_div_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16296,8 +18482,8 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
fast_mod_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16311,8 +18497,8 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_left_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16326,8 +18512,8 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_right_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16341,8 +18527,8 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
concat_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16356,8 +18542,8 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN
SAVE_OPLINE();
is_identical_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16372,8 +18558,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE
SAVE_OPLINE();
is_identical_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
Z_LVAL_P(result) = !Z_LVAL_P(result);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
@@ -16389,8 +18575,8 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
ZVAL_BOOL(result, fast_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16405,8 +18591,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN
SAVE_OPLINE();
ZVAL_BOOL(result, fast_not_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16421,8 +18607,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16437,8 +18623,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_VAR_VAR_HANDLER(ZEND_OPC
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16452,8 +18638,8 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
bitwise_or_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16467,8 +18653,8 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
bitwise_and_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16482,8 +18668,8 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
bitwise_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16497,8 +18683,8 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
boolean_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -16509,10 +18695,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin
{
USE_OPLINE
zend_free_op free_op1, free_op2, free_op_data1;
- zval **object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval **object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zval *object;
- zval *property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
+ zval *property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
int have_get_ptr = 0;
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -16541,7 +18727,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin
/* here property is a string */
if (opline->extended_value == ZEND_ASSIGN_OBJ
&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -16630,7 +18816,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_VAR(int (*binary_
return zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval **container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
@@ -16640,17 +18826,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_VAR(int (*binary_
}
return zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
- zval *dim = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, IS_VAR, BP_VAR_RW TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
}
}
break;
default:
- value = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
/* do nothing */
break;
}
@@ -16773,8 +18959,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_VAR(incdec_t i
int have_get_ptr = 0;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
retval = &EX_T(opline->result.var).var.ptr;
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -16803,7 +18989,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_VAR(incdec_t i
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -16877,8 +19063,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_VAR(incdec_t
int have_get_ptr = 0;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
retval = &EX_T(opline->result.var).tmp_var;
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -16904,7 +19090,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_VAR(incdec_t
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
have_get_ptr = 1;
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -16979,7 +19165,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_VAR(int type, ZE
ulong hash_value;
SAVE_OPLINE();
- varname = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR != IS_CONST && UNEXPECTED(Z_TYPE_P(varname) != IS_STRING)) {
ZVAL_COPY_VALUE(&tmp_varname, varname);
@@ -17119,7 +19305,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_H
{
USE_OPLINE
- return zend_fetch_var_address_helper_SPEC_VAR_VAR(ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ return zend_fetch_var_address_helper_SPEC_VAR_VAR(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -17143,8 +19329,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND
if (IS_VAR == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -17158,12 +19344,12 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_W TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_W TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -17192,12 +19378,12 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_RW TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_RW TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -17214,8 +19400,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN
zval *container;
SAVE_OPLINE();
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_IS TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_IS TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -17229,13 +19415,13 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCO
SAVE_OPLINE();
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
- zval **container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ zval **container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_W TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_W TSRMLS_CC);
if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
}
@@ -17247,8 +19433,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCO
if (IS_VAR == IS_UNUSED) {
zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
}
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
}
@@ -17263,7 +19449,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -17273,7 +19459,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_UNSET TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_UNSET TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -17281,6 +19467,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (UNEXPECTED(EX_T(opline->result.var).var.ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
+ ZEND_VM_NEXT_OPCODE();
} else {
zend_free_op free_res;
zval **retval_ptr = EX_T(opline->result.var).var.ptr_ptr;
@@ -17305,8 +19492,8 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_VAR(ZE
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -17352,17 +19539,12 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
-
- if (IS_VAR == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
- PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
- EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr;
- }
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
}
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
@@ -17401,8 +19583,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
@@ -17433,8 +19615,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -17470,15 +19652,15 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCO
{
USE_OPLINE
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
/* Behave like FETCH_OBJ_W */
zend_free_op free_op1, free_op2;
zval *property;
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
@@ -17511,8 +19693,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_
zval *property;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_VAR == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -17554,8 +19736,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
zval *property_name;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- property_name = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property_name);
@@ -17563,7 +19745,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_OBJ, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -17583,19 +19765,19 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
zval **object_ptr;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
zend_free_op free_op2;
- zval *property_name = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property_name);
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_DIM, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -17604,14 +19786,14 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
} else {
zend_free_op free_op2, free_op_data1, free_op_data2;
zval *value;
- zval *dim = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval **variable_ptr_ptr;
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), object_ptr, dim, IS_VAR, BP_VAR_W TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
if (RETURN_VALUE_USED(opline)) {
@@ -17665,8 +19847,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_A
zval **variable_ptr_ptr;
SAVE_OPLINE();
- value = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- variable_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T(opline->op1.var), value, IS_VAR TSRMLS_CC)) {
@@ -17721,7 +19903,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
zval **value_ptr_ptr;
SAVE_OPLINE();
- value_ptr_ptr = _get_zval_ptr_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ value_ptr_ptr = _get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_VAR == IS_VAR &&
value_ptr_ptr &&
@@ -17744,7 +19926,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL
zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object");
}
- variable_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if ((IS_VAR == IS_VAR && UNEXPECTED(value_ptr_ptr == NULL)) ||
(IS_VAR == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL))) {
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
@@ -17774,63 +19956,72 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE
char *function_name_strval;
int function_name_strlen;
zend_free_op free_op1, free_op2;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
- function_name = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_VAR != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ call->object = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (IS_VAR != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((IS_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (IS_VAR == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -17844,9 +20035,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (IS_VAR == IS_CONST) {
/* no function found. try a static method in class */
@@ -17862,24 +20053,24 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND
}
CACHE_PTR(opline->op1.literal->cache_slot, ce);
}
- EX(called_scope) = ce;
+ call->called_scope = ce;
} else {
ce = EX_T(opline->op1.var).class_entry;
if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
- EX(called_scope) = EG(called_scope);
+ call->called_scope = EG(called_scope);
} else {
- EX(called_scope) = ce;
+ call->called_scope = ce;
}
}
if (IS_VAR == IS_CONST &&
IS_VAR == IS_CONST &&
CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
} else if (IS_VAR != IS_CONST &&
IS_VAR == IS_CONST &&
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
/* do nothing */
} else if (IS_VAR != IS_UNUSED) {
char *function_name_strval = NULL;
@@ -17890,9 +20081,12 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND
function_name_strval = Z_STRVAL_P(opline->op2.zv);
function_name_strlen = Z_STRLEN_P(opline->op2.zv);
} else {
- function_name = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Function name must be a string");
} else {
function_name_strval = Z_STRVAL_P(function_name);
@@ -17902,20 +20096,20 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND
if (function_name_strval) {
if (ce->get_static_method) {
- EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
+ call->fbc = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
} else {
- EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ call->fbc = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
}
- if (UNEXPECTED(EX(fbc) == NULL)) {
+ if (UNEXPECTED(call->fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
}
if (IS_VAR == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
if (IS_VAR == IS_CONST) {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
} else {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, EX(fbc));
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, call->fbc);
}
}
}
@@ -17929,29 +20123,31 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND
if (EG(This) && Z_OBJCE_P(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name);
}
- EX(fbc) = ce->constructor;
+ call->fbc = ce->constructor;
}
- if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
- EX(object) = NULL;
+ if (call->fbc->common.fn_flags & ZEND_ACC_STATIC) {
+ call->object = NULL;
} else {
if (EG(This) &&
Z_OBJ_HT_P(EG(This))->get_class_entry &&
!instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
- if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
} else {
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
}
}
- if ((EX(object) = EG(This))) {
- Z_ADDREF_P(EX(object));
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if ((call->object = EG(This))) {
+ Z_ADDREF_P(call->object);
+ call->called_scope = Z_OBJCE_P(call->object);
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -17967,8 +20163,8 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
is_equal_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -17983,7 +20179,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD
SAVE_OPLINE();
if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && opline->extended_value) {
- zval **expr_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval **expr_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(expr_ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets");
@@ -17992,7 +20188,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD
expr_ptr = *expr_ptr_ptr;
Z_ADDREF_P(expr_ptr);
} else {
- expr_ptr=_get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ expr_ptr=_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (0) { /* temporary variable */
zval *new_expr;
@@ -18013,7 +20209,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD
if (IS_VAR != IS_UNUSED) {
zend_free_op free_op2;
- zval *offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
ulong hval;
switch (Z_TYPE_P(offset)) {
@@ -18099,7 +20295,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE
ZEND_VM_NEXT_OPCODE();
}
- varname = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -18162,11 +20358,11 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE
ulong hval;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
- offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_VAR != IS_VAR || container) {
switch (Z_TYPE_PP(container)) {
@@ -18261,8 +20457,8 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_VAR != IS_VAR || container) {
if (IS_VAR == IS_CV && container != &EG(uninitialized_zval_ptr)) {
@@ -18318,7 +20514,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD
} else {
HashTable *target_symbol_table;
zend_free_op free_op1;
- zval tmp, *varname = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval tmp, *varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -18383,22 +20579,22 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_VAR(in
{
USE_OPLINE
zend_free_op free_op1, free_op2;
- zval **container;
+ zval *container;
zval **value = NULL;
int result = 0;
ulong hval;
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
+ if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) {
HashTable *ht;
int isset = 0;
- ht = Z_ARRVAL_PP(container);
+ ht = Z_ARRVAL_P(container);
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
@@ -18417,9 +20613,7 @@ num_index_prop:
if (IS_VAR == IS_CONST) {
hval = Z_HASH_P(offset);
} else {
- if (!prop_dim) {
- ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
- }
+ ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
@@ -18454,20 +20648,20 @@ num_index_prop:
}
}
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
- } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ } else if (Z_TYPE_P(container) == IS_OBJECT) {
if (0) {
MAKE_REAL_ZVAL_PTR(offset);
}
if (prop_dim) {
- if (Z_OBJ_HT_P(*container)->has_property) {
- result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_property) {
+ result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check property of non-object");
result = 0;
}
} else {
- if (Z_OBJ_HT_P(*container)->has_dimension) {
- result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_dimension) {
+ result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
result = 0;
@@ -18478,7 +20672,7 @@ num_index_prop:
} else {
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
}
- } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
+ } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */
zval tmp;
if (Z_TYPE_P(offset) != IS_LONG) {
@@ -18496,11 +20690,11 @@ num_index_prop:
}
if (Z_TYPE_P(offset) == IS_LONG) {
if (opline->extended_value & ZEND_ISSET) {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) {
result = 1;
}
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') {
result = 1;
}
}
@@ -18533,14 +20727,174 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_
return zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_VAR(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_VAR != IS_UNUSED) {
+ zend_free_op free_op1;
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* If a function call result is yielded and the function did
+ * not return by reference we throw a notice. */
+ if (IS_VAR == IS_VAR && !Z_ISREF_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+ }
+ } else {
+ zval *value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_VAR != IS_UNUSED) {
+ zend_free_op free_op2;
+ zval *key = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zend_free_op free_op1, free_op_data1;
- zval **object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval **object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zval *object;
zval *property = NULL;
- zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
+ zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
int have_get_ptr = 0;
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -18569,7 +20923,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (*
/* here property is a string */
if (opline->extended_value == ZEND_ASSIGN_OBJ
&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_UNUSED == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_UNUSED == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -18658,7 +21012,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_UNUSED(int (*bina
return zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval **container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
@@ -18671,14 +21025,14 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_UNUSED(int (*bina
zval *dim = NULL;
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, IS_UNUSED, BP_VAR_RW TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
}
}
break;
default:
value = NULL;
- var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
/* do nothing */
break;
}
@@ -18800,7 +21154,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_UNUSED(int type,
ulong hash_value;
SAVE_OPLINE();
- varname = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR != IS_CONST && UNEXPECTED(Z_TYPE_P(varname) != IS_STRING)) {
ZVAL_COPY_VALUE(&tmp_varname, varname);
@@ -18940,7 +21294,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCOD
{
USE_OPLINE
- return zend_fetch_var_address_helper_SPEC_VAR_UNUSED(ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ return zend_fetch_var_address_helper_SPEC_VAR_UNUSED(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -18960,7 +21314,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_H
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
@@ -18994,7 +21348,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
@@ -19016,8 +21370,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_O
SAVE_OPLINE();
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
- zval **container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ zval **container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
@@ -19034,7 +21388,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_O
if (IS_UNUSED == IS_UNUSED) {
zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
}
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, NULL, IS_UNUSED, BP_VAR_R TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -19050,7 +21404,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA
zval **object_ptr;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
@@ -19062,7 +21416,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA
if (0) {
MAKE_REAL_ZVAL_PTR(property_name);
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_DIM, ((IS_UNUSED == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_UNUSED == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -19076,8 +21430,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), object_ptr, dim, IS_UNUSED, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
if (RETURN_VALUE_USED(opline)) {
@@ -19128,9 +21482,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER(Z
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (IS_VAR == IS_CONST) {
/* no function found. try a static method in class */
@@ -19146,24 +21500,24 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER(Z
}
CACHE_PTR(opline->op1.literal->cache_slot, ce);
}
- EX(called_scope) = ce;
+ call->called_scope = ce;
} else {
ce = EX_T(opline->op1.var).class_entry;
if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
- EX(called_scope) = EG(called_scope);
+ call->called_scope = EG(called_scope);
} else {
- EX(called_scope) = ce;
+ call->called_scope = ce;
}
}
if (IS_VAR == IS_CONST &&
IS_UNUSED == IS_CONST &&
CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
} else if (IS_VAR != IS_CONST &&
IS_UNUSED == IS_CONST &&
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
/* do nothing */
} else if (IS_UNUSED != IS_UNUSED) {
char *function_name_strval = NULL;
@@ -19177,6 +21531,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER(Z
function_name = NULL;
if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Function name must be a string");
} else {
function_name_strval = Z_STRVAL_P(function_name);
@@ -19186,20 +21543,20 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER(Z
if (function_name_strval) {
if (ce->get_static_method) {
- EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
+ call->fbc = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
} else {
- EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_UNUSED == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ call->fbc = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_UNUSED == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
}
- if (UNEXPECTED(EX(fbc) == NULL)) {
+ if (UNEXPECTED(call->fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
}
if (IS_UNUSED == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
if (IS_VAR == IS_CONST) {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
} else {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, EX(fbc));
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, call->fbc);
}
}
}
@@ -19213,29 +21570,31 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER(Z
if (EG(This) && Z_OBJCE_P(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name);
}
- EX(fbc) = ce->constructor;
+ call->fbc = ce->constructor;
}
- if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
- EX(object) = NULL;
+ if (call->fbc->common.fn_flags & ZEND_ACC_STATIC) {
+ call->object = NULL;
} else {
if (EG(This) &&
Z_OBJ_HT_P(EG(This))->get_class_entry &&
!instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
- if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
} else {
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
}
}
- if ((EX(object) = EG(This))) {
- Z_ADDREF_P(EX(object));
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if ((call->object = EG(This))) {
+ Z_ADDREF_P(call->object);
+ call->called_scope = Z_OBJCE_P(call->object);
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -19249,7 +21608,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OP
SAVE_OPLINE();
if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && opline->extended_value) {
- zval **expr_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval **expr_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(expr_ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets");
@@ -19258,7 +21617,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OP
expr_ptr = *expr_ptr_ptr;
Z_ADDREF_P(expr_ptr);
} else {
- expr_ptr=_get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ expr_ptr=_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (0) { /* temporary variable */
zval *new_expr;
@@ -19365,7 +21724,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HAN
ZEND_VM_NEXT_OPCODE();
}
- varname = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -19443,7 +21802,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OP
} else {
HashTable *target_symbol_table;
zend_free_op free_op1;
- zval tmp, *varname = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval tmp, *varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -19512,8 +21871,8 @@ static int ZEND_FASTCALL ZEND_SEPARATE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HAND
SAVE_OPLINE();
var_ptr = EX_T(opline->op1.var).var.ptr;
if (Z_TYPE_P(var_ptr) != IS_OBJECT &&
- !PZVAL_IS_REF(var_ptr) &&
- Z_REFCOUNT_P(var_ptr) > 1) {
+ !PZVAL_IS_REF(var_ptr) &&
+ Z_REFCOUNT_P(var_ptr) > 1) {
Z_DELREF_P(var_ptr);
ALLOC_ZVAL(new_zv);
@@ -19525,6 +21884,165 @@ static int ZEND_FASTCALL ZEND_SEPARATE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HAND
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_VAR != IS_UNUSED) {
+ zend_free_op free_op1;
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* If a function call result is yielded and the function did
+ * not return by reference we throw a notice. */
+ if (IS_VAR == IS_VAR && !Z_ISREF_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+ }
+ } else {
+ zval *value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_UNUSED != IS_UNUSED) {
+
+ zval *key = NULL;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_ADD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -19532,8 +22050,8 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_add_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19547,8 +22065,8 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_sub_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19562,8 +22080,8 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_mul_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19577,8 +22095,8 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_div_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19592,8 +22110,8 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_mod_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19607,8 +22125,8 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_left_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19622,8 +22140,8 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_right_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19637,8 +22155,8 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
concat_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19652,8 +22170,8 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND
SAVE_OPLINE();
is_identical_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19668,8 +22186,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_
SAVE_OPLINE();
is_identical_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
Z_LVAL_P(result) = !Z_LVAL_P(result);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -19685,8 +22203,8 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
ZVAL_BOOL(result, fast_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19701,8 +22219,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND
SAVE_OPLINE();
ZVAL_BOOL(result, fast_not_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19717,8 +22235,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19733,8 +22251,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_VAR_CV_HANDLER(ZEND_OPCO
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC));
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19748,8 +22266,8 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
bitwise_or_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19763,8 +22281,8 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
bitwise_and_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19778,8 +22296,8 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
bitwise_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19793,8 +22311,8 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
boolean_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -19805,10 +22323,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina
{
USE_OPLINE
zend_free_op free_op1, free_op_data1;
- zval **object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval **object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
zval *object;
- zval *property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
- zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
+ zval *property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
+ zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
int have_get_ptr = 0;
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -19837,7 +22355,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina
/* here property is a string */
if (opline->extended_value == ZEND_ASSIGN_OBJ
&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -19926,7 +22444,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CV(int (*binary_o
return zend_binary_assign_op_obj_helper_SPEC_VAR_CV(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval **container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
@@ -19936,17 +22454,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CV(int (*binary_o
}
return zend_binary_assign_op_obj_helper_SPEC_VAR_CV(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
- zval *dim = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ zval *dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, IS_CV, BP_VAR_RW TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
}
}
break;
default:
- value = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
- var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
/* do nothing */
break;
}
@@ -20068,8 +22586,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CV(incdec_t in
int have_get_ptr = 0;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
retval = &EX_T(opline->result.var).var.ptr;
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -20098,7 +22616,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CV(incdec_t in
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -20172,8 +22690,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CV(incdec_t i
int have_get_ptr = 0;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
retval = &EX_T(opline->result.var).tmp_var;
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -20199,7 +22717,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CV(incdec_t i
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
have_get_ptr = 1;
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -20274,8 +22792,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL
if (IS_VAR == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -20289,12 +22807,12 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_W TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_W TSRMLS_CC);
if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -20323,12 +22841,12 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_RW TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_RW TSRMLS_CC);
if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -20345,8 +22863,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND
zval *container;
SAVE_OPLINE();
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_IS TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_IS TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
CHECK_EXCEPTION();
@@ -20360,13 +22878,13 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCOD
SAVE_OPLINE();
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
- zval **container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ zval **container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_W TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_W TSRMLS_CC);
if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
}
@@ -20378,8 +22896,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCOD
if (IS_CV == IS_UNUSED) {
zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
}
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
}
@@ -20394,7 +22912,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_H
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -20404,7 +22922,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_H
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_UNSET TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_UNSET TSRMLS_CC);
if (IS_VAR == IS_VAR && (free_op1.var != NULL) && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -20412,6 +22930,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_H
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
if (UNEXPECTED(EX_T(opline->result.var).var.ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
+ ZEND_VM_NEXT_OPCODE();
} else {
zend_free_op free_res;
zval **retval_ptr = EX_T(opline->result.var).var.ptr_ptr;
@@ -20436,8 +22955,8 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_VAR_CV(ZEN
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -20483,17 +23002,12 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
-
- if (IS_VAR == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
- PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
- EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr;
- }
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
}
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
@@ -20532,8 +23046,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
@@ -20564,8 +23078,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -20601,15 +23115,15 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCOD
{
USE_OPLINE
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
/* Behave like FETCH_OBJ_W */
zend_free_op free_op1;
zval *property;
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
@@ -20642,8 +23156,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_H
zval *property;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_VAR == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -20685,8 +23199,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
zval *property_name;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- property_name = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property_name);
@@ -20694,7 +23208,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_OBJ, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -20714,19 +23228,19 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
zval **object_ptr;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
- zval *property_name = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ zval *property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property_name);
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_DIM, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -20735,13 +23249,13 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
} else {
zend_free_op free_op_data1, free_op_data2;
zval *value;
- zval *dim = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ zval *dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zval **variable_ptr_ptr;
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), object_ptr, dim, IS_CV, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
if (RETURN_VALUE_USED(opline)) {
@@ -20795,8 +23309,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_AR
zval **variable_ptr_ptr;
SAVE_OPLINE();
- value = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
- variable_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T(opline->op1.var), value, IS_CV TSRMLS_CC)) {
@@ -20850,7 +23364,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
zval **value_ptr_ptr;
SAVE_OPLINE();
- value_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op2.var TSRMLS_CC);
+ value_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op2.var TSRMLS_CC);
if (IS_CV == IS_VAR &&
value_ptr_ptr &&
@@ -20873,7 +23387,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE
zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object");
}
- variable_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if ((IS_CV == IS_VAR && UNEXPECTED(value_ptr_ptr == NULL)) ||
(IS_VAR == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL))) {
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
@@ -20902,63 +23416,72 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_
char *function_name_strval;
int function_name_strlen;
zend_free_op free_op1;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
- function_name = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_CV != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ call->object = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (IS_CV != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((IS_CV == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_CV == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (IS_CV == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
@@ -20971,9 +23494,9 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_
USE_OPLINE
zval *function_name;
zend_class_entry *ce;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
if (IS_VAR == IS_CONST) {
/* no function found. try a static method in class */
@@ -20989,24 +23512,24 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_
}
CACHE_PTR(opline->op1.literal->cache_slot, ce);
}
- EX(called_scope) = ce;
+ call->called_scope = ce;
} else {
ce = EX_T(opline->op1.var).class_entry;
if (opline->extended_value == ZEND_FETCH_CLASS_PARENT || opline->extended_value == ZEND_FETCH_CLASS_SELF) {
- EX(called_scope) = EG(called_scope);
+ call->called_scope = EG(called_scope);
} else {
- EX(called_scope) = ce;
+ call->called_scope = ce;
}
}
if (IS_VAR == IS_CONST &&
IS_CV == IS_CONST &&
CACHED_PTR(opline->op2.literal->cache_slot)) {
- EX(fbc) = CACHED_PTR(opline->op2.literal->cache_slot);
+ call->fbc = CACHED_PTR(opline->op2.literal->cache_slot);
} else if (IS_VAR != IS_CONST &&
IS_CV == IS_CONST &&
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce))) {
/* do nothing */
} else if (IS_CV != IS_UNUSED) {
char *function_name_strval = NULL;
@@ -21017,9 +23540,12 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_
function_name_strval = Z_STRVAL_P(opline->op2.zv);
function_name_strlen = Z_STRLEN_P(opline->op2.zv);
} else {
- function_name = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Function name must be a string");
} else {
function_name_strval = Z_STRVAL_P(function_name);
@@ -21029,20 +23555,20 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_
if (function_name_strval) {
if (ce->get_static_method) {
- EX(fbc) = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
+ call->fbc = ce->get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC);
} else {
- EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_CV == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ call->fbc = zend_std_get_static_method(ce, function_name_strval, function_name_strlen, ((IS_CV == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
}
- if (UNEXPECTED(EX(fbc) == NULL)) {
+ if (UNEXPECTED(call->fbc == NULL)) {
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name, function_name_strval);
}
if (IS_CV == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0)) {
if (IS_VAR == IS_CONST) {
- CACHE_PTR(opline->op2.literal->cache_slot, EX(fbc));
+ CACHE_PTR(opline->op2.literal->cache_slot, call->fbc);
} else {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, EX(fbc));
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce, call->fbc);
}
}
}
@@ -21056,29 +23582,31 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_
if (EG(This) && Z_OBJCE_P(EG(This)) != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) {
zend_error_noreturn(E_ERROR, "Cannot call private %s::__construct()", ce->name);
}
- EX(fbc) = ce->constructor;
+ call->fbc = ce->constructor;
}
- if (EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) {
- EX(object) = NULL;
+ if (call->fbc->common.fn_flags & ZEND_ACC_STATIC) {
+ call->object = NULL;
} else {
if (EG(This) &&
Z_OBJ_HT_P(EG(This))->get_class_entry &&
!instanceof_function(Z_OBJCE_P(EG(This)), ce TSRMLS_CC)) {
/* We are calling method of the other (incompatible) class,
but passing $this. This is done for compatibility with php-4. */
- if (EX(fbc)->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
- zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ if (call->fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) {
+ zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
} else {
/* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */
- zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", EX(fbc)->common.scope->name, EX(fbc)->common.function_name);
+ zend_error_noreturn(E_ERROR, "Non-static method %s::%s() cannot be called statically, assuming $this from incompatible context", call->fbc->common.scope->name, call->fbc->common.function_name);
}
}
- if ((EX(object) = EG(This))) {
- Z_ADDREF_P(EX(object));
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if ((call->object = EG(This))) {
+ Z_ADDREF_P(call->object);
+ call->called_scope = Z_OBJCE_P(call->object);
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -21094,8 +23622,8 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
is_equal_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -21109,7 +23637,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE
SAVE_OPLINE();
if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && opline->extended_value) {
- zval **expr_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ zval **expr_ptr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(expr_ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets");
@@ -21118,7 +23646,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE
expr_ptr = *expr_ptr_ptr;
Z_ADDREF_P(expr_ptr);
} else {
- expr_ptr=_get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ expr_ptr=_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (0) { /* temporary variable */
zval *new_expr;
@@ -21139,7 +23667,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE
if (IS_CV != IS_UNUSED) {
- zval *offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ zval *offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
ulong hval;
switch (Z_TYPE_P(offset)) {
@@ -21210,11 +23738,11 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER
ulong hval;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
- offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_VAR != IS_VAR || container) {
switch (Z_TYPE_PP(container)) {
@@ -21309,8 +23837,8 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
- offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_VAR != IS_VAR || container) {
if (IS_VAR == IS_CV && container != &EG(uninitialized_zval_ptr)) {
@@ -21346,22 +23874,22 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CV(int
{
USE_OPLINE
zend_free_op free_op1;
- zval **container;
+ zval *container;
zval **value = NULL;
int result = 0;
ulong hval;
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC);
+ container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
- if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
+ if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) {
HashTable *ht;
int isset = 0;
- ht = Z_ARRVAL_PP(container);
+ ht = Z_ARRVAL_P(container);
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
@@ -21380,9 +23908,7 @@ num_index_prop:
if (IS_CV == IS_CONST) {
hval = Z_HASH_P(offset);
} else {
- if (!prop_dim) {
- ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
- }
+ ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
@@ -21417,20 +23943,20 @@ num_index_prop:
}
}
- } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ } else if (Z_TYPE_P(container) == IS_OBJECT) {
if (0) {
MAKE_REAL_ZVAL_PTR(offset);
}
if (prop_dim) {
- if (Z_OBJ_HT_P(*container)->has_property) {
- result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_property) {
+ result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check property of non-object");
result = 0;
}
} else {
- if (Z_OBJ_HT_P(*container)->has_dimension) {
- result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_dimension) {
+ result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
result = 0;
@@ -21441,7 +23967,7 @@ num_index_prop:
} else {
}
- } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
+ } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */
zval tmp;
if (Z_TYPE_P(offset) != IS_LONG) {
@@ -21459,11 +23985,11 @@ num_index_prop:
}
if (Z_TYPE_P(offset) == IS_LONG) {
if (opline->extended_value & ZEND_ISSET) {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) {
result = 1;
}
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') {
result = 1;
}
}
@@ -21496,6 +24022,165 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_CV_HANDLER(ZEND_O
return zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CV(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_VAR != IS_UNUSED) {
+ zend_free_op free_op1;
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* If a function call result is yielded and the function did
+ * not return by reference we throw a notice. */
+ if (IS_VAR == IS_VAR && !Z_ISREF_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+ }
+ } else {
+ zval *value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_CV != IS_UNUSED) {
+
+ zval *key = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -21510,6 +24195,9 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARG
if (IS_UNUSED == IS_CONST ||
UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "__clone method called on non-object");
}
@@ -21588,7 +24276,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int
zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
zval *object;
zval *property = opline->op2.zv;
- zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
+ zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
int have_get_ptr = 0;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -21617,7 +24305,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int
/* here property is a string */
if (opline->extended_value == ZEND_ASSIGN_OBJ
&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -21718,8 +24406,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_CONST(int (*bi
zval *dim = opline->op2.zv;
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, IS_CONST, BP_VAR_RW TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
}
}
break;
@@ -21877,7 +24565,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(incde
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -21978,7 +24666,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CONST(incd
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
have_get_ptr = 1;
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -22099,11 +24787,6 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE
SAVE_OPLINE();
property = opline->op2.zv;
- if (IS_UNUSED == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
- PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
- EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr;
- }
-
if (0) {
MAKE_REAL_ZVAL_PTR(property);
}
@@ -22213,7 +24896,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST_HANDLER(ZEND
{
USE_OPLINE
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
/* Behave like FETCH_OBJ_W */
zend_free_op free_op1;
zval *property;
@@ -22305,7 +24988,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_
if (IS_UNUSED == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_OBJ, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -22371,63 +25054,72 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_O
char *function_name_strval;
int function_name_strlen;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
function_name = opline->op2.zv;
if (IS_CONST != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = _get_obj_zval_ptr_unused(TSRMLS_C);
+ call->object = _get_obj_zval_ptr_unused(TSRMLS_C);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (IS_CONST != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((IS_CONST == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_CONST == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (IS_CONST == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
@@ -22519,6 +25211,9 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPC
}
ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value);
zval_copy_ctor(&EX_T(opline->result.var).tmp_var);
+ } else if (Z_STRLEN_P(opline->op2.zv) == sizeof("class")-1 && strcmp(Z_STRVAL_P(opline->op2.zv), "class") == 0) {
+ /* "class" is assigned as a case-sensitive keyword from zend_do_resolve_class_name */
+ ZVAL_STRINGL(&EX_T(opline->result.var).tmp_var, ce->name, ce->name_length, 1);
} else {
zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(opline->op2.zv));
}
@@ -22685,22 +25380,22 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CON
{
USE_OPLINE
- zval **container;
+ zval *container;
zval **value = NULL;
int result = 0;
ulong hval;
zval *offset;
SAVE_OPLINE();
- container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
+ container = _get_obj_zval_ptr_unused(TSRMLS_C);
offset = opline->op2.zv;
- if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
+ if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) {
HashTable *ht;
int isset = 0;
- ht = Z_ARRVAL_PP(container);
+ ht = Z_ARRVAL_P(container);
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
@@ -22719,9 +25414,7 @@ num_index_prop:
if (IS_CONST == IS_CONST) {
hval = Z_HASH_P(offset);
} else {
- if (!prop_dim) {
- ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
- }
+ ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
@@ -22756,20 +25449,20 @@ num_index_prop:
}
}
- } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ } else if (Z_TYPE_P(container) == IS_OBJECT) {
if (0) {
MAKE_REAL_ZVAL_PTR(offset);
}
if (prop_dim) {
- if (Z_OBJ_HT_P(*container)->has_property) {
- result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_property) {
+ result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check property of non-object");
result = 0;
}
} else {
- if (Z_OBJ_HT_P(*container)->has_dimension) {
- result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_dimension) {
+ result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
result = 0;
@@ -22780,7 +25473,7 @@ num_index_prop:
} else {
}
- } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
+ } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */
zval tmp;
if (Z_TYPE_P(offset) != IS_LONG) {
@@ -22798,11 +25491,11 @@ num_index_prop:
}
if (Z_TYPE_P(offset) == IS_LONG) {
if (opline->extended_value & ZEND_ISSET) {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) {
result = 1;
}
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') {
result = 1;
}
}
@@ -22833,14 +25526,171 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST_HANDLER(
return zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CONST(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_UNUSED != IS_UNUSED) {
+
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = NULL;
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = NULL;
+
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* If a function call result is yielded and the function did
+ * not return by reference we throw a notice. */
+ if (IS_UNUSED == IS_VAR && !Z_ISREF_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = NULL;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_CONST != IS_UNUSED) {
+
+ zval *key = opline->op2.zv;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zend_free_op free_op2, free_op_data1;
zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
zval *object;
- zval *property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
+ zval *property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
int have_get_ptr = 0;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -22869,7 +25719,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (*
/* here property is a string */
if (opline->extended_value == ZEND_ASSIGN_OBJ
&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -22967,16 +25817,16 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_TMP(int (*bina
}
return zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
- zval *dim = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, IS_TMP_VAR, BP_VAR_RW TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
}
}
break;
default:
- value = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
var_ptr = NULL;
/* do nothing */
break;
@@ -23101,7 +25951,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_TMP(incdec_
SAVE_OPLINE();
object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
retval = &EX_T(opline->result.var).var.ptr;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -23130,7 +25980,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_TMP(incdec_
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -23205,7 +26055,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_TMP(incdec
SAVE_OPLINE();
object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
retval = &EX_T(opline->result.var).tmp_var;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -23231,7 +26081,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_TMP(incdec
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
have_get_ptr = 1;
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -23305,7 +26155,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_UNUSED_TMP
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(TSRMLS_C);
- offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -23350,12 +26200,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_H
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
-
- if (IS_UNUSED == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
- PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
- EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr;
- }
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (1) {
MAKE_REAL_ZVAL_PTR(property);
@@ -23398,7 +26243,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
if (1) {
@@ -23431,7 +26276,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(TSRMLS_C);
- offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -23466,14 +26311,14 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP_HANDLER(ZEND_O
{
USE_OPLINE
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
/* Behave like FETCH_OBJ_W */
zend_free_op free_op1, free_op2;
zval *property;
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
if (1) {
@@ -23508,7 +26353,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCO
SAVE_OPLINE();
container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_UNUSED == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -23550,7 +26395,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HA
SAVE_OPLINE();
object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- property_name = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (1) {
MAKE_REAL_ZVAL_PTR(property_name);
@@ -23558,7 +26403,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HA
if (IS_UNUSED == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_OBJ, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (1) {
zval_ptr_dtor(&property_name);
} else {
@@ -23581,7 +26426,7 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDL
int use_copy = 0;
SAVE_OPLINE();
- var = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ var = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_UNUSED == IS_UNUSED) {
/* Initialize for erealloc in add_string_to_string */
@@ -23623,63 +26468,72 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP_HANDLER(ZEND_OPC
char *function_name_strval;
int function_name_strlen;
zend_free_op free_op2;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
- function_name = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ function_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_TMP_VAR != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = _get_obj_zval_ptr_unused(TSRMLS_C);
+ call->object = _get_obj_zval_ptr_unused(TSRMLS_C);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (IS_TMP_VAR != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((IS_TMP_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_TMP_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (IS_TMP_VAR == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ zval_dtor(free_op2.var);
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
zval_dtor(free_op2.var);
@@ -23714,7 +26568,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HAN
if (IS_UNUSED == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
- offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_UNUSED != IS_VAR || container) {
switch (Z_TYPE_PP(container)) {
@@ -23809,7 +26663,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HAN
SAVE_OPLINE();
container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_UNUSED != IS_VAR || container) {
if (IS_UNUSED == IS_CV && container != &EG(uninitialized_zval_ptr)) {
@@ -23844,22 +26698,22 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_TMP
{
USE_OPLINE
zend_free_op free_op2;
- zval **container;
+ zval *container;
zval **value = NULL;
int result = 0;
ulong hval;
zval *offset;
SAVE_OPLINE();
- container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
+ container = _get_obj_zval_ptr_unused(TSRMLS_C);
- offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
+ if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) {
HashTable *ht;
int isset = 0;
- ht = Z_ARRVAL_PP(container);
+ ht = Z_ARRVAL_P(container);
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
@@ -23878,9 +26732,7 @@ num_index_prop:
if (IS_TMP_VAR == IS_CONST) {
hval = Z_HASH_P(offset);
} else {
- if (!prop_dim) {
- ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
- }
+ ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
@@ -23915,20 +26767,20 @@ num_index_prop:
}
}
zval_dtor(free_op2.var);
- } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ } else if (Z_TYPE_P(container) == IS_OBJECT) {
if (1) {
MAKE_REAL_ZVAL_PTR(offset);
}
if (prop_dim) {
- if (Z_OBJ_HT_P(*container)->has_property) {
- result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_property) {
+ result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check property of non-object");
result = 0;
}
} else {
- if (Z_OBJ_HT_P(*container)->has_dimension) {
- result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_dimension) {
+ result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
result = 0;
@@ -23939,7 +26791,7 @@ num_index_prop:
} else {
zval_dtor(free_op2.var);
}
- } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
+ } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */
zval tmp;
if (Z_TYPE_P(offset) != IS_LONG) {
@@ -23957,11 +26809,11 @@ num_index_prop:
}
if (Z_TYPE_P(offset) == IS_LONG) {
if (opline->extended_value & ZEND_ISSET) {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) {
result = 1;
}
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') {
result = 1;
}
}
@@ -23992,14 +26844,171 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMP_HANDLER(ZE
return zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_TMP(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_UNUSED != IS_UNUSED) {
+
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = NULL;
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = NULL;
+
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* If a function call result is yielded and the function did
+ * not return by reference we throw a notice. */
+ if (IS_UNUSED == IS_VAR && !Z_ISREF_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = NULL;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_TMP_VAR != IS_UNUSED) {
+ zend_free_op free_op2;
+ zval *key = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!1) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zend_free_op free_op2, free_op_data1;
zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
zval *object;
- zval *property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
+ zval *property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
int have_get_ptr = 0;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -24028,7 +27037,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (*
/* here property is a string */
if (opline->extended_value == ZEND_ASSIGN_OBJ
&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -24126,16 +27135,16 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_VAR(int (*bina
}
return zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
- zval *dim = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, IS_VAR, BP_VAR_RW TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
}
}
break;
default:
- value = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ value = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
var_ptr = NULL;
/* do nothing */
break;
@@ -24260,7 +27269,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_VAR(incdec_
SAVE_OPLINE();
object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
retval = &EX_T(opline->result.var).var.ptr;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -24289,7 +27298,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_VAR(incdec_
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -24364,7 +27373,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_VAR(incdec
SAVE_OPLINE();
object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
retval = &EX_T(opline->result.var).tmp_var;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -24390,7 +27399,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_VAR(incdec
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
have_get_ptr = 1;
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -24464,7 +27473,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_UNUSED_VAR
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(TSRMLS_C);
- offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -24509,12 +27518,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_H
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
-
- if (IS_UNUSED == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
- PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
- EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr;
- }
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
@@ -24557,7 +27561,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
if (0) {
@@ -24590,7 +27594,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(TSRMLS_C);
- offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -24625,14 +27629,14 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_VAR_HANDLER(ZEND_O
{
USE_OPLINE
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
/* Behave like FETCH_OBJ_W */
zend_free_op free_op1, free_op2;
zval *property;
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
if (0) {
@@ -24667,7 +27671,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCO
SAVE_OPLINE();
container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_UNUSED == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -24709,7 +27713,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HA
SAVE_OPLINE();
object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- property_name = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property_name);
@@ -24717,7 +27721,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HA
if (IS_UNUSED == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_OBJ, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -24740,7 +27744,7 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDL
int use_copy = 0;
SAVE_OPLINE();
- var = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ var = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_UNUSED == IS_UNUSED) {
/* Initialize for erealloc in add_string_to_string */
@@ -24782,63 +27786,72 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_VAR_HANDLER(ZEND_OPC
char *function_name_strval;
int function_name_strlen;
zend_free_op free_op2;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
- function_name = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_VAR != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = _get_obj_zval_ptr_unused(TSRMLS_C);
+ call->object = _get_obj_zval_ptr_unused(TSRMLS_C);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (IS_VAR != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((IS_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (IS_VAR == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
@@ -24873,7 +27886,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HAN
if (IS_UNUSED == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
- offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_UNUSED != IS_VAR || container) {
switch (Z_TYPE_PP(container)) {
@@ -24968,7 +27981,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HAN
SAVE_OPLINE();
container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_UNUSED != IS_VAR || container) {
if (IS_UNUSED == IS_CV && container != &EG(uninitialized_zval_ptr)) {
@@ -25003,22 +28016,22 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_VAR
{
USE_OPLINE
zend_free_op free_op2;
- zval **container;
+ zval *container;
zval **value = NULL;
int result = 0;
ulong hval;
zval *offset;
SAVE_OPLINE();
- container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
+ container = _get_obj_zval_ptr_unused(TSRMLS_C);
- offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
+ if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) {
HashTable *ht;
int isset = 0;
- ht = Z_ARRVAL_PP(container);
+ ht = Z_ARRVAL_P(container);
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
@@ -25037,9 +28050,7 @@ num_index_prop:
if (IS_VAR == IS_CONST) {
hval = Z_HASH_P(offset);
} else {
- if (!prop_dim) {
- ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
- }
+ ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
@@ -25074,20 +28085,20 @@ num_index_prop:
}
}
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
- } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ } else if (Z_TYPE_P(container) == IS_OBJECT) {
if (0) {
MAKE_REAL_ZVAL_PTR(offset);
}
if (prop_dim) {
- if (Z_OBJ_HT_P(*container)->has_property) {
- result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_property) {
+ result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check property of non-object");
result = 0;
}
} else {
- if (Z_OBJ_HT_P(*container)->has_dimension) {
- result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_dimension) {
+ result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
result = 0;
@@ -25098,7 +28109,7 @@ num_index_prop:
} else {
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
}
- } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
+ } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */
zval tmp;
if (Z_TYPE_P(offset) != IS_LONG) {
@@ -25116,11 +28127,11 @@ num_index_prop:
}
if (Z_TYPE_P(offset) == IS_LONG) {
if (opline->extended_value & ZEND_ISSET) {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) {
result = 1;
}
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') {
result = 1;
}
}
@@ -25151,6 +28162,164 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_VAR_HANDLER(ZE
return zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_VAR(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_UNUSED != IS_UNUSED) {
+
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = NULL;
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = NULL;
+
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* If a function call result is yielded and the function did
+ * not return by reference we throw a notice. */
+ if (IS_UNUSED == IS_VAR && !Z_ISREF_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = NULL;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_VAR != IS_UNUSED) {
+ zend_free_op free_op2;
+ zval *key = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -25158,7 +28327,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int
zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
zval *object;
zval *property = NULL;
- zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
+ zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
int have_get_ptr = 0;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -25187,7 +28356,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int
/* here property is a string */
if (opline->extended_value == ZEND_ASSIGN_OBJ
&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_UNUSED == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_UNUSED == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -25288,8 +28457,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_UNUSED(int (*b
zval *dim = NULL;
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, IS_UNUSED, BP_VAR_RW TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
}
}
break;
@@ -25420,14 +28589,171 @@ static int ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE
}
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_UNUSED != IS_UNUSED) {
+
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = NULL;
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = NULL;
+
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* If a function call result is yielded and the function did
+ * not return by reference we throw a notice. */
+ if (IS_UNUSED == IS_VAR && !Z_ISREF_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = NULL;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_UNUSED != IS_UNUSED) {
+
+ zval *key = NULL;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zend_free_op free_op_data1;
zval **object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
zval *object;
- zval *property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
- zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
+ zval *property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
+ zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
int have_get_ptr = 0;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -25456,7 +28782,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b
/* here property is a string */
if (opline->extended_value == ZEND_ASSIGN_OBJ
&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -25554,16 +28880,16 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_CV(int (*binar
}
return zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
- zval *dim = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ zval *dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, IS_CV, BP_VAR_RW TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
}
}
break;
default:
- value = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
var_ptr = NULL;
/* do nothing */
break;
@@ -25687,7 +29013,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CV(incdec_t
SAVE_OPLINE();
object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
retval = &EX_T(opline->result.var).var.ptr;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -25716,7 +29042,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CV(incdec_t
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -25791,7 +29117,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CV(incdec_
SAVE_OPLINE();
object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
retval = &EX_T(opline->result.var).tmp_var;
if (IS_UNUSED == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -25817,7 +29143,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CV(incdec_
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
have_get_ptr = 1;
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -25891,7 +29217,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_UNUSED_CV(
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(TSRMLS_C);
- offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -25936,12 +29262,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HA
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
-
- if (IS_UNUSED == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
- PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
- EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr;
- }
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
@@ -25984,7 +29305,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_H
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
if (0) {
@@ -26017,7 +29338,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_H
SAVE_OPLINE();
container = _get_obj_zval_ptr_unused(TSRMLS_C);
- offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -26052,14 +29373,14 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV_HANDLER(ZEND_OP
{
USE_OPLINE
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
/* Behave like FETCH_OBJ_W */
zend_free_op free_op1;
zval *property;
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
if (0) {
@@ -26094,7 +29415,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV_HANDLER(ZEND_OPCOD
SAVE_OPLINE();
container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_UNUSED == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -26136,7 +29457,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HAN
SAVE_OPLINE();
object_ptr = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- property_name = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property_name);
@@ -26144,7 +29465,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HAN
if (IS_UNUSED == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_OBJ, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -26167,7 +29488,7 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLE
int use_copy = 0;
SAVE_OPLINE();
- var = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ var = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_UNUSED == IS_UNUSED) {
/* Initialize for erealloc in add_string_to_string */
@@ -26208,63 +29529,72 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCO
char *function_name_strval;
int function_name_strlen;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
- function_name = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_CV != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = _get_obj_zval_ptr_unused(TSRMLS_C);
+ call->object = _get_obj_zval_ptr_unused(TSRMLS_C);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (IS_CV != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((IS_CV == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_CV == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (IS_CV == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
@@ -26298,7 +29628,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HAND
if (IS_UNUSED == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
- offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_UNUSED != IS_VAR || container) {
switch (Z_TYPE_PP(container)) {
@@ -26393,7 +29723,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HAND
SAVE_OPLINE();
container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
- offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_UNUSED != IS_VAR || container) {
if (IS_UNUSED == IS_CV && container != &EG(uninitialized_zval_ptr)) {
@@ -26428,22 +29758,22 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CV(
{
USE_OPLINE
- zval **container;
+ zval *container;
zval **value = NULL;
int result = 0;
ulong hval;
zval *offset;
SAVE_OPLINE();
- container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C);
+ container = _get_obj_zval_ptr_unused(TSRMLS_C);
- offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
- if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
+ if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) {
HashTable *ht;
int isset = 0;
- ht = Z_ARRVAL_PP(container);
+ ht = Z_ARRVAL_P(container);
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
@@ -26462,9 +29792,7 @@ num_index_prop:
if (IS_CV == IS_CONST) {
hval = Z_HASH_P(offset);
} else {
- if (!prop_dim) {
- ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
- }
+ ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
@@ -26499,20 +29827,20 @@ num_index_prop:
}
}
- } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ } else if (Z_TYPE_P(container) == IS_OBJECT) {
if (0) {
MAKE_REAL_ZVAL_PTR(offset);
}
if (prop_dim) {
- if (Z_OBJ_HT_P(*container)->has_property) {
- result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_property) {
+ result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check property of non-object");
result = 0;
}
} else {
- if (Z_OBJ_HT_P(*container)->has_dimension) {
- result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_dimension) {
+ result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
result = 0;
@@ -26523,7 +29851,7 @@ num_index_prop:
} else {
}
- } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
+ } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */
zval tmp;
if (Z_TYPE_P(offset) != IS_LONG) {
@@ -26541,11 +29869,11 @@ num_index_prop:
}
if (Z_TYPE_P(offset) == IS_LONG) {
if (opline->extended_value & ZEND_ISSET) {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) {
result = 1;
}
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') {
result = 1;
}
}
@@ -26576,6 +29904,163 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV_HANDLER(ZEN
return zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CV(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_UNUSED != IS_UNUSED) {
+
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = NULL;
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = NULL;
+
+ if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* If a function call result is yielded and the function did
+ * not return by reference we throw a notice. */
+ if (IS_UNUSED == IS_VAR && !Z_ISREF_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = NULL;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_CV != IS_UNUSED) {
+
+ zval *key = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_BW_NOT_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -26583,7 +30068,7 @@ static int ZEND_FASTCALL ZEND_BW_NOT_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
bitwise_not_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -26596,7 +30081,7 @@ static int ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
boolean_not_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -26609,7 +30094,7 @@ static int ZEND_FASTCALL ZEND_PRE_INC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zval **var_ptr;
SAVE_OPLINE();
- var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
@@ -26655,7 +30140,7 @@ static int ZEND_FASTCALL ZEND_PRE_DEC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zval **var_ptr;
SAVE_OPLINE();
- var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
@@ -26701,7 +30186,7 @@ static int ZEND_FASTCALL ZEND_POST_INC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
zval **var_ptr, *retval;
SAVE_OPLINE();
- var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
@@ -26743,7 +30228,7 @@ static int ZEND_FASTCALL ZEND_POST_DEC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
zval **var_ptr, *retval;
SAVE_OPLINE();
- var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
@@ -26785,7 +30270,7 @@ static int ZEND_FASTCALL ZEND_ECHO_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zval *z;
SAVE_OPLINE();
- z = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ z = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_TMP_VAR && Z_TYPE_P(z) == IS_OBJECT) {
INIT_PZVAL(z);
@@ -26812,7 +30297,7 @@ static int ZEND_FASTCALL ZEND_JMPZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
int ret;
SAVE_OPLINE();
- val = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ val = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
ret = Z_LVAL_P(val);
@@ -26842,7 +30327,7 @@ static int ZEND_FASTCALL ZEND_JMPNZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
int ret;
SAVE_OPLINE();
- val = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ val = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
ret = Z_LVAL_P(val);
@@ -26872,7 +30357,7 @@ static int ZEND_FASTCALL ZEND_JMPZNZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
int retval;
SAVE_OPLINE();
- val = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ val = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
retval = Z_LVAL_P(val);
@@ -26906,7 +30391,7 @@ static int ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
int retval;
SAVE_OPLINE();
- val = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ val = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
retval = Z_LVAL_P(val);
@@ -26937,7 +30422,7 @@ static int ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
int retval;
SAVE_OPLINE();
- val = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ val = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_TMP_VAR && EXPECTED(Z_TYPE_P(val) == IS_BOOL)) {
retval = Z_LVAL_P(val);
@@ -26967,20 +30452,23 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
- retval_ptr = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ retval_ptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (!EG(return_value_ptr_ptr)) {
if (IS_CV == IS_TMP_VAR) {
}
- } else if (!0) { /* Not a temp var */
+ } else {
if (IS_CV == IS_CONST ||
- (PZVAL_IS_REF(retval_ptr) && Z_REFCOUNT_P(retval_ptr) > 0)) {
+ IS_CV == IS_TMP_VAR ||
+ PZVAL_IS_REF(retval_ptr)) {
zval *ret;
ALLOC_ZVAL(ret);
INIT_PZVAL_COPY(ret, retval_ptr);
- zval_copy_ctor(ret);
+ if (IS_CV != IS_TMP_VAR) {
+ zval_copy_ctor(ret);
+ }
*EG(return_value_ptr_ptr) = ret;
} else if ((IS_CV == IS_CV || IS_CV == IS_VAR) &&
retval_ptr == &EG(uninitialized_zval)) {
@@ -26992,12 +30480,6 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
*EG(return_value_ptr_ptr) = retval_ptr;
Z_ADDREF_P(retval_ptr);
}
- } else {
- zval *ret;
-
- ALLOC_ZVAL(ret);
- INIT_PZVAL_COPY(ret, retval_ptr);
- *EG(return_value_ptr_ptr) = ret;
}
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -27017,7 +30499,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER
/* Not supposed to happen, but we'll allow it */
zend_error(E_NOTICE, "Only variable references should be returned by reference");
- retval_ptr = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ retval_ptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (!EG(return_value_ptr_ptr)) {
if (IS_CV == IS_TMP_VAR) {
@@ -27039,7 +30521,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER
break;
}
- retval_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ retval_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(retval_ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference");
@@ -27081,11 +30563,15 @@ static int ZEND_FASTCALL ZEND_THROW_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
- value = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Can only throw objects");
}
+
zend_exception_save(TSRMLS_C);
/* Not sure if a complete copy is what we want here */
ALLOC_ZVAL(exception);
@@ -27105,7 +30591,7 @@ static int ZEND_FASTCALL zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARG
USE_OPLINE
zval *varptr;
- varptr = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ varptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (varptr == &EG(uninitialized_zval)) {
ALLOC_ZVAL(varptr);
@@ -27139,7 +30625,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL
if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) {
return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
- } else if (!ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.opline_num)) {
+ } else if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) {
return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
@@ -27150,7 +30636,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL
varptr = EX_T(opline->op1.var).var.ptr;
PZVAL_UNLOCK_EX(varptr, &free_op1, 0);
} else {
- varptr = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ varptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
}
if ((!(opline->extended_value & ZEND_ARG_SEND_FUNCTION) ||
EX_T(opline->op1.var).var.fcall_returned_reference) &&
@@ -27165,7 +30651,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL
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.opline_num)) {
+ !ARG_MAY_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) {
zend_error(E_STRICT, "Only variables should be passed by reference");
}
ALLOC_ZVAL(valptr);
@@ -27188,7 +30674,7 @@ static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
zval *varptr;
SAVE_OPLINE();
- varptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ varptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(varptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Only variables can be passed by reference");
@@ -27203,7 +30689,7 @@ static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
if (opline->extended_value == ZEND_DO_FCALL_BY_NAME &&
EX(function_state).function->type == ZEND_INTERNAL_FUNCTION &&
- !ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.opline_num)) {
+ !ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) {
return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
@@ -27221,7 +30707,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
USE_OPLINE
if ((opline->extended_value == ZEND_DO_FCALL_BY_NAME)
- && ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.opline_num)) {
+ && ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, opline->op2.opline_num)) {
return ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
SAVE_OPLINE();
@@ -27236,7 +30722,7 @@ static int ZEND_FASTCALL ZEND_BOOL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
/* PHP 3.0 returned "" for false and 1 for true, here we use 0 and 1 for now */
- ZVAL_BOOL(retval, i_zend_is_true(_get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC)));
+ ZVAL_BOOL(retval, i_zend_is_true(_get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC)));
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -27252,10 +30738,13 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zend_object_clone_obj_t clone_call;
SAVE_OPLINE();
- obj = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ obj = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_CONST ||
UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "__clone method called on non-object");
}
@@ -27313,7 +30802,7 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zval *result = &EX_T(opline->result.var).tmp_var;
SAVE_OPLINE();
- expr = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ expr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (opline->extended_value != IS_STRING) {
ZVAL_COPY_VALUE(result, expr);
@@ -27370,11 +30859,11 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL
zend_op_array *new_op_array=NULL;
zval *inc_filename;
- zval *tmp_inc_filename = NULL;
+ zval *tmp_inc_filename = NULL;
zend_bool failure_retval=0;
SAVE_OPLINE();
- inc_filename = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ inc_filename = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (inc_filename->type!=IS_STRING) {
MAKE_STD_ZVAL(tmp_inc_filename);
@@ -27462,8 +30951,6 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL
EG(return_value_ptr_ptr) = NULL;
}
- EX(current_object) = EX(object);
-
EX(function_state).function = (zend_function *) new_op_array;
EX(object) = NULL;
@@ -27471,14 +30958,13 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL
zend_rebuild_symbol_table(TSRMLS_C);
}
- if (EXPECTED(zend_execute == execute)) {
+ if (EXPECTED(zend_execute_ex == execute_ex)) {
ZEND_VM_ENTER();
} else {
zend_execute(new_op_array TSRMLS_CC);
}
EX(function_state).function = (zend_function *) EX(op_array);
- EX(object) = EX(current_object);
EG(opline_ptr) = &EX(opline);
EG(active_op_array) = EX(op_array);
@@ -27488,15 +30974,6 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL
if (UNEXPECTED(EG(exception) != NULL)) {
zend_throw_exception_internal(NULL TSRMLS_CC);
HANDLE_EXCEPTION();
- } else if (RETURN_VALUE_USED(opline)) {
- if (!EX_T(opline->result.var).var.ptr) { /* there was no return statement */
- zval *retval;
-
- ALLOC_ZVAL(retval);
- ZVAL_BOOL(retval, 1);
- INIT_PZVAL(retval);
- EX_T(opline->result.var).var.ptr = retval;
- }
}
} else if (RETURN_VALUE_USED(opline)) {
@@ -27524,7 +31001,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
if ((IS_CV == IS_CV || IS_CV == IS_VAR) &&
(opline->extended_value & ZEND_FE_RESET_VARIABLE)) {
- array_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ array_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (array_ptr_ptr == NULL || array_ptr_ptr == &EG(uninitialized_zval_ptr)) {
MAKE_STD_ZVAL(array_ptr);
ZVAL_NULL(array_ptr);
@@ -27551,7 +31028,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
Z_ADDREF_P(array_ptr);
}
} else {
- array_ptr = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ array_ptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (0) { /* IS_TMP_VAR */
zval *tmp;
@@ -27629,7 +31106,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
zend_uchar key_type;
key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &str_key_len, &int_key, 0, NULL);
- if (key_type != HASH_KEY_NON_EXISTANT &&
+ if (key_type != HASH_KEY_NON_EXISTENT &&
(key_type == HASH_KEY_IS_LONG ||
zend_check_property_access(zobj, str_key, str_key_len-1 TSRMLS_CC) == SUCCESS)) {
break;
@@ -27660,7 +31137,7 @@ static int ZEND_FASTCALL ZEND_EXIT_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
if (IS_CV != IS_UNUSED) {
- zval *ptr = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval *ptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (Z_TYPE_P(ptr) == IS_LONG) {
EG(exit_status) = Z_LVAL_P(ptr);
@@ -27681,7 +31158,7 @@ static int ZEND_FASTCALL ZEND_JMP_SET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zval *value;
SAVE_OPLINE();
- value = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (i_zend_is_true(value)) {
ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, value);
@@ -27706,7 +31183,7 @@ static int ZEND_FASTCALL ZEND_JMP_SET_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_A
zval *value, *ret;
SAVE_OPLINE();
- value = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (i_zend_is_true(value)) {
if (IS_CV == IS_VAR || IS_CV == IS_CV) {
@@ -27740,7 +31217,7 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
zval *value;
SAVE_OPLINE();
- value = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, value);
if (!0) {
@@ -27758,7 +31235,7 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER
zval *value, *ret;
SAVE_OPLINE();
- value = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR || IS_CV == IS_CV) {
Z_ADDREF_P(value);
@@ -27786,7 +31263,7 @@ static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_AR
zend_bool result;
SAVE_OPLINE();
- expr = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ expr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (Z_TYPE_P(expr) == IS_OBJECT && Z_OBJ_HT_P(expr)->get_class_entry) {
result = instanceof_function(Z_OBJCE_P(expr), EX_T(opline->op2.var).class_entry TSRMLS_CC);
@@ -27806,7 +31283,7 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
fast_add_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
@@ -27821,7 +31298,7 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
fast_sub_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
@@ -27836,7 +31313,7 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
fast_mul_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
@@ -27851,7 +31328,7 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
fast_div_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
@@ -27866,7 +31343,7 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
fast_mod_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
@@ -27881,7 +31358,7 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
shift_left_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
@@ -27896,7 +31373,7 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
shift_right_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
@@ -27911,7 +31388,7 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
concat_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
@@ -27926,7 +31403,7 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA
SAVE_OPLINE();
is_identical_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
@@ -27942,7 +31419,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_CONST_HANDLER(ZEND_OPCOD
SAVE_OPLINE();
is_identical_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
Z_LVAL_P(result) = !Z_LVAL_P(result);
@@ -27959,7 +31436,7 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLE
SAVE_OPLINE();
ZVAL_BOOL(result, fast_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC));
@@ -27975,7 +31452,7 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA
SAVE_OPLINE();
ZVAL_BOOL(result, fast_not_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC));
@@ -27991,7 +31468,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC));
@@ -28007,7 +31484,7 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_CONST_HANDLER(ZEND_OP
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC));
@@ -28022,7 +31499,7 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
bitwise_or_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
@@ -28037,7 +31514,7 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
bitwise_and_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
@@ -28052,7 +31529,7 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
bitwise_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
@@ -28067,7 +31544,7 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLE
SAVE_OPLINE();
boolean_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
@@ -28079,10 +31556,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi
{
USE_OPLINE
zend_free_op free_op_data1;
- zval **object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval **object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
zval *object;
zval *property = opline->op2.zv;
- zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
+ zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
int have_get_ptr = 0;
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -28111,7 +31588,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi
/* here property is a string */
if (opline->extended_value == ZEND_ASSIGN_OBJ
&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -28199,7 +31676,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_CONST(int (*binary
return zend_binary_assign_op_obj_helper_SPEC_CV_CONST(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **container = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval **container = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
@@ -28212,14 +31689,14 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_CONST(int (*binary
zval *dim = opline->op2.zv;
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, IS_CONST, BP_VAR_RW TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
}
}
break;
default:
value = opline->op2.zv;
- var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
/* do nothing */
break;
}
@@ -28341,7 +31818,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CONST(incdec_t
int have_get_ptr = 0;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
property = opline->op2.zv;
retval = &EX_T(opline->result.var).var.ptr;
@@ -28371,7 +31848,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CONST(incdec_t
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -28445,7 +31922,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CONST(incdec_t
int have_get_ptr = 0;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
property = opline->op2.zv;
retval = &EX_T(opline->result.var).tmp_var;
@@ -28472,7 +31949,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CONST(incdec_t
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
have_get_ptr = 1;
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -28547,7 +32024,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_CONST(int type, Z
ulong hash_value;
SAVE_OPLINE();
- varname = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ varname = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV != IS_CONST && UNEXPECTED(Z_TYPE_P(varname) != IS_STRING)) {
ZVAL_COPY_VALUE(&tmp_varname, varname);
@@ -28687,7 +32164,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_
{
USE_OPLINE
- return zend_fetch_var_address_helper_SPEC_CV_CONST(ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ return zend_fetch_var_address_helper_SPEC_CV_CONST(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -28711,7 +32188,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN
if (IS_CV == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
- container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC);
@@ -28726,7 +32203,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
@@ -28759,7 +32236,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
@@ -28781,7 +32258,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA
zval *container;
SAVE_OPLINE();
- container = _get_zval_ptr_cv_BP_VAR_IS(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_IS TSRMLS_CC);
@@ -28796,8 +32273,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPC
SAVE_OPLINE();
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
- zval **container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ zval **container = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
@@ -28814,7 +32291,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPC
if (IS_CONST == IS_UNUSED) {
zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
}
- container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, opline->op2.zv, IS_CONST, BP_VAR_R TSRMLS_CC);
@@ -28830,7 +32307,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -28848,6 +32325,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE
if (UNEXPECTED(EX_T(opline->result.var).var.ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
+ ZEND_VM_NEXT_OPCODE();
} else {
zend_free_op free_res;
zval **retval_ptr = EX_T(opline->result.var).var.ptr_ptr;
@@ -28872,7 +32350,7 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_CV_CONST(Z
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
offset = opline->op2.zv;
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
@@ -28920,15 +32398,10 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN
SAVE_OPLINE();
property = opline->op2.zv;
- if (IS_CV == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
- PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
- EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr;
- }
-
if (0) {
MAKE_REAL_ZVAL_PTR(property);
}
- container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
@@ -28967,7 +32440,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA
SAVE_OPLINE();
property = opline->op2.zv;
- container = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
@@ -28998,7 +32471,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_cv_BP_VAR_IS(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
offset = opline->op2.zv;
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
@@ -29034,7 +32507,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPC
{
USE_OPLINE
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
/* Behave like FETCH_OBJ_W */
zend_free_op free_op1;
zval *property;
@@ -29042,7 +32515,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPC
SAVE_OPLINE();
property = opline->op2.zv;
- container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
@@ -29075,7 +32548,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE
zval *property;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC);
property = opline->op2.zv;
if (IS_CV == IS_CV) {
@@ -29117,7 +32590,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND
zval *property_name;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
property_name = opline->op2.zv;
if (0) {
@@ -29126,7 +32599,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_OBJ, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -29146,7 +32619,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND
zval **object_ptr;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
@@ -29158,7 +32631,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND
if (0) {
MAKE_REAL_ZVAL_PTR(property_name);
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_DIM, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -29172,8 +32645,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), object_ptr, dim, IS_CONST, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
if (RETURN_VALUE_USED(opline)) {
@@ -29228,7 +32701,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
value = opline->op2.zv;
- variable_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ variable_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T(opline->op1.var), value, IS_CONST TSRMLS_CC)) {
@@ -29279,63 +32752,72 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_HANDLER(ZEND_OPCOD
char *function_name_strval;
int function_name_strlen;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
function_name = opline->op2.zv;
if (IS_CONST != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ call->object = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (IS_CONST != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((IS_CONST == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_CONST == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (IS_CONST == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
@@ -29352,7 +32834,7 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
is_equal_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
opline->op2.zv TSRMLS_CC);
CHECK_EXCEPTION();
@@ -29367,7 +32849,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCO
SAVE_OPLINE();
if ((IS_CV == IS_VAR || IS_CV == IS_CV) && opline->extended_value) {
- zval **expr_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval **expr_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(expr_ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets");
@@ -29376,7 +32858,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCO
expr_ptr = *expr_ptr_ptr;
Z_ADDREF_P(expr_ptr);
} else {
- expr_ptr=_get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ expr_ptr=_get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (0) { /* temporary variable */
zval *new_expr;
@@ -29483,7 +32965,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL
ZEND_VM_NEXT_OPCODE();
}
- varname = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ varname = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -29546,7 +33028,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL
ulong hval;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
@@ -29644,7 +33126,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC);
offset = opline->op2.zv;
if (IS_CV != IS_VAR || container) {
@@ -29700,7 +33182,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCO
} else {
HashTable *target_symbol_table;
- zval tmp, *varname = _get_zval_ptr_cv_BP_VAR_IS(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval tmp, *varname = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -29765,22 +33247,22 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CONST(i
{
USE_OPLINE
- zval **container;
+ zval *container;
zval **value = NULL;
int result = 0;
ulong hval;
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_IS(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
offset = opline->op2.zv;
- if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
+ if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) {
HashTable *ht;
int isset = 0;
- ht = Z_ARRVAL_PP(container);
+ ht = Z_ARRVAL_P(container);
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
@@ -29799,9 +33281,7 @@ num_index_prop:
if (IS_CONST == IS_CONST) {
hval = Z_HASH_P(offset);
} else {
- if (!prop_dim) {
- ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
- }
+ ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
@@ -29836,20 +33316,20 @@ num_index_prop:
}
}
- } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ } else if (Z_TYPE_P(container) == IS_OBJECT) {
if (0) {
MAKE_REAL_ZVAL_PTR(offset);
}
if (prop_dim) {
- if (Z_OBJ_HT_P(*container)->has_property) {
- result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_property) {
+ result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CONST == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check property of non-object");
result = 0;
}
} else {
- if (Z_OBJ_HT_P(*container)->has_dimension) {
- result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_dimension) {
+ result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
result = 0;
@@ -29860,7 +33340,7 @@ num_index_prop:
} else {
}
- } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
+ } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */
zval tmp;
if (Z_TYPE_P(offset) != IS_LONG) {
@@ -29878,11 +33358,11 @@ num_index_prop:
}
if (Z_TYPE_P(offset) == IS_LONG) {
if (opline->extended_value & ZEND_ISSET) {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) {
result = 1;
}
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') {
result = 1;
}
}
@@ -29913,6 +33393,163 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST_HANDLER(ZEND
return zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CONST(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_CV != IS_UNUSED) {
+
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
+
+ if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* If a function call result is yielded and the function did
+ * not return by reference we throw a notice. */
+ if (IS_CV == IS_VAR && !Z_ISREF_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_CONST != IS_UNUSED) {
+
+ zval *key = opline->op2.zv;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_ADD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -29920,8 +33557,8 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_add_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -29935,8 +33572,8 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_sub_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -29950,8 +33587,8 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_mul_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -29965,8 +33602,8 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_div_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -29980,8 +33617,8 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_mod_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -29995,8 +33632,8 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_left_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -30010,8 +33647,8 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_right_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -30025,8 +33662,8 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
concat_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -30040,8 +33677,8 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND
SAVE_OPLINE();
is_identical_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -30056,8 +33693,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_
SAVE_OPLINE();
is_identical_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
Z_LVAL_P(result) = !Z_LVAL_P(result);
zval_dtor(free_op2.var);
@@ -30073,8 +33710,8 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
ZVAL_BOOL(result, fast_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -30089,8 +33726,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND
SAVE_OPLINE();
ZVAL_BOOL(result, fast_not_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -30105,8 +33742,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -30121,8 +33758,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_TMP_HANDLER(ZEND_OPCO
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -30136,8 +33773,8 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
bitwise_or_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -30151,8 +33788,8 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
bitwise_and_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -30166,8 +33803,8 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
bitwise_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -30181,8 +33818,8 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
boolean_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -30193,10 +33830,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*bina
{
USE_OPLINE
zend_free_op free_op2, free_op_data1;
- zval **object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval **object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
zval *object;
- zval *property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
+ zval *property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
int have_get_ptr = 0;
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -30225,7 +33862,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*bina
/* here property is a string */
if (opline->extended_value == ZEND_ASSIGN_OBJ
&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -30313,7 +33950,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_TMP(int (*binary_o
return zend_binary_assign_op_obj_helper_SPEC_CV_TMP(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **container = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval **container = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
@@ -30323,17 +33960,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_TMP(int (*binary_o
}
return zend_binary_assign_op_obj_helper_SPEC_CV_TMP(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
- zval *dim = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, IS_TMP_VAR, BP_VAR_RW TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
}
}
break;
default:
- value = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
/* do nothing */
break;
}
@@ -30456,8 +34093,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_TMP(incdec_t in
int have_get_ptr = 0;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
retval = &EX_T(opline->result.var).var.ptr;
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -30486,7 +34123,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_TMP(incdec_t in
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -30560,8 +34197,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_TMP(incdec_t i
int have_get_ptr = 0;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
retval = &EX_T(opline->result.var).tmp_var;
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -30587,7 +34224,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_TMP(incdec_t i
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
have_get_ptr = 1;
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -30662,8 +34299,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL
if (IS_CV == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
- container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -30677,12 +34314,12 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_W TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_W TSRMLS_CC);
zval_dtor(free_op2.var);
if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -30710,12 +34347,12 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_RW TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_RW TSRMLS_CC);
zval_dtor(free_op2.var);
if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -30732,8 +34369,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND
zval *container;
SAVE_OPLINE();
- container = _get_zval_ptr_cv_BP_VAR_IS(EX_CVs(), opline->op1.var TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_IS TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_IS TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -30747,13 +34384,13 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCOD
SAVE_OPLINE();
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
- zval **container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ zval **container = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_W TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_W TSRMLS_CC);
if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
}
@@ -30765,8 +34402,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCOD
if (IS_TMP_VAR == IS_UNUSED) {
zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
}
- container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_R TSRMLS_CC);
zval_dtor(free_op2.var);
}
@@ -30781,7 +34418,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_H
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -30791,7 +34428,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_H
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_UNSET TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR, BP_VAR_UNSET TSRMLS_CC);
zval_dtor(free_op2.var);
if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -30799,6 +34436,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_H
if (UNEXPECTED(EX_T(opline->result.var).var.ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
+ ZEND_VM_NEXT_OPCODE();
} else {
zend_free_op free_res;
zval **retval_ptr = EX_T(opline->result.var).var.ptr_ptr;
@@ -30823,8 +34461,8 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_CV_TMP(ZEN
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
- offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+ offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -30869,17 +34507,12 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
-
- if (IS_CV == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
- PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
- EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr;
- }
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (1) {
MAKE_REAL_ZVAL_PTR(property);
}
- container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
@@ -30917,8 +34550,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- container = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (1) {
MAKE_REAL_ZVAL_PTR(property);
@@ -30949,8 +34582,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_cv_BP_VAR_IS(EX_CVs(), opline->op1.var TSRMLS_CC);
- offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
+ offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -30985,15 +34618,15 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCOD
{
USE_OPLINE
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
/* Behave like FETCH_OBJ_W */
zend_free_op free_op1, free_op2;
zval *property;
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (1) {
MAKE_REAL_ZVAL_PTR(property);
@@ -31026,8 +34659,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_H
zval *property;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(EX_CVs(), opline->op1.var TSRMLS_CC);
- property = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC);
+ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_CV == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -31068,8 +34701,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE
zval *property_name;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
- property_name = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
+ property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (1) {
MAKE_REAL_ZVAL_PTR(property_name);
@@ -31077,7 +34710,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_OBJ, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (1) {
zval_ptr_dtor(&property_name);
} else {
@@ -31097,19 +34730,19 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE
zval **object_ptr;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
zend_free_op free_op2;
- zval *property_name = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (1) {
MAKE_REAL_ZVAL_PTR(property_name);
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_DIM, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (1) {
zval_ptr_dtor(&property_name);
} else {
@@ -31118,14 +34751,14 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE
} else {
zend_free_op free_op2, free_op_data1, free_op_data2;
zval *value;
- zval *dim = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval **variable_ptr_ptr;
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), object_ptr, dim, IS_TMP_VAR, BP_VAR_W TSRMLS_CC);
zval_dtor(free_op2.var);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
if (RETURN_VALUE_USED(opline)) {
@@ -31179,8 +34812,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
zval **variable_ptr_ptr;
SAVE_OPLINE();
- value = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- variable_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ variable_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T(opline->op1.var), value, IS_TMP_VAR TSRMLS_CC)) {
@@ -31231,63 +34864,72 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_
char *function_name_strval;
int function_name_strlen;
zend_free_op free_op2;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
- function_name = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ function_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_TMP_VAR != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ call->object = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (IS_TMP_VAR != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((IS_TMP_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_TMP_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (IS_TMP_VAR == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ zval_dtor(free_op2.var);
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
zval_dtor(free_op2.var);
@@ -31305,8 +34947,8 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
is_equal_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
zval_dtor(free_op2.var);
CHECK_EXCEPTION();
@@ -31321,7 +34963,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE
SAVE_OPLINE();
if ((IS_CV == IS_VAR || IS_CV == IS_CV) && opline->extended_value) {
- zval **expr_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval **expr_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(expr_ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets");
@@ -31330,7 +34972,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE
expr_ptr = *expr_ptr_ptr;
Z_ADDREF_P(expr_ptr);
} else {
- expr_ptr=_get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ expr_ptr=_get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (0) { /* temporary variable */
zval *new_expr;
@@ -31351,7 +34993,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE
if (IS_TMP_VAR != IS_UNUSED) {
zend_free_op free_op2;
- zval *offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
ulong hval;
switch (Z_TYPE_P(offset)) {
@@ -31422,11 +35064,11 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER
ulong hval;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
- offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_CV != IS_VAR || container) {
switch (Z_TYPE_PP(container)) {
@@ -31520,8 +35162,8 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(EX_CVs(), opline->op1.var TSRMLS_CC);
- offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC);
+ offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_CV != IS_VAR || container) {
if (IS_CV == IS_CV && container != &EG(uninitialized_zval_ptr)) {
@@ -31556,22 +35198,22 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_TMP(int
{
USE_OPLINE
zend_free_op free_op2;
- zval **container;
+ zval *container;
zval **value = NULL;
int result = 0;
ulong hval;
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_IS(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
- offset = _get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
+ if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) {
HashTable *ht;
int isset = 0;
- ht = Z_ARRVAL_PP(container);
+ ht = Z_ARRVAL_P(container);
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
@@ -31590,9 +35232,7 @@ num_index_prop:
if (IS_TMP_VAR == IS_CONST) {
hval = Z_HASH_P(offset);
} else {
- if (!prop_dim) {
- ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
- }
+ ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
@@ -31627,20 +35267,20 @@ num_index_prop:
}
}
zval_dtor(free_op2.var);
- } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ } else if (Z_TYPE_P(container) == IS_OBJECT) {
if (1) {
MAKE_REAL_ZVAL_PTR(offset);
}
if (prop_dim) {
- if (Z_OBJ_HT_P(*container)->has_property) {
- result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_property) {
+ result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_TMP_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check property of non-object");
result = 0;
}
} else {
- if (Z_OBJ_HT_P(*container)->has_dimension) {
- result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_dimension) {
+ result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
result = 0;
@@ -31651,7 +35291,7 @@ num_index_prop:
} else {
zval_dtor(free_op2.var);
}
- } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
+ } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */
zval tmp;
if (Z_TYPE_P(offset) != IS_LONG) {
@@ -31669,11 +35309,11 @@ num_index_prop:
}
if (Z_TYPE_P(offset) == IS_LONG) {
if (opline->extended_value & ZEND_ISSET) {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) {
result = 1;
}
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') {
result = 1;
}
}
@@ -31704,6 +35344,163 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMP_HANDLER(ZEND_O
return zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_TMP(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_CV != IS_UNUSED) {
+
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
+
+ if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* If a function call result is yielded and the function did
+ * not return by reference we throw a notice. */
+ if (IS_CV == IS_VAR && !Z_ISREF_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_TMP_VAR != IS_UNUSED) {
+ zend_free_op free_op2;
+ zval *key = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!1) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_ADD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -31711,8 +35508,8 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_add_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31726,8 +35523,8 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_sub_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31741,8 +35538,8 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_mul_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31756,8 +35553,8 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_div_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31771,8 +35568,8 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_mod_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31786,8 +35583,8 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_left_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31801,8 +35598,8 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_right_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31816,8 +35613,8 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
concat_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31831,8 +35628,8 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND
SAVE_OPLINE();
is_identical_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31847,8 +35644,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_
SAVE_OPLINE();
is_identical_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
Z_LVAL_P(result) = !Z_LVAL_P(result);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
@@ -31864,8 +35661,8 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
ZVAL_BOOL(result, fast_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31880,8 +35677,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND
SAVE_OPLINE();
ZVAL_BOOL(result, fast_not_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31896,8 +35693,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31912,8 +35709,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_VAR_HANDLER(ZEND_OPCO
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC));
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31927,8 +35724,8 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
bitwise_or_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31942,8 +35739,8 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
bitwise_and_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31957,8 +35754,8 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
SAVE_OPLINE();
bitwise_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31972,8 +35769,8 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_
SAVE_OPLINE();
boolean_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -31984,10 +35781,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina
{
USE_OPLINE
zend_free_op free_op2, free_op_data1;
- zval **object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval **object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
zval *object;
- zval *property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
+ zval *property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
int have_get_ptr = 0;
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -32016,7 +35813,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina
/* here property is a string */
if (opline->extended_value == ZEND_ASSIGN_OBJ
&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -32104,7 +35901,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_VAR(int (*binary_o
return zend_binary_assign_op_obj_helper_SPEC_CV_VAR(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **container = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval **container = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
@@ -32114,17 +35911,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_VAR(int (*binary_o
}
return zend_binary_assign_op_obj_helper_SPEC_CV_VAR(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
- zval *dim = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, IS_VAR, BP_VAR_RW TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
}
}
break;
default:
- value = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ value = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
/* do nothing */
break;
}
@@ -32247,8 +36044,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_VAR(incdec_t in
int have_get_ptr = 0;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
retval = &EX_T(opline->result.var).var.ptr;
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -32277,7 +36074,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_VAR(incdec_t in
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -32351,8 +36148,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_VAR(incdec_t i
int have_get_ptr = 0;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
retval = &EX_T(opline->result.var).tmp_var;
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -32378,7 +36175,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_VAR(incdec_t i
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
have_get_ptr = 1;
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -32453,7 +36250,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_VAR(int type, ZEN
ulong hash_value;
SAVE_OPLINE();
- varname = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ varname = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV != IS_CONST && UNEXPECTED(Z_TYPE_P(varname) != IS_STRING)) {
ZVAL_COPY_VALUE(&tmp_varname, varname);
@@ -32593,7 +36390,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HA
{
USE_OPLINE
- return zend_fetch_var_address_helper_SPEC_CV_VAR(ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ return zend_fetch_var_address_helper_SPEC_CV_VAR(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -32617,8 +36414,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL
if (IS_CV == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
- container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -32632,12 +36429,12 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_W TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_W TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -32665,12 +36462,12 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_RW TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_RW TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -32687,8 +36484,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND
zval *container;
SAVE_OPLINE();
- container = _get_zval_ptr_cv_BP_VAR_IS(EX_CVs(), opline->op1.var TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_IS TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_IS TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -32702,13 +36499,13 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCOD
SAVE_OPLINE();
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
- zval **container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ zval **container = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_W TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_W TSRMLS_CC);
if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
}
@@ -32720,8 +36517,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCOD
if (IS_VAR == IS_UNUSED) {
zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
}
- container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_R TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
}
@@ -32736,7 +36533,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_H
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -32746,7 +36543,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_H
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_UNSET TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR, BP_VAR_UNSET TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -32754,6 +36551,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_H
if (UNEXPECTED(EX_T(opline->result.var).var.ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
+ ZEND_VM_NEXT_OPCODE();
} else {
zend_free_op free_res;
zval **retval_ptr = EX_T(opline->result.var).var.ptr_ptr;
@@ -32778,8 +36576,8 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_CV_VAR(ZEN
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
- offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+ offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -32824,17 +36622,12 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
-
- if (IS_CV == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
- PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
- EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr;
- }
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
}
- container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
@@ -32872,8 +36665,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- container = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
@@ -32904,8 +36697,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_cv_BP_VAR_IS(EX_CVs(), opline->op1.var TSRMLS_CC);
- offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
+ offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -32940,15 +36733,15 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCOD
{
USE_OPLINE
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
/* Behave like FETCH_OBJ_W */
zend_free_op free_op1, free_op2;
zval *property;
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
@@ -32981,8 +36774,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_H
zval *property;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(EX_CVs(), opline->op1.var TSRMLS_CC);
- property = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC);
+ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_CV == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -33023,8 +36816,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
zval *property_name;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
- property_name = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
+ property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property_name);
@@ -33032,7 +36825,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_OBJ, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -33052,19 +36845,19 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
zval **object_ptr;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
zend_free_op free_op2;
- zval *property_name = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property_name);
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_DIM, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -33073,14 +36866,14 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
} else {
zend_free_op free_op2, free_op_data1, free_op_data2;
zval *value;
- zval *dim = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
zval **variable_ptr_ptr;
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), object_ptr, dim, IS_VAR, BP_VAR_W TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
if (RETURN_VALUE_USED(opline)) {
@@ -33134,8 +36927,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
zval **variable_ptr_ptr;
SAVE_OPLINE();
- value = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
- variable_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ value = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+ variable_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T(opline->op1.var), value, IS_VAR TSRMLS_CC)) {
@@ -33188,7 +36981,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
zval **value_ptr_ptr;
SAVE_OPLINE();
- value_ptr_ptr = _get_zval_ptr_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ value_ptr_ptr = _get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_VAR == IS_VAR &&
value_ptr_ptr &&
@@ -33211,7 +37004,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE
zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object");
}
- variable_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ variable_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if ((IS_VAR == IS_VAR && UNEXPECTED(value_ptr_ptr == NULL)) ||
(IS_CV == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL))) {
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
@@ -33240,63 +37033,72 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_
char *function_name_strval;
int function_name_strlen;
zend_free_op free_op2;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
- function_name = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_VAR != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ call->object = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (IS_VAR != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((IS_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_VAR == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (IS_VAR == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
@@ -33314,8 +37116,8 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
is_equal_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC);
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
CHECK_EXCEPTION();
@@ -33330,7 +37132,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_VAR_HANDLER(ZEND_OPCODE
SAVE_OPLINE();
if ((IS_CV == IS_VAR || IS_CV == IS_CV) && opline->extended_value) {
- zval **expr_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval **expr_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(expr_ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets");
@@ -33339,7 +37141,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_VAR_HANDLER(ZEND_OPCODE
expr_ptr = *expr_ptr_ptr;
Z_ADDREF_P(expr_ptr);
} else {
- expr_ptr=_get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ expr_ptr=_get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (0) { /* temporary variable */
zval *new_expr;
@@ -33360,7 +37162,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_VAR_HANDLER(ZEND_OPCODE
if (IS_VAR != IS_UNUSED) {
zend_free_op free_op2;
- zval *offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
ulong hval;
switch (Z_TYPE_P(offset)) {
@@ -33446,7 +37248,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER
ZEND_VM_NEXT_OPCODE();
}
- varname = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ varname = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -33509,11 +37311,11 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER
ulong hval;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
- offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_CV != IS_VAR || container) {
switch (Z_TYPE_PP(container)) {
@@ -33607,8 +37409,8 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(EX_CVs(), opline->op1.var TSRMLS_CC);
- offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC);
+ offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_CV != IS_VAR || container) {
if (IS_CV == IS_CV && container != &EG(uninitialized_zval_ptr)) {
@@ -33663,7 +37465,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE
} else {
HashTable *target_symbol_table;
- zval tmp, *varname = _get_zval_ptr_cv_BP_VAR_IS(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval tmp, *varname = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -33728,22 +37530,22 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_VAR(int
{
USE_OPLINE
zend_free_op free_op2;
- zval **container;
+ zval *container;
zval **value = NULL;
int result = 0;
ulong hval;
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_IS(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
- offset = _get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC);
+ offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
- if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
+ if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) {
HashTable *ht;
int isset = 0;
- ht = Z_ARRVAL_PP(container);
+ ht = Z_ARRVAL_P(container);
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
@@ -33762,9 +37564,7 @@ num_index_prop:
if (IS_VAR == IS_CONST) {
hval = Z_HASH_P(offset);
} else {
- if (!prop_dim) {
- ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
- }
+ ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
@@ -33799,20 +37599,20 @@ num_index_prop:
}
}
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
- } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ } else if (Z_TYPE_P(container) == IS_OBJECT) {
if (0) {
MAKE_REAL_ZVAL_PTR(offset);
}
if (prop_dim) {
- if (Z_OBJ_HT_P(*container)->has_property) {
- result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_property) {
+ result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_VAR == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check property of non-object");
result = 0;
}
} else {
- if (Z_OBJ_HT_P(*container)->has_dimension) {
- result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_dimension) {
+ result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
result = 0;
@@ -33823,7 +37623,7 @@ num_index_prop:
} else {
if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
}
- } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
+ } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */
zval tmp;
if (Z_TYPE_P(offset) != IS_LONG) {
@@ -33841,11 +37641,11 @@ num_index_prop:
}
if (Z_TYPE_P(offset) == IS_LONG) {
if (opline->extended_value & ZEND_ISSET) {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) {
result = 1;
}
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') {
result = 1;
}
}
@@ -33876,14 +37676,172 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_VAR_HANDLER(ZEND_O
return zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_VAR(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_CV != IS_UNUSED) {
+
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
+
+ if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* If a function call result is yielded and the function did
+ * not return by reference we throw a notice. */
+ if (IS_CV == IS_VAR && !Z_ISREF_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_VAR != IS_UNUSED) {
+ zend_free_op free_op2;
+ zval *key = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ if (free_op2.var) {zval_ptr_dtor(&free_op2.var);};
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC), ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
zend_free_op free_op_data1;
- zval **object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval **object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
zval *object;
zval *property = NULL;
- zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
+ zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
int have_get_ptr = 0;
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -33912,7 +37870,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*b
/* here property is a string */
if (opline->extended_value == ZEND_ASSIGN_OBJ
&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_UNUSED == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_UNUSED == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -34000,7 +37958,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_UNUSED(int (*binar
return zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **container = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval **container = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
@@ -34013,14 +37971,14 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_UNUSED(int (*binar
zval *dim = NULL;
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, IS_UNUSED, BP_VAR_RW TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
}
}
break;
default:
value = NULL;
- var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
/* do nothing */
break;
}
@@ -34142,7 +38100,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_UNUSED(int type,
ulong hash_value;
SAVE_OPLINE();
- varname = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ varname = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV != IS_CONST && UNEXPECTED(Z_TYPE_P(varname) != IS_STRING)) {
ZVAL_COPY_VALUE(&tmp_varname, varname);
@@ -34282,7 +38240,7 @@ static int ZEND_FASTCALL ZEND_FETCH_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE
{
USE_OPLINE
- return zend_fetch_var_address_helper_SPEC_CV_UNUSED(ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ return zend_fetch_var_address_helper_SPEC_CV_UNUSED(ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))?BP_VAR_W:BP_VAR_R, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
static int ZEND_FASTCALL ZEND_FETCH_UNSET_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -34302,7 +38260,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HA
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
@@ -34335,7 +38293,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_H
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
@@ -34357,8 +38315,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OP
SAVE_OPLINE();
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
- zval **container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ zval **container = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
@@ -34375,7 +38333,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OP
if (IS_UNUSED == IS_UNUSED) {
zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
}
- container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, NULL, IS_UNUSED, BP_VAR_R TSRMLS_CC);
@@ -34391,7 +38349,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN
zval **object_ptr;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
@@ -34403,7 +38361,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN
if (0) {
MAKE_REAL_ZVAL_PTR(property_name);
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_DIM, ((IS_UNUSED == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_UNUSED == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -34417,8 +38375,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), object_ptr, dim, IS_UNUSED, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
if (RETURN_VALUE_USED(opline)) {
@@ -34472,7 +38430,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPC
SAVE_OPLINE();
if ((IS_CV == IS_VAR || IS_CV == IS_CV) && opline->extended_value) {
- zval **expr_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval **expr_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(expr_ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets");
@@ -34481,7 +38439,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPC
expr_ptr = *expr_ptr_ptr;
Z_ADDREF_P(expr_ptr);
} else {
- expr_ptr=_get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ expr_ptr=_get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (0) { /* temporary variable */
zval *new_expr;
@@ -34588,7 +38546,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAND
ZEND_VM_NEXT_OPCODE();
}
- varname = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ varname = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -34666,7 +38624,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPC
} else {
HashTable *target_symbol_table;
- zval tmp, *varname = _get_zval_ptr_cv_BP_VAR_IS(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval tmp, *varname = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_COPY_VALUE(&tmp, varname);
@@ -34727,6 +38685,163 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPC
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_CV != IS_UNUSED) {
+
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
+
+ if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* If a function call result is yielded and the function did
+ * not return by reference we throw a notice. */
+ if (IS_CV == IS_VAR && !Z_ISREF_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_UNUSED != IS_UNUSED) {
+
+ zval *key = NULL;
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_ADD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -34734,8 +38849,8 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_add_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -34749,8 +38864,8 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_sub_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -34764,8 +38879,8 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_mul_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -34779,8 +38894,8 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_div_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -34794,8 +38909,8 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
fast_mod_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -34809,8 +38924,8 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_left_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -34824,8 +38939,8 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
SAVE_OPLINE();
shift_right_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -34839,8 +38954,8 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
concat_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -34854,8 +38969,8 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL
SAVE_OPLINE();
is_identical_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -34870,8 +38985,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_H
SAVE_OPLINE();
is_identical_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
Z_LVAL_P(result) = !Z_LVAL_P(result);
@@ -34887,8 +39002,8 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
ZVAL_BOOL(result, fast_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC));
CHECK_EXCEPTION();
@@ -34903,8 +39018,8 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL
SAVE_OPLINE();
ZVAL_BOOL(result, fast_not_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC));
CHECK_EXCEPTION();
@@ -34919,8 +39034,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC));
CHECK_EXCEPTION();
@@ -34935,8 +39050,8 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_CV_HANDLER(ZEND_OPCOD
SAVE_OPLINE();
ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC));
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC));
CHECK_EXCEPTION();
@@ -34950,8 +39065,8 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
SAVE_OPLINE();
bitwise_or_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -34965,8 +39080,8 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
bitwise_and_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -34980,8 +39095,8 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
SAVE_OPLINE();
bitwise_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -34995,8 +39110,8 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_A
SAVE_OPLINE();
boolean_xor_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
@@ -35007,10 +39122,10 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar
{
USE_OPLINE
zend_free_op free_op_data1;
- zval **object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval **object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
zval *object;
- zval *property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
- zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
+ zval *property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
+ zval *value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
int have_get_ptr = 0;
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -35039,7 +39154,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar
/* here property is a string */
if (opline->extended_value == ZEND_ASSIGN_OBJ
&& Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -35127,7 +39242,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_CV(int (*binary_op
return zend_binary_assign_op_obj_helper_SPEC_CV_CV(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
break;
case ZEND_ASSIGN_DIM: {
- zval **container = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval **container = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
@@ -35137,17 +39252,17 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_CV(int (*binary_op
}
return zend_binary_assign_op_obj_helper_SPEC_CV_CV(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
} else {
- zval *dim = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ zval *dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), container, dim, IS_CV, BP_VAR_RW TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
}
}
break;
default:
- value = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
- var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
+ var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
/* do nothing */
break;
}
@@ -35269,8 +39384,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CV(incdec_t inc
int have_get_ptr = 0;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
retval = &EX_T(opline->result.var).var.ptr;
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -35299,7 +39414,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CV(incdec_t inc
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -35373,8 +39488,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CV(incdec_t in
int have_get_ptr = 0;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
retval = &EX_T(opline->result.var).tmp_var;
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
@@ -35400,7 +39515,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CV(incdec_t in
}
if (Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
- zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zval **zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (zptr != NULL) { /* NULL means no success in getting PTR */
have_get_ptr = 1;
SEPARATE_ZVAL_IF_NOT_REF(zptr);
@@ -35475,8 +39590,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE
if (IS_CV == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
- container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
CHECK_EXCEPTION();
@@ -35490,12 +39605,12 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_W TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_W TSRMLS_CC);
if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -35523,12 +39638,12 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_RW TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_RW TSRMLS_CC);
if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -35545,8 +39660,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL
zval *container;
SAVE_OPLINE();
- container = _get_zval_ptr_cv_BP_VAR_IS(EX_CVs(), opline->op1.var TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_IS TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_IS TSRMLS_CC);
CHECK_EXCEPTION();
@@ -35560,13 +39675,13 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE
SAVE_OPLINE();
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
- zval **container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ zval **container = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_W TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_W TSRMLS_CC);
if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
}
@@ -35578,8 +39693,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE
if (IS_CV == IS_UNUSED) {
zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
}
- container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
- zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+ zend_fetch_dimension_address_read(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_R TSRMLS_CC);
}
@@ -35594,7 +39709,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HA
zval **container;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -35604,7 +39719,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HA
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_UNSET TSRMLS_CC);
+ zend_fetch_dimension_address(&EX_T(opline->result.var), container, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV, BP_VAR_UNSET TSRMLS_CC);
if (IS_CV == IS_VAR && 0 && READY_TO_DESTROY(free_op1.var)) {
EXTRACT_ZVAL_PTR(&EX_T(opline->result.var));
@@ -35612,6 +39727,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HA
if (UNEXPECTED(EX_T(opline->result.var).var.ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot unset string offsets");
+ ZEND_VM_NEXT_OPCODE();
} else {
zend_free_op free_res;
zval **retval_ptr = EX_T(opline->result.var).var.ptr_ptr;
@@ -35636,8 +39752,8 @@ static int ZEND_FASTCALL zend_fetch_property_address_read_helper_SPEC_CV_CV(ZEND
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
- offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+ offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -35682,17 +39798,12 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
-
- if (IS_CV == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) {
- PZVAL_LOCK(*EX_T(opline->op1.var).var.ptr_ptr);
- EX_T(opline->op1.var).var.ptr = *EX_T(opline->op1.var).var.ptr_ptr;
- }
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
}
- container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
@@ -35730,8 +39841,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
- container = _get_zval_ptr_ptr_cv_BP_VAR_RW(EX_CVs(), opline->op1.var TSRMLS_CC);
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
@@ -35762,8 +39873,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_cv_BP_VAR_IS(EX_CVs(), opline->op1.var TSRMLS_CC);
- offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
+ offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT) ||
UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) {
@@ -35798,15 +39909,15 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE
{
USE_OPLINE
- if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
+ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->fbc, (opline->extended_value & ZEND_FETCH_ARG_MASK))) {
/* Behave like FETCH_OBJ_W */
zend_free_op free_op1;
zval *property;
zval **container;
SAVE_OPLINE();
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
- container = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property);
@@ -35839,8 +39950,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HA
zval *property;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(EX_CVs(), opline->op1.var TSRMLS_CC);
- property = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC);
+ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_CV == IS_CV) {
if (container != &EG(uninitialized_zval_ptr)) {
@@ -35881,8 +39992,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
zval *property_name;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
- property_name = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
+ property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property_name);
@@ -35890,7 +40001,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_OBJ, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -35910,19 +40021,19 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
zval **object_ptr;
SAVE_OPLINE();
- object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ object_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
}
if (Z_TYPE_PP(object_ptr) == IS_OBJECT) {
- zval *property_name = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ zval *property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (0) {
MAKE_REAL_ZVAL_PTR(property_name);
}
- zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), ZEND_ASSIGN_DIM, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ zend_assign_to_object(RETURN_VALUE_USED(opline)?&EX_T(opline->result.var).var.ptr:NULL, object_ptr, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
if (0) {
zval_ptr_dtor(&property_name);
} else {
@@ -35931,13 +40042,13 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
} else {
zend_free_op free_op_data1, free_op_data2;
zval *value;
- zval *dim = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ zval *dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
zval **variable_ptr_ptr;
zend_fetch_dimension_address(&EX_T((opline+1)->op2.var), object_ptr, dim, IS_CV, BP_VAR_W TSRMLS_CC);
- value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, EX_Ts(), &free_op_data1, BP_VAR_R);
- variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, EX_Ts(), &free_op_data2 TSRMLS_CC);
+ value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R);
+ variable_ptr_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC);
if (UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T((opline+1)->op2.var), value, (opline+1)->op1_type TSRMLS_CC)) {
if (RETURN_VALUE_USED(opline)) {
@@ -35991,8 +40102,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
zval **variable_ptr_ptr;
SAVE_OPLINE();
- value = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
- variable_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
+ variable_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL)) {
if (zend_assign_to_string_offset(&EX_T(opline->op1.var), value, IS_CV TSRMLS_CC)) {
@@ -36044,7 +40155,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
zval **value_ptr_ptr;
SAVE_OPLINE();
- value_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op2.var TSRMLS_CC);
+ value_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op2.var TSRMLS_CC);
if (IS_CV == IS_VAR &&
value_ptr_ptr &&
@@ -36067,7 +40178,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER
zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object");
}
- variable_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ variable_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if ((IS_CV == IS_VAR && UNEXPECTED(value_ptr_ptr == NULL)) ||
(IS_CV == IS_VAR && UNEXPECTED(variable_ptr_ptr == NULL))) {
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects");
@@ -36095,63 +40206,72 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_H
char *function_name_strval;
int function_name_strlen;
+ call_slot *call = EX(call_slots) + opline->result.num;
SAVE_OPLINE();
- zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope));
- function_name = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_CV != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Method name must be a string");
}
function_name_strval = Z_STRVAL_P(function_name);
function_name_strlen = Z_STRLEN_P(function_name);
- EX(object) = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ call->object = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
- if (EXPECTED(EX(object) != NULL) &&
- EXPECTED(Z_TYPE_P(EX(object)) == IS_OBJECT)) {
- EX(called_scope) = Z_OBJCE_P(EX(object));
+ if (EXPECTED(call->object != NULL) &&
+ EXPECTED(Z_TYPE_P(call->object) == IS_OBJECT)) {
+ call->called_scope = Z_OBJCE_P(call->object);
if (IS_CV != IS_CONST ||
- (EX(fbc) = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope))) == NULL) {
- zval *object = EX(object);
+ (call->fbc = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope)) == NULL) {
+ zval *object = call->object;
- if (UNEXPECTED(Z_OBJ_HT_P(EX(object))->get_method == NULL)) {
+ if (UNEXPECTED(Z_OBJ_HT_P(call->object)->get_method == NULL)) {
zend_error_noreturn(E_ERROR, "Object does not support method calls");
}
/* First, locate the function. */
- EX(fbc) = Z_OBJ_HT_P(EX(object))->get_method(&EX(object), function_name_strval, function_name_strlen, ((IS_CV == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
- if (UNEXPECTED(EX(fbc) == NULL)) {
- zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(EX(object)), function_name_strval);
+ call->fbc = Z_OBJ_HT_P(call->object)->get_method(&call->object, function_name_strval, function_name_strlen, ((IS_CV == IS_CONST) ? (opline->op2.literal + 1) : NULL) TSRMLS_CC);
+ if (UNEXPECTED(call->fbc == NULL)) {
+ zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", Z_OBJ_CLASS_NAME_P(call->object), function_name_strval);
}
if (IS_CV == IS_CONST &&
- EXPECTED(EX(fbc)->type <= ZEND_USER_FUNCTION) &&
- EXPECTED((EX(fbc)->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
- EXPECTED(EX(object) == object)) {
- CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, EX(called_scope), EX(fbc));
+ EXPECTED(call->fbc->type <= ZEND_USER_FUNCTION) &&
+ EXPECTED((call->fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_HANDLER|ZEND_ACC_NEVER_CACHE)) == 0) &&
+ EXPECTED(call->object == object)) {
+ CACHE_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, call->called_scope, call->fbc);
}
}
} else {
+ if (UNEXPECTED(EG(exception) != NULL)) {
+
+ HANDLE_EXCEPTION();
+ }
zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval);
}
- if ((EX(fbc)->common.fn_flags & ZEND_ACC_STATIC) != 0) {
- EX(object) = NULL;
+ if ((call->fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) {
+ call->object = NULL;
} else {
- if (!PZVAL_IS_REF(EX(object))) {
- Z_ADDREF_P(EX(object)); /* For $this pointer */
+ if (!PZVAL_IS_REF(call->object)) {
+ Z_ADDREF_P(call->object); /* For $this pointer */
} else {
zval *this_ptr;
ALLOC_ZVAL(this_ptr);
- INIT_PZVAL_COPY(this_ptr, EX(object));
+ INIT_PZVAL_COPY(this_ptr, call->object);
zval_copy_ctor(this_ptr);
- EX(object) = this_ptr;
+ call->object = this_ptr;
}
}
+ call->is_ctor_call = 0;
+ EX(call) = call;
CHECK_EXCEPTION();
@@ -36168,8 +40288,8 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
PZVAL_LOCK(EX_T(opline->op1.var).var.ptr);
}
is_equal_function(&EX_T(opline->result.var).tmp_var,
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC),
- _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC) TSRMLS_CC);
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC),
+ _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -36183,7 +40303,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_
SAVE_OPLINE();
if ((IS_CV == IS_VAR || IS_CV == IS_CV) && opline->extended_value) {
- zval **expr_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->op1.var TSRMLS_CC);
+ zval **expr_ptr_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_VAR && UNEXPECTED(expr_ptr_ptr == NULL)) {
zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets");
@@ -36192,7 +40312,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_
expr_ptr = *expr_ptr_ptr;
Z_ADDREF_P(expr_ptr);
} else {
- expr_ptr=_get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op1.var TSRMLS_CC);
+ expr_ptr=_get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
if (0) { /* temporary variable */
zval *new_expr;
@@ -36213,7 +40333,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_
if (IS_CV != IS_UNUSED) {
- zval *offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ zval *offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
ulong hval;
switch (Z_TYPE_P(offset)) {
@@ -36284,11 +40404,11 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_
ulong hval;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC);
if (IS_CV == IS_CV && container != &EG(uninitialized_zval_ptr)) {
SEPARATE_ZVAL_IF_NOT_REF(container);
}
- offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_CV != IS_VAR || container) {
switch (Z_TYPE_PP(container)) {
@@ -36382,8 +40502,8 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(EX_CVs(), opline->op1.var TSRMLS_CC);
- offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ container = _get_zval_ptr_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC);
+ offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_CV != IS_VAR || container) {
if (IS_CV == IS_CV && container != &EG(uninitialized_zval_ptr)) {
@@ -36418,22 +40538,22 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CV(int
{
USE_OPLINE
- zval **container;
+ zval *container;
zval **value = NULL;
int result = 0;
ulong hval;
zval *offset;
SAVE_OPLINE();
- container = _get_zval_ptr_ptr_cv_BP_VAR_IS(EX_CVs(), opline->op1.var TSRMLS_CC);
+ container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC);
- offset = _get_zval_ptr_cv_BP_VAR_R(EX_CVs(), opline->op2.var TSRMLS_CC);
+ offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
- if (Z_TYPE_PP(container) == IS_ARRAY && !prop_dim) {
+ if (Z_TYPE_P(container) == IS_ARRAY && !prop_dim) {
HashTable *ht;
int isset = 0;
- ht = Z_ARRVAL_PP(container);
+ ht = Z_ARRVAL_P(container);
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
@@ -36452,9 +40572,7 @@ num_index_prop:
if (IS_CV == IS_CONST) {
hval = Z_HASH_P(offset);
} else {
- if (!prop_dim) {
- ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
- }
+ ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
if (IS_INTERNED(Z_STRVAL_P(offset))) {
hval = INTERNED_HASH(Z_STRVAL_P(offset));
} else {
@@ -36489,20 +40607,20 @@ num_index_prop:
}
}
- } else if (Z_TYPE_PP(container) == IS_OBJECT) {
+ } else if (Z_TYPE_P(container) == IS_OBJECT) {
if (0) {
MAKE_REAL_ZVAL_PTR(offset);
}
if (prop_dim) {
- if (Z_OBJ_HT_P(*container)->has_property) {
- result = Z_OBJ_HT_P(*container)->has_property(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_property) {
+ result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0, ((IS_CV == IS_CONST) ? opline->op2.literal : NULL) TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check property of non-object");
result = 0;
}
} else {
- if (Z_OBJ_HT_P(*container)->has_dimension) {
- result = Z_OBJ_HT_P(*container)->has_dimension(*container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
+ if (Z_OBJ_HT_P(container)->has_dimension) {
+ result = Z_OBJ_HT_P(container)->has_dimension(container, offset, (opline->extended_value & ZEND_ISEMPTY) != 0 TSRMLS_CC);
} else {
zend_error(E_NOTICE, "Trying to check element of non-array");
result = 0;
@@ -36513,7 +40631,7 @@ num_index_prop:
} else {
}
- } else if ((*container)->type == IS_STRING && !prop_dim) { /* string offsets */
+ } else if (Z_TYPE_P(container) == IS_STRING && !prop_dim) { /* string offsets */
zval tmp;
if (Z_TYPE_P(offset) != IS_LONG) {
@@ -36531,11 +40649,11 @@ num_index_prop:
}
if (Z_TYPE_P(offset) == IS_LONG) {
if (opline->extended_value & ZEND_ISSET) {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container)) {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) {
result = 1;
}
} else /* if (opline->extended_value & ZEND_ISEMPTY) */ {
- if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_PP(container) && Z_STRVAL_PP(container)[offset->value.lval] != '0') {
+ if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container) && Z_STRVAL_P(container)[offset->value.lval] != '0') {
result = 1;
}
}
@@ -36566,9 +40684,167 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV_HANDLER(ZEND_OP
return zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CV(1, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
+static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+
+ /* The generator object is stored in return_value_ptr_ptr */
+ zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
+
+ if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
+ zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
+ }
+
+ /* Destroy the previously yielded value */
+ if (generator->value) {
+ zval_ptr_dtor(&generator->value);
+ }
+
+ /* Destroy the previously yielded key */
+ if (generator->key) {
+ zval_ptr_dtor(&generator->key);
+ }
+
+ /* Set the new yielded value */
+ if (IS_CV != IS_UNUSED) {
+
+
+ if (EX(op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
+ /* Constants and temporary variables aren't yieldable by reference,
+ * but we still allow them with a notice. */
+ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) {
+ zval *value, *copy;
+
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ zval **value_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
+
+ if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) {
+ zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference");
+ }
+
+ /* If a function call result is yielded and the function did
+ * not return by reference we throw a notice. */
+ if (IS_CV == IS_VAR && !Z_ISREF_PP(value_ptr)
+ && !(opline->extended_value == ZEND_RETURNS_FUNCTION
+ && EX_T(opline->op1.var).var.fcall_returned_reference)
+ && EX_T(opline->op1.var).var.ptr_ptr == &EX_T(opline->op1.var).var.ptr) {
+ zend_error(E_NOTICE, "Only variable references should be yielded by reference");
+
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ } else {
+ SEPARATE_ZVAL_TO_MAKE_IS_REF(value_ptr);
+ Z_ADDREF_PP(value_ptr);
+ generator->value = *value_ptr;
+ }
+
+ }
+ } else {
+ zval *value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
+ || (PZVAL_IS_REF(value) && Z_REFCOUNT_P(value) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, value);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->value = copy;
+ } else {
+ Z_ADDREF_P(value);
+ generator->value = value;
+ }
+
+ }
+ } else {
+ /* If no value was specified yield null */
+ Z_ADDREF(EG(uninitialized_zval));
+ generator->value = &EG(uninitialized_zval);
+ }
+
+ /* Set the new yielded key */
+ if (IS_CV != IS_UNUSED) {
+
+ zval *key = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
+
+ /* Consts, temporary variables and references need copying */
+ if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR
+ || (PZVAL_IS_REF(key) && Z_REFCOUNT_P(key) > 0)
+ ) {
+ zval *copy;
+
+ ALLOC_ZVAL(copy);
+ INIT_PZVAL_COPY(copy, key);
+
+ /* Temporary variables don't need ctor copying */
+ if (!0) {
+ zval_copy_ctor(copy);
+ }
+
+ generator->key = copy;
+ } else {
+ Z_ADDREF_P(key);
+ generator->key = key;
+ }
+
+ if (Z_TYPE_P(generator->key) == IS_LONG
+ && Z_LVAL_P(generator->key) > generator->largest_used_integer_key
+ ) {
+ generator->largest_used_integer_key = Z_LVAL_P(generator->key);
+ }
+
+ } else {
+ /* If no key was specified we use auto-increment keys */
+ generator->largest_used_integer_key++;
+
+ ALLOC_INIT_ZVAL(generator->key);
+ ZVAL_LONG(generator->key, generator->largest_used_integer_key);
+ }
+
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
+
+ /* We increment to the next op, so we are at the correct position when the
+ * generator is resumed. */
+ ZEND_VM_INC_OPCODE();
+
+ /* The GOTO VM uses a local opline variable. We need to set the opline
+ * variable in execute_data so we don't resume at an old position. */
+ SAVE_OPLINE();
+
+ ZEND_VM_RETURN();
+}
+
static int ZEND_FASTCALL ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
zend_error_noreturn(E_ERROR, "Invalid opcode %d/%d/%d.", OPLINE->opcode, OPLINE->op1_type, OPLINE->op2_type);
+ ZEND_VM_NEXT_OPCODE(); /* Never reached */
}
@@ -38600,16 +42876,16 @@ void zend_init_opcodes_handlers(void)
ZEND_FETCH_R_SPEC_CV_VAR_HANDLER,
ZEND_FETCH_R_SPEC_CV_UNUSED_HANDLER,
ZEND_NULL_HANDLER,
+ ZEND_FETCH_DIM_R_SPEC_CONST_CONST_HANDLER,
+ ZEND_FETCH_DIM_R_SPEC_CONST_TMP_HANDLER,
+ ZEND_FETCH_DIM_R_SPEC_CONST_VAR_HANDLER,
ZEND_NULL_HANDLER,
+ ZEND_FETCH_DIM_R_SPEC_CONST_CV_HANDLER,
+ ZEND_FETCH_DIM_R_SPEC_TMP_CONST_HANDLER,
+ ZEND_FETCH_DIM_R_SPEC_TMP_TMP_HANDLER,
+ ZEND_FETCH_DIM_R_SPEC_TMP_VAR_HANDLER,
ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
- ZEND_NULL_HANDLER,
+ ZEND_FETCH_DIM_R_SPEC_TMP_CV_HANDLER,
ZEND_FETCH_DIM_R_SPEC_VAR_CONST_HANDLER,
ZEND_FETCH_DIM_R_SPEC_VAR_TMP_HANDLER,
ZEND_FETCH_DIM_R_SPEC_VAR_VAR_HANDLER,
@@ -40550,6 +44826,131 @@ void zend_init_opcodes_handlers(void)
ZEND_JMP_SET_VAR_SPEC_CV_HANDLER,
ZEND_JMP_SET_VAR_SPEC_CV_HANDLER,
ZEND_JMP_SET_VAR_SPEC_CV_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_DISCARD_EXCEPTION_SPEC_HANDLER,
+ ZEND_YIELD_SPEC_CONST_CONST_HANDLER,
+ ZEND_YIELD_SPEC_CONST_TMP_HANDLER,
+ ZEND_YIELD_SPEC_CONST_VAR_HANDLER,
+ ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER,
+ ZEND_YIELD_SPEC_CONST_CV_HANDLER,
+ ZEND_YIELD_SPEC_TMP_CONST_HANDLER,
+ ZEND_YIELD_SPEC_TMP_TMP_HANDLER,
+ ZEND_YIELD_SPEC_TMP_VAR_HANDLER,
+ ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER,
+ ZEND_YIELD_SPEC_TMP_CV_HANDLER,
+ ZEND_YIELD_SPEC_VAR_CONST_HANDLER,
+ ZEND_YIELD_SPEC_VAR_TMP_HANDLER,
+ ZEND_YIELD_SPEC_VAR_VAR_HANDLER,
+ ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER,
+ ZEND_YIELD_SPEC_VAR_CV_HANDLER,
+ ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER,
+ ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER,
+ ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER,
+ ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER,
+ ZEND_YIELD_SPEC_UNUSED_CV_HANDLER,
+ ZEND_YIELD_SPEC_CV_CONST_HANDLER,
+ ZEND_YIELD_SPEC_CV_TMP_HANDLER,
+ ZEND_YIELD_SPEC_CV_VAR_HANDLER,
+ ZEND_YIELD_SPEC_CV_UNUSED_HANDLER,
+ ZEND_YIELD_SPEC_CV_CV_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_GENERATOR_RETURN_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_CALL_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
+ ZEND_FAST_RET_SPEC_HANDLER,
ZEND_NULL_HANDLER
};
zend_opcode_handlers = (opcode_handler_t*)labels;
diff --git a/Zend/zend_vm_execute.skl b/Zend/zend_vm_execute.skl
index 6d1b2e70e7..13fd88e2d8 100644
--- a/Zend/zend_vm_execute.skl
+++ b/Zend/zend_vm_execute.skl
@@ -1,67 +1,25 @@
{%DEFINES%}
-ZEND_API void {%EXECUTOR_NAME%}(zend_op_array *op_array TSRMLS_DC)
+ZEND_API void {%EXECUTOR_NAME%}_ex(zend_execute_data *execute_data TSRMLS_DC)
{
DCL_OPLINE
- zend_execute_data *execute_data;
- zend_bool nested = 0;
+ zend_bool original_in_execution;
+
{%HELPER_VARS%}
- {%EXECUTION_STATUS%}
{%INTERNAL_LABELS%}
- if (EG(exception)) {
- return;
- }
-
+ original_in_execution = EG(in_execution);
EG(in_execution) = 1;
+ if (0) {
zend_vm_enter:
- /* Initialize execute_data */
- execute_data = (zend_execute_data *)zend_vm_stack_alloc(
- 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 + ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data)));
- memset(EX(CVs), 0, sizeof(zval**) * op_array->last_var);
- 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;
- EX(old_error_reporting) = NULL;
- EX(op_array) = op_array;
- EX(symbol_table) = EG(active_symbol_table);
- EX(prev_execute_data) = EG(current_execute_data);
- EG(current_execute_data) = execute_data;
- EX(nested) = nested;
- nested = 1;
-
- LOAD_REGS();
-
- if (!op_array->run_time_cache && op_array->last_cache_slot) {
- op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*));
+ execute_data = i_create_execute_data_from_op_array(EG(active_op_array), 1 TSRMLS_CC);
}
- if (op_array->this_var != -1 && EG(This)) {
- Z_ADDREF_P(EG(This)); /* For $this pointer */
- if (!EG(active_symbol_table)) {
- EX_CV(op_array->this_var) = (zval**)EX_CVs() + (op_array->last_var + op_array->this_var);
- *EX_CV(op_array->this_var) = EG(This);
- } else {
- if (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), (void**)&EX_CV(op_array->this_var))==FAILURE) {
- Z_DELREF_P(EG(This));
- }
- }
- }
-
- EX(opline) = UNEXPECTED((op_array->fn_flags & ZEND_ACC_INTERACTIVE) != 0) && EG(start_op) ? EG(start_op) : op_array->opcodes;
- EG(opline_ptr) = &EX(opline);
+ LOAD_REGS();
LOAD_OPLINE();
- EX(function_state).function = (zend_function *) op_array;
- EX(function_state).arguments = NULL;
-
while (1) {
{%ZEND_VM_CONTINUE_LABEL%}
#ifdef ZEND_WIN32
@@ -78,6 +36,14 @@ zend_vm_enter:
zend_error_noreturn(E_ERROR, "Arrived at end of main loop which shouldn't happen");
}
+ZEND_API void zend_{%EXECUTOR_NAME%}(zend_op_array *op_array TSRMLS_DC)
+{
+ if (EG(exception)) {
+ return;
+ }
+ zend_{%EXECUTOR_NAME%}_ex(i_create_execute_data_from_op_array(op_array, 0 TSRMLS_CC) TSRMLS_CC);
+}
+
{%EXTERNAL_EXECUTOR%}
void {%INITIALIZER_NAME%}(void)
diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php
index 4bab9e5e3d..98e7f3e045 100644
--- a/Zend/zend_vm_gen.php
+++ b/Zend/zend_vm_gen.php
@@ -118,75 +118,75 @@ $op2_free = array(
);
$op1_get_zval_ptr = array(
- "ANY" => "get_zval_ptr(opline->op1_type, &opline->op1, EX_Ts(), &free_op1, \\1)",
- "TMP" => "_get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC)",
- "VAR" => "_get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC)",
+ "ANY" => "get_zval_ptr(opline->op1_type, &opline->op1, execute_data, &free_op1, \\1)",
+ "TMP" => "_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC)",
+ "VAR" => "_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC)",
"CONST" => "opline->op1.zv",
"UNUSED" => "NULL",
- "CV" => "_get_zval_ptr_cv_\\1(EX_CVs(), opline->op1.var TSRMLS_CC)",
+ "CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op1.var TSRMLS_CC)",
);
$op2_get_zval_ptr = array(
- "ANY" => "get_zval_ptr(opline->op2_type, &opline->op2, EX_Ts(), &free_op2, \\1)",
- "TMP" => "_get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC)",
- "VAR" => "_get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC)",
+ "ANY" => "get_zval_ptr(opline->op2_type, &opline->op2, execute_data, &free_op2, \\1)",
+ "TMP" => "_get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC)",
+ "VAR" => "_get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC)",
"CONST" => "opline->op2.zv",
"UNUSED" => "NULL",
- "CV" => "_get_zval_ptr_cv_\\1(EX_CVs(), opline->op2.var TSRMLS_CC)",
+ "CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op2.var TSRMLS_CC)",
);
$op1_get_zval_ptr_ptr = array(
- "ANY" => "get_zval_ptr_ptr(opline->op1_type, &opline->op1, EX_Ts(), &free_op1, \\1)",
+ "ANY" => "get_zval_ptr_ptr(opline->op1_type, &opline->op1, execute_data, &free_op1, \\1)",
"TMP" => "NULL",
- "VAR" => "_get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC)",
+ "VAR" => "_get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC)",
"CONST" => "NULL",
"UNUSED" => "NULL",
- "CV" => "_get_zval_ptr_ptr_cv_\\1(EX_CVs(), opline->op1.var TSRMLS_CC)",
+ "CV" => "_get_zval_ptr_ptr_cv_\\1(execute_data, opline->op1.var TSRMLS_CC)",
);
$op2_get_zval_ptr_ptr = array(
- "ANY" => "get_zval_ptr_ptr(opline->op2_type, &opline->op2, EX_Ts(), &free_op2, \\1)",
+ "ANY" => "get_zval_ptr_ptr(opline->op2_type, &opline->op2, execute_data, &free_op2, \\1)",
"TMP" => "NULL",
- "VAR" => "_get_zval_ptr_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC)",
+ "VAR" => "_get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC)",
"CONST" => "NULL",
"UNUSED" => "NULL",
- "CV" => "_get_zval_ptr_ptr_cv_\\1(EX_CVs(), opline->op2.var TSRMLS_CC)",
+ "CV" => "_get_zval_ptr_ptr_cv_\\1(execute_data, opline->op2.var TSRMLS_CC)",
);
$op1_get_obj_zval_ptr = array(
- "ANY" => "get_obj_zval_ptr(opline->op1_type, &opline->op1, EX_Ts(), &free_op1, \\1)",
- "TMP" => "_get_zval_ptr_tmp(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC)",
- "VAR" => "_get_zval_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC)",
+ "ANY" => "get_obj_zval_ptr(opline->op1_type, &opline->op1, execute_data, &free_op1, \\1)",
+ "TMP" => "_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC)",
+ "VAR" => "_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC)",
"CONST" => "opline->op1.zv",
"UNUSED" => "_get_obj_zval_ptr_unused(TSRMLS_C)",
- "CV" => "_get_zval_ptr_cv_\\1(EX_CVs(), opline->op1.var TSRMLS_CC)",
+ "CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op1.var TSRMLS_CC)",
);
$op2_get_obj_zval_ptr = array(
- "ANY" => "get_obj_zval_ptr(opline->op2_type, &opline->op2, EX_Ts(), &free_op2, \\1)",
- "TMP" => "_get_zval_ptr_tmp(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC)",
- "VAR" => "_get_zval_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC)",
+ "ANY" => "get_obj_zval_ptr(opline->op2_type, &opline->op2, execute_data, &free_op2, \\1)",
+ "TMP" => "_get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC)",
+ "VAR" => "_get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC)",
"CONST" => "opline->op2.zv",
"UNUSED" => "_get_obj_zval_ptr_unused(TSRMLS_C)",
- "CV" => "_get_zval_ptr_cv_\\1(EX_CVs(), opline->op2.var TSRMLS_CC)",
+ "CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op2.var TSRMLS_CC)",
);
$op1_get_obj_zval_ptr_ptr = array(
- "ANY" => "get_obj_zval_ptr_ptr(opline->op1_type, &opline->op1, EX_Ts(), &free_op1, \\1)",
+ "ANY" => "get_obj_zval_ptr_ptr(opline->op1_type, &opline->op1, execute_data, &free_op1, \\1)",
"TMP" => "NULL",
- "VAR" => "_get_zval_ptr_ptr_var(opline->op1.var, EX_Ts(), &free_op1 TSRMLS_CC)",
+ "VAR" => "_get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC)",
"CONST" => "NULL",
"UNUSED" => "_get_obj_zval_ptr_ptr_unused(TSRMLS_C)",
- "CV" => "_get_zval_ptr_ptr_cv_\\1(EX_CVs(), opline->op1.var TSRMLS_CC)",
+ "CV" => "_get_zval_ptr_ptr_cv_\\1(execute_data, opline->op1.var TSRMLS_CC)",
);
$op2_get_obj_zval_ptr_ptr = array(
- "ANY" => "get_obj_zval_ptr_ptr(opline->op2_type, &opline->op2, EX_Ts(), &free_op2, \\1)",
+ "ANY" => "get_obj_zval_ptr_ptr(opline->op2_type, &opline->op2, execute_data, &free_op2, \\1)",
"TMP" => "NULL",
- "VAR" => "_get_zval_ptr_ptr_var(opline->op2.var, EX_Ts(), &free_op2 TSRMLS_CC)",
+ "VAR" => "_get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC)",
"CONST" => "NULL",
"UNUSED" => "_get_obj_zval_ptr_ptr_unused(TSRMLS_C)",
- "CV" => "_get_zval_ptr_ptr_cv_\\1(EX_CVs(), opline->op2.var TSRMLS_CC)",
+ "CV" => "_get_zval_ptr_ptr_cv_\\1(execute_data, opline->op2.var TSRMLS_CC)",
);
$op1_is_tmp_free = array(
@@ -387,52 +387,67 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) {
// Updating code according to selected threading model
switch($kind) {
case ZEND_VM_KIND_CALL:
- $code = preg_replace(
+ $code = preg_replace_callback(
array(
"/EXECUTE_DATA/m",
"/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m",
- "/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*\)/me",
- "/ZEND_VM_DISPATCH_TO_HELPER_EX\(\s*([A-Za-z_]*)\s*,\s*[A-Za-z_]*\s*,\s*(.*)\s*\);/me",
- ),
- array(
- "execute_data",
- "return \\1".($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2]."_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)",
- "'return '.helper_name('\\1',$spec,'$op1','$op2').'(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)'",
- "'return '.helper_name('\\1',$spec,'$op1','$op2').'(\\2, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);'",
+ "/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*\)/m",
+ "/ZEND_VM_DISPATCH_TO_HELPER_EX\(\s*([A-Za-z_]*)\s*,\s*[A-Za-z_]*\s*,\s*(.*)\s*\);/m",
),
+ function($matches) use ($spec, $prefix, $op1, $op2) {
+ if (strncasecmp($matches[0], "EXECUTE_DATA", strlen("EXECUTE_DATA")) == 0) {
+ return "execute_data";
+ } else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HANDLER", strlen("ZEND_VM_DISPATCH_TO_HANDLER")) == 0) {
+ return "return " . $matches[1] . ($spec?"_SPEC":"") . $prefix[$op1] . $prefix[$op2] . "_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)";
+ } else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HELPER_EX", strlen("ZEND_VM_DISPATCH_TO_HELPER_EX")) == 0) {
+ return "return " . helper_name($matches[1], $spec, $op1, $op2) . "(" . $matches[2]. ", ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);";
+ } else {
+ return "return " . helper_name($matches[1], $spec, $op1, $op2) . "(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)";
+ }
+ },
$code);
break;
case ZEND_VM_KIND_SWITCH:
- $code = preg_replace(
+ $code = preg_replace_callback(
array(
"/EXECUTE_DATA/m",
"/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m",
- "/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*\)/me",
- "/ZEND_VM_DISPATCH_TO_HELPER_EX\(\s*([A-Za-z_]*)\s*,\s*([A-Za-z_]*)\s*,\s*(.*)\s*\);/me",
- ),
- array(
- "execute_data",
- "goto \\1".($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2]."_LABEL",
- "'goto '.helper_name('\\1',$spec,'$op1','$op2')",
- "'\\2 = \\3; goto '.helper_name('\\1',$spec,'$op1','$op2').';'",
+ "/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*\)/m",
+ "/ZEND_VM_DISPATCH_TO_HELPER_EX\(\s*([A-Za-z_]*)\s*,\s*([A-Za-z_]*)\s*,\s*(.*)\s*\);/m",
),
- $code);
+ function($matches) use ($spec, $prefix, $op1, $op2) {
+ if (strncasecmp($matches[0], "EXECUTE_DATA", strlen("EXECUTE_DATA")) == 0) {
+ return "execute_data";
+ } else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HANDLER", strlen("ZEND_VM_DISPATCH_TO_HANDLER")) == 0) {
+ return "goto " . $matches[1] . ($spec?"_SPEC":"") . $prefix[$op1] . $prefix[$op2] . "_LABEL";
+ } else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HELPER_EX", strlen("ZEND_VM_DISPATCH_TO_HELPER_EX")) == 0) {
+ return $matches[2] . " = " . $matches[3] . "; goto " . helper_name($matches[1], $spec, $op1, $op2) . ";";
+ } else {
+ return "goto " . helper_name($matches[1], $spec, $op1, $op2);
+ }
+ },
+ $code);
break;
case ZEND_VM_KIND_GOTO:
- $code = preg_replace(
+ $code = preg_replace_callback(
array(
"/EXECUTE_DATA/m",
"/ZEND_VM_DISPATCH_TO_HANDLER\(\s*([A-Z_]*)\s*\)/m",
- "/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*\)/me",
- "/ZEND_VM_DISPATCH_TO_HELPER_EX\(\s*([A-Za-z_]*)\s*,\s*([A-Za-z_]*)\s*,\s*(.*)\s*\);/me",
- ),
- array(
- "execute_data",
- "goto \\1".($spec?"_SPEC":"").$prefix[$op1].$prefix[$op2]."_HANDLER",
- "'goto '.helper_name('\\1',$spec,'$op1','$op2')",
- "'\\2 = \\3; goto '.helper_name('\\1',$spec,'$op1','$op2').';'",
+ "/ZEND_VM_DISPATCH_TO_HELPER\(\s*([A-Za-z_]*)\s*\)/m",
+ "/ZEND_VM_DISPATCH_TO_HELPER_EX\(\s*([A-Za-z_]*)\s*,\s*([A-Za-z_]*)\s*,\s*(.*)\s*\);/m",
),
- $code);
+ function($matches) use ($spec, $prefix, $op1, $op2) {
+ if (strncasecmp($matches[0], "EXECUTE_DATA", strlen("EXECUTE_DATA")) == 0) {
+ return "execute_data";
+ } else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HANDLER", strlen("ZEND_VM_DISPATCH_TO_HANDLER")) == 0) {
+ return "goto " . $matches[1] . ($spec?"_SPEC":"") . $prefix[$op1] . $prefix[$op2] . "_HANDLER";
+ } else if (strncasecmp($matches[0], "ZEND_VM_DISPATCH_TO_HELPER_EX", strlen("ZEND_VM_DISPATCH_TO_HELPER_EX")) == 0) {
+ return $matches[2] . " = " . $matches[3] . "; goto " . helper_name($matches[1], $spec, $op1, $op2) . ";";
+ } else {
+ return "goto " . helper_name($matches[1], $spec, $op1, $op2);
+ }
+ },
+ $code);
break;
}
@@ -695,6 +710,7 @@ function gen_null_handler($f) {
out($f,"static int ZEND_FASTCALL ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)\n");
out($f,"{\n");
out($f,"\tzend_error_noreturn(E_ERROR, \"Invalid opcode %d/%d/%d.\", OPLINE->opcode, OPLINE->op1_type, OPLINE->op2_type);\n");
+ out($f,"\tZEND_VM_NEXT_OPCODE(); /* Never reached */\n");
out($f,"}\n\n");
}
}
@@ -769,10 +785,12 @@ function gen_executor_code($f, $spec, $kind, $prolog) {
case ZEND_VM_KIND_SWITCH:
out($f,"default:\n");
out($f,"\tzend_error_noreturn(E_ERROR, \"Invalid opcode %d/%d/%d.\", OPLINE->opcode, OPLINE->op1_type, OPLINE->op2_type);\n");
+ out($f,"\tZEND_VM_NEXT_OPCODE(); /* Never reached */\n");
break;
case ZEND_VM_KIND_GOTO:
out($f,"ZEND_NULL_HANDLER:\n");
out($f,"\tzend_error_noreturn(E_ERROR, \"Invalid opcode %d/%d/%d.\", OPLINE->opcode, OPLINE->op1_type, OPLINE->op2_type);\n");
+ out($f,"\tZEND_VM_NEXT_OPCODE(); /* Never reached */\n");
break;
}
}
@@ -824,16 +842,6 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name,
out($f,"#define ZEND_VM_LEAVE() return 3\n");
out($f,"#define ZEND_VM_DISPATCH(opcode, opline) return zend_vm_get_opcode_handler(opcode, opline)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);\n\n");
out($f,"#define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL execute_data TSRMLS_CC\n");
- out($f,"#undef EX\n");
- out($f,"#define EX(element) execute_data->element\n\n");
- out($f,"#undef EX_CV\n");
- out($f,"#define EX_CV(var) EX(CVs)[var]\n");
- out($f,"#undef EX_CVs\n");
- out($f,"#define EX_CVs() EX(CVs)\n");
- out($f,"#undef EX_T\n");
- out($f,"#define EX_T(offset) (*(temp_variable *)((char *) EX(Ts) + offset))\n");
- out($f,"#undef EX_Ts\n");
- out($f,"#define EX_Ts() EX(Ts)\n\n");
break;
case ZEND_VM_KIND_SWITCH:
out($f,"\n");
@@ -853,23 +861,13 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name,
out($f,"#define CHECK_EXCEPTION() LOAD_OPLINE()\n");
out($f,"#define HANDLE_EXCEPTION() LOAD_OPLINE(); ZEND_VM_CONTINUE()\n");
out($f,"#define HANDLE_EXCEPTION_LEAVE() LOAD_OPLINE(); ZEND_VM_LEAVE()\n");
- out($f,"#define LOAD_REGS() do {Ts = EX(Ts); CVs = EX(CVs);} while (0)\n");
+ out($f,"#define LOAD_REGS()\n");
out($f,"#define ZEND_VM_CONTINUE() goto zend_vm_continue\n");
out($f,"#define ZEND_VM_RETURN() EG(in_execution) = original_in_execution; return\n");
- out($f,"#define ZEND_VM_ENTER() op_array = EG(active_op_array); goto zend_vm_enter\n");
+ out($f,"#define ZEND_VM_ENTER() goto zend_vm_enter\n");
out($f,"#define ZEND_VM_LEAVE() ZEND_VM_CONTINUE()\n");
out($f,"#define ZEND_VM_DISPATCH(opcode, opline) dispatch_handler = zend_vm_get_opcode_handler(opcode, opline); goto zend_vm_dispatch;\n\n");
out($f,"#define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL execute_data TSRMLS_CC\n");
- out($f,"#undef EX\n");
- out($f,"#define EX(element) execute_data->element\n\n");
- out($f,"#undef EX_CV\n");
- out($f,"#define EX_CV(var) CVs[var]\n");
- out($f,"#undef EX_CVs\n");
- out($f,"#define EX_CVs() CVs\n");
- out($f,"#undef EX_T\n");
- out($f,"#define EX_T(offset) T(offset)\n");
- out($f,"#undef EX_Ts\n");
- out($f,"#define EX_Ts() Ts\n\n");
break;
case ZEND_VM_KIND_GOTO:
out($f,"\n");
@@ -895,24 +893,13 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name,
out($f,"#define HANDLE_EXCEPTION() goto ZEND_HANDLE_EXCEPTION_HANDLER\n");
out($f,"#define HANDLE_EXCEPTION_LEAVE() goto ZEND_HANDLE_EXCEPTION_HANDLER\n");
}
-
- out($f,"#define LOAD_REGS() do {Ts = EX(Ts); CVs = EX(CVs);} while (0)\n");
+ out($f,"#define LOAD_REGS()\n");
out($f,"#define ZEND_VM_CONTINUE() goto *(void**)(OPLINE->handler)\n");
out($f,"#define ZEND_VM_RETURN() EG(in_execution) = original_in_execution; return\n");
- out($f,"#define ZEND_VM_ENTER() op_array = EG(active_op_array); goto zend_vm_enter\n");
+ out($f,"#define ZEND_VM_ENTER() goto zend_vm_enter\n");
out($f,"#define ZEND_VM_LEAVE() ZEND_VM_CONTINUE()\n");
out($f,"#define ZEND_VM_DISPATCH(opcode, opline) goto *(void**)(zend_vm_get_opcode_handler(opcode, opline));\n\n");
out($f,"#define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL execute_data TSRMLS_CC\n");
- out($f,"#undef EX\n");
- out($f,"#define EX(element) execute_data->element\n\n");
- out($f,"#undef EX_CV\n");
- out($f,"#define EX_CV(var) CVs[var]\n");
- out($f,"#undef EX_CVs\n");
- out($f,"#define EX_CVs() CVs\n");
- out($f,"#undef EX_T\n");
- out($f,"#define EX_T(offset) T(offset)\n\n");
- out($f,"#undef EX_Ts\n");
- out($f,"#define EX_Ts() Ts\n\n");
break;
}
break;
@@ -921,8 +908,6 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name,
break;
case "HELPER_VARS":
if ($kind != ZEND_VM_KIND_CALL) {
- out($f,$m[1]."temp_variable *Ts;\n");
- out($f,$m[1]."zval ***CVs;\n");
if ($kind == ZEND_VM_KIND_SWITCH) {
out($f,$m[1]."opcode_handler_t dispatch_handler;\n");
}
@@ -934,19 +919,12 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name,
skip_blanks($f, $m[1], $m[3]."\n");
}
break;
- case "EXECUTION_STATUS":
- if ($kind != ZEND_VM_KIND_GOTO) {
- out($f, $m[1] . "zend_bool original_in_execution = EG(in_execution);\n");
- } else {
- out($f, $m[1] . "zend_bool original_in_execution = op_array? EG(in_execution) : 0;\n");
- }
- break;
case "INTERNAL_LABELS":
if ($kind == ZEND_VM_KIND_GOTO) {
// Emit array of labels of opcode handlers and code for
// zend_opcode_handlers initialization
$prolog = $m[1];
- out($f,$prolog."if (op_array == NULL) {\n");
+ out($f,$prolog."if (execute_data == NULL) {\n");
out($f,$prolog."\tstatic const opcode_handler_t labels[] = {\n");
gen_labels($f, $spec, $kind, $prolog."\t\t");
out($f,$prolog."\t};\n");
@@ -990,10 +968,11 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name,
$m[1]."\t\tEG(in_execution) = original_in_execution;\n".
$m[1]."\t\treturn;\n".
$m[1]."\tcase 2:\n" .
- $m[1]."\t\top_array = EG(active_op_array);\n".
$m[1]."\t\tgoto zend_vm_enter;\n".
+ $m[1]."\t\tbreak;\n" .
$m[1]."\tcase 3:\n" .
$m[1]."\t\texecute_data = EG(current_execute_data);\n".
+ $m[1]."\t\tbreak;\n" .
$m[1]."\tdefault:\n".
$m[1]."\t\tbreak;\n".
$m[1]."}".$m[3]."\n");
@@ -1020,9 +999,9 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name,
$prolog = $m[1];
if ($kind == ZEND_VM_KIND_GOTO) {
// Labels are defined in the executor itself, so we call it
- // with op_array NULL and it sets zend_opcode_handlers array
+ // with execute_data NULL and it sets zend_opcode_handlers array
out($f,$prolog."TSRMLS_FETCH();\n");
- out($f,$prolog."zend_execute(NULL TSRMLS_CC);\n");
+ out($f,$prolog.$executor_name."_ex(NULL TSRMLS_CC);\n");
} else {
if ($old) {
// Reserving space for user-defined opcodes
@@ -1196,7 +1175,7 @@ function gen_vm($def, $skel) {
// Generate opcode #defines (zend_vm_opcodes.h)
$code_len = strlen((string)$max_opcode);
- $f = fopen("zend_vm_opcodes.h", "w+") or die("ERROR: Cannot create zend_vm_opcodes.h\n");
+ $f = fopen(__DIR__ . "/zend_vm_opcodes.h", "w+") or die("ERROR: Cannot create zend_vm_opcodes.h\n");
// Insert header
out($f, $GLOBALS['header_text']);
@@ -1215,7 +1194,7 @@ function gen_vm($def, $skel) {
echo "zend_vm_opcodes.h generated successfully.\n";
// zend_vm_opcodes.c
- $f = fopen("zend_vm_opcodes.c", "w+") or die("ERROR: Cannot create zend_vm_opcodes.c\n");
+ $f = fopen(__DIR__ . "/zend_vm_opcodes.c", "w+") or die("ERROR: Cannot create zend_vm_opcodes.c\n");
// Insert header
out($f, $GLOBALS['header_text']);
@@ -1236,14 +1215,32 @@ function gen_vm($def, $skel) {
echo "zend_vm_opcodes.c generated successfully.\n";
// Generate zend_vm_execute.h
- $f = fopen("zend_vm_execute.h", "w+") or die("ERROR: Cannot create zend_vm_execute.h\n");
- $executor_file = realpath("zend_vm_execute.h");
+ $f = fopen(__DIR__ . "/zend_vm_execute.h", "w+") or die("ERROR: Cannot create zend_vm_execute.h\n");
+ $executor_file = realpath(__DIR__ . "/zend_vm_execute.h");
// Insert header
out($f, $GLOBALS['header_text']);
+ out($f, "#ifdef ZEND_WIN32\n");
// Suppress free_op1 warnings on Windows
- out($f, "#ifdef ZEND_WIN32\n# pragma warning(once : 4101)\n#endif\n");
+ out($f, "# pragma warning(once : 4101)\n");
+ if (ZEND_VM_SPEC) {
+ // Suppress (<non-zero constant> || <expression>) warnings on windows
+ out($f, "# pragma warning(once : 6235)\n");
+ // Suppress (<zero> && <expression>) warnings on windows
+ out($f, "# pragma warning(once : 6237)\n");
+ // Suppress (<non-zero constant> && <expression>) warnings on windows
+ out($f, "# pragma warning(once : 6239)\n");
+ // Suppress (<expression> && <non-zero constant>) warnings on windows
+ out($f, "# pragma warning(once : 6240)\n");
+ // Suppress (<non-zero constant> || <non-zero constant>) warnings on windows
+ out($f, "# pragma warning(once : 6285)\n");
+ // Suppress (<non-zero constant> || <expression>) warnings on windows
+ out($f, "# pragma warning(once : 6286)\n");
+ // Suppress constant with constant comparsion warnings on windows
+ out($f, "# pragma warning(once : 6326)\n");
+ }
+ out($f, "#endif\n");
// Support for ZEND_USER_OPCODE
out($f, "static user_opcode_handler_t zend_user_opcode_handlers[256] = {\n");
@@ -1265,14 +1262,6 @@ function gen_vm($def, $skel) {
// Generate un-specialized executor
if (ZEND_VM_OLD_EXECUTOR) {
out($f,"\n/* Old executor */\n\n");
- out($f,"#undef EX\n");
- out($f,"#define EX(element) execute_data.element\n\n");
- out($f,"#undef EX_CV\n");
- out($f,"#define EX_CV(var) EX(CVs)[var]\n");
- out($f,"#undef EX_CVs\n");
- out($f,"#define EX_CVs() EX(CVs)\n");
- out($f,"#undef EX_T\n");
- out($f,"#define EX_T(offset) (*(temp_variable *)((char *) EX(Ts) + offset))\n\n");
out($f,"#undef ZEND_VM_CONTINUE\n\n");
out($f,"#undef ZEND_VM_RETURN\n\n");
out($f,"#undef ZEND_VM_ENTER\n\n");
@@ -1345,14 +1334,6 @@ function gen_vm($def, $skel) {
out($f,"#define CHECK_EXCEPTION() LOAD_OPLINE()\n");
out($f,"#define HANDLE_EXCEPTION() LOAD_OPLINE(); ZEND_VM_CONTINUE()\n");
out($f,"#define HANDLE_EXCEPTION_LEAVE() LOAD_OPLINE(); ZEND_VM_LEAVE()\n");
- out($f,"#undef EX\n");
- out($f,"#define EX(element) execute_data->element\n\n");
- out($f,"#undef EX_CV\n");
- out($f,"#define EX_CV(var) EX(CVs)[var]\n");
- out($f,"#undef EX_CVs\n");
- out($f,"#define EX_CVs() EX(CVs)\n");
- out($f,"#undef EX_T\n");
- out($f,"#define EX_T(offset) (*(temp_variable *)((char *) EX(Ts) + offset))\n\n");
out($f,"#undef ZEND_VM_CONTINUE\n");
out($f,"#undef ZEND_VM_RETURN\n");
out($f,"#undef ZEND_VM_ENTER\n");
@@ -1480,6 +1461,6 @@ if (!defined("ZEND_VM_LINES")) {
define("ZEND_VM_LINES", 0);
}
-gen_vm("zend_vm_def.h", "zend_vm_execute.skl");
+gen_vm(__DIR__ . "/zend_vm_def.h", __DIR__ . "/zend_vm_execute.skl");
?>
diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c
index 0cd8df0d94..05c9aeb140 100644
--- a/Zend/zend_vm_opcodes.c
+++ b/Zend/zend_vm_opcodes.c
@@ -21,7 +21,7 @@
#include <stdio.h>
#include <zend.h>
-const char *zend_vm_opcodes_map[159] = {
+const char *zend_vm_opcodes_map[164] = {
"ZEND_NOP",
"ZEND_ADD",
"ZEND_SUB",
@@ -181,6 +181,11 @@ const char *zend_vm_opcodes_map[159] = {
"ZEND_SEPARATE",
"ZEND_QM_ASSIGN_VAR",
"ZEND_JMP_SET_VAR",
+ "ZEND_DISCARD_EXCEPTION",
+ "ZEND_YIELD",
+ "ZEND_GENERATOR_RETURN",
+ "ZEND_FAST_CALL",
+ "ZEND_FAST_RET",
};
ZEND_API const char* zend_get_opcode_name(zend_uchar opcode) {
diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h
index 331bc7a187..911eee4434 100644
--- a/Zend/zend_vm_opcodes.h
+++ b/Zend/zend_vm_opcodes.h
@@ -164,5 +164,10 @@ ZEND_API const char *zend_get_opcode_name(zend_uchar opcode);
#define ZEND_SEPARATE 156
#define ZEND_QM_ASSIGN_VAR 157
#define ZEND_JMP_SET_VAR 158
+#define ZEND_DISCARD_EXCEPTION 159
+#define ZEND_YIELD 160
+#define ZEND_GENERATOR_RETURN 161
+#define ZEND_FAST_CALL 162
+#define ZEND_FAST_RET 163
#endif \ No newline at end of file
diff --git a/acinclude.m4 b/acinclude.m4
index 448659f920..3284978804 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -2226,7 +2226,7 @@ AC_DEFUN([PHP_SETUP_ICU],[
AC_MSG_RESULT([$icu_install_prefix])
dnl Check ICU version
- AC_MSG_CHECKING([for ICU 3.4 or greater])
+ AC_MSG_CHECKING([for ICU 4.0 or greater])
icu_version_full=`$ICU_CONFIG --version`
ac_IFS=$IFS
IFS="."
@@ -2235,8 +2235,8 @@ AC_DEFUN([PHP_SETUP_ICU],[
icu_version=`expr [$]1 \* 1000 + [$]2`
AC_MSG_RESULT([found $icu_version_full])
- if test "$icu_version" -lt "3004"; then
- AC_MSG_ERROR([ICU version 3.4 or later is required])
+ if test "$icu_version" -lt "4000"; then
+ AC_MSG_ERROR([ICU version 4.0 or later is required])
fi
ICU_VERSION=$icu_version
diff --git a/build/libtool.m4 b/build/libtool.m4
index 77735d36b3..56658ccbb4 100644
--- a/build/libtool.m4
+++ b/build/libtool.m4
@@ -193,11 +193,11 @@ AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL],
enable_win32_dll=yes, enable_win32_dll=no)
AC_ARG_ENABLE([libtool-lock],
-[ --disable-libtool-lock avoid locking (might break parallel builds)])
+[ --disable-libtool-lock Avoid locking (might break parallel builds)])
test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
AC_ARG_WITH([pic],
-[ --with-pic try to use only PIC/non-PIC objects [default=use both]],
+[ --with-pic Try to use only PIC/non-PIC objects [default=use both]],
[pic_mode="$withval"],
[pic_mode=default])
test -z "$pic_mode" && pic_mode=default
@@ -1919,7 +1919,7 @@ fi
AC_DEFUN([_LT_AC_TAGCONFIG],
[AC_REQUIRE([LT_AC_PROG_SED])dnl
AC_ARG_WITH([tags],
-[ --with-tags[=TAGS] include additional configurations [automatic]
+[ --with-tags[=TAGS] Include additional configurations [automatic]
],
[tagnames="$withval"])
@@ -2023,7 +2023,7 @@ AC_DEFUN([AC_ENABLE_SHARED],
[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
AC_ARG_ENABLE([shared],
changequote(<<, >>)dnl
-<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT],
+<< --enable-shared[=PKGS] Build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT],
changequote([, ])dnl
[p=${PACKAGE-default}
case $enableval in
@@ -2063,7 +2063,7 @@ AC_DEFUN([AC_ENABLE_STATIC],
[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
AC_ARG_ENABLE([static],
changequote(<<, >>)dnl
-<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT],
+<< --enable-static[=PKGS] Build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT],
changequote([, ])dnl
[p=${PACKAGE-default}
case $enableval in
@@ -2103,7 +2103,8 @@ AC_DEFUN([AC_ENABLE_FAST_INSTALL],
[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
AC_ARG_ENABLE([fast-install],
changequote(<<, >>)dnl
-<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT],
+<< --enable-fast-install[=PKGS]
+ Optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT],
changequote([, ])dnl
[p=${PACKAGE-default}
case $enableval in
@@ -2241,7 +2242,7 @@ fi
# find the pathname to the GNU or non-GNU linker
AC_DEFUN([AC_PROG_LD],
[AC_ARG_WITH([gnu-ld],
-[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
+[ --with-gnu-ld Assume the C compiler uses GNU ld [default=no]],
[test "$withval" = no || with_gnu_ld=yes],
[with_gnu_ld=no])
AC_REQUIRE([LT_AC_PROG_SED])dnl
diff --git a/build/shtool b/build/shtool
index 684a01f5df..fc6ae1e6ef 100755
--- a/build/shtool
+++ b/build/shtool
@@ -1003,7 +1003,14 @@ mkdir )
if [ ".$opt_t" = .yes ]; then
echo "mkdir $pathcomp" 1>&2
fi
- mkdir $pathcomp || errstatus=$?
+ # See https://bugs.php.net/51076
+ # The fix is from Debian who have sent it
+ # upstream, too; but upstream seems dead.
+ mkdir $pathcomp || {
+ _errstatus=$?
+ [ -d "$pathcomp" ] || errstatus=${_errstatus}
+ unset _errstatus
+ }
if [ ".$opt_o" != . ]; then
if [ ".$opt_t" = .yes ]; then
echo "chown $opt_o $pathcomp" 1>&2
diff --git a/config.guess b/config.guess
index d407b8cde6..1578aa1736 100644
--- a/config.guess
+++ b/config.guess
@@ -1,10 +1,10 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
-# Free Software Foundation, Inc.
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+# 2011, 2012, 2013 Free Software Foundation, Inc.
-timestamp='2008-01-23'
+timestamp='2012-12-23'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -17,9 +17,7 @@ timestamp='2008-01-23'
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -27,16 +25,16 @@ timestamp='2008-01-23'
# the same distribution terms that you use for the rest of that program.
-# Originally written by Per Bothner <per@bothner.com>.
-# Please send patches to <config-patches@gnu.org>. Submit a context
-# diff and a properly formatted ChangeLog entry.
+# Originally written by Per Bothner. Please send patches (context
+# diff format) to <config-patches@gnu.org> and include a ChangeLog
+# entry.
#
# This script attempts to guess a canonical system name similar to
# config.sub. If it succeeds, it prints the system name on stdout, and
# exits with 0. Otherwise, it exits with 1.
#
-# The plan is that this can be called by configure scripts if you
-# don't specify an explicit build system type.
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
me=`echo "$0" | sed -e 's,.*/,,'`
@@ -56,8 +54,9 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
+2012, 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -144,7 +143,7 @@ UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:NetBSD:*:*)
# NetBSD (nbsd) targets should (where applicable) match one or
- # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
# switched to ELF, *-*-netbsd* would select the old
# object file format. This provides both forward
@@ -170,7 +169,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
eval $set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
- | grep __ELF__ >/dev/null
+ | grep -q __ELF__
then
# Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
# Return netbsd for either. FIX?
@@ -180,7 +179,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
fi
;;
*)
- os=netbsd
+ os=netbsd
;;
esac
# The OS release
@@ -201,6 +200,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
echo "${machine}-${os}${release}"
exit ;;
+ *:Bitrig:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+ exit ;;
*:OpenBSD:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
@@ -223,7 +226,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
;;
*5.*)
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
;;
esac
# According to Compaq, /usr/sbin/psrinfo has been available on
@@ -269,7 +272,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- exit ;;
+ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+ exitcode=$?
+ trap '' 0
+ exit $exitcode ;;
Alpha\ *:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# Should we change UNAME_MACHINE based on the output of uname instead
@@ -295,12 +301,12 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
echo s390-ibm-zvmoe
exit ;;
*:OS400:*:*)
- echo powerpc-ibm-os400
+ echo powerpc-ibm-os400
exit ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
exit ;;
- arm:riscos:*:*|arm:RISCOS:*:*)
+ arm*:riscos:*:*|arm*:RISCOS:*:*)
echo arm-unknown-riscos
exit ;;
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
@@ -324,14 +330,33 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
case `/usr/bin/uname -p` in
sparc) echo sparc-icl-nx7; exit ;;
esac ;;
+ s390x:SunOS:*:*)
+ echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
sun4H:SunOS:5.*:*)
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
+ i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+ echo i386-pc-auroraux${UNAME_RELEASE}
+ exit ;;
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
- echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ eval $set_cc_for_build
+ SUN_ARCH="i386"
+ # If there is a compiler, see if it is configured for 64-bit objects.
+ # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ # This test works for both compilers.
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ SUN_ARCH="x86_64"
+ fi
+ fi
+ echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
@@ -375,23 +400,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# MiNT. But MiNT is downward compatible to TOS, so this should
# be no problem.
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
+ echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
+ exit ;;
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
+ echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
- echo m68k-milan-mint${UNAME_RELEASE}
- exit ;;
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit ;;
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
- echo m68k-hades-mint${UNAME_RELEASE}
- exit ;;
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit ;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
- echo m68k-unknown-mint${UNAME_RELEASE}
- exit ;;
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit ;;
m68k:machten:*:*)
echo m68k-apple-machten${UNAME_RELEASE}
exit ;;
@@ -461,8 +486,8 @@ EOF
echo m88k-motorola-sysv3
exit ;;
AViiON:dgux:*:*)
- # DG/UX returns AViiON for all architectures
- UNAME_PROCESSOR=`/usr/bin/uname -p`
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
then
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
@@ -475,7 +500,7 @@ EOF
else
echo i586-dg-dgux${UNAME_RELEASE}
fi
- exit ;;
+ exit ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
echo m88k-dolphin-sysv3
exit ;;
@@ -575,52 +600,52 @@ EOF
9000/[678][0-9][0-9])
if [ -x /usr/bin/getconf ]; then
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
- sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
- case "${sc_cpu_version}" in
- 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
- 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
- 532) # CPU_PA_RISC2_0
- case "${sc_kernel_bits}" in
- 32) HP_ARCH="hppa2.0n" ;;
- 64) HP_ARCH="hppa2.0w" ;;
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
'') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
- esac ;;
- esac
+ esac ;;
+ esac
fi
if [ "${HP_ARCH}" = "" ]; then
eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
+ sed 's/^ //' << EOF >$dummy.c
- #define _HPUX_SOURCE
- #include <stdlib.h>
- #include <unistd.h>
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
- int main ()
- {
- #if defined(_SC_KERNEL_BITS)
- long bits = sysconf(_SC_KERNEL_BITS);
- #endif
- long cpu = sysconf (_SC_CPU_VERSION);
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
- case CPU_PA_RISC2_0:
- #if defined(_SC_KERNEL_BITS)
- switch (bits)
- {
- case 64: puts ("hppa2.0w"); break;
- case 32: puts ("hppa2.0n"); break;
- default: puts ("hppa2.0"); break;
- } break;
- #else /* !defined(_SC_KERNEL_BITS) */
- puts ("hppa2.0"); break;
- #endif
- default: puts ("hppa1.0"); break;
- }
- exit (0);
- }
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
EOF
(CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
test -z "$HP_ARCH" && HP_ARCH=hppa
@@ -640,7 +665,7 @@ EOF
# => hppa64-hp-hpux11.23
if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
- grep __LP64__ >/dev/null
+ grep -q __LP64__
then
HP_ARCH="hppa2.0w"
else
@@ -711,22 +736,22 @@ EOF
exit ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
echo c1-convex-bsd
- exit ;;
+ exit ;;
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
- exit ;;
+ exit ;;
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
echo c34-convex-bsd
- exit ;;
+ exit ;;
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
echo c38-convex-bsd
- exit ;;
+ exit ;;
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
echo c4-convex-bsd
- exit ;;
+ exit ;;
CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
@@ -750,14 +775,14 @@ EOF
exit ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
- echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
5000:UNIX_System_V:4.*:*)
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
- echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
@@ -769,34 +794,39 @@ EOF
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit ;;
*:FreeBSD:*:*)
- case ${UNAME_MACHINE} in
- pc98)
- echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ case ${UNAME_PROCESSOR} in
amd64)
echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
*)
- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
esac
exit ;;
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
exit ;;
+ *:MINGW64*:*)
+ echo ${UNAME_MACHINE}-pc-mingw64
+ exit ;;
*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
+ i*:MSYS*:*)
+ echo ${UNAME_MACHINE}-pc-msys
+ exit ;;
i*:windows32*:*)
- # uname -m includes "-pc" on this system.
- echo ${UNAME_MACHINE}-mingw32
+ # uname -m includes "-pc" on this system.
+ echo ${UNAME_MACHINE}-mingw32
exit ;;
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
exit ;;
- *:Interix*:[3456]*)
- case ${UNAME_MACHINE} in
+ *:Interix*:*)
+ case ${UNAME_MACHINE} in
x86)
echo i586-pc-interix${UNAME_RELEASE}
exit ;;
- EM64T | authenticamd)
+ authenticamd | genuineintel | EM64T)
echo x86_64-unknown-interix${UNAME_RELEASE}
exit ;;
IA64)
@@ -806,6 +836,9 @@ EOF
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
echo i${UNAME_MACHINE}-pc-mks
exit ;;
+ 8664:Windows_NT:*)
+ echo x86_64-pc-mks
+ exit ;;
i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
@@ -835,6 +868,27 @@ EOF
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
exit ;;
+ aarch64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ aarch64_be:Linux:*:*)
+ UNAME_MACHINE=aarch64_be
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep -q ld.so.1
+ if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+ exit ;;
arm*:Linux:*:*)
eval $set_cc_for_build
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
@@ -842,20 +896,40 @@ EOF
then
echo ${UNAME_MACHINE}-unknown-linux-gnu
else
- echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_PCS_VFP
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
+ fi
fi
exit ;;
avr32*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
cris:Linux:*:*)
- echo cris-axis-linux-gnu
+ echo ${UNAME_MACHINE}-axis-linux-gnu
exit ;;
crisv32:Linux:*:*)
- echo crisv32-axis-linux-gnu
+ echo ${UNAME_MACHINE}-axis-linux-gnu
exit ;;
frv:Linux:*:*)
- echo frv-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ hexagon:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
+ i*86:Linux:*:*)
+ LIBC=gnu
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #ifdef __dietlibc__
+ LIBC=dietlibc
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+ echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
exit ;;
ia64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
@@ -866,74 +940,33 @@ EOF
m68*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
- mips:Linux:*:*)
+ mips:Linux:*:* | mips64:Linux:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#undef CPU
- #undef mips
- #undef mipsel
+ #undef ${UNAME_MACHINE}
+ #undef ${UNAME_MACHINE}el
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=mipsel
+ CPU=${UNAME_MACHINE}el
#else
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=mips
+ CPU=${UNAME_MACHINE}
#else
CPU=
#endif
#endif
EOF
- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- /^CPU/{
- s: ::g
- p
- }'`"
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
- ;;
- mips64:Linux:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #undef CPU
- #undef mips64
- #undef mips64el
- #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=mips64el
- #else
- #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=mips64
- #else
- CPU=
- #endif
- #endif
-EOF
- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- /^CPU/{
- s: ::g
- p
- }'`"
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
;;
or32:Linux:*:*)
- echo or32-unknown-linux-gnu
- exit ;;
- ppc:Linux:*:*)
- echo powerpc-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
- ppc64:Linux:*:*)
- echo powerpc64-unknown-linux-gnu
+ padre:Linux:*:*)
+ echo sparc-unknown-linux-gnu
exit ;;
- alpha:Linux:*:*)
- case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
- EV5) UNAME_MACHINE=alphaev5 ;;
- EV56) UNAME_MACHINE=alphaev56 ;;
- PCA56) UNAME_MACHINE=alphapca56 ;;
- PCA57) UNAME_MACHINE=alphapca56 ;;
- EV6) UNAME_MACHINE=alphaev6 ;;
- EV67) UNAME_MACHINE=alphaev67 ;;
- EV68*) UNAME_MACHINE=alphaev68 ;;
- esac
- objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
- if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
- echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-gnu
exit ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
@@ -943,14 +976,17 @@ EOF
*) echo hppa-unknown-linux-gnu ;;
esac
exit ;;
- parisc64:Linux:*:* | hppa64:Linux:*:*)
- echo hppa64-unknown-linux-gnu
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-gnu
+ exit ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-gnu
exit ;;
s390:Linux:*:* | s390x:Linux:*:*)
echo ${UNAME_MACHINE}-ibm-linux
exit ;;
sh64*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
sh*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
@@ -958,78 +994,18 @@ EOF
sparc:Linux:*:* | sparc64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
+ tile*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit ;;
vax:Linux:*:*)
echo ${UNAME_MACHINE}-dec-linux-gnu
exit ;;
x86_64:Linux:*:*)
- echo x86_64-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
xtensa*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
- i*86:Linux:*:*)
- # The BFD linker knows what the default object file format is, so
- # first see if it will tell us. cd to the root directory to prevent
- # problems with other programs or directories called `ld' in the path.
- # Set LC_ALL=C to ensure ld outputs messages in English.
- ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
- | sed -ne '/supported targets:/!d
- s/[ ][ ]*/ /g
- s/.*supported targets: *//
- s/ .*//
- p'`
- case "$ld_supported_targets" in
- elf32-i386)
- TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
- ;;
- a.out-i386-linux)
- echo "${UNAME_MACHINE}-pc-linux-gnuaout"
- exit ;;
- coff-i386)
- echo "${UNAME_MACHINE}-pc-linux-gnucoff"
- exit ;;
- "")
- # Either a pre-BFD a.out linker (linux-gnuoldld) or
- # one that does not give us useful --help.
- echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
- exit ;;
- esac
- # Determine whether the default compiler is a.out or elf
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <features.h>
- #ifdef __ELF__
- # ifdef __GLIBC__
- # if __GLIBC__ >= 2
- LIBC=gnu
- # else
- LIBC=gnulibc1
- # endif
- # else
- LIBC=gnulibc1
- # endif
- #else
- #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
- LIBC=gnu
- #else
- LIBC=gnuaout
- #endif
- #endif
- #ifdef __dietlibc__
- LIBC=dietlibc
- #endif
-EOF
- eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
- /^LIBC/{
- s: ::g
- p
- }'`"
- test x"${LIBC}" != x && {
- echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
- exit
- }
- test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
- ;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
# earlier versions are messed up and put the nodename in both
@@ -1037,11 +1013,11 @@ EOF
echo i386-sequent-sysv4
exit ;;
i*86:UNIX_SV:4.2MP:2.*)
- # Unixware is an offshoot of SVR4, but it has its own version
- # number series starting with 2...
- # I am not positive that other SVR4 systems won't match this,
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
# I just have to hope. -- rms.
- # Use sysv4.2uw... so that sysv4* matches it.
+ # Use sysv4.2uw... so that sysv4* matches it.
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
exit ;;
i*86:OS/2:*:*)
@@ -1058,7 +1034,7 @@ EOF
i*86:syllable:*:*)
echo ${UNAME_MACHINE}-pc-syllable
exit ;;
- i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
echo i386-unknown-lynxos${UNAME_RELEASE}
exit ;;
i*86:*DOS:*:*)
@@ -1073,7 +1049,7 @@ EOF
fi
exit ;;
i*86:*:5:[678]*)
- # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
case `/bin/uname -X | grep "^Machine"` in
*486*) UNAME_MACHINE=i486 ;;
*Pentium) UNAME_MACHINE=i586 ;;
@@ -1101,10 +1077,13 @@ EOF
exit ;;
pc:*:*:*)
# Left here for compatibility:
- # uname -m prints for DJGPP always 'pc', but it prints nothing about
- # the processor, so we play safe by assuming i386.
- echo i386-pc-msdosdjgpp
- exit ;;
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configure will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
+ exit ;;
Intel:Mach:3*:*)
echo i386-pc-mach3
exit ;;
@@ -1139,8 +1118,18 @@ EOF
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4; exit; } ;;
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
echo m68k-unknown-lynxos${UNAME_RELEASE}
exit ;;
@@ -1153,7 +1142,7 @@ EOF
rs6000:LynxOS:2.*:*)
echo rs6000-unknown-lynxos${UNAME_RELEASE}
exit ;;
- PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
echo powerpc-unknown-lynxos${UNAME_RELEASE}
exit ;;
SM[BE]S:UNIX_SV:*:*)
@@ -1173,10 +1162,10 @@ EOF
echo ns32k-sni-sysv
fi
exit ;;
- PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
- # says <Richard.M.Bartel@ccMail.Census.GOV>
- echo i586-unisys-sysv4
- exit ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit ;;
*:UNIX_System_V:4*:FTX*)
# From Gerald Hewes <hewes@openmarket.com>.
# How about differentiating between stratus architectures? -djm
@@ -1202,11 +1191,11 @@ EOF
exit ;;
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
if [ -d /usr/nec ]; then
- echo mips-nec-sysv${UNAME_RELEASE}
+ echo mips-nec-sysv${UNAME_RELEASE}
else
- echo mips-unknown-sysv${UNAME_RELEASE}
+ echo mips-unknown-sysv${UNAME_RELEASE}
fi
- exit ;;
+ exit ;;
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
echo powerpc-be-beos
exit ;;
@@ -1216,6 +1205,12 @@ EOF
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
echo i586-pc-beos
exit ;;
+ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
+ echo i586-pc-haiku
+ exit ;;
+ x86_64:Haiku:*:*)
+ echo x86_64-unknown-haiku
+ exit ;;
SX-4:SUPER-UX:*:*)
echo sx4-nec-superux${UNAME_RELEASE}
exit ;;
@@ -1243,6 +1238,16 @@ EOF
*:Darwin:*:*)
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
case $UNAME_PROCESSOR in
+ i386)
+ eval $set_cc_for_build
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ UNAME_PROCESSOR="x86_64"
+ fi
+ fi ;;
unknown) UNAME_PROCESSOR=powerpc ;;
esac
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
@@ -1258,7 +1263,10 @@ EOF
*:QNX:*:4*)
echo i386-pc-qnx
exit ;;
- NSE-?:NONSTOP_KERNEL:*:*)
+ NEO-?:NONSTOP_KERNEL:*:*)
+ echo neo-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSE-*:NONSTOP_KERNEL:*:*)
echo nse-tandem-nsk${UNAME_RELEASE}
exit ;;
NSR-?:NONSTOP_KERNEL:*:*)
@@ -1303,13 +1311,13 @@ EOF
echo pdp10-unknown-its
exit ;;
SEI:*:*:SEIUX)
- echo mips-sei-seiux${UNAME_RELEASE}
+ echo mips-sei-seiux${UNAME_RELEASE}
exit ;;
*:DragonFly:*:*)
echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit ;;
*:*VMS:*:*)
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
case "${UNAME_MACHINE}" in
A*) echo alpha-dec-vms ; exit ;;
I*) echo ia64-dec-vms ; exit ;;
@@ -1324,11 +1332,14 @@ EOF
i*86:rdos:*:*)
echo ${UNAME_MACHINE}-pc-rdos
exit ;;
+ i*86:AROS:*:*)
+ echo ${UNAME_MACHINE}-pc-aros
+ exit ;;
+ x86_64:VMkernel:*:*)
+ echo ${UNAME_MACHINE}-unknown-esx
+ exit ;;
esac
-#echo '(No uname command or uname output not recognized.)' 1>&2
-#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
-
eval $set_cc_for_build
cat >$dummy.c <<EOF
#ifdef _SEQUENT_
@@ -1346,11 +1357,11 @@ main ()
#include <sys/param.h>
printf ("m68k-sony-newsos%s\n",
#ifdef NEWSOS4
- "4"
+ "4"
#else
- ""
+ ""
#endif
- ); exit (0);
+ ); exit (0);
#endif
#endif
diff --git a/config.sub b/config.sub
index 3995776dda..3fe955dea0 100644
--- a/config.sub
+++ b/config.sub
@@ -1,10 +1,10 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
-# Free Software Foundation, Inc.
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+# 2011, 2012, 2013 Free Software Foundation, Inc.
-timestamp='2008-01-16'
+timestamp='2012-12-23'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
@@ -21,9 +21,7 @@ timestamp='2008-01-16'
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -32,13 +30,16 @@ timestamp='2008-01-16'
# Please send patches to <config-patches@gnu.org>. Submit a context
-# diff and a properly formatted ChangeLog entry.
+# diff and a properly formatted GNU ChangeLog entry.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
# If it is invalid, we print an error message on stderr and exit with code 1.
# Otherwise, we print the canonical config type on stdout and succeed.
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
# This file is supposed to be the same for all GNU packages
# and recognize all the CPU types, system types and aliases
# that are meaningful with *any* GNU software.
@@ -72,8 +73,9 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
+2012, 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -120,12 +122,18 @@ esac
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
- nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
- uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+ knetbsd*-gnu* | netbsd*-gnu* | \
+ kopensolaris*-gnu* | \
storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
+ android-linux)
+ os=-linux-android
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+ ;;
*)
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
if [ $basic_machine != $1 ]
@@ -148,10 +156,13 @@ case $os in
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
- -apple | -axis | -knuth | -cray)
+ -apple | -axis | -knuth | -cray | -microblaze*)
os=
basic_machine=$1
;;
+ -bluegene*)
+ os=-cnk
+ ;;
-sim | -cisco | -oki | -wec | -winbond)
os=
basic_machine=$1
@@ -166,10 +177,10 @@ case $os in
os=-chorusos
basic_machine=$1
;;
- -chorusrdb)
- os=-chorusrdb
+ -chorusrdb)
+ os=-chorusrdb
basic_machine=$1
- ;;
+ ;;
-hiux*)
os=-hiuxwe2
;;
@@ -214,6 +225,12 @@ case $os in
-isc*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
+ -lynx*178)
+ os=-lynxos178
+ ;;
+ -lynx*5)
+ os=-lynxos5
+ ;;
-lynx*)
os=-lynxos
;;
@@ -238,24 +255,34 @@ case $basic_machine in
# Some are omitted here because they have special meanings below.
1750a | 580 \
| a29k \
+ | aarch64 | aarch64_be \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
- | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+ | arc \
+ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+ | avr | avr32 \
+ | be32 | be64 \
| bfin \
| c4x | clipper \
| d10v | d30v | dlx | dsp16xx \
+ | epiphany \
| fido | fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | hexagon \
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
+ | le32 | le64 \
+ | lm32 \
| m32c | m32r | m32rle | m68000 | m68k | m88k \
- | maxq | mb | microblaze | mcore | mep \
+ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
- | mips64vr | mips64vrel \
+ | mips64octeon | mips64octeonel \
| mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
| mips64vr4100 | mips64vr4100el \
| mips64vr4300 | mips64vr4300el \
| mips64vr5000 | mips64vr5000el \
@@ -268,29 +295,42 @@ case $basic_machine in
| mipsisa64sr71k | mipsisa64sr71kel \
| mipstx39 | mipstx39el \
| mn10200 | mn10300 \
+ | moxie \
| mt \
| msp430 \
+ | nds32 | nds32le | nds32be \
| nios | nios2 \
| ns16k | ns32k \
+ | open8 \
| or32 \
| pdp10 | pdp11 | pj | pjl \
- | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+ | powerpc | powerpc64 | powerpc64le | powerpcle \
| pyramid \
+ | rl78 | rx \
| score \
- | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
- | spu | strongarm \
- | tahoe | thumb | tic4x | tic80 | tron \
- | v850 | v850e \
+ | spu \
+ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+ | ubicom32 \
+ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
| we32k \
- | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
- | z8k)
+ | x86 | xc16x | xstormy16 | xtensa \
+ | z8k | z80)
basic_machine=$basic_machine-unknown
;;
- m6811 | m68hc11 | m6812 | m68hc12)
- # Motorola 68HC11/12.
+ c54x)
+ basic_machine=tic54x-unknown
+ ;;
+ c55x)
+ basic_machine=tic55x-unknown
+ ;;
+ c6x)
+ basic_machine=tic6x-unknown
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
basic_machine=$basic_machine-unknown
os=-none
;;
@@ -300,6 +340,21 @@ case $basic_machine in
basic_machine=mt-unknown
;;
+ strongarm | thumb | xscale)
+ basic_machine=arm-unknown
+ ;;
+ xgate)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ xscaleeb)
+ basic_machine=armeb-unknown
+ ;;
+
+ xscaleel)
+ basic_machine=armel-unknown
+ ;;
+
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
# (2) the word "unknown" tends to confuse beginning users.
@@ -314,29 +369,37 @@ case $basic_machine in
# Recognize the basic CPU types with company name.
580-* \
| a29k-* \
+ | aarch64-* | aarch64_be-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* | avr32-* \
+ | be32-* | be64-* \
| bfin-* | bs2000-* \
- | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* \
| clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | hexagon-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* | iq2000-* \
+ | le32-* | le64-* \
+ | lm32-* \
| m32c-* | m32r-* | m32rle-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
- | m88110-* | m88k-* | maxq-* | mcore-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+ | microblaze-* | microblazeel-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \
| mips64-* | mips64el-* \
- | mips64vr-* | mips64vrel-* \
+ | mips64octeon-* | mips64octeonel-* \
| mips64orion-* | mips64orionel-* \
+ | mips64r5900-* | mips64r5900el-* \
+ | mips64vr-* | mips64vrel-* \
| mips64vr4100-* | mips64vr4100el-* \
| mips64vr4300-* | mips64vr4300el-* \
| mips64vr5000-* | mips64vr5000el-* \
@@ -351,27 +414,32 @@ case $basic_machine in
| mmix-* \
| mt-* \
| msp430-* \
+ | nds32-* | nds32le-* | nds32be-* \
| nios-* | nios2-* \
| none-* | np1-* | ns16k-* | ns32k-* \
+ | open8-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
- | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
| pyramid-* \
- | romp-* | rs6000-* \
- | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | rl78-* | romp-* | rs6000-* | rx-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
| sparclite-* \
- | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
- | tahoe-* | thumb-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+ | tahoe-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tile*-* \
| tron-* \
- | v850-* | v850e-* | vax-* \
+ | ubicom32-* \
+ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+ | vax-* \
| we32k-* \
- | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* \
| xstormy16-* | xtensa*-* \
| ymp-* \
- | z8k-*)
+ | z8k-* | z80-*)
;;
# Recognize the basic CPU types without company name, with glob match.
xtensa*)
@@ -393,7 +461,7 @@ case $basic_machine in
basic_machine=a29k-amd
os=-udi
;;
- abacus)
+ abacus)
basic_machine=abacus-unknown
;;
adobe68k)
@@ -439,6 +507,10 @@ case $basic_machine in
basic_machine=m68k-apollo
os=-bsd
;;
+ aros)
+ basic_machine=i386-pc
+ os=-aros
+ ;;
aux)
basic_machine=m68k-apple
os=-aux
@@ -455,10 +527,27 @@ case $basic_machine in
basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
+ bluegene*)
+ basic_machine=powerpc-ibm
+ os=-cnk
+ ;;
+ c54x-*)
+ basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c55x-*)
+ basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c6x-*)
+ basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
c90)
basic_machine=c90-cray
os=-unicos
;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=-cegcc
+ ;;
convex-c1)
basic_machine=c1-convex
os=-bsd
@@ -487,7 +576,7 @@ case $basic_machine in
basic_machine=craynv-cray
os=-unicosmp
;;
- cr16)
+ cr16 | cr16-*)
basic_machine=cr16-unknown
os=-elf
;;
@@ -526,6 +615,10 @@ case $basic_machine in
basic_machine=m88k-motorola
os=-sysv3
;;
+ dicos)
+ basic_machine=i686-pc
+ os=-dicos
+ ;;
djgpp)
basic_machine=i586-pc
os=-msdosdjgpp
@@ -641,7 +734,6 @@ case $basic_machine in
i370-ibm* | ibm*)
basic_machine=i370-ibm
;;
-# I'm not sure what "Sysv32" means. Should this be sysv3.2?
i*86v32)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv32
@@ -699,6 +791,13 @@ case $basic_machine in
basic_machine=ns32k-utek
os=-sysv
;;
+ microblaze*)
+ basic_machine=microblaze-xilinx
+ ;;
+ mingw64)
+ basic_machine=x86_64-pc
+ os=-mingw64
+ ;;
mingw32)
basic_machine=i386-pc
os=-mingw32
@@ -735,10 +834,18 @@ case $basic_machine in
ms1-*)
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
;;
+ msys)
+ basic_machine=i386-pc
+ os=-msys
+ ;;
mvs)
basic_machine=i370-ibm
os=-mvs
;;
+ nacl)
+ basic_machine=le32-unknown
+ os=-nacl
+ ;;
ncr3000)
basic_machine=i486-ncr
os=-sysv4
@@ -803,6 +910,12 @@ case $basic_machine in
np1)
basic_machine=np1-gould
;;
+ neo-tandem)
+ basic_machine=neo-tandem
+ ;;
+ nse-tandem)
+ basic_machine=nse-tandem
+ ;;
nsr-tandem)
basic_machine=nsr-tandem
;;
@@ -885,9 +998,10 @@ case $basic_machine in
;;
power) basic_machine=power-ibm
;;
- ppc) basic_machine=powerpc-unknown
+ ppc | ppcbe) basic_machine=powerpc-unknown
;;
- ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ppc-* | ppcbe-*)
+ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
@@ -912,7 +1026,11 @@ case $basic_machine in
basic_machine=i586-unknown
os=-pw32
;;
- rdos)
+ rdos | rdos64)
+ basic_machine=x86_64-pc
+ os=-rdos
+ ;;
+ rdos32)
basic_machine=i386-pc
os=-rdos
;;
@@ -981,6 +1099,9 @@ case $basic_machine in
basic_machine=i860-stratus
os=-sysv4
;;
+ strongarm-* | thumb-*)
+ basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
sun2)
basic_machine=m68000-sun
;;
@@ -1037,20 +1158,8 @@ case $basic_machine in
basic_machine=t90-cray
os=-unicos
;;
- tic54x | c54x*)
- basic_machine=tic54x-unknown
- os=-coff
- ;;
- tic55x | c55x*)
- basic_machine=tic55x-unknown
- os=-coff
- ;;
- tic6x | c6x*)
- basic_machine=tic6x-unknown
- os=-coff
- ;;
tile*)
- basic_machine=tile-unknown
+ basic_machine=$basic_machine-unknown
os=-linux-gnu
;;
tx39)
@@ -1120,6 +1229,9 @@ case $basic_machine in
xps | xps100)
basic_machine=xps100-honeywell
;;
+ xscale-* | xscalee[bl]-*)
+ basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+ ;;
ymp)
basic_machine=ymp-cray
os=-unicos
@@ -1128,6 +1240,10 @@ case $basic_machine in
basic_machine=z8k-unknown
os=-sim
;;
+ z80-*-coff)
+ basic_machine=z80-unknown
+ os=-sim
+ ;;
none)
basic_machine=none-none
os=-none
@@ -1166,7 +1282,7 @@ case $basic_machine in
we32k)
basic_machine=we32k-att
;;
- sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
+ sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown
;;
sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
@@ -1213,9 +1329,12 @@ esac
if [ x"$os" != x"" ]
then
case $os in
- # First match some system type aliases
- # that might get confused with valid system types.
+ # First match some system type aliases
+ # that might get confused with valid system types.
# -solaris* is a basic system type, with this one exception.
+ -auroraux)
+ os=-auroraux
+ ;;
-solaris1 | -solaris1.*)
os=`echo $os | sed -e 's|solaris1|sunos4|'`
;;
@@ -1236,21 +1355,23 @@ case $os in
# Each alternative MUST END IN A *, to match a version number.
# -sysv* is not here because it comes later, after sysvr4.
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
- | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
- | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+ | -sym* | -kopensolaris* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* \
+ | -aos* | -aros* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
- | -openbsd* | -solidbsd* \
+ | -bitrig* | -openbsd* | -solidbsd* \
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
- | -chorusos* | -chorusrdb* \
- | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+ | -chorusos* | -chorusrdb* | -cegcc* \
+ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+ | -linux-newlib* | -linux-musl* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
@@ -1258,7 +1379,7 @@ case $os in
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
- | -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1297,7 +1418,7 @@ case $os in
-opened*)
os=-openedition
;;
- -os400*)
+ -os400*)
os=-os400
;;
-wince*)
@@ -1346,7 +1467,7 @@ case $os in
-sinix*)
os=-sysv4
;;
- -tpf*)
+ -tpf*)
os=-tpf
;;
-triton*)
@@ -1388,6 +1509,11 @@ case $os in
-zvmoe)
os=-zvmoe
;;
+ -dicos*)
+ os=-dicos
+ ;;
+ -nacl*)
+ ;;
-none)
;;
*)
@@ -1410,10 +1536,10 @@ else
# system, and we'll never get to this point.
case $basic_machine in
- score-*)
+ score-*)
os=-elf
;;
- spu-*)
+ spu-*)
os=-elf
;;
*-acorn)
@@ -1425,8 +1551,20 @@ case $basic_machine in
arm*-semi)
os=-aout
;;
- c4x-* | tic4x-*)
- os=-coff
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ hexagon-*)
+ os=-elf
+ ;;
+ tic54x-*)
+ os=-coff
+ ;;
+ tic55x-*)
+ os=-coff
+ ;;
+ tic6x-*)
+ os=-coff
;;
# This must come before the *-dec entry.
pdp10-*)
@@ -1446,14 +1584,11 @@ case $basic_machine in
;;
m68000-sun)
os=-sunos3
- # This also exists in the configure program, but was not the
- # default.
- # os=-sunos4
;;
m68*-cisco)
os=-aout
;;
- mep-*)
+ mep-*)
os=-elf
;;
mips*-cisco)
@@ -1480,7 +1615,7 @@ case $basic_machine in
*-ibm)
os=-aix
;;
- *-knuth)
+ *-knuth)
os=-mmixware
;;
*-wec)
@@ -1585,7 +1720,7 @@ case $basic_machine in
-sunos*)
vendor=sun
;;
- -aix*)
+ -cnk*|-aix*)
vendor=ibm
;;
-beos*)
diff --git a/configure.in b/configure.in
index c57c343520..1f4080f258 100644
--- a/configure.in
+++ b/configure.in
@@ -118,8 +118,8 @@ int zend_sprintf(char *buffer, const char *format, ...);
])
PHP_MAJOR_VERSION=5
-PHP_MINOR_VERSION=4
-PHP_RELEASE_VERSION=25
+PHP_MINOR_VERSION=5
+PHP_RELEASE_VERSION=9
PHP_EXTRA_VERSION="-dev"
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`
@@ -1006,7 +1006,7 @@ dnl Check if all enabled by default extensions should be disabled
dnl
AC_ARG_ENABLE(all,
-[ --disable-all Disable all extensions which are enabled by default
+[ --disable-all Disable all extensions which are enabled by default
], [
PHP_ENABLE_ALL=$enableval
])
@@ -1443,7 +1443,7 @@ PHP_ADD_SOURCES(main, main.c snprintf.c spprintf.c php_sprintf.c \
fopen_wrappers.c alloca.c php_scandir.c \
php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c \
- network.c php_open_temporary_file.c php_logos.c \
+ network.c php_open_temporary_file.c \
output.c getopt.c)
PHP_ADD_SOURCES(main/streams, streams.c cast.c memory.c filter.c \
@@ -1472,7 +1472,7 @@ PHP_ADD_SOURCES(Zend, \
zend_list.c zend_indent.c zend_builtin_functions.c zend_sprintf.c \
zend_ini.c zend_qsort.c zend_multibyte.c zend_ts_hash.c zend_stream.c \
zend_iterators.c zend_interfaces.c zend_exceptions.c zend_strtod.c zend_gc.c \
- zend_closures.c zend_float.c zend_string.c zend_signal.c)
+ zend_closures.c zend_float.c zend_string.c zend_signal.c zend_generators.c)
if test -r "$abs_srcdir/Zend/zend_objects.c"; then
PHP_ADD_SOURCES(Zend, zend_objects.c zend_object_handlers.c zend_objects_API.c zend_default_classes.c)
@@ -1587,9 +1587,9 @@ cat <<X
X
fi
- if test "$PHP_SAPI" = "apache2handler" || test "$PHP_SAPI" = "apache2filter"; then
- if test "$APACHE_VERSION" -ge 2004001; then
- if test -z "$APACHE_THREADED_MPM"; then
+ if test "$PHP_SAPI" = "apache2handler" || test "$PHP_SAPI" = "apache2filter"; then
+ if test "$APACHE_VERSION" -ge 2004001; then
+ if test -z "$APACHE_THREADED_MPM"; then
cat <<X
+--------------------------------------------------------------------+
| *** WARNING *** |
@@ -1598,9 +1598,9 @@ cat <<X
| If you change Apache to use a threaded MPM you must reconfigure |
| PHP with --enable-maintainer-zts |
X
+ fi
fi
fi
- fi
# Warn about linking Apache with libpthread if oci8 extension is enabled on linux.
if test "$PHP_OCI8" != "no"; then
diff --git a/ext/bcmath/libbcmath/src/recmul.c b/ext/bcmath/libbcmath/src/recmul.c
index c31d09dc72..64014f3a6e 100644
--- a/ext/bcmath/libbcmath/src/recmul.c
+++ b/ext/bcmath/libbcmath/src/recmul.c
@@ -183,7 +183,6 @@ _bc_rec_mul (bc_num u, int ulen, bc_num v, int vlen, bc_num *prod,
int full_scale TSRMLS_DC)
{
bc_num u0, u1, v0, v1;
- int u0len, v0len;
bc_num m1, m2, m3, d1, d2;
int n, prodlen, m1zero;
int d1len, d2len;
@@ -216,10 +215,8 @@ _bc_rec_mul (bc_num u, int ulen, bc_num v, int vlen, bc_num *prod,
}
_bc_rm_leading_zeros (u1);
_bc_rm_leading_zeros (u0);
- u0len = u0->n_len;
_bc_rm_leading_zeros (v1);
_bc_rm_leading_zeros (v0);
- v0len = v0->n_len;
m1zero = bc_is_zero(u1 TSRMLS_CC) || bc_is_zero(v1 TSRMLS_CC);
diff --git a/ext/bz2/bz2_filter.c b/ext/bz2/bz2_filter.c
index a8a164085c..b31ab3c261 100644
--- a/ext/bz2/bz2_filter.c
+++ b/ext/bz2/bz2_filter.c
@@ -216,7 +216,6 @@ static php_stream_filter_status_t php_bz2_compress_filter(
size_t consumed = 0;
int status;
php_stream_filter_status_t exit_status = PSFS_FEED_ME;
- bz_stream *streamp;
if (!thisfilter || !thisfilter->abstract) {
/* Should never happen */
@@ -224,7 +223,6 @@ static php_stream_filter_status_t php_bz2_compress_filter(
}
data = (php_bz2_filter_data *)(thisfilter->abstract);
- streamp = &(data->strm);
while (buckets_in->head) {
size_t bin = 0, desired;
diff --git a/ext/bz2/config.m4 b/ext/bz2/config.m4
index 3e6aa78d05..55917c07f4 100644
--- a/ext/bz2/config.m4
+++ b/ext/bz2/config.m4
@@ -3,7 +3,7 @@ dnl $Id$
dnl
PHP_ARG_WITH(bz2, for BZip2 support,
-[ --with-bz2[=DIR] Include BZip2 support])
+[ --with-bz2[=DIR] Include BZip2 support])
if test "$PHP_BZ2" != "no"; then
if test -r $PHP_BZ2/include/bzlib.h; then
diff --git a/ext/calendar/calendar.c b/ext/calendar/calendar.c
index 06d3add252..34b34da371 100644
--- a/ext/calendar/calendar.c
+++ b/ext/calendar/calendar.c
@@ -140,7 +140,7 @@ const zend_function_entry calendar_functions[] = {
PHP_FE(frenchtojd, arginfo_frenchtojd)
PHP_FE(jddayofweek, arginfo_jddayofweek)
PHP_FE(jdmonthname, arginfo_jdmonthname)
- PHP_FE(easter_date, arginfo_easter_date)
+ PHP_FE(easter_date, arginfo_easter_date)
PHP_FE(easter_days, arginfo_easter_days)
PHP_FE(unixtojd, arginfo_unixtojd)
PHP_FE(jdtounix, arginfo_jdtounix)
@@ -199,11 +199,14 @@ static struct cal_entry_t cal_conversion_table[CAL_NUM_CALS] = {
{"Julian", "CAL_JULIAN", JulianToSdn, SdnToJulian, 12, 31,
MonthNameShort, MonthNameLong},
{"Jewish", "CAL_JEWISH", JewishToSdn, SdnToJewish, 13, 30,
- JewishMonthName, JewishMonthName},
+ JewishMonthNameLeap, JewishMonthNameLeap},
{"French", "CAL_FRENCH", FrenchToSdn, SdnToFrench, 13, 30,
FrenchMonthName, FrenchMonthName}
};
+#define JEWISH_MONTH_NAME(year) ((monthsPerYear[((year)-1) % 19] == 13)?JewishMonthNameLeap:JewishMonthName)
+#define JEWISH_HEB_MONTH_NAME(year) ((monthsPerYear[((year)-1) % 19] == 13)?JewishMonthHebNameLeap:JewishMonthHebName)
+
/* For jddayofweek */
enum { CAL_DOW_DAYNO, CAL_DOW_SHORT, CAL_DOW_LONG };
@@ -288,7 +291,7 @@ static void _php_cal_info(int cal, zval **ret)
PHP_FUNCTION(cal_info)
{
long cal = -1;
-
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &cal) == FAILURE) {
RETURN_FALSE;
@@ -418,8 +421,14 @@ PHP_FUNCTION(cal_from_jd)
add_assoc_string(return_value, "abbrevdayname", DayNameShort[dow], 1);
add_assoc_string(return_value, "dayname", DayNameLong[dow], 1);
/* month name */
- add_assoc_string(return_value, "abbrevmonth", calendar->month_name_short[month], 1);
- add_assoc_string(return_value, "monthname", calendar->month_name_long[month], 1);
+ if(cal == CAL_JEWISH) {
+ /* special case for Jewish calendar */
+ add_assoc_string(return_value, "abbrevmonth", JEWISH_MONTH_NAME(year)[month], 1);
+ add_assoc_string(return_value, "monthname", JEWISH_MONTH_NAME(year)[month], 1);
+ } else {
+ add_assoc_string(return_value, "abbrevmonth", calendar->month_name_short[month], 1);
+ add_assoc_string(return_value, "monthname", calendar->month_name_long[month], 1);
+ }
}
/* }}} */
@@ -608,7 +617,7 @@ PHP_FUNCTION(jdtojewish)
RETURN_FALSE;
}
- snprintf(hebdate, sizeof(hebdate), "%s %s %s", heb_number_to_chars(day, fl, &dayp), JewishMonthHebName[month], heb_number_to_chars(year, fl, &yearp));
+ snprintf(hebdate, sizeof(hebdate), "%s %s %s", heb_number_to_chars(day, fl, &dayp), JEWISH_HEB_MONTH_NAME(year)[month], heb_number_to_chars(year, fl, &yearp));
if (dayp) {
efree(dayp);
@@ -728,7 +737,7 @@ PHP_FUNCTION(jdmonthname)
break;
case CAL_MONTH_JEWISH: /* jewish month */
SdnToJewish(julday, &year, &month, &day);
- monthname = JewishMonthName[month];
+ monthname = JEWISH_MONTH_NAME(year)[month];
break;
case CAL_MONTH_FRENCH: /* french month */
SdnToFrench(julday, &year, &month, &day);
diff --git a/ext/calendar/jewish.c b/ext/calendar/jewish.c
index fcc0e5c0b8..ddc8aaaf86 100644
--- a/ext/calendar/jewish.c
+++ b/ext/calendar/jewish.c
@@ -85,8 +85,8 @@
* 3 Kislev 29 30 30 29 30 30 (variable)
* 4 Tevet 29 29 29 29 29 29
* 5 Shevat 30 30 30 30 30 30
- * 6 Adar I 29 29 29 30 30 30 (variable)
- * 7 Adar II -- -- -- 29 29 29 (optional)
+ * 6 Adar I -- -- -- 30 30 30 (optional)
+ * 7 Adar (II) 29 29 29 29 29 29
* 8 Nisan 30 30 30 30 30 30
* 9 Iyyar 29 29 29 29 29 29
* 10 Sivan 30 30 30 30 30 30
@@ -100,8 +100,8 @@
* have multiple possible spellings in the Roman character set. I have
* chosen to use the spellings found in the Encyclopedia Judaica.
*
- * Adar II, the month added for leap years, is sometimes referred to as
- * the 13th month, but I have chosen to assign it the number 7 to keep
+ * Adar I, the month added for leap years, is sometimes referred to as
+ * the 13th month, but I have chosen to assign it the number 6 to keep
* the months in chronological order. This may not be consistent with
* other numbering schemes.
*
@@ -287,7 +287,7 @@
#define AM3_11_20 ((9 * HALAKIM_PER_HOUR) + 204)
#define AM9_32_43 ((15 * HALAKIM_PER_HOUR) + 589)
-static int monthsPerYear[19] =
+int monthsPerYear[19] =
{
12, 12, 13, 12, 12, 13, 12, 13, 12, 12, 13, 12, 12, 13, 12, 12, 13, 12, 13
};
@@ -298,16 +298,36 @@ static int yearOffset[19] =
136, 148, 160, 173, 185, 197, 210, 222
};
+/* names for leap (13-month) year */
+char *JewishMonthNameLeap[14] =
+{
+ "",
+ "Tishri",
+ "Heshvan",
+ "Kislev",
+ "Tevet",
+ "Shevat",
+ "Adar I",
+ "Adar II",
+ "Nisan",
+ "Iyyar",
+ "Sivan",
+ "Tammuz",
+ "Av",
+ "Elul"
+};
+
+/* names for regular year */
char *JewishMonthName[14] =
{
- "",
+ "",
"Tishri",
"Heshvan",
"Kislev",
"Tevet",
"Shevat",
- "AdarI",
- "AdarII",
+ "",
+ "Adar",
"Nisan",
"Iyyar",
"Sivan",
@@ -316,16 +336,36 @@ char *JewishMonthName[14] =
"Elul"
};
+/* names for leap (13-month) year */
+char *JewishMonthHebNameLeap[14] =
+{
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ " '",
+ " '",
+ "",
+ "",
+ "",
+ "",
+ "",
+ ""
+};
+
+/* names for regular year */
char *JewishMonthHebName[14] =
{
- "",
+ "",
"",
"",
"",
"",
"",
+ "",
"",
- "' ",
"",
"",
"",
@@ -588,11 +628,11 @@ void SdnToJewish(
(*pMonth)--;
(*pDay) += 30;
} else {
- *pMonth = 6;
+ *pMonth = 7;
*pDay = inputDay - tishri1 + 207;
if (*pDay > 0)
return;
- (*pMonth)--;
+ (*pMonth) -= 2;
(*pDay) += 30;
}
if (*pDay > 0)
diff --git a/ext/calendar/sdncal.h b/ext/calendar/sdncal.h
index 81328d1369..c0463c80d4 100644
--- a/ext/calendar/sdncal.h
+++ b/ext/calendar/sdncal.h
@@ -79,7 +79,10 @@ long int JulianToSdn(int year, int month, int day);
void SdnToJewish(long int sdn, int *pYear, int *pMonth, int *pDay);
long int JewishToSdn(int year, int month, int day);
extern char *JewishMonthName[14];
+extern char *JewishMonthNameLeap[14];
extern char *JewishMonthHebName[14];
+extern char *JewishMonthHebNameLeap[14];
+extern int monthsPerYear[19];
/* French republic calendar conversions. */
void SdnToFrench(long int sdn, int *pYear, int *pMonth, int *pDay);
diff --git a/ext/calendar/tests/bug54254.phpt b/ext/calendar/tests/bug54254.phpt
new file mode 100644
index 0000000000..df9362320c
--- /dev/null
+++ b/ext/calendar/tests/bug54254.phpt
@@ -0,0 +1,59 @@
+--TEST--
+Bug #54254 (cal_days_in_month incompatible with jdtojewish in non-leap-years)
+--SKIPIF--
+<?php include 'skipif.inc'; ?>
+--FILE--
+<?php
+var_dump(cal_days_in_month(CAL_JEWISH, 1, 5771));
+var_dump(cal_days_in_month(CAL_JEWISH, 2, 5771));
+var_dump(cal_days_in_month(CAL_JEWISH, 3, 5771));
+var_dump(cal_days_in_month(CAL_JEWISH, 4, 5771));
+var_dump(cal_days_in_month(CAL_JEWISH, 5, 5771));
+var_dump(cal_days_in_month(CAL_JEWISH, 6, 5771));
+var_dump(cal_days_in_month(CAL_JEWISH, 7, 5771));
+var_dump(cal_days_in_month(CAL_JEWISH, 8, 5771));
+var_dump(cal_days_in_month(CAL_JEWISH, 9, 5771));
+var_dump(cal_days_in_month(CAL_JEWISH, 10, 5771));
+var_dump(cal_days_in_month(CAL_JEWISH, 11, 5771));
+var_dump(cal_days_in_month(CAL_JEWISH, 12, 5771));
+var_dump(cal_days_in_month(CAL_JEWISH, 13, 5771));
+var_dump(cal_days_in_month(CAL_JEWISH, 1, 5772));
+var_dump(cal_days_in_month(CAL_JEWISH, 2, 5772));
+var_dump(cal_days_in_month(CAL_JEWISH, 3, 5772));
+var_dump(cal_days_in_month(CAL_JEWISH, 4, 5772));
+var_dump(cal_days_in_month(CAL_JEWISH, 5, 5772));
+var_dump(cal_days_in_month(CAL_JEWISH, 6, 5772));
+var_dump(cal_days_in_month(CAL_JEWISH, 7, 5772));
+var_dump(cal_days_in_month(CAL_JEWISH, 8, 5772));
+var_dump(cal_days_in_month(CAL_JEWISH, 9, 5772));
+var_dump(cal_days_in_month(CAL_JEWISH, 10, 5772));
+var_dump(cal_days_in_month(CAL_JEWISH, 11, 5772));
+var_dump(cal_days_in_month(CAL_JEWISH, 12, 5772));
+var_dump(cal_days_in_month(CAL_JEWISH, 13, 5772));
+--EXPECT--
+int(30)
+int(30)
+int(30)
+int(29)
+int(30)
+int(30)
+int(29)
+int(30)
+int(29)
+int(30)
+int(29)
+int(30)
+int(29)
+int(30)
+int(29)
+int(30)
+int(29)
+int(30)
+int(0)
+int(29)
+int(30)
+int(29)
+int(30)
+int(29)
+int(30)
+int(29)
diff --git a/ext/calendar/tests/cal_info.phpt b/ext/calendar/tests/cal_info.phpt
index 2e3e612925..7edb4ce67c 100644
--- a/ext/calendar/tests/cal_info.phpt
+++ b/ext/calendar/tests/cal_info.phpt
@@ -100,8 +100,8 @@ Array
[3] => Kislev
[4] => Tevet
[5] => Shevat
- [6] => AdarI
- [7] => AdarII
+ [6] => Adar I
+ [7] => Adar II
[8] => Nisan
[9] => Iyyar
[10] => Sivan
@@ -117,8 +117,8 @@ Array
[3] => Kislev
[4] => Tevet
[5] => Shevat
- [6] => AdarI
- [7] => AdarII
+ [6] => Adar I
+ [7] => Adar II
[8] => Nisan
[9] => Iyyar
[10] => Sivan
diff --git a/ext/calendar/tests/jdmonthname.phpt b/ext/calendar/tests/jdmonthname.phpt
index d05d3c595e..07ed1161b1 100644
--- a/ext/calendar/tests/jdmonthname.phpt
+++ b/ext/calendar/tests/jdmonthname.phpt
@@ -75,8 +75,8 @@ December
--- mode 4 ---
Tevet
Shevat
-AdarI
-AdarII
+Adar I
+Adar II
Nisan
Iyyar
Sivan
@@ -178,7 +178,7 @@ Heshvan
Kislev
Tevet
Shevat
-AdarI
+Adar
Nisan
Iyyar
Sivan
@@ -279,7 +279,7 @@ Heshvan
Kislev
Tevet
Shevat
-AdarI
+Adar
Nisan
Iyyar
Sivan
diff --git a/ext/calendar/tests/jdtojewish.phpt b/ext/calendar/tests/jdtojewish.phpt
index 484b95749c..bc0ecbdd88 100644
--- a/ext/calendar/tests/jdtojewish.phpt
+++ b/ext/calendar/tests/jdtojewish.phpt
@@ -14,10 +14,11 @@ var_dump(jdtojewish(gregoriantojd(10,28,2002))."\r\n".
jdtojewish(gregoriantojd(10,8,2002),true, CAL_JEWISH_ADD_GERESHAYIM)."\r\n".
jdtojewish(gregoriantojd(10,8,2002),true, CAL_JEWISH_ADD_GERESHAYIM+CAL_JEWISH_ADD_ALAFIM_GERESH)."\r\n".
jdtojewish(gregoriantojd(10,8,2002),true, CAL_JEWISH_ADD_GERESHAYIM+CAL_JEWISH_ADD_ALAFIM)."\r\n".
- jdtojewish(gregoriantojd(10,8,2002),true, CAL_JEWISH_ADD_GERESHAYIM+CAL_JEWISH_ADD_ALAFIM+CAL_JEWISH_ADD_ALAFIM_GERESH)."\r\n");
+ jdtojewish(gregoriantojd(10,8,2002),true, CAL_JEWISH_ADD_GERESHAYIM+CAL_JEWISH_ADD_ALAFIM+CAL_JEWISH_ADD_ALAFIM_GERESH)."\r\n".
+ jdtojewish(gregoriantojd(3,10,2007))."\r\n");
?>
---EXPECT--
-string(184) "2/22/5763
+--EXPECTF--
+string(%d) "2/22/5763
'
@@ -27,4 +28,5 @@ string(184) "2/22/5763
' '"
' "
' ' "
+7/20/5767
"
diff --git a/ext/com_dotnet/com_iterator.c b/ext/com_dotnet/com_iterator.c
index 2f8ba5eb44..d6f22efcdf 100644
--- a/ext/com_dotnet/com_iterator.c
+++ b/ext/com_dotnet/com_iterator.c
@@ -74,16 +74,15 @@ static void com_iter_get_data(zend_object_iterator *iter, zval ***data TSRMLS_DC
*data = &I->zdata;
}
-static int com_iter_get_key(zend_object_iterator *iter, char **str_key, uint *str_key_len,
- ulong *int_key TSRMLS_DC)
+static void com_iter_get_key(zend_object_iterator *iter, zval *key TSRMLS_DC)
{
struct php_com_iterator *I = (struct php_com_iterator*)iter->data;
if (I->key == (ulong)-1) {
- return HASH_KEY_NON_EXISTANT;
+ ZVAL_NULL(key);
+ } else {
+ ZVAL_LONG(key, I->key);
}
- *int_key = I->key;
- return HASH_KEY_IS_LONG;
}
static int com_iter_move_forwards(zend_object_iterator *iter TSRMLS_DC)
diff --git a/ext/com_dotnet/com_saproxy.c b/ext/com_dotnet/com_saproxy.c
index b19c516444..0d557e60ee 100644
--- a/ext/com_dotnet/com_saproxy.c
+++ b/ext/com_dotnet/com_saproxy.c
@@ -519,16 +519,15 @@ static void saproxy_iter_get_data(zend_object_iterator *iter, zval ***data TSRML
*data = ptr_ptr;
}
-static int saproxy_iter_get_key(zend_object_iterator *iter, char **str_key, uint *str_key_len,
- ulong *int_key TSRMLS_DC)
+static void saproxy_iter_get_key(zend_object_iterator *iter, zval *key TSRMLS_DC)
{
php_com_saproxy_iter *I = (php_com_saproxy_iter*)iter->data;
if (I->key == -1) {
- return HASH_KEY_NON_EXISTANT;
+ ZVAL_NULL(key);
+ } else {
+ ZVAL_LONG(key, I->key);
}
- *int_key = (ulong)I->key;
- return HASH_KEY_IS_LONG;
}
static int saproxy_iter_move_forwards(zend_object_iterator *iter TSRMLS_DC)
diff --git a/ext/com_dotnet/com_variant.c b/ext/com_dotnet/com_variant.c
index af80f00528..4e044b20b8 100644
--- a/ext/com_dotnet/com_variant.c
+++ b/ext/com_dotnet/com_variant.c
@@ -53,7 +53,7 @@ static void safe_array_from_zval(VARIANT *v, zval *z, int codepage TSRMLS_DC)
if (HASH_KEY_IS_STRING == keytype) {
goto bogus;
- } else if (HASH_KEY_NON_EXISTANT == keytype) {
+ } else if (HASH_KEY_NON_EXISTENT == keytype) {
break;
}
if (intindex > max_index) {
diff --git a/ext/com_dotnet/com_wrapper.c b/ext/com_dotnet/com_wrapper.c
index 363bb70561..54b6fb9ae7 100644
--- a/ext/com_dotnet/com_wrapper.c
+++ b/ext/com_dotnet/com_wrapper.c
@@ -467,7 +467,7 @@ static void generate_dispids(php_dispatchex *disp TSRMLS_DC)
/* properties */
if (Z_OBJPROP_P(disp->object)) {
zend_hash_internal_pointer_reset_ex(Z_OBJPROP_P(disp->object), &pos);
- while (HASH_KEY_NON_EXISTANT != (keytype =
+ while (HASH_KEY_NON_EXISTENT != (keytype =
zend_hash_get_current_key_ex(Z_OBJPROP_P(disp->object), &name,
&namelen, &pid, 0, &pos))) {
char namebuf[32];
@@ -498,7 +498,7 @@ static void generate_dispids(php_dispatchex *disp TSRMLS_DC)
/* functions */
if (Z_OBJCE_P(disp->object)) {
zend_hash_internal_pointer_reset_ex(&Z_OBJCE_P(disp->object)->function_table, &pos);
- while (HASH_KEY_NON_EXISTANT != (keytype =
+ while (HASH_KEY_NON_EXISTENT != (keytype =
zend_hash_get_current_key_ex(&Z_OBJCE_P(disp->object)->function_table,
&name, &namelen, &pid, 0, &pos))) {
@@ -598,7 +598,7 @@ PHP_COM_DOTNET_API IDispatch *php_com_wrapper_export_as_sink(zval *val, GUID *si
zend_hash_init(disp->name_to_dispid, 0, NULL, ZVAL_PTR_DTOR, 0);
zend_hash_internal_pointer_reset_ex(id_to_name, &pos);
- while (HASH_KEY_NON_EXISTANT != (keytype =
+ while (HASH_KEY_NON_EXISTENT != (keytype =
zend_hash_get_current_key_ex(id_to_name, &name, &namelen, &pid, 0, &pos))) {
if (keytype == HASH_KEY_IS_LONG) {
diff --git a/ext/curl/config.m4 b/ext/curl/config.m4
index fbb4f5b4e5..2f82c3485d 100644
--- a/ext/curl/config.m4
+++ b/ext/curl/config.m4
@@ -3,11 +3,7 @@ dnl $Id$
dnl
PHP_ARG_WITH(curl, for cURL support,
-[ --with-curl[=DIR] Include cURL support])
-
-dnl Temporary option while we develop this aspect of the extension
-PHP_ARG_WITH(curlwrappers, if we should use cURL for url streams,
-[ --with-curlwrappers EXPERIMENTAL: Use cURL for url streams], no, no)
+[ --with-curl[=DIR] Include cURL support])
if test "$PHP_CURL" != "no"; then
if test -r $PHP_CURL/include/curl/easy.h; then
@@ -131,13 +127,6 @@ int main(int argc, char *argv[])
$CURL_LIBS -L$CURL_DIR/$PHP_LIBDIR
])
- PHP_CHECK_LIBRARY(curl,curl_version_info,
- [
- AC_DEFINE(HAVE_CURL_VERSION_INFO,1,[ ])
- ],[],[
- $CURL_LIBS -L$CURL_DIR/$PHP_LIBDIR
- ])
-
PHP_CHECK_LIBRARY(curl,curl_easy_strerror,
[
AC_DEFINE(HAVE_CURL_EASY_STRERROR,1,[ ])
@@ -152,10 +141,6 @@ int main(int argc, char *argv[])
$CURL_LIBS -L$CURL_DIR/$PHP_LIBDIR
])
- if test "$PHP_CURLWRAPPERS" != "no" ; then
- AC_DEFINE(PHP_CURL_URL_WRAPPERS,1,[ ])
- fi
-
- PHP_NEW_EXTENSION(curl, interface.c multi.c streams.c, $ext_shared)
+ PHP_NEW_EXTENSION(curl, interface.c multi.c share.c curl_file.c, $ext_shared)
PHP_SUBST(CURL_SHARED_LIBADD)
fi
diff --git a/ext/curl/config.w32 b/ext/curl/config.w32
index 930adcfd41..965721318e 100644
--- a/ext/curl/config.w32
+++ b/ext/curl/config.w32
@@ -13,15 +13,13 @@ if (PHP_CURL != "no") {
&& (((PHP_ZLIB=="no") && (CHECK_LIB("zlib_a.lib;zlib.lib", "curl", PHP_CURL))) ||
(PHP_ZLIB_SHARED && CHECK_LIB("zlib.lib", "curl", PHP_CURL)) || (PHP_ZLIB == "yes" && (!PHP_ZLIB_SHARED)))
) {
- EXTENSION("curl", "interface.c multi.c streams.c", true);
+ EXTENSION("curl", "interface.c multi.c share.c curl_file.c", true);
AC_DEFINE('HAVE_CURL', 1, 'Have cURL library');
AC_DEFINE('HAVE_CURL_SSL', 1, 'Have SSL suppurt in cURL');
AC_DEFINE('HAVE_CURL_EASY_STRERROR', 1, 'Have curl_easy_strerror in cURL');
AC_DEFINE('HAVE_CURL_MULTI_STRERROR', 1, 'Have curl_multi_strerror in cURL');
- AC_DEFINE('HAVE_CURL_VERSION_INFO', 1, 'Have curl_version_info in cURL');
ADD_FLAG("CFLAGS_CURL", "/D CURL_STATICLIB");
// TODO: check for curl_version_info
- // AC_DEFINE('PHP_CURL_URL_WRAPPERS', 0, 'Use curl for URL wrappers [experimental]');
} else {
WARNING("curl not enabled; libraries and headers not found");
}
diff --git a/ext/curl/curl.dsp b/ext/curl/curl.dsp
index 81d823183d..6524fceb89 100644
--- a/ext/curl/curl.dsp
+++ b/ext/curl/curl.dsp
@@ -166,6 +166,10 @@ SOURCE=.\multi.c
# End Source File
# Begin Source File
+SOURCE=.\share.c
+# End Source File
+
+# Begin Source File
SOURCE=.\streams.c
# End Source File
diff --git a/ext/curl/curl_file.c b/ext/curl/curl_file.c
new file mode 100644
index 0000000000..9f371df538
--- /dev/null
+++ b/ext/curl/curl_file.c
@@ -0,0 +1,177 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2014 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: Stanislav Malyshev <stas@php.net> |
+ +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "php.h"
+#include "Zend/zend_exceptions.h"
+#include "php_curl.h"
+#if HAVE_CURL
+
+PHP_CURL_API zend_class_entry *curl_CURLFile_class;
+
+static void curlfile_ctor(INTERNAL_FUNCTION_PARAMETERS)
+{
+ char *fname = NULL, *mime = NULL, *postname = NULL;
+ int fname_len, mime_len, postname_len;
+ zval *cf = return_value;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ss", &fname, &fname_len, &mime, &mime_len, &postname, &postname_len) == FAILURE) {
+ return;
+ }
+
+ if (fname) {
+ zend_update_property_string(curl_CURLFile_class, cf, "name", sizeof("name")-1, fname TSRMLS_CC);
+ }
+
+ if (mime) {
+ zend_update_property_string(curl_CURLFile_class, cf, "mime", sizeof("mime")-1, mime TSRMLS_CC);
+ }
+
+ if (postname) {
+ zend_update_property_string(curl_CURLFile_class, cf, "postname", sizeof("postname")-1, postname TSRMLS_CC);
+ }
+}
+
+/* {{{ proto void CURLFile::__construct(string $name, [string $mimetype [, string $postfilename]])
+ Create the CURLFile object */
+ZEND_METHOD(CURLFile, __construct)
+{
+ return_value = getThis();
+ curlfile_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+/* }}} */
+
+/* {{{ proto CURLFile curl_file_create(string $name, [string $mimetype [, string $postfilename]])
+ Create the CURLFile object */
+PHP_FUNCTION(curl_file_create)
+{
+ object_init_ex( return_value, curl_CURLFile_class );
+ curlfile_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+/* }}} */
+
+static void curlfile_get_property(char *name, INTERNAL_FUNCTION_PARAMETERS)
+{
+ zval *res;
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+ res = zend_read_property(curl_CURLFile_class, getThis(), name, strlen(name), 1 TSRMLS_CC);
+ *return_value = *res;
+ zval_copy_ctor(return_value);
+ INIT_PZVAL(return_value);
+}
+
+static void curlfile_set_property(char *name, INTERNAL_FUNCTION_PARAMETERS)
+{
+ char *arg = NULL;
+ int arg_len;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
+ return;
+ }
+ zend_update_property_string(curl_CURLFile_class, getThis(), name, strlen(name), arg TSRMLS_CC);
+}
+
+/* {{{ proto string CURLFile::getFilename()
+ Get file name */
+ZEND_METHOD(CURLFile, getFilename)
+{
+ curlfile_get_property("name", INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+/* }}} */
+
+/* {{{ proto string CURLFile::getMimeType()
+ Get MIME type */
+ZEND_METHOD(CURLFile, getMimeType)
+{
+ curlfile_get_property("mime", INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+/* }}} */
+
+/* {{{ proto string CURLFile::getPostFilename()
+ Get file name for POST */
+ZEND_METHOD(CURLFile, getPostFilename)
+{
+ curlfile_get_property("postname", INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+/* }}} */
+
+/* {{{ proto void CURLFile::setMimeType(string $mime)
+ Set MIME type */
+ZEND_METHOD(CURLFile, setMimeType)
+{
+ curlfile_set_property("mime", INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+/* }}} */
+
+/* {{{ proto void CURLFile::setPostFilename(string $name)
+ Set file name for POST */
+ZEND_METHOD(CURLFile, setPostFilename)
+{
+ curlfile_set_property("postname", INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+/* }}} */
+
+/* {{{ proto void CURLFile::__wakeup()
+ Unserialization handler */
+ZEND_METHOD(CURLFile, __wakeup)
+{
+ zend_update_property_string(curl_CURLFile_class, getThis(), "name", sizeof("name")-1, "" TSRMLS_CC);
+ zend_throw_exception(NULL, "Unserialization of CURLFile instances is not allowed", 0 TSRMLS_CC);
+}
+/* }}} */
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_curlfile_create, 0, 0, 1)
+ ZEND_ARG_INFO(0, filename)
+ ZEND_ARG_INFO(0, mimetype)
+ ZEND_ARG_INFO(0, postname)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_curlfile_name, 0)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+
+static const zend_function_entry curlfile_funcs[] = {
+ PHP_ME(CURLFile, __construct, arginfo_curlfile_create, ZEND_ACC_CTOR|ZEND_ACC_PUBLIC)
+ PHP_ME(CURLFile, getFilename, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(CURLFile, getMimeType, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(CURLFile, setMimeType, arginfo_curlfile_name, ZEND_ACC_PUBLIC)
+ PHP_ME(CURLFile, getPostFilename, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(CURLFile, setPostFilename, arginfo_curlfile_name, ZEND_ACC_PUBLIC)
+ PHP_ME(CURLFile, __wakeup, NULL, ZEND_ACC_PUBLIC)
+ PHP_FE_END
+};
+
+void curlfile_register_class(TSRMLS_D)
+{
+ zend_class_entry ce;
+ INIT_CLASS_ENTRY( ce, "CURLFile", curlfile_funcs );
+ curl_CURLFile_class = zend_register_internal_class(&ce TSRMLS_CC);
+ zend_declare_property_string(curl_CURLFile_class, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
+ zend_declare_property_string(curl_CURLFile_class, "mime", sizeof("mime")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
+ zend_declare_property_string(curl_CURLFile_class, "postname", sizeof("postname")-1, "", ZEND_ACC_PUBLIC TSRMLS_CC);
+}
+
+#endif
diff --git a/ext/curl/interface.c b/ext/curl/interface.c
index 8915625047..5f7783e669 100644
--- a/ext/curl/interface.c
+++ b/ext/curl/interface.c
@@ -90,6 +90,7 @@
int le_curl;
int le_curl_multi_handle;
+int le_curl_share_handle;
#ifdef PHP_CURL_NEED_OPENSSL_TSL /* {{{ */
static MUTEX_T *php_curl_openssl_tsl = NULL;
@@ -261,7 +262,6 @@ int _php_curl_verify_handlers(php_curl *ch, int reporterror TSRMLS_DC) /* {{{ */
ch->handlers->write->stream = NULL;
ch->handlers->write->method = PHP_CURL_STDOUT;
- ch->handlers->write->type = PHP_CURL_ASCII;
curl_easy_setopt(ch->cp, CURLOPT_FILE, (void *) ch);
}
}
@@ -314,6 +314,30 @@ ZEND_BEGIN_ARG_INFO(arginfo_curl_close, 0)
ZEND_ARG_INFO(0, ch)
ZEND_END_ARG_INFO()
+#if LIBCURL_VERSION_NUM >= 0x070c01 /* 7.12.1 */
+ZEND_BEGIN_ARG_INFO(arginfo_curl_reset, 0)
+ ZEND_ARG_INFO(0, ch)
+ZEND_END_ARG_INFO()
+#endif
+
+#if LIBCURL_VERSION_NUM > 0x070f03 /* 7.15.4 */
+ZEND_BEGIN_ARG_INFO(arginfo_curl_escape, 0)
+ ZEND_ARG_INFO(0, ch)
+ ZEND_ARG_INFO(0, str)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_curl_unescape, 0)
+ ZEND_ARG_INFO(0, ch)
+ ZEND_ARG_INFO(0, str)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_curl_multi_setopt, 0)
+ ZEND_ARG_INFO(0, sh)
+ ZEND_ARG_INFO(0, option)
+ ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO()
+#endif
+
ZEND_BEGIN_ARG_INFO(arginfo_curl_multi_init, 0)
ZEND_END_ARG_INFO()
@@ -349,6 +373,42 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_curl_multi_close, 0)
ZEND_ARG_INFO(0, mh)
ZEND_END_ARG_INFO()
+
+#if LIBCURL_VERSION_NUM >= 0x070c00 /* Available since 7.12.0 */
+ZEND_BEGIN_ARG_INFO(arginfo_curl_strerror, 0)
+ ZEND_ARG_INFO(0, errornum)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_curl_multi_strerror, 0)
+ ZEND_ARG_INFO(0, errornum)
+ZEND_END_ARG_INFO()
+#endif
+
+ZEND_BEGIN_ARG_INFO(arginfo_curl_share_init, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_curl_share_close, 0)
+ ZEND_ARG_INFO(0, sh)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_curl_share_setopt, 0)
+ ZEND_ARG_INFO(0, sh)
+ ZEND_ARG_INFO(0, option)
+ ZEND_ARG_INFO(0, value)
+ZEND_END_ARG_INFO()
+
+#if LIBCURL_VERSION_NUM >= 0x071200 /* Available since 7.18.0 */
+ZEND_BEGIN_ARG_INFO(arginfo_curl_pause, 0)
+ ZEND_ARG_INFO(0, ch)
+ ZEND_ARG_INFO(0, bitmask)
+ZEND_END_ARG_INFO()
+#endif
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_curlfile_create, 0, 0, 1)
+ ZEND_ARG_INFO(0, filename)
+ ZEND_ARG_INFO(0, mimetype)
+ ZEND_ARG_INFO(0, postname)
+ZEND_END_ARG_INFO()
/* }}} */
/* {{{ curl_functions[]
@@ -364,6 +424,20 @@ const zend_function_entry curl_functions[] = {
PHP_FE(curl_error, arginfo_curl_error)
PHP_FE(curl_errno, arginfo_curl_errno)
PHP_FE(curl_close, arginfo_curl_close)
+#if LIBCURL_VERSION_NUM >= 0x070c00 /* 7.12.0 */
+ PHP_FE(curl_strerror, arginfo_curl_strerror)
+ PHP_FE(curl_multi_strerror, arginfo_curl_multi_strerror)
+#endif
+#if LIBCURL_VERSION_NUM >= 0x070c01 /* 7.12.1 */
+ PHP_FE(curl_reset, arginfo_curl_reset)
+#endif
+#if LIBCURL_VERSION_NUM >= 0x070f04 /* 7.15.4 */
+ PHP_FE(curl_escape, arginfo_curl_escape)
+ PHP_FE(curl_unescape, arginfo_curl_unescape)
+#endif
+#if LIBCURL_VERSION_NUM >= 0x071200 /* 7.18.0 */
+ PHP_FE(curl_pause, arginfo_curl_pause)
+#endif
PHP_FE(curl_multi_init, arginfo_curl_multi_init)
PHP_FE(curl_multi_add_handle, arginfo_curl_multi_add_handle)
PHP_FE(curl_multi_remove_handle, arginfo_curl_multi_remove_handle)
@@ -372,6 +446,13 @@ const zend_function_entry curl_functions[] = {
PHP_FE(curl_multi_getcontent, arginfo_curl_multi_getcontent)
PHP_FE(curl_multi_info_read, arginfo_curl_multi_info_read)
PHP_FE(curl_multi_close, arginfo_curl_multi_close)
+#if LIBCURL_VERSION_NUM >= 0x070f04 /* 7.15.4 */
+ PHP_FE(curl_multi_setopt, arginfo_curl_multi_setopt)
+#endif
+ PHP_FE(curl_share_init, arginfo_curl_share_init)
+ PHP_FE(curl_share_close, arginfo_curl_share_close)
+ PHP_FE(curl_share_setopt, arginfo_curl_share_setopt)
+ PHP_FE(curl_file_create, arginfo_curlfile_create)
PHP_FE_END
};
/* }}} */
@@ -428,42 +509,40 @@ PHP_MINFO_FUNCTION(curl)
unsigned int i;
static const struct feat feats[] = {
-#if LIBCURL_VERSION_NUM > 0x070a06 /* 7.10.7 */
+#if LIBCURL_VERSION_NUM >= 0x070a07 /* 7.10.7 */
{"AsynchDNS", CURL_VERSION_ASYNCHDNS},
#endif
-#if LIBCURL_VERSION_NUM > 0x070a05 /* 7.10.6 */
+#if LIBCURL_VERSION_NUM >= 0x070f04 /* 7.15.4 */
+ {"CharConv", CURL_VERSION_CONV},
+#endif
+#if LIBCURL_VERSION_NUM >= 0x070a06 /* 7.10.6 */
{"Debug", CURL_VERSION_DEBUG},
{"GSS-Negotiate", CURL_VERSION_GSSNEGOTIATE},
#endif
-#if LIBCURL_VERSION_NUM > 0x070b02 /* 7.12.0 */
+#if LIBCURL_VERSION_NUM >= 0x070c00 /* 7.12.0 */
{"IDN", CURL_VERSION_IDN},
#endif
-#ifdef CURL_VERSION_IPV6
{"IPv6", CURL_VERSION_IPV6},
-#endif
-#if LIBCURL_VERSION_NUM > 0x070b00 /* 7.11.1 */
+ {"krb4", CURL_VERSION_KERBEROS4},
+#if LIBCURL_VERSION_NUM >= 0x070b01 /* 7.11.1 */
{"Largefile", CURL_VERSION_LARGEFILE},
#endif
-#if LIBCURL_VERSION_NUM > 0x070a05 /* 7.10.6 */
+ {"libz", CURL_VERSION_LIBZ},
+#if LIBCURL_VERSION_NUM >= 0x070a06 /* 7.10.6 */
{"NTLM", CURL_VERSION_NTLM},
#endif
-#if LIBCURL_VERSION_NUM > 0x070a07 /* 7.10.8 */
+#if LIBCURL_VERSION_NUM >= 0x071600 /* 7.22.0 */
+ {"NTLMWB", CURL_VERSION_NTLM_WB},
+#endif
+#if LIBCURL_VERSION_NUM >= 0x070a08 /* 7.10.8 */
{"SPNEGO", CURL_VERSION_SPNEGO},
#endif
-#ifdef CURL_VERSION_SSL
{"SSL", CURL_VERSION_SSL},
-#endif
-#if LIBCURL_VERSION_NUM > 0x070d01 /* 7.13.2 */
+#if LIBCURL_VERSION_NUM >= 0x070d02 /* 7.13.2 */
{"SSPI", CURL_VERSION_SSPI},
#endif
-#ifdef CURL_VERSION_KERBEROS4
- {"krb4", CURL_VERSION_KERBEROS4},
-#endif
-#ifdef CURL_VERSION_LIBZ
- {"libz", CURL_VERSION_LIBZ},
-#endif
-#if LIBCURL_VERSION_NUM > 0x070f03 /* 7.15.4 */
- {"CharConv", CURL_VERSION_CONV},
+#if LIBCURL_VERSION_NUM >= 0x071504 /* 7.21.4 */
+ {"TLS-SRP", CURL_VERSION_TLSAUTH_SRP},
#endif
{NULL, 0}
};
@@ -528,6 +607,7 @@ PHP_MINIT_FUNCTION(curl)
{
le_curl = zend_register_list_destructors_ex(_php_curl_close, NULL, "curl", module_number);
le_curl_multi_handle = zend_register_list_destructors_ex(_php_curl_multi_close, NULL, "curl_multi", module_number);
+ le_curl_share_handle = zend_register_list_destructors_ex(_php_curl_share_close, NULL, "curl_share", module_number);
REGISTER_INI_ENTRIES();
@@ -536,358 +616,586 @@ PHP_MINIT_FUNCTION(curl)
of options and which version they were introduced */
/* Constants for curl_setopt() */
-#if LIBCURL_VERSION_NUM > 0x070a07 /* CURLOPT_IPRESOLVE is available since curl 7.10.8 */
- REGISTER_CURL_CONSTANT(CURLOPT_IPRESOLVE);
- REGISTER_CURL_CONSTANT(CURL_IPRESOLVE_WHATEVER);
- REGISTER_CURL_CONSTANT(CURL_IPRESOLVE_V4);
- REGISTER_CURL_CONSTANT(CURL_IPRESOLVE_V6);
-#endif
- REGISTER_CURL_CONSTANT(CURLOPT_DNS_USE_GLOBAL_CACHE);
+ REGISTER_CURL_CONSTANT(CURLOPT_AUTOREFERER);
+ REGISTER_CURL_CONSTANT(CURLOPT_BINARYTRANSFER);
+ REGISTER_CURL_CONSTANT(CURLOPT_BUFFERSIZE);
+ REGISTER_CURL_CONSTANT(CURLOPT_CAINFO);
+ REGISTER_CURL_CONSTANT(CURLOPT_CAPATH);
+ REGISTER_CURL_CONSTANT(CURLOPT_CLOSEPOLICY);
+ REGISTER_CURL_CONSTANT(CURLOPT_CONNECTTIMEOUT);
+ REGISTER_CURL_CONSTANT(CURLOPT_COOKIE);
+ REGISTER_CURL_CONSTANT(CURLOPT_COOKIEFILE);
+ REGISTER_CURL_CONSTANT(CURLOPT_COOKIEJAR);
+ REGISTER_CURL_CONSTANT(CURLOPT_COOKIESESSION);
+ REGISTER_CURL_CONSTANT(CURLOPT_CRLF);
+ REGISTER_CURL_CONSTANT(CURLOPT_CUSTOMREQUEST);
REGISTER_CURL_CONSTANT(CURLOPT_DNS_CACHE_TIMEOUT);
- REGISTER_CURL_CONSTANT(CURLOPT_PORT);
+ REGISTER_CURL_CONSTANT(CURLOPT_DNS_USE_GLOBAL_CACHE);
+ REGISTER_CURL_CONSTANT(CURLOPT_EGDSOCKET);
+ REGISTER_CURL_CONSTANT(CURLOPT_ENCODING);
+ REGISTER_CURL_CONSTANT(CURLOPT_FAILONERROR);
REGISTER_CURL_CONSTANT(CURLOPT_FILE);
- REGISTER_CURL_CONSTANT(CURLOPT_READDATA);
- REGISTER_CURL_CONSTANT(CURLOPT_INFILE);
- REGISTER_CURL_CONSTANT(CURLOPT_INFILESIZE);
- REGISTER_CURL_CONSTANT(CURLOPT_URL);
- REGISTER_CURL_CONSTANT(CURLOPT_PROXY);
- REGISTER_CURL_CONSTANT(CURLOPT_VERBOSE);
+ REGISTER_CURL_CONSTANT(CURLOPT_FILETIME);
+ REGISTER_CURL_CONSTANT(CURLOPT_FOLLOWLOCATION);
+ REGISTER_CURL_CONSTANT(CURLOPT_FORBID_REUSE);
+ REGISTER_CURL_CONSTANT(CURLOPT_FRESH_CONNECT);
+ REGISTER_CURL_CONSTANT(CURLOPT_FTPAPPEND);
+ REGISTER_CURL_CONSTANT(CURLOPT_FTPLISTONLY);
+ REGISTER_CURL_CONSTANT(CURLOPT_FTPPORT);
+ REGISTER_CURL_CONSTANT(CURLOPT_FTP_USE_EPRT);
+ REGISTER_CURL_CONSTANT(CURLOPT_FTP_USE_EPSV);
REGISTER_CURL_CONSTANT(CURLOPT_HEADER);
+ REGISTER_CURL_CONSTANT(CURLOPT_HEADERFUNCTION);
+ REGISTER_CURL_CONSTANT(CURLOPT_HTTP200ALIASES);
+ REGISTER_CURL_CONSTANT(CURLOPT_HTTPGET);
REGISTER_CURL_CONSTANT(CURLOPT_HTTPHEADER);
- REGISTER_CURL_CONSTANT(CURLOPT_NOPROGRESS);
- REGISTER_CURL_CONSTANT(CURLOPT_PROGRESSFUNCTION);
+ REGISTER_CURL_CONSTANT(CURLOPT_HTTPPROXYTUNNEL);
+ REGISTER_CURL_CONSTANT(CURLOPT_HTTP_VERSION);
+ REGISTER_CURL_CONSTANT(CURLOPT_INFILE);
+ REGISTER_CURL_CONSTANT(CURLOPT_INFILESIZE);
+ REGISTER_CURL_CONSTANT(CURLOPT_INTERFACE);
+ REGISTER_CURL_CONSTANT(CURLOPT_KRB4LEVEL);
+ REGISTER_CURL_CONSTANT(CURLOPT_LOW_SPEED_LIMIT);
+ REGISTER_CURL_CONSTANT(CURLOPT_LOW_SPEED_TIME);
+ REGISTER_CURL_CONSTANT(CURLOPT_MAXCONNECTS);
+ REGISTER_CURL_CONSTANT(CURLOPT_MAXREDIRS);
+ REGISTER_CURL_CONSTANT(CURLOPT_NETRC);
REGISTER_CURL_CONSTANT(CURLOPT_NOBODY);
- REGISTER_CURL_CONSTANT(CURLOPT_FAILONERROR);
- REGISTER_CURL_CONSTANT(CURLOPT_UPLOAD);
+ REGISTER_CURL_CONSTANT(CURLOPT_NOPROGRESS);
+ REGISTER_CURL_CONSTANT(CURLOPT_NOSIGNAL);
+ REGISTER_CURL_CONSTANT(CURLOPT_PORT);
REGISTER_CURL_CONSTANT(CURLOPT_POST);
- REGISTER_CURL_CONSTANT(CURLOPT_FTPLISTONLY);
- REGISTER_CURL_CONSTANT(CURLOPT_FTPAPPEND);
- REGISTER_CURL_CONSTANT(CURLOPT_NETRC);
- REGISTER_CURL_CONSTANT(CURLOPT_FOLLOWLOCATION);
-#if CURLOPT_FTPASCII != 0
- REGISTER_CURL_CONSTANT(CURLOPT_FTPASCII);
-#endif
- REGISTER_CURL_CONSTANT(CURLOPT_PUT);
-#if CURLOPT_MUTE != 0
- REGISTER_CURL_CONSTANT(CURLOPT_MUTE);
-#endif
- REGISTER_CURL_CONSTANT(CURLOPT_USERPWD);
+ REGISTER_CURL_CONSTANT(CURLOPT_POSTFIELDS);
+ REGISTER_CURL_CONSTANT(CURLOPT_POSTQUOTE);
+ REGISTER_CURL_CONSTANT(CURLOPT_PREQUOTE);
+ REGISTER_CURL_CONSTANT(CURLOPT_PRIVATE);
+ REGISTER_CURL_CONSTANT(CURLOPT_PROGRESSFUNCTION);
+ REGISTER_CURL_CONSTANT(CURLOPT_PROXY);
+ REGISTER_CURL_CONSTANT(CURLOPT_PROXYPORT);
+ REGISTER_CURL_CONSTANT(CURLOPT_PROXYTYPE);
REGISTER_CURL_CONSTANT(CURLOPT_PROXYUSERPWD);
+ REGISTER_CURL_CONSTANT(CURLOPT_PUT);
+ REGISTER_CURL_CONSTANT(CURLOPT_QUOTE);
+ REGISTER_CURL_CONSTANT(CURLOPT_RANDOM_FILE);
REGISTER_CURL_CONSTANT(CURLOPT_RANGE);
- REGISTER_CURL_CONSTANT(CURLOPT_TIMEOUT);
-#if LIBCURL_VERSION_NUM > 0x071002
- REGISTER_CURL_CONSTANT(CURLOPT_TIMEOUT_MS);
-#endif
- REGISTER_CURL_CONSTANT(CURLOPT_POSTFIELDS);
+ REGISTER_CURL_CONSTANT(CURLOPT_READDATA);
+ REGISTER_CURL_CONSTANT(CURLOPT_READFUNCTION);
REGISTER_CURL_CONSTANT(CURLOPT_REFERER);
- REGISTER_CURL_CONSTANT(CURLOPT_USERAGENT);
- REGISTER_CURL_CONSTANT(CURLOPT_FTPPORT);
- REGISTER_CURL_CONSTANT(CURLOPT_FTP_USE_EPSV);
- REGISTER_CURL_CONSTANT(CURLOPT_LOW_SPEED_LIMIT);
- REGISTER_CURL_CONSTANT(CURLOPT_LOW_SPEED_TIME);
REGISTER_CURL_CONSTANT(CURLOPT_RESUME_FROM);
- REGISTER_CURL_CONSTANT(CURLOPT_COOKIE);
- REGISTER_CURL_CONSTANT(CURLOPT_COOKIESESSION);
- REGISTER_CURL_CONSTANT(CURLOPT_AUTOREFERER);
+ REGISTER_CURL_CONSTANT(CURLOPT_RETURNTRANSFER);
+ REGISTER_CURL_CONSTANT(CURLOPT_SHARE);
REGISTER_CURL_CONSTANT(CURLOPT_SSLCERT);
REGISTER_CURL_CONSTANT(CURLOPT_SSLCERTPASSWD);
- REGISTER_CURL_CONSTANT(CURLOPT_WRITEHEADER);
- REGISTER_CURL_CONSTANT(CURLOPT_SSL_VERIFYHOST);
- REGISTER_CURL_CONSTANT(CURLOPT_COOKIEFILE);
+ REGISTER_CURL_CONSTANT(CURLOPT_SSLCERTTYPE);
+ REGISTER_CURL_CONSTANT(CURLOPT_SSLENGINE);
+ REGISTER_CURL_CONSTANT(CURLOPT_SSLENGINE_DEFAULT);
+ REGISTER_CURL_CONSTANT(CURLOPT_SSLKEY);
+ REGISTER_CURL_CONSTANT(CURLOPT_SSLKEYPASSWD);
+ REGISTER_CURL_CONSTANT(CURLOPT_SSLKEYTYPE);
REGISTER_CURL_CONSTANT(CURLOPT_SSLVERSION);
+ REGISTER_CURL_CONSTANT(CURLOPT_SSL_CIPHER_LIST);
+ REGISTER_CURL_CONSTANT(CURLOPT_SSL_VERIFYHOST);
+ REGISTER_CURL_CONSTANT(CURLOPT_SSL_VERIFYPEER);
+ REGISTER_CURL_CONSTANT(CURLOPT_STDERR);
+ REGISTER_CURL_CONSTANT(CURLOPT_TELNETOPTIONS);
REGISTER_CURL_CONSTANT(CURLOPT_TIMECONDITION);
+ REGISTER_CURL_CONSTANT(CURLOPT_TIMEOUT);
REGISTER_CURL_CONSTANT(CURLOPT_TIMEVALUE);
- REGISTER_CURL_CONSTANT(CURLOPT_CUSTOMREQUEST);
- REGISTER_CURL_CONSTANT(CURLOPT_STDERR);
REGISTER_CURL_CONSTANT(CURLOPT_TRANSFERTEXT);
- REGISTER_CURL_CONSTANT(CURLOPT_RETURNTRANSFER);
- REGISTER_CURL_CONSTANT(CURLOPT_QUOTE);
- REGISTER_CURL_CONSTANT(CURLOPT_POSTQUOTE);
- REGISTER_CURL_CONSTANT(CURLOPT_INTERFACE);
- REGISTER_CURL_CONSTANT(CURLOPT_KRB4LEVEL);
- REGISTER_CURL_CONSTANT(CURLOPT_HTTPPROXYTUNNEL);
- REGISTER_CURL_CONSTANT(CURLOPT_FILETIME);
- REGISTER_CURL_CONSTANT(CURLOPT_WRITEFUNCTION);
- REGISTER_CURL_CONSTANT(CURLOPT_READFUNCTION);
-#if CURLOPT_PASSWDFUNCTION != 0
- REGISTER_CURL_CONSTANT(CURLOPT_PASSWDFUNCTION);
-#endif
- REGISTER_CURL_CONSTANT(CURLOPT_HEADERFUNCTION);
- REGISTER_CURL_CONSTANT(CURLOPT_MAXREDIRS);
- REGISTER_CURL_CONSTANT(CURLOPT_MAXCONNECTS);
- REGISTER_CURL_CONSTANT(CURLOPT_CLOSEPOLICY);
- REGISTER_CURL_CONSTANT(CURLOPT_FRESH_CONNECT);
- REGISTER_CURL_CONSTANT(CURLOPT_FORBID_REUSE);
- REGISTER_CURL_CONSTANT(CURLOPT_RANDOM_FILE);
- REGISTER_CURL_CONSTANT(CURLOPT_EGDSOCKET);
- REGISTER_CURL_CONSTANT(CURLOPT_CONNECTTIMEOUT);
-#if LIBCURL_VERSION_NUM > 0x071002
- REGISTER_CURL_CONSTANT(CURLOPT_CONNECTTIMEOUT_MS);
-#endif
- REGISTER_CURL_CONSTANT(CURLOPT_SSL_VERIFYPEER);
- REGISTER_CURL_CONSTANT(CURLOPT_CAINFO);
- REGISTER_CURL_CONSTANT(CURLOPT_CAPATH);
- REGISTER_CURL_CONSTANT(CURLOPT_COOKIEJAR);
- REGISTER_CURL_CONSTANT(CURLOPT_SSL_CIPHER_LIST);
- REGISTER_CURL_CONSTANT(CURLOPT_BINARYTRANSFER);
- REGISTER_CURL_CONSTANT(CURLOPT_NOSIGNAL);
- REGISTER_CURL_CONSTANT(CURLOPT_PROXYTYPE);
- REGISTER_CURL_CONSTANT(CURLOPT_BUFFERSIZE);
- REGISTER_CURL_CONSTANT(CURLOPT_HTTPGET);
- REGISTER_CURL_CONSTANT(CURLOPT_HTTP_VERSION);
- REGISTER_CURL_CONSTANT(CURLOPT_SSLKEY);
- REGISTER_CURL_CONSTANT(CURLOPT_SSLKEYTYPE);
- REGISTER_CURL_CONSTANT(CURLOPT_SSLKEYPASSWD);
- REGISTER_CURL_CONSTANT(CURLOPT_SSLENGINE);
- REGISTER_CURL_CONSTANT(CURLOPT_SSLENGINE_DEFAULT);
- REGISTER_CURL_CONSTANT(CURLOPT_SSLCERTTYPE);
- REGISTER_CURL_CONSTANT(CURLOPT_CRLF);
- REGISTER_CURL_CONSTANT(CURLOPT_ENCODING);
- REGISTER_CURL_CONSTANT(CURLOPT_PROXYPORT);
REGISTER_CURL_CONSTANT(CURLOPT_UNRESTRICTED_AUTH);
- REGISTER_CURL_CONSTANT(CURLOPT_FTP_USE_EPRT);
-#if LIBCURL_VERSION_NUM > 0x070b01 /* CURLOPT_TCP_NODELAY is available since curl 7.11.2 */
- REGISTER_CURL_CONSTANT(CURLOPT_TCP_NODELAY);
-#endif
- REGISTER_CURL_CONSTANT(CURLOPT_HTTP200ALIASES);
- REGISTER_CURL_CONSTANT(CURL_TIMECOND_IFMODSINCE);
- REGISTER_CURL_CONSTANT(CURL_TIMECOND_IFUNMODSINCE);
- REGISTER_CURL_CONSTANT(CURL_TIMECOND_LASTMOD);
-
-#if LIBCURL_VERSION_NUM > 0x070f04 /* CURLOPT_MAX_RECV_SPEED_LARGE & CURLOPT_MAX_SEND_SPEED_LARGE are available since curl 7.15.5 */
- REGISTER_CURL_CONSTANT(CURLOPT_MAX_RECV_SPEED_LARGE);
- REGISTER_CURL_CONSTANT(CURLOPT_MAX_SEND_SPEED_LARGE);
-#endif
-
-#if LIBCURL_VERSION_NUM > 0x070a05 /* CURLOPT_HTTPAUTH is available since curl 7.10.6 */
- REGISTER_CURL_CONSTANT(CURLOPT_HTTPAUTH);
- /* http authentication options */
- REGISTER_CURL_CONSTANT(CURLAUTH_BASIC);
- REGISTER_CURL_CONSTANT(CURLAUTH_DIGEST);
- REGISTER_CURL_CONSTANT(CURLAUTH_GSSNEGOTIATE);
- REGISTER_CURL_CONSTANT(CURLAUTH_NTLM);
- REGISTER_CURL_CONSTANT(CURLAUTH_ANY);
- REGISTER_CURL_CONSTANT(CURLAUTH_ANYSAFE);
-#endif
-
-#if LIBCURL_VERSION_NUM > 0x070a06 /* CURLOPT_PROXYAUTH & CURLOPT_FTP_CREATE_MISSING_DIRS are available since curl 7.10.7 */
- REGISTER_CURL_CONSTANT(CURLOPT_PROXYAUTH);
- REGISTER_CURL_CONSTANT(CURLOPT_FTP_CREATE_MISSING_DIRS);
-#endif
-
- REGISTER_CURL_CONSTANT(CURLOPT_PRIVATE);
+ REGISTER_CURL_CONSTANT(CURLOPT_UPLOAD);
+ REGISTER_CURL_CONSTANT(CURLOPT_URL);
+ REGISTER_CURL_CONSTANT(CURLOPT_USERAGENT);
+ REGISTER_CURL_CONSTANT(CURLOPT_USERPWD);
+ REGISTER_CURL_CONSTANT(CURLOPT_VERBOSE);
+ REGISTER_CURL_CONSTANT(CURLOPT_WRITEFUNCTION);
+ REGISTER_CURL_CONSTANT(CURLOPT_WRITEHEADER);
/* Constants effecting the way CURLOPT_CLOSEPOLICY works */
+ REGISTER_CURL_CONSTANT(CURLCLOSEPOLICY_CALLBACK);
REGISTER_CURL_CONSTANT(CURLCLOSEPOLICY_LEAST_RECENTLY_USED);
REGISTER_CURL_CONSTANT(CURLCLOSEPOLICY_LEAST_TRAFFIC);
- REGISTER_CURL_CONSTANT(CURLCLOSEPOLICY_SLOWEST);
- REGISTER_CURL_CONSTANT(CURLCLOSEPOLICY_CALLBACK);
REGISTER_CURL_CONSTANT(CURLCLOSEPOLICY_OLDEST);
+ REGISTER_CURL_CONSTANT(CURLCLOSEPOLICY_SLOWEST);
- /* Info constants */
- REGISTER_CURL_CONSTANT(CURLINFO_EFFECTIVE_URL);
- REGISTER_CURL_CONSTANT(CURLINFO_HTTP_CODE);
- REGISTER_CURL_CONSTANT(CURLINFO_HEADER_SIZE);
- REGISTER_CURL_CONSTANT(CURLINFO_REQUEST_SIZE);
- REGISTER_CURL_CONSTANT(CURLINFO_TOTAL_TIME);
- REGISTER_CURL_CONSTANT(CURLINFO_NAMELOOKUP_TIME);
- REGISTER_CURL_CONSTANT(CURLINFO_CONNECT_TIME);
- REGISTER_CURL_CONSTANT(CURLINFO_PRETRANSFER_TIME);
- REGISTER_CURL_CONSTANT(CURLINFO_SIZE_UPLOAD);
- REGISTER_CURL_CONSTANT(CURLINFO_SIZE_DOWNLOAD);
- REGISTER_CURL_CONSTANT(CURLINFO_SPEED_DOWNLOAD);
- REGISTER_CURL_CONSTANT(CURLINFO_SPEED_UPLOAD);
- REGISTER_CURL_CONSTANT(CURLINFO_FILETIME);
- REGISTER_CURL_CONSTANT(CURLINFO_SSL_VERIFYRESULT);
- REGISTER_CURL_CONSTANT(CURLINFO_CONTENT_LENGTH_DOWNLOAD);
- REGISTER_CURL_CONSTANT(CURLINFO_CONTENT_LENGTH_UPLOAD);
- REGISTER_CURL_CONSTANT(CURLINFO_STARTTRANSFER_TIME);
- REGISTER_CURL_CONSTANT(CURLINFO_CONTENT_TYPE);
- REGISTER_CURL_CONSTANT(CURLINFO_REDIRECT_TIME);
- REGISTER_CURL_CONSTANT(CURLINFO_REDIRECT_COUNT);
- REGISTER_CURL_CONSTANT(CURLINFO_HEADER_OUT);
- REGISTER_CURL_CONSTANT(CURLINFO_PRIVATE);
-#if LIBCURL_VERSION_NUM > 0x071301
- REGISTER_CURL_CONSTANT(CURLINFO_CERTINFO);
-#endif
-#if LIBCURL_VERSION_NUM >= 0x071202
- REGISTER_CURL_CONSTANT(CURLINFO_REDIRECT_URL);
-#endif
-#if LIBCURL_VERSION_NUM >= 0x071300 /* 7.19.0 */
- REGISTER_CURL_CONSTANT(CURLINFO_PRIMARY_IP);
-#endif
-#if LIBCURL_VERSION_NUM >= 0x071500 /* 7.21.0 */
- REGISTER_CURL_CONSTANT(CURLINFO_PRIMARY_PORT);
- REGISTER_CURL_CONSTANT(CURLINFO_LOCAL_IP);
- REGISTER_CURL_CONSTANT(CURLINFO_LOCAL_PORT);
-#endif
-
-
- /* cURL protocol constants (curl_version) */
- REGISTER_CURL_CONSTANT(CURL_VERSION_IPV6);
- REGISTER_CURL_CONSTANT(CURL_VERSION_KERBEROS4);
- REGISTER_CURL_CONSTANT(CURL_VERSION_SSL);
- REGISTER_CURL_CONSTANT(CURL_VERSION_LIBZ);
-
- /* version constants */
- REGISTER_CURL_CONSTANT(CURLVERSION_NOW);
-
- /* Error Constants */
- REGISTER_CURL_CONSTANT(CURLE_OK);
- REGISTER_CURL_CONSTANT(CURLE_UNSUPPORTED_PROTOCOL);
- REGISTER_CURL_CONSTANT(CURLE_FAILED_INIT);
- REGISTER_CURL_CONSTANT(CURLE_URL_MALFORMAT);
- REGISTER_CURL_CONSTANT(CURLE_URL_MALFORMAT_USER);
- REGISTER_CURL_CONSTANT(CURLE_COULDNT_RESOLVE_PROXY);
- REGISTER_CURL_CONSTANT(CURLE_COULDNT_RESOLVE_HOST);
+ /* */
+ REGISTER_CURL_CONSTANT(CURLE_ABORTED_BY_CALLBACK);
+ REGISTER_CURL_CONSTANT(CURLE_BAD_CALLING_ORDER);
+ REGISTER_CURL_CONSTANT(CURLE_BAD_CONTENT_ENCODING);
+ REGISTER_CURL_CONSTANT(CURLE_BAD_DOWNLOAD_RESUME);
+ REGISTER_CURL_CONSTANT(CURLE_BAD_FUNCTION_ARGUMENT);
+ REGISTER_CURL_CONSTANT(CURLE_BAD_PASSWORD_ENTERED);
REGISTER_CURL_CONSTANT(CURLE_COULDNT_CONNECT);
- REGISTER_CURL_CONSTANT(CURLE_FTP_WEIRD_SERVER_REPLY);
+ REGISTER_CURL_CONSTANT(CURLE_COULDNT_RESOLVE_HOST);
+ REGISTER_CURL_CONSTANT(CURLE_COULDNT_RESOLVE_PROXY);
+ REGISTER_CURL_CONSTANT(CURLE_FAILED_INIT);
+ REGISTER_CURL_CONSTANT(CURLE_FILE_COULDNT_READ_FILE);
REGISTER_CURL_CONSTANT(CURLE_FTP_ACCESS_DENIED);
- REGISTER_CURL_CONSTANT(CURLE_FTP_USER_PASSWORD_INCORRECT);
- REGISTER_CURL_CONSTANT(CURLE_FTP_WEIRD_PASS_REPLY);
- REGISTER_CURL_CONSTANT(CURLE_FTP_WEIRD_USER_REPLY);
- REGISTER_CURL_CONSTANT(CURLE_FTP_WEIRD_PASV_REPLY);
- REGISTER_CURL_CONSTANT(CURLE_FTP_WEIRD_227_FORMAT);
+ REGISTER_CURL_CONSTANT(CURLE_FTP_BAD_DOWNLOAD_RESUME);
REGISTER_CURL_CONSTANT(CURLE_FTP_CANT_GET_HOST);
REGISTER_CURL_CONSTANT(CURLE_FTP_CANT_RECONNECT);
- REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_SET_BINARY);
- REGISTER_CURL_CONSTANT(CURLE_PARTIAL_FILE);
+ REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_GET_SIZE);
REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_RETR_FILE);
- REGISTER_CURL_CONSTANT(CURLE_FTP_WRITE_ERROR);
- REGISTER_CURL_CONSTANT(CURLE_FTP_QUOTE_ERROR);
- REGISTER_CURL_CONSTANT(CURLE_HTTP_NOT_FOUND);
- REGISTER_CURL_CONSTANT(CURLE_WRITE_ERROR);
- REGISTER_CURL_CONSTANT(CURLE_MALFORMAT_USER);
- REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_STOR_FILE);
- REGISTER_CURL_CONSTANT(CURLE_READ_ERROR);
- REGISTER_CURL_CONSTANT(CURLE_OUT_OF_MEMORY);
- REGISTER_CURL_CONSTANT(CURLE_OPERATION_TIMEOUTED);
REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_SET_ASCII);
- REGISTER_CURL_CONSTANT(CURLE_FTP_PORT_FAILED);
+ REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_SET_BINARY);
+ REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_STOR_FILE);
REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_USE_REST);
- REGISTER_CURL_CONSTANT(CURLE_FTP_COULDNT_GET_SIZE);
- REGISTER_CURL_CONSTANT(CURLE_HTTP_RANGE_ERROR);
+ REGISTER_CURL_CONSTANT(CURLE_FTP_PARTIAL_FILE);
+ REGISTER_CURL_CONSTANT(CURLE_FTP_PORT_FAILED);
+ REGISTER_CURL_CONSTANT(CURLE_FTP_QUOTE_ERROR);
+ REGISTER_CURL_CONSTANT(CURLE_FTP_USER_PASSWORD_INCORRECT);
+ REGISTER_CURL_CONSTANT(CURLE_FTP_WEIRD_227_FORMAT);
+ REGISTER_CURL_CONSTANT(CURLE_FTP_WEIRD_PASS_REPLY);
+ REGISTER_CURL_CONSTANT(CURLE_FTP_WEIRD_PASV_REPLY);
+ REGISTER_CURL_CONSTANT(CURLE_FTP_WEIRD_SERVER_REPLY);
+ REGISTER_CURL_CONSTANT(CURLE_FTP_WEIRD_USER_REPLY);
+ REGISTER_CURL_CONSTANT(CURLE_FTP_WRITE_ERROR);
+ REGISTER_CURL_CONSTANT(CURLE_FUNCTION_NOT_FOUND);
+ REGISTER_CURL_CONSTANT(CURLE_GOT_NOTHING);
+ REGISTER_CURL_CONSTANT(CURLE_HTTP_NOT_FOUND);
+ REGISTER_CURL_CONSTANT(CURLE_HTTP_PORT_FAILED);
REGISTER_CURL_CONSTANT(CURLE_HTTP_POST_ERROR);
- REGISTER_CURL_CONSTANT(CURLE_SSL_CONNECT_ERROR);
- REGISTER_CURL_CONSTANT(CURLE_FTP_BAD_DOWNLOAD_RESUME);
- REGISTER_CURL_CONSTANT(CURLE_FILE_COULDNT_READ_FILE);
+ REGISTER_CURL_CONSTANT(CURLE_HTTP_RANGE_ERROR);
+ REGISTER_CURL_CONSTANT(CURLE_HTTP_RETURNED_ERROR);
REGISTER_CURL_CONSTANT(CURLE_LDAP_CANNOT_BIND);
REGISTER_CURL_CONSTANT(CURLE_LDAP_SEARCH_FAILED);
REGISTER_CURL_CONSTANT(CURLE_LIBRARY_NOT_FOUND);
- REGISTER_CURL_CONSTANT(CURLE_FUNCTION_NOT_FOUND);
- REGISTER_CURL_CONSTANT(CURLE_ABORTED_BY_CALLBACK);
- REGISTER_CURL_CONSTANT(CURLE_BAD_FUNCTION_ARGUMENT);
- REGISTER_CURL_CONSTANT(CURLE_BAD_CALLING_ORDER);
- REGISTER_CURL_CONSTANT(CURLE_HTTP_PORT_FAILED);
- REGISTER_CURL_CONSTANT(CURLE_BAD_PASSWORD_ENTERED);
- REGISTER_CURL_CONSTANT(CURLE_TOO_MANY_REDIRECTS);
- REGISTER_CURL_CONSTANT(CURLE_UNKNOWN_TELNET_OPTION);
- REGISTER_CURL_CONSTANT(CURLE_TELNET_OPTION_SYNTAX);
+ REGISTER_CURL_CONSTANT(CURLE_MALFORMAT_USER);
REGISTER_CURL_CONSTANT(CURLE_OBSOLETE);
- REGISTER_CURL_CONSTANT(CURLE_SSL_PEER_CERTIFICATE);
- REGISTER_CURL_CONSTANT(CURLE_GOT_NOTHING);
- REGISTER_CURL_CONSTANT(CURLE_SSL_ENGINE_NOTFOUND);
- REGISTER_CURL_CONSTANT(CURLE_SSL_ENGINE_SETFAILED);
- REGISTER_CURL_CONSTANT(CURLE_SEND_ERROR);
+ REGISTER_CURL_CONSTANT(CURLE_OK);
+ REGISTER_CURL_CONSTANT(CURLE_OPERATION_TIMEDOUT);
+ REGISTER_CURL_CONSTANT(CURLE_OPERATION_TIMEOUTED);
+ REGISTER_CURL_CONSTANT(CURLE_OUT_OF_MEMORY);
+ REGISTER_CURL_CONSTANT(CURLE_PARTIAL_FILE);
+ REGISTER_CURL_CONSTANT(CURLE_READ_ERROR);
REGISTER_CURL_CONSTANT(CURLE_RECV_ERROR);
+ REGISTER_CURL_CONSTANT(CURLE_SEND_ERROR);
REGISTER_CURL_CONSTANT(CURLE_SHARE_IN_USE);
+ REGISTER_CURL_CONSTANT(CURLE_SSL_CACERT);
REGISTER_CURL_CONSTANT(CURLE_SSL_CERTPROBLEM);
REGISTER_CURL_CONSTANT(CURLE_SSL_CIPHER);
- REGISTER_CURL_CONSTANT(CURLE_SSL_CACERT);
- REGISTER_CURL_CONSTANT(CURLE_BAD_CONTENT_ENCODING);
-#if LIBCURL_VERSION_NUM >= 0x070a08
- REGISTER_CURL_CONSTANT(CURLE_LDAP_INVALID_URL);
- REGISTER_CURL_CONSTANT(CURLE_FILESIZE_EXCEEDED);
-#endif
-#if LIBCURL_VERSION_NUM >= 0x070b00
- REGISTER_CURL_CONSTANT(CURLE_FTP_SSL_FAILED);
-#endif
+ REGISTER_CURL_CONSTANT(CURLE_SSL_CONNECT_ERROR);
+ REGISTER_CURL_CONSTANT(CURLE_SSL_ENGINE_NOTFOUND);
+ REGISTER_CURL_CONSTANT(CURLE_SSL_ENGINE_SETFAILED);
+ REGISTER_CURL_CONSTANT(CURLE_SSL_PEER_CERTIFICATE);
+ REGISTER_CURL_CONSTANT(CURLE_TELNET_OPTION_SYNTAX);
+ REGISTER_CURL_CONSTANT(CURLE_TOO_MANY_REDIRECTS);
+ REGISTER_CURL_CONSTANT(CURLE_UNKNOWN_TELNET_OPTION);
+ REGISTER_CURL_CONSTANT(CURLE_UNSUPPORTED_PROTOCOL);
+ REGISTER_CURL_CONSTANT(CURLE_URL_MALFORMAT);
+ REGISTER_CURL_CONSTANT(CURLE_URL_MALFORMAT_USER);
+ REGISTER_CURL_CONSTANT(CURLE_WRITE_ERROR);
+
+ /* cURL info constants */
+ REGISTER_CURL_CONSTANT(CURLINFO_CONNECT_TIME);
+ REGISTER_CURL_CONSTANT(CURLINFO_CONTENT_LENGTH_DOWNLOAD);
+ REGISTER_CURL_CONSTANT(CURLINFO_CONTENT_LENGTH_UPLOAD);
+ REGISTER_CURL_CONSTANT(CURLINFO_CONTENT_TYPE);
+ REGISTER_CURL_CONSTANT(CURLINFO_EFFECTIVE_URL);
+ REGISTER_CURL_CONSTANT(CURLINFO_FILETIME);
+ REGISTER_CURL_CONSTANT(CURLINFO_HEADER_OUT);
+ REGISTER_CURL_CONSTANT(CURLINFO_HEADER_SIZE);
+ REGISTER_CURL_CONSTANT(CURLINFO_HTTP_CODE);
+ REGISTER_CURL_CONSTANT(CURLINFO_LASTONE);
+ REGISTER_CURL_CONSTANT(CURLINFO_NAMELOOKUP_TIME);
+ REGISTER_CURL_CONSTANT(CURLINFO_PRETRANSFER_TIME);
+ REGISTER_CURL_CONSTANT(CURLINFO_PRIVATE);
+ REGISTER_CURL_CONSTANT(CURLINFO_REDIRECT_COUNT);
+ REGISTER_CURL_CONSTANT(CURLINFO_REDIRECT_TIME);
+ REGISTER_CURL_CONSTANT(CURLINFO_REQUEST_SIZE);
+ REGISTER_CURL_CONSTANT(CURLINFO_SIZE_DOWNLOAD);
+ REGISTER_CURL_CONSTANT(CURLINFO_SIZE_UPLOAD);
+ REGISTER_CURL_CONSTANT(CURLINFO_SPEED_DOWNLOAD);
+ REGISTER_CURL_CONSTANT(CURLINFO_SPEED_UPLOAD);
+ REGISTER_CURL_CONSTANT(CURLINFO_SSL_VERIFYRESULT);
+ REGISTER_CURL_CONSTANT(CURLINFO_STARTTRANSFER_TIME);
+ REGISTER_CURL_CONSTANT(CURLINFO_TOTAL_TIME);
+
+ /* Other */
+ REGISTER_CURL_CONSTANT(CURLMSG_DONE);
+ REGISTER_CURL_CONSTANT(CURLVERSION_NOW);
+
+ /* Curl Multi Constants */
+ REGISTER_CURL_CONSTANT(CURLM_BAD_EASY_HANDLE);
+ REGISTER_CURL_CONSTANT(CURLM_BAD_HANDLE);
+ REGISTER_CURL_CONSTANT(CURLM_CALL_MULTI_PERFORM);
+ REGISTER_CURL_CONSTANT(CURLM_INTERNAL_ERROR);
+ REGISTER_CURL_CONSTANT(CURLM_OK);
+ REGISTER_CURL_CONSTANT(CURLM_OUT_OF_MEMORY);
+
+ /* Curl proxy constants */
REGISTER_CURL_CONSTANT(CURLPROXY_HTTP);
REGISTER_CURL_CONSTANT(CURLPROXY_SOCKS4);
REGISTER_CURL_CONSTANT(CURLPROXY_SOCKS5);
- REGISTER_CURL_CONSTANT(CURL_NETRC_OPTIONAL);
- REGISTER_CURL_CONSTANT(CURL_NETRC_IGNORED);
- REGISTER_CURL_CONSTANT(CURL_NETRC_REQUIRED);
+ /* Curl Share constants */
+ REGISTER_CURL_CONSTANT(CURLSHOPT_NONE);
+ REGISTER_CURL_CONSTANT(CURLSHOPT_SHARE);
+ REGISTER_CURL_CONSTANT(CURLSHOPT_UNSHARE);
- REGISTER_CURL_CONSTANT(CURL_HTTP_VERSION_NONE);
+ /* Curl Http Version constants (CURLOPT_HTTP_VERSION) */
REGISTER_CURL_CONSTANT(CURL_HTTP_VERSION_1_0);
REGISTER_CURL_CONSTANT(CURL_HTTP_VERSION_1_1);
+ REGISTER_CURL_CONSTANT(CURL_HTTP_VERSION_NONE);
- REGISTER_CURL_CONSTANT(CURLM_CALL_MULTI_PERFORM);
- REGISTER_CURL_CONSTANT(CURLM_OK);
- REGISTER_CURL_CONSTANT(CURLM_BAD_HANDLE);
- REGISTER_CURL_CONSTANT(CURLM_BAD_EASY_HANDLE);
- REGISTER_CURL_CONSTANT(CURLM_OUT_OF_MEMORY);
- REGISTER_CURL_CONSTANT(CURLM_INTERNAL_ERROR);
+ /* Curl Lock constants */
+ REGISTER_CURL_CONSTANT(CURL_LOCK_DATA_COOKIE);
+ REGISTER_CURL_CONSTANT(CURL_LOCK_DATA_DNS);
+ REGISTER_CURL_CONSTANT(CURL_LOCK_DATA_SSL_SESSION);
- REGISTER_CURL_CONSTANT(CURLMSG_DONE);
+ /* Curl NETRC constants (CURLOPT_NETRC) */
+ REGISTER_CURL_CONSTANT(CURL_NETRC_IGNORED);
+ REGISTER_CURL_CONSTANT(CURL_NETRC_OPTIONAL);
+ REGISTER_CURL_CONSTANT(CURL_NETRC_REQUIRED);
-#if LIBCURL_VERSION_NUM >= 0x070c02
- REGISTER_CURL_CONSTANT(CURLOPT_FTPSSLAUTH);
+ /* Curl SSL Version constants (CURLOPT_SSLVERSION) */
+ REGISTER_CURL_CONSTANT(CURL_SSLVERSION_DEFAULT);
+ REGISTER_CURL_CONSTANT(CURL_SSLVERSION_SSLv2);
+ REGISTER_CURL_CONSTANT(CURL_SSLVERSION_SSLv3);
+ REGISTER_CURL_CONSTANT(CURL_SSLVERSION_TLSv1);
+
+ /* Curl TIMECOND constants (CURLOPT_TIMECONDITION) */
+ REGISTER_CURL_CONSTANT(CURL_TIMECOND_IFMODSINCE);
+ REGISTER_CURL_CONSTANT(CURL_TIMECOND_IFUNMODSINCE);
+ REGISTER_CURL_CONSTANT(CURL_TIMECOND_LASTMOD);
+ REGISTER_CURL_CONSTANT(CURL_TIMECOND_NONE);
+
+ /* Curl version constants */
+ REGISTER_CURL_CONSTANT(CURL_VERSION_IPV6);
+ REGISTER_CURL_CONSTANT(CURL_VERSION_KERBEROS4);
+ REGISTER_CURL_CONSTANT(CURL_VERSION_LIBZ);
+ REGISTER_CURL_CONSTANT(CURL_VERSION_SSL);
+
+#if LIBCURL_VERSION_NUM >= 0x070a06 /* Available since 7.10.6 */
+ REGISTER_CURL_CONSTANT(CURLOPT_HTTPAUTH);
+ /* http authentication options */
+ REGISTER_CURL_CONSTANT(CURLAUTH_ANY);
+ REGISTER_CURL_CONSTANT(CURLAUTH_ANYSAFE);
+ REGISTER_CURL_CONSTANT(CURLAUTH_BASIC);
+ REGISTER_CURL_CONSTANT(CURLAUTH_DIGEST);
+ REGISTER_CURL_CONSTANT(CURLAUTH_GSSNEGOTIATE);
+ REGISTER_CURL_CONSTANT(CURLAUTH_NONE);
+ REGISTER_CURL_CONSTANT(CURLAUTH_NTLM);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x070a07 /* Available since 7.10.7 */
+ REGISTER_CURL_CONSTANT(CURLINFO_HTTP_CONNECTCODE);
+ REGISTER_CURL_CONSTANT(CURLOPT_FTP_CREATE_MISSING_DIRS);
+ REGISTER_CURL_CONSTANT(CURLOPT_PROXYAUTH);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x070a08 /* Available since 7.10.8 */
+ REGISTER_CURL_CONSTANT(CURLE_FILESIZE_EXCEEDED);
+ REGISTER_CURL_CONSTANT(CURLE_LDAP_INVALID_URL);
+ REGISTER_CURL_CONSTANT(CURLINFO_HTTPAUTH_AVAIL);
+ REGISTER_CURL_CONSTANT(CURLINFO_RESPONSE_CODE);
+ REGISTER_CURL_CONSTANT(CURLINFO_PROXYAUTH_AVAIL);
+ REGISTER_CURL_CONSTANT(CURLOPT_FTP_RESPONSE_TIMEOUT);
+ REGISTER_CURL_CONSTANT(CURLOPT_IPRESOLVE);
+ REGISTER_CURL_CONSTANT(CURLOPT_MAXFILESIZE);
+ REGISTER_CURL_CONSTANT(CURL_IPRESOLVE_V4);
+ REGISTER_CURL_CONSTANT(CURL_IPRESOLVE_V6);
+ REGISTER_CURL_CONSTANT(CURL_IPRESOLVE_WHATEVER);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x070b00 /* Available since 7.11.0 */
+ REGISTER_CURL_CONSTANT(CURLE_FTP_SSL_FAILED);
+ REGISTER_CURL_CONSTANT(CURLFTPSSL_ALL);
+ REGISTER_CURL_CONSTANT(CURLFTPSSL_CONTROL);
+ REGISTER_CURL_CONSTANT(CURLFTPSSL_NONE);
+ REGISTER_CURL_CONSTANT(CURLFTPSSL_TRY);
+ REGISTER_CURL_CONSTANT(CURLOPT_FTP_SSL);
+ REGISTER_CURL_CONSTANT(CURLOPT_NETRC_FILE);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x070c02 /* Available since 7.12.2 */
REGISTER_CURL_CONSTANT(CURLFTPAUTH_DEFAULT);
REGISTER_CURL_CONSTANT(CURLFTPAUTH_SSL);
REGISTER_CURL_CONSTANT(CURLFTPAUTH_TLS);
+ REGISTER_CURL_CONSTANT(CURLOPT_FTPSSLAUTH);
#endif
-#if LIBCURL_VERSION_NUM > 0x070b00
- REGISTER_CURL_CONSTANT(CURLOPT_FTP_SSL);
- REGISTER_CURL_CONSTANT(CURLFTPSSL_NONE);
- REGISTER_CURL_CONSTANT(CURLFTPSSL_TRY);
- REGISTER_CURL_CONSTANT(CURLFTPSSL_CONTROL);
- REGISTER_CURL_CONSTANT(CURLFTPSSL_ALL);
+#if LIBCURL_VERSION_NUM >= 0x070d00 /* Available since 7.13.0 */
+ REGISTER_CURL_CONSTANT(CURLOPT_FTP_ACCOUNT);
#endif
-#if LIBCURL_VERSION_NUM > 0x071301
- REGISTER_CURL_CONSTANT(CURLOPT_CERTINFO);
- REGISTER_CURL_CONSTANT(CURLOPT_POSTREDIR);
+#if LIBCURL_VERSION_NUM >= 0x070b02 /* Available since 7.11.2 */
+ REGISTER_CURL_CONSTANT(CURLOPT_TCP_NODELAY);
#endif
-/* SSH support works in 7.19.0+ using libssh2 */
-#if LIBCURL_VERSION_NUM >= 0x071300
- REGISTER_CURL_CONSTANT(CURLSSH_AUTH_NONE);
- REGISTER_CURL_CONSTANT(CURLSSH_AUTH_PUBLICKEY);
- REGISTER_CURL_CONSTANT(CURLSSH_AUTH_PASSWORD);
- REGISTER_CURL_CONSTANT(CURLSSH_AUTH_HOST);
- REGISTER_CURL_CONSTANT(CURLSSH_AUTH_KEYBOARD);
- REGISTER_CURL_CONSTANT(CURLSSH_AUTH_DEFAULT);
+#if LIBCURL_VERSION_NUM >= 0x070c02 /* Available since 7.12.2 */
+ REGISTER_CURL_CONSTANT(CURLINFO_OS_ERRNO);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x070c03 /* Available since 7.12.3 */
+ REGISTER_CURL_CONSTANT(CURLINFO_NUM_CONNECTS);
+ REGISTER_CURL_CONSTANT(CURLINFO_SSL_ENGINES);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x070e01 /* Available since 7.14.1 */
+ REGISTER_CURL_CONSTANT(CURLINFO_COOKIELIST);
+ REGISTER_CURL_CONSTANT(CURLOPT_COOKIELIST);
+ REGISTER_CURL_CONSTANT(CURLOPT_IGNORE_CONTENT_LENGTH);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x070f00 /* Available since 7.15.0 */
+ REGISTER_CURL_CONSTANT(CURLOPT_FTP_SKIP_PASV_IP);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x070f01 /* Available since 7.15.1 */
+ REGISTER_CURL_CONSTANT(CURLOPT_FTP_FILEMETHOD);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x070f02 /* Available since 7.15.2 */
+ REGISTER_CURL_CONSTANT(CURLOPT_CONNECT_ONLY);
+ REGISTER_CURL_CONSTANT(CURLOPT_LOCALPORT);
+ REGISTER_CURL_CONSTANT(CURLOPT_LOCALPORTRANGE);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x070f03 /* Available since 7.15.3 */
+ REGISTER_CURL_CONSTANT(CURLFTPMETHOD_MULTICWD);
+ REGISTER_CURL_CONSTANT(CURLFTPMETHOD_NOCWD);
+ REGISTER_CURL_CONSTANT(CURLFTPMETHOD_SINGLECWD);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x070f04 /* Available since 7.15.4 */
+ REGISTER_CURL_CONSTANT(CURLINFO_FTP_ENTRY_PATH);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x070f05 /* Available since 7.15.5 */
+ REGISTER_CURL_CONSTANT(CURLOPT_FTP_ALTERNATIVE_TO_USER);
+ REGISTER_CURL_CONSTANT(CURLOPT_MAX_RECV_SPEED_LARGE);
+ REGISTER_CURL_CONSTANT(CURLOPT_MAX_SEND_SPEED_LARGE);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x071000 /* Available since 7.16.0 */
+ REGISTER_CURL_CONSTANT(CURLOPT_SSL_SESSIONID_CACHE);
+ REGISTER_CURL_CONSTANT(CURLMOPT_PIPELINING);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x071001 /* Available since 7.16.1 */
+ REGISTER_CURL_CONSTANT(CURLE_SSH);
+ REGISTER_CURL_CONSTANT(CURLOPT_FTP_SSL_CCC);
REGISTER_CURL_CONSTANT(CURLOPT_SSH_AUTH_TYPES);
- REGISTER_CURL_CONSTANT(CURLOPT_KEYPASSWD);
- REGISTER_CURL_CONSTANT(CURLOPT_SSH_PUBLIC_KEYFILE);
REGISTER_CURL_CONSTANT(CURLOPT_SSH_PRIVATE_KEYFILE);
+ REGISTER_CURL_CONSTANT(CURLOPT_SSH_PUBLIC_KEYFILE);
+ REGISTER_CURL_CONSTANT(CURLFTPSSL_CCC_ACTIVE);
+ REGISTER_CURL_CONSTANT(CURLFTPSSL_CCC_NONE);
+ REGISTER_CURL_CONSTANT(CURLFTPSSL_CCC_PASSIVE);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x071002 /* Available since 7.16.2 */
+ REGISTER_CURL_CONSTANT(CURLOPT_CONNECTTIMEOUT_MS);
+ REGISTER_CURL_CONSTANT(CURLOPT_HTTP_CONTENT_DECODING);
+ REGISTER_CURL_CONSTANT(CURLOPT_HTTP_TRANSFER_DECODING);
+ REGISTER_CURL_CONSTANT(CURLOPT_TIMEOUT_MS);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x071003 /* Available since 7.16.3 */
+ REGISTER_CURL_CONSTANT(CURLMOPT_MAXCONNECTS);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x071004 /* Available since 7.16.4 */
+ REGISTER_CURL_CONSTANT(CURLOPT_KRBLEVEL);
+ REGISTER_CURL_CONSTANT(CURLOPT_NEW_DIRECTORY_PERMS);
+ REGISTER_CURL_CONSTANT(CURLOPT_NEW_FILE_PERMS);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x071100 /* Available since 7.17.0 */
+ REGISTER_CURL_CONSTANT(CURLOPT_APPEND);
+ REGISTER_CURL_CONSTANT(CURLOPT_DIRLISTONLY);
+ REGISTER_CURL_CONSTANT(CURLOPT_USE_SSL);
+ /* Curl SSL Constants */
+ REGISTER_CURL_CONSTANT(CURLUSESSL_ALL);
+ REGISTER_CURL_CONSTANT(CURLUSESSL_CONTROL);
+ REGISTER_CURL_CONSTANT(CURLUSESSL_NONE);
+ REGISTER_CURL_CONSTANT(CURLUSESSL_TRY);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x071101 /* Available since 7.17.1 */
REGISTER_CURL_CONSTANT(CURLOPT_SSH_HOST_PUBLIC_KEY_MD5);
- REGISTER_CURL_CONSTANT(CURLE_SSH);
#endif
-#if LIBCURL_VERSION_NUM >= 0x071304
- REGISTER_CURL_CONSTANT(CURLOPT_REDIR_PROTOCOLS);
+#if LIBCURL_VERSION_NUM >= 0x071200 /* Available since 7.18.0 */
+ REGISTER_CURL_CONSTANT(CURLOPT_PROXY_TRANSFER_MODE);
+ REGISTER_CURL_CONSTANT(CURLPAUSE_ALL);
+ REGISTER_CURL_CONSTANT(CURLPAUSE_CONT);
+ REGISTER_CURL_CONSTANT(CURLPAUSE_RECV);
+ REGISTER_CURL_CONSTANT(CURLPAUSE_RECV_CONT);
+ REGISTER_CURL_CONSTANT(CURLPAUSE_SEND);
+ REGISTER_CURL_CONSTANT(CURLPAUSE_SEND_CONT);
+ REGISTER_CURL_CONSTANT(CURL_READFUNC_PAUSE);
+ REGISTER_CURL_CONSTANT(CURL_WRITEFUNC_PAUSE);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x071202 /* Available since 7.18.2 */
+ REGISTER_CURL_CONSTANT(CURLINFO_REDIRECT_URL);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x071300 /* Available since 7.19.0 */
+ REGISTER_CURL_CONSTANT(CURLINFO_APPCONNECT_TIME);
+ REGISTER_CURL_CONSTANT(CURLINFO_PRIMARY_IP);
+
+ REGISTER_CURL_CONSTANT(CURLOPT_ADDRESS_SCOPE);
+ REGISTER_CURL_CONSTANT(CURLOPT_CRLFILE);
+ REGISTER_CURL_CONSTANT(CURLOPT_ISSUERCERT);
+ REGISTER_CURL_CONSTANT(CURLOPT_KEYPASSWD);
+
+ REGISTER_CURL_CONSTANT(CURLSSH_AUTH_ANY);
+ REGISTER_CURL_CONSTANT(CURLSSH_AUTH_DEFAULT);
+ REGISTER_CURL_CONSTANT(CURLSSH_AUTH_HOST);
+ REGISTER_CURL_CONSTANT(CURLSSH_AUTH_KEYBOARD);
+ REGISTER_CURL_CONSTANT(CURLSSH_AUTH_NONE);
+ REGISTER_CURL_CONSTANT(CURLSSH_AUTH_PASSWORD);
+ REGISTER_CURL_CONSTANT(CURLSSH_AUTH_PUBLICKEY);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x071301 /* Available since 7.19.1 */
+ REGISTER_CURL_CONSTANT(CURLINFO_CERTINFO);
+ REGISTER_CURL_CONSTANT(CURLOPT_CERTINFO);
+ REGISTER_CURL_CONSTANT(CURLOPT_PASSWORD);
+ REGISTER_CURL_CONSTANT(CURLOPT_POSTREDIR);
+ REGISTER_CURL_CONSTANT(CURLOPT_PROXYPASSWORD);
+ REGISTER_CURL_CONSTANT(CURLOPT_PROXYUSERNAME);
+ REGISTER_CURL_CONSTANT(CURLOPT_USERNAME);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x071303 /* Available since 7.19.3 */
+ REGISTER_CURL_CONSTANT(CURLAUTH_DIGEST_IE);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x071304 /* Available since 7.19.4 */
+ REGISTER_CURL_CONSTANT(CURLINFO_CONDITION_UNMET);
+
+ REGISTER_CURL_CONSTANT(CURLOPT_NOPROXY);
REGISTER_CURL_CONSTANT(CURLOPT_PROTOCOLS);
- REGISTER_CURL_CONSTANT(CURLPROTO_HTTP);
- REGISTER_CURL_CONSTANT(CURLPROTO_HTTPS);
+ REGISTER_CURL_CONSTANT(CURLOPT_REDIR_PROTOCOLS);
+ REGISTER_CURL_CONSTANT(CURLOPT_SOCKS5_GSSAPI_NEC);
+ REGISTER_CURL_CONSTANT(CURLOPT_SOCKS5_GSSAPI_SERVICE);
+ REGISTER_CURL_CONSTANT(CURLOPT_TFTP_BLKSIZE);
+
+ REGISTER_CURL_CONSTANT(CURLPROTO_ALL);
+ REGISTER_CURL_CONSTANT(CURLPROTO_DICT);
+ REGISTER_CURL_CONSTANT(CURLPROTO_FILE);
REGISTER_CURL_CONSTANT(CURLPROTO_FTP);
REGISTER_CURL_CONSTANT(CURLPROTO_FTPS);
+ REGISTER_CURL_CONSTANT(CURLPROTO_HTTP);
+ REGISTER_CURL_CONSTANT(CURLPROTO_HTTPS);
+ REGISTER_CURL_CONSTANT(CURLPROTO_LDAP);
+ REGISTER_CURL_CONSTANT(CURLPROTO_LDAPS);
REGISTER_CURL_CONSTANT(CURLPROTO_SCP);
REGISTER_CURL_CONSTANT(CURLPROTO_SFTP);
REGISTER_CURL_CONSTANT(CURLPROTO_TELNET);
- REGISTER_CURL_CONSTANT(CURLPROTO_LDAP);
- REGISTER_CURL_CONSTANT(CURLPROTO_LDAPS);
- REGISTER_CURL_CONSTANT(CURLPROTO_DICT);
- REGISTER_CURL_CONSTANT(CURLPROTO_FILE);
REGISTER_CURL_CONSTANT(CURLPROTO_TFTP);
- REGISTER_CURL_CONSTANT(CURLPROTO_ALL);
#endif
-#if LIBCURL_VERSION_NUM >= 0x070f01
- REGISTER_CURL_CONSTANT(CURLOPT_FTP_FILEMETHOD);
- REGISTER_CURL_CONSTANT(CURLOPT_FTP_SKIP_PASV_IP);
+#if LIBCURL_VERSION_NUM >= 0x071306 /* Available since 7.19.6 */
+ REGISTER_CURL_CONSTANT(CURLOPT_SSH_KNOWNHOSTS);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x071400 /* Available since 7.20.0 */
+ REGISTER_CURL_CONSTANT(CURLINFO_RTSP_CLIENT_CSEQ);
+ REGISTER_CURL_CONSTANT(CURLINFO_RTSP_CSEQ_RECV);
+ REGISTER_CURL_CONSTANT(CURLINFO_RTSP_SERVER_CSEQ);
+ REGISTER_CURL_CONSTANT(CURLINFO_RTSP_SESSION_ID);
+ REGISTER_CURL_CONSTANT(CURLOPT_FTP_USE_PRET);
+ REGISTER_CURL_CONSTANT(CURLOPT_MAIL_FROM);
+ REGISTER_CURL_CONSTANT(CURLOPT_MAIL_RCPT);
+ REGISTER_CURL_CONSTANT(CURLOPT_RTSP_CLIENT_CSEQ);
+ REGISTER_CURL_CONSTANT(CURLOPT_RTSP_REQUEST);
+ REGISTER_CURL_CONSTANT(CURLOPT_RTSP_SERVER_CSEQ);
+ REGISTER_CURL_CONSTANT(CURLOPT_RTSP_SESSION_ID);
+ REGISTER_CURL_CONSTANT(CURLOPT_RTSP_STREAM_URI);
+ REGISTER_CURL_CONSTANT(CURLOPT_RTSP_TRANSPORT);
+ REGISTER_CURL_CONSTANT(CURLPROTO_IMAP);
+ REGISTER_CURL_CONSTANT(CURLPROTO_IMAPS);
+ REGISTER_CURL_CONSTANT(CURLPROTO_POP3);
+ REGISTER_CURL_CONSTANT(CURLPROTO_POP3S);
+ REGISTER_CURL_CONSTANT(CURLPROTO_RTSP);
+ REGISTER_CURL_CONSTANT(CURLPROTO_SMTP);
+ REGISTER_CURL_CONSTANT(CURLPROTO_SMTPS);
+ REGISTER_CURL_CONSTANT(CURL_RTSPREQ_ANNOUNCE);
+ REGISTER_CURL_CONSTANT(CURL_RTSPREQ_DESCRIBE);
+ REGISTER_CURL_CONSTANT(CURL_RTSPREQ_GET_PARAMETER);
+ REGISTER_CURL_CONSTANT(CURL_RTSPREQ_OPTIONS);
+ REGISTER_CURL_CONSTANT(CURL_RTSPREQ_PAUSE);
+ REGISTER_CURL_CONSTANT(CURL_RTSPREQ_PLAY);
+ REGISTER_CURL_CONSTANT(CURL_RTSPREQ_RECEIVE);
+ REGISTER_CURL_CONSTANT(CURL_RTSPREQ_RECORD);
+ REGISTER_CURL_CONSTANT(CURL_RTSPREQ_SETUP);
+ REGISTER_CURL_CONSTANT(CURL_RTSPREQ_SET_PARAMETER);
+ REGISTER_CURL_CONSTANT(CURL_RTSPREQ_TEARDOWN);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x071500 /* Available since 7.21.0 */
+ REGISTER_CURL_CONSTANT(CURLINFO_LOCAL_IP);
+ REGISTER_CURL_CONSTANT(CURLINFO_LOCAL_PORT);
+ REGISTER_CURL_CONSTANT(CURLINFO_PRIMARY_PORT);
+ REGISTER_CURL_CONSTANT(CURLOPT_FNMATCH_FUNCTION);
+ REGISTER_CURL_CONSTANT(CURLOPT_WILDCARDMATCH);
+ REGISTER_CURL_CONSTANT(CURLPROTO_RTMP);
+ REGISTER_CURL_CONSTANT(CURLPROTO_RTMPE);
+ REGISTER_CURL_CONSTANT(CURLPROTO_RTMPS);
+ REGISTER_CURL_CONSTANT(CURLPROTO_RTMPT);
+ REGISTER_CURL_CONSTANT(CURLPROTO_RTMPTE);
+ REGISTER_CURL_CONSTANT(CURLPROTO_RTMPTS);
+ REGISTER_CURL_CONSTANT(CURL_FNMATCHFUNC_FAIL);
+ REGISTER_CURL_CONSTANT(CURL_FNMATCHFUNC_MATCH);
+ REGISTER_CURL_CONSTANT(CURL_FNMATCHFUNC_NOMATCH);
#endif
-#if LIBCURL_VERSION_NUM >= 0x071001
- REGISTER_CURL_CONSTANT(CURLFTPMETHOD_MULTICWD);
- REGISTER_CURL_CONSTANT(CURLFTPMETHOD_NOCWD);
- REGISTER_CURL_CONSTANT(CURLFTPMETHOD_SINGLECWD);
+#if LIBCURL_VERSION_NUM >= 0x071502 /* Available since 7.21.2 */
+ REGISTER_CURL_CONSTANT(CURLPROTO_GOPHER);
#endif
+#if LIBCURL_VERSION_NUM >= 0x071503 /* Available since 7.21.3 */
+ REGISTER_CURL_CONSTANT(CURLAUTH_ONLY);
+ REGISTER_CURL_CONSTANT(CURLOPT_RESOLVE);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x071504 /* Available since 7.21.4 */
+ REGISTER_CURL_CONSTANT(CURLOPT_TLSAUTH_PASSWORD);
+ REGISTER_CURL_CONSTANT(CURLOPT_TLSAUTH_TYPE);
+ REGISTER_CURL_CONSTANT(CURLOPT_TLSAUTH_USERNAME);
+ REGISTER_CURL_CONSTANT(CURL_TLSAUTH_SRP);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x071506 /* Available since 7.21.6 */
+ REGISTER_CURL_CONSTANT(CURLOPT_ACCEPT_ENCODING);
+ REGISTER_CURL_CONSTANT(CURLOPT_TRANSFER_ENCODING);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x071600 /* Available since 7.22.0 */
+ REGISTER_CURL_CONSTANT(CURLGSSAPI_DELEGATION_FLAG);
+ REGISTER_CURL_CONSTANT(CURLGSSAPI_DELEGATION_POLICY_FLAG);
+ REGISTER_CURL_CONSTANT(CURLOPT_GSSAPI_DELEGATION);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x071800 /* Available since 7.24.0 */
+ REGISTER_CURL_CONSTANT(CURLOPT_ACCEPTTIMEOUT_MS);
+ REGISTER_CURL_CONSTANT(CURLOPT_DNS_SERVERS);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x071900 /* Available since 7.25.0 */
+ REGISTER_CURL_CONSTANT(CURLOPT_MAIL_AUTH);
+ REGISTER_CURL_CONSTANT(CURLOPT_SSL_OPTIONS);
+ REGISTER_CURL_CONSTANT(CURLOPT_TCP_KEEPALIVE);
+ REGISTER_CURL_CONSTANT(CURLOPT_TCP_KEEPIDLE);
+ REGISTER_CURL_CONSTANT(CURLOPT_TCP_KEEPINTVL);
+ REGISTER_CURL_CONSTANT(CURLSSLOPT_ALLOW_BEAST);
+#endif
+
+#if CURLOPT_FTPASCII != 0
+ REGISTER_CURL_CONSTANT(CURLOPT_FTPASCII);
+#endif
+#if CURLOPT_MUTE != 0
+ REGISTER_CURL_CONSTANT(CURLOPT_MUTE);
+#endif
+#if CURLOPT_PASSWDFUNCTION != 0
+ REGISTER_CURL_CONSTANT(CURLOPT_PASSWDFUNCTION);
+#endif
+ REGISTER_CURL_CONSTANT(CURLOPT_SAFE_UPLOAD);
+
#ifdef PHP_CURL_NEED_OPENSSL_TSL
if (!CRYPTO_get_id_callback()) {
int i, c = CRYPTO_num_locks();
@@ -913,34 +1221,7 @@ PHP_MINIT_FUNCTION(curl)
return FAILURE;
}
-#ifdef PHP_CURL_URL_WRAPPERS
-# if HAVE_CURL_VERSION_INFO
- {
- curl_version_info_data *info = curl_version_info(CURLVERSION_NOW);
- char **p = (char **)info->protocols;
-
- while (*p != NULL) {
- /* 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
+ curlfile_register_class(TSRMLS_C);
return SUCCESS;
}
@@ -950,12 +1231,6 @@ PHP_MINIT_FUNCTION(curl)
*/
PHP_MSHUTDOWN_FUNCTION(curl)
{
-#ifdef PHP_CURL_URL_WRAPPERS
- php_unregister_url_stream_wrapper("http" TSRMLS_CC);
- php_unregister_url_stream_wrapper("https" TSRMLS_CC);
- php_unregister_url_stream_wrapper("ftp" TSRMLS_CC);
- php_unregister_url_stream_wrapper("ldap" TSRMLS_CC);
-#endif
curl_global_cleanup();
#ifdef PHP_CURL_NEED_OPENSSL_TSL
if (php_curl_openssl_tsl) {
@@ -980,7 +1255,7 @@ PHP_MSHUTDOWN_FUNCTION(curl)
/* {{{ curl_write_nothing
* Used as a work around. See _php_curl_close_ex
*/
-static size_t curl_write_nothing(char *data, size_t size, size_t nmemb, void *ctx)
+static size_t curl_write_nothing(char *data, size_t size, size_t nmemb, void *ctx)
{
return size * nmemb;
}
@@ -1062,6 +1337,71 @@ static size_t curl_write(char *data, size_t size, size_t nmemb, void *ctx)
}
/* }}} */
+#if LIBCURL_VERSION_NUM >= 0x071500 /* Available since 7.21.0 */
+/* {{{ curl_fnmatch
+ */
+static int curl_fnmatch(void *ctx, const char *pattern, const char *string)
+{
+ php_curl *ch = (php_curl *) ctx;
+ php_curl_fnmatch *t = ch->handlers->fnmatch;
+ int rval = CURL_FNMATCHFUNC_FAIL;
+ switch (t->method) {
+ case PHP_CURL_USER: {
+ zval **argv[3];
+ zval *zhandle = NULL;
+ zval *zpattern = NULL;
+ zval *zstring = NULL;
+ zval *retval_ptr;
+ int error;
+ zend_fcall_info fci;
+ TSRMLS_FETCH_FROM_CTX(ch->thread_ctx);
+
+ MAKE_STD_ZVAL(zhandle);
+ MAKE_STD_ZVAL(zpattern);
+ MAKE_STD_ZVAL(zstring);
+
+ ZVAL_RESOURCE(zhandle, ch->id);
+ zend_list_addref(ch->id);
+ ZVAL_STRING(zpattern, pattern, 1);
+ ZVAL_STRING(zstring, string, 1);
+
+ argv[0] = &zhandle;
+ argv[1] = &zpattern;
+ argv[2] = &zstring;
+
+ fci.size = sizeof(fci);
+ fci.function_table = EG(function_table);
+ fci.function_name = t->func_name;
+ fci.object_ptr = NULL;
+ fci.retval_ptr_ptr = &retval_ptr;
+ fci.param_count = 3;
+ fci.params = argv;
+ fci.no_separation = 0;
+ fci.symbol_table = NULL;
+
+ ch->in_callback = 1;
+ error = zend_call_function(&fci, &t->fci_cache TSRMLS_CC);
+ ch->in_callback = 0;
+ if (error == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot call the CURLOPT_FNMATCH_FUNCTION");
+ } else if (retval_ptr) {
+ if (Z_TYPE_P(retval_ptr) != IS_LONG) {
+ convert_to_long_ex(&retval_ptr);
+ }
+ rval = Z_LVAL_P(retval_ptr);
+ zval_ptr_dtor(&retval_ptr);
+ }
+ zval_ptr_dtor(argv[0]);
+ zval_ptr_dtor(argv[1]);
+ zval_ptr_dtor(argv[2]);
+ break;
+ }
+ }
+ return rval;
+}
+/* }}} */
+#endif
+
/* {{{ curl_progress
*/
static size_t curl_progress(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)
@@ -1077,7 +1417,8 @@ static size_t curl_progress(void *clientp, double dltotal, double dlnow, double
switch (t->method) {
case PHP_CURL_USER: {
- zval **argv[4];
+ zval **argv[5];
+ zval *handle = NULL;
zval *zdltotal = NULL;
zval *zdlnow = NULL;
zval *zultotal = NULL;
@@ -1087,27 +1428,31 @@ static size_t curl_progress(void *clientp, double dltotal, double dlnow, double
zend_fcall_info fci;
TSRMLS_FETCH_FROM_CTX(ch->thread_ctx);
+ MAKE_STD_ZVAL(handle);
MAKE_STD_ZVAL(zdltotal);
MAKE_STD_ZVAL(zdlnow);
MAKE_STD_ZVAL(zultotal);
MAKE_STD_ZVAL(zulnow);
+ ZVAL_RESOURCE(handle, ch->id);
+ zend_list_addref(ch->id);
ZVAL_LONG(zdltotal, (long) dltotal);
ZVAL_LONG(zdlnow, (long) dlnow);
ZVAL_LONG(zultotal, (long) ultotal);
ZVAL_LONG(zulnow, (long) ulnow);
- argv[0] = &zdltotal;
- argv[1] = &zdlnow;
- argv[2] = &zultotal;
- argv[3] = &zulnow;
+ argv[0] = &handle;
+ argv[1] = &zdltotal;
+ argv[2] = &zdlnow;
+ argv[3] = &zultotal;
+ argv[4] = &zulnow;
fci.size = sizeof(fci);
fci.function_table = EG(function_table);
fci.function_name = t->func_name;
fci.object_ptr = NULL;
fci.retval_ptr_ptr = &retval_ptr;
- fci.param_count = 4;
+ fci.param_count = 5;
fci.params = argv;
fci.no_separation = 0;
fci.symbol_table = NULL;
@@ -1130,6 +1475,7 @@ static size_t curl_progress(void *clientp, double dltotal, double dlnow, double
zval_ptr_dtor(argv[1]);
zval_ptr_dtor(argv[2]);
zval_ptr_dtor(argv[3]);
+ zval_ptr_dtor(argv[4]);
break;
}
}
@@ -1430,7 +1776,10 @@ static void alloc_curl_handle(php_curl **ch)
(*ch)->handlers->write = ecalloc(1, sizeof(php_curl_write));
(*ch)->handlers->write_header = ecalloc(1, sizeof(php_curl_write));
(*ch)->handlers->read = ecalloc(1, sizeof(php_curl_read));
- (*ch)->handlers->progress = ecalloc(1, sizeof(php_curl_progress));
+ (*ch)->handlers->progress = NULL;
+#if LIBCURL_VERSION_NUM >= 0x071500 /* Available since 7.21.0 */
+ (*ch)->handlers->fnmatch = NULL;
+#endif
(*ch)->in_callback = 0;
(*ch)->header.str_len = 0;
@@ -1442,13 +1791,14 @@ static void alloc_curl_handle(php_curl **ch)
zend_llist_init(&(*ch)->to_free->str, sizeof(char *), (llist_dtor_func_t) curl_free_string, 0);
zend_llist_init(&(*ch)->to_free->post, sizeof(struct HttpPost), (llist_dtor_func_t) curl_free_post, 0);
+ (*ch)->safe_upload = 0; /* for now, for BC reason we allow unsafe API */
(*ch)->to_free->slist = emalloc(sizeof(HashTable));
zend_hash_init((*ch)->to_free->slist, 4, NULL, curl_free_slist, 0);
}
/* }}} */
-#if LIBCURL_VERSION_NUM > 0x071301
+#if LIBCURL_VERSION_NUM >= 0x071301 /* Available since 7.19.1 */
/* {{{ split_certinfo
*/
static void split_certinfo(char *string, zval *hash)
@@ -1458,15 +1808,15 @@ static void split_certinfo(char *string, zval *hash)
char *split;
if(org) {
- do {
+ do {
char *key;
char *val;
char *tmp;
- split = strstr(s, "; ");
- if(split)
- *split = '\0';
-
+ split = strstr(s, "; ");
+ if(split)
+ *split = '\0';
+
key = s;
tmp = memchr(key, '=', 64);
if(tmp) {
@@ -1486,13 +1836,13 @@ static void split_certinfo(char *string, zval *hash)
static void create_certinfo(struct curl_certinfo *ci, zval *listcode TSRMLS_DC)
{
int i;
-
+
if(ci) {
zval *certhash = NULL;
-
+
for(i=0; i<ci->num_of_certs; i++) {
struct curl_slist *slist;
-
+
MAKE_STD_ZVAL(certhash);
array_init(certhash);
for(slist = ci->certinfo[i]; slist; slist = slist->next) {
@@ -1509,14 +1859,14 @@ static void create_certinfo(struct curl_certinfo *ci, zval *listcode TSRMLS_DC)
MAKE_STD_ZVAL(hash);
array_init(hash);
-
+
split_certinfo(&slist->data[len+1], hash);
add_assoc_zval(certhash, s, hash);
} else {
add_assoc_string(certhash, s, &slist->data[len+1], 1);
}
} else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not extract hash key from certificate info");
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not extract hash key from certificate info");
}
}
add_next_index_zval(listcode, certhash);
@@ -1526,6 +1876,36 @@ static void create_certinfo(struct curl_certinfo *ci, zval *listcode TSRMLS_DC)
/* }}} */
#endif
+/* {{{ _php_curl_set_default_options()
+ Set default options for a handle */
+static void _php_curl_set_default_options(php_curl *ch)
+{
+ char *cainfo;
+
+ 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);
+ curl_easy_setopt(ch->cp, CURLOPT_WRITEFUNCTION, curl_write);
+ curl_easy_setopt(ch->cp, CURLOPT_FILE, (void *) ch);
+ curl_easy_setopt(ch->cp, CURLOPT_READFUNCTION, curl_read);
+ curl_easy_setopt(ch->cp, CURLOPT_INFILE, (void *) ch);
+ curl_easy_setopt(ch->cp, CURLOPT_HEADERFUNCTION, curl_write_header);
+ curl_easy_setopt(ch->cp, CURLOPT_WRITEHEADER, (void *) ch);
+ curl_easy_setopt(ch->cp, CURLOPT_DNS_USE_GLOBAL_CACHE, 1);
+ curl_easy_setopt(ch->cp, CURLOPT_DNS_CACHE_TIMEOUT, 120);
+ curl_easy_setopt(ch->cp, CURLOPT_MAXREDIRS, 20); /* prevent infinite redirects */
+
+ cainfo = INI_STR("curl.cainfo");
+ if (cainfo && strlen(cainfo) > 0) {
+ curl_easy_setopt(ch->cp, CURLOPT_CAINFO, cainfo);
+ }
+
+#if defined(ZTS)
+ curl_easy_setopt(ch->cp, CURLOPT_NOSIGNAL, 1);
+#endif
+}
+/* }}} */
+
/* {{{ proto resource curl_init([string url])
Initialize a cURL session */
PHP_FUNCTION(curl_init)
@@ -1535,7 +1915,6 @@ PHP_FUNCTION(curl_init)
zval *clone;
char *url = NULL;
int url_len = 0;
- char *cainfo;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &url, &url_len) == FAILURE) {
return;
@@ -1553,36 +1932,13 @@ PHP_FUNCTION(curl_init)
ch->cp = cp;
ch->handlers->write->method = PHP_CURL_STDOUT;
- ch->handlers->write->type = PHP_CURL_ASCII;
ch->handlers->read->method = PHP_CURL_DIRECT;
ch->handlers->write_header->method = PHP_CURL_IGNORE;
- 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);
- curl_easy_setopt(ch->cp, CURLOPT_WRITEFUNCTION, curl_write);
- curl_easy_setopt(ch->cp, CURLOPT_FILE, (void *) ch);
- curl_easy_setopt(ch->cp, CURLOPT_READFUNCTION, curl_read);
- curl_easy_setopt(ch->cp, CURLOPT_INFILE, (void *) ch);
- curl_easy_setopt(ch->cp, CURLOPT_HEADERFUNCTION, curl_write_header);
- curl_easy_setopt(ch->cp, CURLOPT_WRITEHEADER, (void *) ch);
- curl_easy_setopt(ch->cp, CURLOPT_DNS_USE_GLOBAL_CACHE, 1);
- curl_easy_setopt(ch->cp, CURLOPT_DNS_CACHE_TIMEOUT, 120);
- curl_easy_setopt(ch->cp, CURLOPT_MAXREDIRS, 20); /* prevent infinite redirects */
-
- cainfo = INI_STR("curl.cainfo");
- if (cainfo && strlen(cainfo) > 0) {
- curl_easy_setopt(ch->cp, CURLOPT_CAINFO, cainfo);
- }
-
-#if defined(ZTS)
- curl_easy_setopt(ch->cp, CURLOPT_NOSIGNAL, 1);
-#endif
+ _php_curl_set_default_options(ch);
if (url) {
if (!php_curl_option_url(ch, url, url_len TSRMLS_CC)) {
@@ -1620,14 +1976,12 @@ PHP_FUNCTION(curl_copy_handle)
TSRMLS_SET_CTX(dupch->thread_ctx);
dupch->cp = cp;
- dupch->uses = 0;
- ch->uses++;
+ zend_list_addref(Z_LVAL_P(zid));
if (ch->handlers->write->stream) {
Z_ADDREF_P(ch->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);
}
@@ -1662,18 +2016,34 @@ PHP_FUNCTION(curl_copy_handle)
zval_add_ref(&ch->handlers->write_header->func_name);
dupch->handlers->write_header->func_name = ch->handlers->write_header->func_name;
}
-
- if (ch->handlers->progress->func_name) {
- zval_add_ref(&ch->handlers->progress->func_name);
- dupch->handlers->progress->func_name = ch->handlers->progress->func_name;
- }
- dupch->handlers->progress->method = ch->handlers->progress->method;
curl_easy_setopt(dupch->cp, CURLOPT_ERRORBUFFER, dupch->err.str);
curl_easy_setopt(dupch->cp, CURLOPT_FILE, (void *) dupch);
curl_easy_setopt(dupch->cp, CURLOPT_INFILE, (void *) dupch);
curl_easy_setopt(dupch->cp, CURLOPT_WRITEHEADER, (void *) dupch);
- curl_easy_setopt(dupch->cp, CURLOPT_PROGRESSDATA, (void *) dupch);
+
+ if (ch->handlers->progress) {
+ dupch->handlers->progress = ecalloc(1, sizeof(php_curl_progress));
+ if (ch->handlers->progress->func_name) {
+ zval_add_ref(&ch->handlers->progress->func_name);
+ dupch->handlers->progress->func_name = ch->handlers->progress->func_name;
+ }
+ dupch->handlers->progress->method = ch->handlers->progress->method;
+ curl_easy_setopt(dupch->cp, CURLOPT_PROGRESSDATA, (void *) dupch);
+ }
+
+/* Available since 7.21.0 */
+#if LIBCURL_VERSION_NUM >= 0x071500
+ if (ch->handlers->fnmatch) {
+ dupch->handlers->fnmatch = ecalloc(1, sizeof(php_curl_fnmatch));
+ if (ch->handlers->fnmatch->func_name) {
+ zval_add_ref(&ch->handlers->fnmatch->func_name);
+ dupch->handlers->fnmatch->func_name = ch->handlers->fnmatch->func_name;
+ }
+ dupch->handlers->fnmatch->method = ch->handlers->fnmatch->method;
+ curl_easy_setopt(dupch->cp, CURLOPT_FNMATCH_DATA, (void *) dupch);
+ }
+#endif
efree(dupch->to_free->slist);
efree(dupch->to_free);
@@ -1704,89 +2074,151 @@ static int _php_curl_setopt(php_curl *ch, long option, zval **zvalue, zval *retu
break;
#endif
}
- case CURLOPT_INFILESIZE:
- case CURLOPT_VERBOSE:
- case CURLOPT_HEADER:
- case CURLOPT_NOPROGRESS:
- case CURLOPT_NOBODY:
+ case CURLOPT_AUTOREFERER:
+ case CURLOPT_BUFFERSIZE:
+ case CURLOPT_CLOSEPOLICY:
+ case CURLOPT_CONNECTTIMEOUT:
+ case CURLOPT_COOKIESESSION:
+ case CURLOPT_CRLF:
+ case CURLOPT_DNS_CACHE_TIMEOUT:
+ case CURLOPT_DNS_USE_GLOBAL_CACHE:
case CURLOPT_FAILONERROR:
- case CURLOPT_UPLOAD:
- case CURLOPT_POST:
- case CURLOPT_FTPLISTONLY:
- case CURLOPT_FTPAPPEND:
- case CURLOPT_NETRC:
- case CURLOPT_PUT:
-#if CURLOPT_MUTE != 0
- case CURLOPT_MUTE:
-#endif
- case CURLOPT_TIMEOUT:
-#if LIBCURL_VERSION_NUM > 0x071002
- case CURLOPT_TIMEOUT_MS:
-#endif
+ case CURLOPT_FILETIME:
+ case CURLOPT_FORBID_REUSE:
+ case CURLOPT_FRESH_CONNECT:
+ case CURLOPT_FTP_USE_EPRT:
case CURLOPT_FTP_USE_EPSV:
+ case CURLOPT_HEADER:
+ case CURLOPT_HTTPGET:
+ case CURLOPT_HTTPPROXYTUNNEL:
+ case CURLOPT_HTTP_VERSION:
+ case CURLOPT_INFILESIZE:
case CURLOPT_LOW_SPEED_LIMIT:
- case CURLOPT_SSLVERSION:
case CURLOPT_LOW_SPEED_TIME:
- case CURLOPT_RESUME_FROM:
- case CURLOPT_TIMEVALUE:
- case CURLOPT_TIMECONDITION:
- case CURLOPT_TRANSFERTEXT:
- case CURLOPT_HTTPPROXYTUNNEL:
- case CURLOPT_FILETIME:
- case CURLOPT_MAXREDIRS:
case CURLOPT_MAXCONNECTS:
- case CURLOPT_CLOSEPOLICY:
- case CURLOPT_FRESH_CONNECT:
- case CURLOPT_FORBID_REUSE:
- case CURLOPT_CONNECTTIMEOUT:
-#if LIBCURL_VERSION_NUM > 0x071002
- case CURLOPT_CONNECTTIMEOUT_MS:
-#endif
- case CURLOPT_SSL_VERIFYPEER:
- case CURLOPT_DNS_USE_GLOBAL_CACHE:
+ case CURLOPT_MAXREDIRS:
+ case CURLOPT_NETRC:
+ case CURLOPT_NOBODY:
+ case CURLOPT_NOPROGRESS:
case CURLOPT_NOSIGNAL:
- case CURLOPT_PROXYTYPE:
- case CURLOPT_BUFFERSIZE:
- case CURLOPT_HTTPGET:
- case CURLOPT_HTTP_VERSION:
- case CURLOPT_CRLF:
- case CURLOPT_DNS_CACHE_TIMEOUT:
+ case CURLOPT_PORT:
+ case CURLOPT_POST:
case CURLOPT_PROXYPORT:
- case CURLOPT_FTP_USE_EPRT:
-#if LIBCURL_VERSION_NUM > 0x070a05 /* CURLOPT_HTTPAUTH is available since curl 7.10.6 */
+ case CURLOPT_PROXYTYPE:
+ case CURLOPT_PUT:
+ case CURLOPT_RESUME_FROM:
+ case CURLOPT_SSLVERSION:
+ case CURLOPT_SSL_VERIFYPEER:
+ case CURLOPT_TIMECONDITION:
+ case CURLOPT_TIMEOUT:
+ case CURLOPT_TIMEVALUE:
+ case CURLOPT_TRANSFERTEXT:
+ case CURLOPT_UNRESTRICTED_AUTH:
+ case CURLOPT_UPLOAD:
+ case CURLOPT_VERBOSE:
+#if LIBCURL_VERSION_NUM >= 0x070a06 /* Available since 7.10.6 */
case CURLOPT_HTTPAUTH:
#endif
-#if LIBCURL_VERSION_NUM > 0x070a06 /* CURLOPT_PROXYAUTH & CURLOPT_FTP_CREATE_MISSING_DIRS are available since curl 7.10.7 */
- case CURLOPT_PROXYAUTH:
+#if LIBCURL_VERSION_NUM >= 0x070a07 /* Available since 7.10.7 */
case CURLOPT_FTP_CREATE_MISSING_DIRS:
+ case CURLOPT_PROXYAUTH:
#endif
-
-#if LIBCURL_VERSION_NUM >= 0x070c02
+#if LIBCURL_VERSION_NUM >= 0x070a08 /* Available since 7.10.8 */
+ case CURLOPT_FTP_RESPONSE_TIMEOUT:
+ case CURLOPT_IPRESOLVE:
+ case CURLOPT_MAXFILESIZE:
+#endif
+#if LIBCURL_VERSION_NUM >= 0x070b02 /* Available since 7.11.2 */
+ case CURLOPT_TCP_NODELAY:
+#endif
+#if LIBCURL_VERSION_NUM >= 0x070c02 /* Available since 7.12.2 */
case CURLOPT_FTPSSLAUTH:
#endif
-#if LIBCURL_VERSION_NUM > 0x070b00
+#if LIBCURL_VERSION_NUM >= 0x070e01 /* Available since 7.14.1 */
+ case CURLOPT_IGNORE_CONTENT_LENGTH:
+#endif
+#if LIBCURL_VERSION_NUM >= 0x070f00 /* Available since 7.15.0 */
+ case CURLOPT_FTP_SKIP_PASV_IP:
+#endif
+#if LIBCURL_VERSION_NUM >= 0x070f01 /* Available since 7.15.1 */
+ case CURLOPT_FTP_FILEMETHOD:
+#endif
+#if LIBCURL_VERSION_NUM >= 0x070f02 /* Available since 7.15.2 */
+ case CURLOPT_CONNECT_ONLY:
+ case CURLOPT_LOCALPORT:
+ case CURLOPT_LOCALPORTRANGE:
+#endif
+#if LIBCURL_VERSION_NUM >= 0x071000 /* Available since 7.16.0 */
+ case CURLOPT_SSL_SESSIONID_CACHE:
+#endif
+#if LIBCURL_VERSION_NUM >= 0x071001 /* Available since 7.16.1 */
+ case CURLOPT_FTP_SSL_CCC:
+ case CURLOPT_SSH_AUTH_TYPES:
+#endif
+#if LIBCURL_VERSION_NUM >= 0x071002 /* Available since 7.16.2 */
+ case CURLOPT_CONNECTTIMEOUT_MS:
+ case CURLOPT_HTTP_CONTENT_DECODING:
+ case CURLOPT_HTTP_TRANSFER_DECODING:
+ case CURLOPT_TIMEOUT_MS:
+#endif
+#if LIBCURL_VERSION_NUM >= 0x071004 /* Available since 7.16.4 */
+ case CURLOPT_NEW_DIRECTORY_PERMS:
+ case CURLOPT_NEW_FILE_PERMS:
+#endif
+#if LIBCURL_VERSION_NUM >= 0x071100 /* Available since 7.17.0 */
+ case CURLOPT_USE_SSL:
+#elif LIBCURL_VERSION_NUM >= 0x070b00 /* Available since 7.11.0 */
case CURLOPT_FTP_SSL:
#endif
- case CURLOPT_UNRESTRICTED_AUTH:
- case CURLOPT_PORT:
- case CURLOPT_AUTOREFERER:
- case CURLOPT_COOKIESESSION:
-#if LIBCURL_VERSION_NUM > 0x070b01 /* CURLOPT_TCP_NODELAY is available since curl 7.11.2 */
- case CURLOPT_TCP_NODELAY:
+#if LIBCURL_VERSION_NUM >= 0x071100 /* Available since 7.17.0 */
+ case CURLOPT_APPEND:
+ case CURLOPT_DIRLISTONLY:
+#else
+ case CURLOPT_FTPAPPEND:
+ case CURLOPT_FTPLISTONLY:
#endif
-#if LIBCURL_VERSION_NUM >= 0x71304
- case CURLOPT_REDIR_PROTOCOLS:
+#if LIBCURL_VERSION_NUM >= 0x071200 /* Available since 7.18.0 */
+ case CURLOPT_PROXY_TRANSFER_MODE:
+#endif
+#if LIBCURL_VERSION_NUM >= 0x071300 /* Available since 7.19.0 */
+ case CURLOPT_ADDRESS_SCOPE:
+#endif
+#if LIBCURL_VERSION_NUM > 0x071301 /* Available since 7.19.1 */
+ case CURLOPT_CERTINFO:
+#endif
+#if LIBCURL_VERSION_NUM >= 0x071304 /* Available since 7.19.4 */
+ case CURLOPT_NOPROXY:
case CURLOPT_PROTOCOLS:
+ case CURLOPT_REDIR_PROTOCOLS:
+ case CURLOPT_SOCKS5_GSSAPI_NEC:
+ case CURLOPT_TFTP_BLKSIZE:
#endif
-#if LIBCURL_VERSION_NUM > 0x070a07 /* CURLOPT_IPRESOLVE is available since curl 7.10.8 */
- case CURLOPT_IPRESOLVE:
+#if LIBCURL_VERSION_NUM >= 0x071400 /* Available since 7.20.0 */
+ case CURLOPT_FTP_USE_PRET:
+ case CURLOPT_RTSP_CLIENT_CSEQ:
+ case CURLOPT_RTSP_REQUEST:
+ case CURLOPT_RTSP_SERVER_CSEQ:
#endif
-#if LIBCURL_VERSION_NUM >= 0x070f01
- case CURLOPT_FTP_FILEMETHOD:
- case CURLOPT_FTP_SKIP_PASV_IP:
+#if LIBCURL_VERSION_NUM >= 0x071500 /* Available since 7.21.0 */
+ case CURLOPT_WILDCARDMATCH:
#endif
-#if LIBCURL_VERSION_NUM > 0x071301
- case CURLOPT_CERTINFO:
+#if LIBCURL_VERSION_NUM >= 0x071504 /* Available since 7.21.4 */
+ case CURLOPT_TLSAUTH_TYPE:
+#endif
+#if LIBCURL_VERSION_NUM >= 0x071600 /* Available since 7.22.0 */
+ case CURLOPT_GSSAPI_DELEGATION:
+#endif
+#if LIBCURL_VERSION_NUM >= 0x071800 /* Available since 7.24.0 */
+ case CURLOPT_ACCEPTTIMEOUT_MS:
+#endif
+#if LIBCURL_VERSION_NUM >= 0x071900 /* Available since 7.25.0 */
+ case CURLOPT_SSL_OPTIONS:
+ case CURLOPT_TCP_KEEPALIVE:
+ case CURLOPT_TCP_KEEPIDLE:
+ case CURLOPT_TCP_KEEPINTVL:
+#endif
+#if CURLOPT_MUTE != 0
+ case CURLOPT_MUTE:
#endif
convert_to_long_ex(zvalue);
#if LIBCURL_VERSION_NUM >= 0x71304
@@ -1799,71 +2231,84 @@ static int _php_curl_setopt(php_curl *ch, long option, zval **zvalue, zval *retu
#endif
error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue));
break;
-#if LIBCURL_VERSION_NUM > 0x070f04
- case CURLOPT_MAX_RECV_SPEED_LARGE:
- case CURLOPT_MAX_SEND_SPEED_LARGE:
+ case CURLOPT_SAFE_UPLOAD:
convert_to_long_ex(zvalue);
- error = curl_easy_setopt(ch->cp, option, (curl_off_t)Z_LVAL_PP(zvalue));
+ ch->safe_upload = (Z_LVAL_PP(zvalue) != 0);
break;
-#endif
- case CURLOPT_FOLLOWLOCATION:
- convert_to_long_ex(zvalue);
- if (PG(open_basedir) && *PG(open_basedir)) {
- if (Z_LVAL_PP(zvalue) != 0) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "CURLOPT_FOLLOWLOCATION cannot be activated when an open_basedir is set");
- RETVAL_FALSE;
- return 1;
- }
- }
- error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue));
- break;
-#if LIBCURL_VERSION_NUM > 0x071301
- case CURLOPT_POSTREDIR:
- convert_to_long_ex(zvalue);
- error = curl_easy_setopt(ch->cp, CURLOPT_POSTREDIR, Z_LVAL_PP(zvalue) & CURL_REDIR_POST_ALL);
- break;
-#endif
+
+ /* String options */
+ case CURLOPT_CAINFO:
+ case CURLOPT_CAPATH:
+ case CURLOPT_COOKIE:
+ case CURLOPT_CUSTOMREQUEST:
+ case CURLOPT_EGDSOCKET:
+ case CURLOPT_FTPPORT:
+ case CURLOPT_INTERFACE:
case CURLOPT_PRIVATE:
- case CURLOPT_URL:
case CURLOPT_PROXY:
- case CURLOPT_USERPWD:
case CURLOPT_PROXYUSERPWD:
case CURLOPT_RANGE:
- case CURLOPT_CUSTOMREQUEST:
- case CURLOPT_USERAGENT:
- case CURLOPT_FTPPORT:
- case CURLOPT_COOKIE:
case CURLOPT_REFERER:
- case CURLOPT_INTERFACE:
- case CURLOPT_KRB4LEVEL:
- case CURLOPT_EGDSOCKET:
- case CURLOPT_CAINFO:
- case CURLOPT_CAPATH:
- case CURLOPT_SSL_CIPHER_LIST:
- case CURLOPT_SSLKEY:
- case CURLOPT_SSLKEYTYPE:
- case CURLOPT_SSLKEYPASSWD:
+ case CURLOPT_SSLCERTTYPE:
case CURLOPT_SSLENGINE:
case CURLOPT_SSLENGINE_DEFAULT:
- case CURLOPT_SSLCERTTYPE:
+ case CURLOPT_SSLKEY:
+ case CURLOPT_SSLKEYPASSWD:
+ case CURLOPT_SSLKEYTYPE:
+ case CURLOPT_SSL_CIPHER_LIST:
+ case CURLOPT_URL:
+ case CURLOPT_USERAGENT:
+ case CURLOPT_USERPWD:
+#if LIBCURL_VERSION_NUM >= 0x070d00 /* Available since 7.13.0 */
+ case CURLOPT_FTP_ACCOUNT:
+#endif
+#if LIBCURL_VERSION_NUM >= 0x070e01 /* Available since 7.14.1 */
+ case CURLOPT_COOKIELIST:
+#endif
+#if LIBCURL_VERSION_NUM >= 0x070f05 /* Available since 7.15.5 */
+ case CURLOPT_FTP_ALTERNATIVE_TO_USER:
+#endif
+#if LIBCURL_VERSION_NUM >= 0x071004 /* Available since 7.16.4 */
+ case CURLOPT_KRBLEVEL:
+#else
+ case CURLOPT_KRB4LEVEL:
+#endif
+#if LIBCURL_VERSION_NUM >= 0x071101 /* Available since 7.17.1 */
+ case CURLOPT_SSH_HOST_PUBLIC_KEY_MD5:
+#endif
+#if LIBCURL_VERSION_NUM >= 0x071301 /* Available since 7.19.1 */
+ case CURLOPT_PASSWORD:
+ case CURLOPT_PROXYPASSWORD:
+ case CURLOPT_PROXYUSERNAME:
+ case CURLOPT_USERNAME:
+#endif
+#if LIBCURL_VERSION_NUM >= 0x071304 /* Available since 7.19.4 */
+ case CURLOPT_SOCKS5_GSSAPI_SERVICE:
+#endif
+#if LIBCURL_VERSION_NUM >= 0x071400 /* Available since 7.20.0 */
+ case CURLOPT_MAIL_FROM:
+ case CURLOPT_RTSP_SESSION_ID:
+ case CURLOPT_RTSP_STREAM_URI:
+ case CURLOPT_RTSP_TRANSPORT:
+#endif
+#if LIBCURL_VERSION_NUM >= 0x071504 /* Available since 7.21.4 */
+ case CURLOPT_TLSAUTH_PASSWORD:
+ case CURLOPT_TLSAUTH_USERNAME:
+#endif
+#if LIBCURL_VERSION_NUM >= 0x071506 /* Available since 7.21.6 */
+ case CURLOPT_ACCEPT_ENCODING:
+ case CURLOPT_TRANSFER_ENCODING:
+#else
case CURLOPT_ENCODING:
-#if LIBCURL_VERSION_NUM >= 0x071300
- case CURLOPT_SSH_PUBLIC_KEYFILE:
- case CURLOPT_SSH_PRIVATE_KEYFILE:
+#endif
+#if LIBCURL_VERSION_NUM >= 0x071800 /* Available since 7.24.0 */
+ case CURLOPT_DNS_SERVERS:
+#endif
+#if LIBCURL_VERSION_NUM >= 0x071900 /* Available since 7.25.0 */
+ case CURLOPT_MAIL_AUTH:
#endif
{
convert_to_string_ex(zvalue);
-#if LIBCURL_VERSION_NUM >= 0x071300
- if (
- option == CURLOPT_SSH_PUBLIC_KEYFILE || option == CURLOPT_SSH_PRIVATE_KEYFILE
-
- ) {
- if (php_check_open_basedir(Z_STRVAL_PP(zvalue) TSRMLS_CC)) {
- RETVAL_FALSE;
- return 1;
- }
- }
-#endif
if (option == CURLOPT_URL) {
if (!php_curl_option_url(ch, Z_STRVAL_PP(zvalue), Z_STRLEN_PP(zvalue) TSRMLS_CC)) {
RETVAL_FALSE;
@@ -1882,17 +2327,19 @@ string_copy:
#if LIBCURL_VERSION_NUM >= 0x071100
/* Strings passed to libcurl as ’char *’ arguments, are copied by the library... NOTE: before 7.17.0 strings were not copied. */
error = curl_easy_setopt(ch->cp, option, Z_STRVAL_PP(zvalue));
-#else
- goto string_copy;
+#else
+ goto string_copy;
#endif
}
}
break;
}
+
+ /* Curl file handle options */
case CURLOPT_FILE:
case CURLOPT_INFILE:
- case CURLOPT_WRITEHEADER:
- case CURLOPT_STDERR: {
+ case CURLOPT_STDERR:
+ case CURLOPT_WRITEHEADER: {
FILE *fp = NULL;
int type;
void * what;
@@ -1971,56 +2418,102 @@ string_copy:
error = curl_easy_setopt(ch->cp, option, fp);
break;
}
-
break;
}
- case CURLOPT_RETURNTRANSFER:
- convert_to_long_ex(zvalue);
- if (Z_LVAL_PP(zvalue)) {
- ch->handlers->write->method = PHP_CURL_RETURN;
- } else {
- ch->handlers->write->method = PHP_CURL_STDOUT;
- }
- break;
- case CURLOPT_BINARYTRANSFER:
- convert_to_long_ex(zvalue);
+ /* Curl linked list options */
+ case CURLOPT_HTTP200ALIASES:
+ case CURLOPT_HTTPHEADER:
+ case CURLOPT_POSTQUOTE:
+ case CURLOPT_PREQUOTE:
+ case CURLOPT_QUOTE:
+ case CURLOPT_TELNETOPTIONS:
+#if LIBCURL_VERSION_NUM >= 0x071400 /* Available since 7.20.0 */
+ case CURLOPT_MAIL_RCPT:
+#endif
+#if LIBCURL_VERSION_NUM >= 0x071503 /* Available since 7.21.3 */
+ case CURLOPT_RESOLVE:
+#endif
+ {
+ zval **current;
+ HashTable *ph;
+ struct curl_slist *slist = NULL;
- if (Z_LVAL_PP(zvalue)) {
- ch->handlers->write->type = PHP_CURL_BINARY;
- } else {
- ch->handlers->write->type = PHP_CURL_ASCII;
+ ph = HASH_OF(*zvalue);
+ if (!ph) {
+ char *name = NULL;
+ switch (option) {
+ case CURLOPT_HTTPHEADER:
+ name = "CURLOPT_HTTPHEADER";
+ break;
+ case CURLOPT_QUOTE:
+ name = "CURLOPT_QUOTE";
+ break;
+ case CURLOPT_HTTP200ALIASES:
+ name = "CURLOPT_HTTP200ALIASES";
+ break;
+ case CURLOPT_POSTQUOTE:
+ name = "CURLOPT_POSTQUOTE";
+ break;
+ case CURLOPT_PREQUOTE:
+ name = "CURLOPT_PREQUOTE";
+ break;
+ case CURLOPT_TELNETOPTIONS:
+ name = "CURLOPT_TELNETOPTIONS";
+ break;
+#if LIBCURL_VERSION_NUM >= 0x071400 /* Available since 7.20.0 */
+ case CURLOPT_MAIL_RCPT:
+ name = "CURLOPT_MAIL_RCPT";
+ break;
+#endif
+#if LIBCURL_VERSION_NUM >= 0x071503 /* Available since 7.21.3 */
+ case CURLOPT_RESOLVE:
+ name = "CURLOPT_RESOLVE";
+ break;
+#endif
+ }
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "You must pass either an object or an array with the %s argument", name);
+ RETVAL_FALSE;
+ return 1;
}
- break;
- case CURLOPT_WRITEFUNCTION:
- if (ch->handlers->write->func_name) {
- zval_ptr_dtor(&ch->handlers->write->func_name);
- ch->handlers->write->fci_cache = empty_fcall_info_cache;
+
+ for (zend_hash_internal_pointer_reset(ph);
+ zend_hash_get_current_data(ph, (void **) &current) == SUCCESS;
+ zend_hash_move_forward(ph)
+ ) {
+ SEPARATE_ZVAL(current);
+ convert_to_string_ex(current);
+
+ slist = curl_slist_append(slist, Z_STRVAL_PP(current));
+ if (!slist) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not build curl_slist");
+ RETVAL_FALSE;
+ return 1;
+ }
}
- zval_add_ref(zvalue);
- ch->handlers->write->func_name = *zvalue;
- ch->handlers->write->method = PHP_CURL_USER;
+ zend_hash_index_update(ch->to_free->slist, (ulong) option, &slist, sizeof(struct curl_slist *), NULL);
+
+ error = curl_easy_setopt(ch->cp, option, slist);
+
break;
- case CURLOPT_READFUNCTION:
- if (ch->handlers->read->func_name) {
- zval_ptr_dtor(&ch->handlers->read->func_name);
- ch->handlers->read->fci_cache = empty_fcall_info_cache;
- }
- zval_add_ref(zvalue);
- ch->handlers->read->func_name = *zvalue;
- ch->handlers->read->method = PHP_CURL_USER;
+ }
+
+ case CURLOPT_BINARYTRANSFER:
+ /* Do nothing, just backward compatibility */
break;
- case CURLOPT_PROGRESSFUNCTION:
- curl_easy_setopt(ch->cp, CURLOPT_PROGRESSFUNCTION, curl_progress);
- curl_easy_setopt(ch->cp, CURLOPT_PROGRESSDATA, ch);
- if (ch->handlers->progress->func_name) {
- zval_ptr_dtor(&ch->handlers->progress->func_name);
- ch->handlers->progress->fci_cache = empty_fcall_info_cache;
+
+ case CURLOPT_FOLLOWLOCATION:
+ convert_to_long_ex(zvalue);
+ if (PG(open_basedir) && *PG(open_basedir)) {
+ if (Z_LVAL_PP(zvalue) != 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "CURLOPT_FOLLOWLOCATION cannot be activated when an open_basedir is set");
+ RETVAL_FALSE;
+ return 1;
+ }
}
- zval_add_ref(zvalue);
- ch->handlers->progress->func_name = *zvalue;
- ch->handlers->progress->method = PHP_CURL_USER;
+ error = curl_easy_setopt(ch->cp, option, Z_LVAL_PP(zvalue));
break;
+
case CURLOPT_HEADERFUNCTION:
if (ch->handlers->write_header->func_name) {
zval_ptr_dtor(&ch->handlers->write_header->func_name);
@@ -2030,17 +2523,7 @@ string_copy:
ch->handlers->write_header->func_name = *zvalue;
ch->handlers->write_header->method = PHP_CURL_USER;
break;
-#if CURLOPT_PASSWDFUNCTION != 0
- case CURLOPT_PASSWDFUNCTION:
- if (ch->handlers->passwd) {
- zval_ptr_dtor(&ch->handlers->passwd);
- }
- zval_add_ref(zvalue);
- ch->handlers->passwd = *zvalue;
- error = curl_easy_setopt(ch->cp, CURLOPT_PASSWDFUNCTION, curl_passwd);
- error = curl_easy_setopt(ch->cp, CURLOPT_PASSWDDATA, (void *) ch);
- break;
-#endif
+
case CURLOPT_POSTFIELDS:
if (Z_TYPE_PP(zvalue) == IS_ARRAY || Z_TYPE_PP(zvalue) == IS_OBJECT) {
zval **current;
@@ -2059,14 +2542,11 @@ string_copy:
zend_hash_get_current_data(postfields, (void **) &current) == SUCCESS;
zend_hash_move_forward(postfields)
) {
- char *postval;
- char *string_key = NULL;
- uint string_key_len;
- ulong num_key;
- int numeric_key;
-
- SEPARATE_ZVAL(current);
- convert_to_string_ex(current);
+ char *postval;
+ char *string_key = NULL;
+ uint string_key_len;
+ ulong num_key;
+ int numeric_key;
zend_hash_get_current_key_ex(postfields, &string_key, &string_key_len, &num_key, 0, NULL);
@@ -2079,15 +2559,59 @@ string_copy:
numeric_key = 0;
}
+ if(Z_TYPE_PP(current) == IS_OBJECT && instanceof_function(Z_OBJCE_PP(current), curl_CURLFile_class TSRMLS_CC)) {
+ /* new-style file upload */
+ zval *prop;
+ char *type = NULL, *filename = NULL;
+
+ prop = zend_read_property(curl_CURLFile_class, *current, "name", sizeof("name")-1, 0 TSRMLS_CC);
+ if(Z_TYPE_P(prop) != IS_STRING) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid filename for key %s", string_key);
+ } else {
+ postval = Z_STRVAL_P(prop);
+
+ if (php_check_open_basedir(postval TSRMLS_CC)) {
+ RETVAL_FALSE;
+ return 1;
+ }
+
+ prop = zend_read_property(curl_CURLFile_class, *current, "mime", sizeof("mime")-1, 0 TSRMLS_CC);
+ if(Z_TYPE_P(prop) == IS_STRING && Z_STRLEN_P(prop) > 0) {
+ type = Z_STRVAL_P(prop);
+ }
+ prop = zend_read_property(curl_CURLFile_class, *current, "postname", sizeof("postname")-1, 0 TSRMLS_CC);
+ if(Z_TYPE_P(prop) == IS_STRING && Z_STRLEN_P(prop) > 0) {
+ filename = Z_STRVAL_P(prop);
+ }
+ 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 : "application/octet-stream",
+ CURLFORM_FILE, postval,
+ CURLFORM_END);
+ }
+
+ if (numeric_key) {
+ efree(string_key);
+ }
+ continue;
+ }
+
+ SEPARATE_ZVAL(current);
+ convert_to_string_ex(current);
+
postval = Z_STRVAL_PP(current);
/* The arguments after _NAMELENGTH and _CONTENTSLENGTH
* must be explicitly cast to long in curl_formadd
* use since curl needs a long not an int. */
- if (*postval == '@') {
+ if (!ch->safe_upload && *postval == '@') {
char *type, *filename;
++postval;
+ php_error_docref("curl.curlfile" TSRMLS_CC, E_DEPRECATED, "The usage of the @filename API for file uploading is deprecated. Please use the CURLFile class instead");
+
if ((type = php_memnstr(postval, ";type=", sizeof(";type=") - 1, postval + Z_STRLEN_PP(current)))) {
*type = '\0';
}
@@ -2156,48 +2680,99 @@ string_copy:
#endif
}
break;
- case CURLOPT_HTTPHEADER:
- case CURLOPT_QUOTE:
- case CURLOPT_HTTP200ALIASES:
- case CURLOPT_POSTQUOTE: {
- zval **current;
- HashTable *ph;
- struct curl_slist *slist = NULL;
- ph = HASH_OF(*zvalue);
- if (!ph) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "You must pass either an object or an array with the CURLOPT_HTTPHEADER, CURLOPT_QUOTE, CURLOPT_HTTP200ALIASES and CURLOPT_POSTQUOTE arguments");
- RETVAL_FALSE;
- return 1;
+ case CURLOPT_PROGRESSFUNCTION:
+ curl_easy_setopt(ch->cp, CURLOPT_PROGRESSFUNCTION, curl_progress);
+ curl_easy_setopt(ch->cp, CURLOPT_PROGRESSDATA, ch);
+ if (ch->handlers->progress == NULL) {
+ ch->handlers->progress = ecalloc(1, sizeof(php_curl_progress));
+ } else if (ch->handlers->progress->func_name) {
+ zval_ptr_dtor(&ch->handlers->progress->func_name);
+ ch->handlers->progress->fci_cache = empty_fcall_info_cache;
+ }
+ zval_add_ref(zvalue);
+ ch->handlers->progress->func_name = *zvalue;
+ ch->handlers->progress->method = PHP_CURL_USER;
+ break;
+
+ case CURLOPT_READFUNCTION:
+ if (ch->handlers->read->func_name) {
+ zval_ptr_dtor(&ch->handlers->read->func_name);
+ ch->handlers->read->fci_cache = empty_fcall_info_cache;
}
+ zval_add_ref(zvalue);
+ ch->handlers->read->func_name = *zvalue;
+ ch->handlers->read->method = PHP_CURL_USER;
+ break;
- for (zend_hash_internal_pointer_reset(ph);
- zend_hash_get_current_data(ph, (void **) &current) == SUCCESS;
- zend_hash_move_forward(ph)
- ) {
- SEPARATE_ZVAL(current);
- convert_to_string_ex(current);
+ case CURLOPT_RETURNTRANSFER:
+ convert_to_long_ex(zvalue);
+ if (Z_LVAL_PP(zvalue)) {
+ ch->handlers->write->method = PHP_CURL_RETURN;
+ } else {
+ ch->handlers->write->method = PHP_CURL_STDOUT;
+ }
+ break;
- slist = curl_slist_append(slist, Z_STRVAL_PP(current));
- if (!slist) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not build curl_slist");
- RETVAL_FALSE;
- return 1;
- }
+ case CURLOPT_WRITEFUNCTION:
+ if (ch->handlers->write->func_name) {
+ zval_ptr_dtor(&ch->handlers->write->func_name);
+ ch->handlers->write->fci_cache = empty_fcall_info_cache;
}
- zend_hash_index_update(ch->to_free->slist, (ulong) option, &slist, sizeof(struct curl_slist *), NULL);
+ zval_add_ref(zvalue);
+ ch->handlers->write->func_name = *zvalue;
+ ch->handlers->write->method = PHP_CURL_USER;
+ break;
- error = curl_easy_setopt(ch->cp, option, slist);
+#if LIBCURL_VERSION_NUM >= 0x070f05 /* Available since 7.15.5 */
+ case CURLOPT_MAX_RECV_SPEED_LARGE:
+ case CURLOPT_MAX_SEND_SPEED_LARGE:
+ convert_to_long_ex(zvalue);
+ error = curl_easy_setopt(ch->cp, option, (curl_off_t)Z_LVAL_PP(zvalue));
+ break;
+#endif
+#if LIBCURL_VERSION_NUM >= 0x071301 /* Available since 7.19.1 */
+ case CURLOPT_POSTREDIR:
+ convert_to_long_ex(zvalue);
+ error = curl_easy_setopt(ch->cp, CURLOPT_POSTREDIR, Z_LVAL_PP(zvalue) & CURL_REDIR_POST_ALL);
break;
- }
+#endif
+
+#if CURLOPT_PASSWDFUNCTION != 0
+ case CURLOPT_PASSWDFUNCTION:
+ if (ch->handlers->passwd) {
+ zval_ptr_dtor(&ch->handlers->passwd);
+ }
+ zval_add_ref(zvalue);
+ ch->handlers->passwd = *zvalue;
+ error = curl_easy_setopt(ch->cp, CURLOPT_PASSWDFUNCTION, curl_passwd);
+ error = curl_easy_setopt(ch->cp, CURLOPT_PASSWDDATA, (void *) ch);
+ break;
+#endif
+
/* the following options deal with files, therefore the open_basedir check
* is required.
*/
+ case CURLOPT_COOKIEFILE:
case CURLOPT_COOKIEJAR:
- case CURLOPT_SSLCERT:
case CURLOPT_RANDOM_FILE:
- case CURLOPT_COOKIEFILE: {
+ case CURLOPT_SSLCERT:
+#if LIBCURL_VERSION_NUM >= 0x070b00 /* Available since 7.11.0 */
+ case CURLOPT_NETRC_FILE:
+#endif
+#if LIBCURL_VERSION_NUM >= 0x071001 /* Available since 7.16.1 */
+ case CURLOPT_SSH_PRIVATE_KEYFILE:
+ case CURLOPT_SSH_PUBLIC_KEYFILE:
+#endif
+#if LIBCURL_VERSION_NUM >= 0x071300 /* Available since 7.19.0 */
+ case CURLOPT_CRLFILE:
+ case CURLOPT_ISSUERCERT:
+#endif
+#if LIBCURL_VERSION_NUM >= 0x071306 /* Available since 7.19.6 */
+ case CURLOPT_SSH_KNOWNHOSTS:
+#endif
+ {
#if LIBCURL_VERSION_NUM < 0x071100
char *copystr = NULL;
#endif
@@ -2219,6 +2794,7 @@ string_copy:
#endif
break;
}
+
case CURLINFO_HEADER_OUT:
convert_to_long_ex(zvalue);
if (Z_LVAL_PP(zvalue) == 1) {
@@ -2231,6 +2807,32 @@ string_copy:
curl_easy_setopt(ch->cp, CURLOPT_VERBOSE, 0);
}
break;
+
+ case CURLOPT_SHARE:
+ {
+ php_curlsh *sh = NULL;
+ ZEND_FETCH_RESOURCE_NO_RETURN(sh, php_curlsh *, zvalue, -1, le_curl_share_handle_name, le_curl_share_handle);
+ if (sh) {
+ curl_easy_setopt(ch->cp, CURLOPT_SHARE, sh->share);
+ }
+ }
+
+#if LIBCURL_VERSION_NUM >= 0x071500 /* Available since 7.21.0 */
+ case CURLOPT_FNMATCH_FUNCTION:
+ curl_easy_setopt(ch->cp, CURLOPT_FNMATCH_FUNCTION, curl_fnmatch);
+ curl_easy_setopt(ch->cp, CURLOPT_FNMATCH_DATA, ch);
+ if (ch->handlers->fnmatch == NULL) {
+ ch->handlers->fnmatch = ecalloc(1, sizeof(php_curl_fnmatch));
+ } else if (ch->handlers->fnmatch->func_name) {
+ zval_ptr_dtor(&ch->handlers->fnmatch->func_name);
+ ch->handlers->fnmatch->fci_cache = empty_fcall_info_cache;
+ }
+ zval_add_ref(zvalue);
+ ch->handlers->fnmatch->func_name = *zvalue;
+ ch->handlers->fnmatch->method = PHP_CURL_USER;
+ break;
+#endif
+
}
SAVE_CURL_ERROR(ch, error);
@@ -2256,7 +2858,7 @@ PHP_FUNCTION(curl_setopt)
ZEND_FETCH_RESOURCE(ch, php_curl *, &zid, -1, le_curl_name, le_curl);
- if (options <= 0) {
+ if (options <= 0 && options != CURLOPT_SAFE_UPLOAD) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid curl configuration option");
RETURN_FALSE;
}
@@ -2467,7 +3069,17 @@ PHP_FUNCTION(curl_getinfo)
if (curl_easy_getinfo(ch->cp, CURLINFO_REDIRECT_TIME, &d_code) == CURLE_OK) {
CAAD("redirect_time", d_code);
}
-#if LIBCURL_VERSION_NUM > 0x071301
+#if LIBCURL_VERSION_NUM >= 0x071202 /* Available since 7.18.2 */
+ if (curl_easy_getinfo(ch->cp, CURLINFO_REDIRECT_URL, &s_code) == CURLE_OK) {
+ CAAS("redirect_url", s_code);
+ }
+#endif
+#if LIBCURL_VERSION_NUM >= 0x071300 /* Available since 7.19.0 */
+ if (curl_easy_getinfo(ch->cp, CURLINFO_PRIMARY_IP, &s_code) == CURLE_OK) {
+ CAAS("primary_ip", s_code);
+ }
+#endif
+#if LIBCURL_VERSION_NUM >= 0x071301 /* Available since 7.19.1 */
if (curl_easy_getinfo(ch->cp, CURLINFO_CERTINFO, &ci) == CURLE_OK) {
MAKE_STD_ZVAL(listcode);
array_init(listcode);
@@ -2475,12 +3087,7 @@ PHP_FUNCTION(curl_getinfo)
CAAZ("certinfo", listcode);
}
#endif
-#if LIBCURL_VERSION_NUM >= 0x071300 /* 7.19.0 */
- if (curl_easy_getinfo(ch->cp, CURLINFO_PRIMARY_IP, &s_code) == CURLE_OK) {
- CAAS("primary_ip", s_code);
- }
-#endif
-#if LIBCURL_VERSION_NUM > 0x071500
+#if LIBCURL_VERSION_NUM >= 0x071500 /* Available since 7.21.0 */
if (curl_easy_getinfo(ch->cp, CURLINFO_PRIMARY_PORT, &l_code) == CURLE_OK) {
CAAL("primary_port", l_code);
}
@@ -2491,93 +3098,23 @@ PHP_FUNCTION(curl_getinfo)
CAAL("local_port", l_code);
}
#endif
-#if LIBCURL_VERSION_NUM >= 0x071202
- if (curl_easy_getinfo(ch->cp, CURLINFO_REDIRECT_URL, &s_code) == CURLE_OK) {
- CAAS("redirect_url", s_code);
- }
-#endif
if (ch->header.str_len > 0) {
CAAS("request_header", ch->header.str);
}
} else {
switch (option) {
- /* string variable types */
-#if LIBCURL_VERSION_NUM >= 0x071300 /* 7.19.0 */
- case CURLINFO_PRIMARY_IP:
-#endif
-#if LIBCURL_VERSION_NUM >= 0x071500 /* 7.21.0 */
- case CURLINFO_LOCAL_IP:
-#endif
- case CURLINFO_PRIVATE:
- case CURLINFO_EFFECTIVE_URL:
- case CURLINFO_CONTENT_TYPE:
-#if LIBCURL_VERSION_NUM >= 0x071202
- case CURLINFO_REDIRECT_URL:
-#endif
- {
- char *s_code = NULL;
-
- if (curl_easy_getinfo(ch->cp, option, &s_code) == CURLE_OK && s_code) {
- RETURN_STRING(s_code, 1);
- } else {
- RETURN_FALSE;
- }
- break;
- }
- /* Long variable types */
-#if LIBCURL_VERSION_NUM >= 0x071500 /* 7.21.0 */
- case CURLINFO_PRIMARY_PORT:
- case CURLINFO_LOCAL_PORT:
-#endif
- case CURLINFO_HTTP_CODE:
- case CURLINFO_HEADER_SIZE:
- case CURLINFO_REQUEST_SIZE:
- case CURLINFO_FILETIME:
- case CURLINFO_SSL_VERIFYRESULT:
- case CURLINFO_REDIRECT_COUNT: {
- long code = 0;
-
- if (curl_easy_getinfo(ch->cp, option, &code) == CURLE_OK) {
- RETURN_LONG(code);
- } else {
- RETURN_FALSE;
- }
- break;
- }
- /* Double variable types */
- case CURLINFO_TOTAL_TIME:
- case CURLINFO_NAMELOOKUP_TIME:
- case CURLINFO_CONNECT_TIME:
- case CURLINFO_PRETRANSFER_TIME:
- case CURLINFO_SIZE_UPLOAD:
- case CURLINFO_SIZE_DOWNLOAD:
- case CURLINFO_SPEED_DOWNLOAD:
- case CURLINFO_SPEED_UPLOAD:
- case CURLINFO_CONTENT_LENGTH_DOWNLOAD:
- case CURLINFO_CONTENT_LENGTH_UPLOAD:
- case CURLINFO_STARTTRANSFER_TIME:
- case CURLINFO_REDIRECT_TIME: {
- double code = 0.0;
-
- if (curl_easy_getinfo(ch->cp, option, &code) == CURLE_OK) {
- RETURN_DOUBLE(code);
- } else {
- RETURN_FALSE;
- }
- break;
- }
case CURLINFO_HEADER_OUT:
if (ch->header.str_len > 0) {
RETURN_STRINGL(ch->header.str, ch->header.str_len, 1);
} else {
RETURN_FALSE;
}
-#if LIBCURL_VERSION_NUM > 0x071301
+#if LIBCURL_VERSION_NUM >= 0x071301 /* Available since 7.19.1 */
case CURLINFO_CERTINFO: {
struct curl_certinfo *ci = NULL;
array_init(return_value);
-
+
if (curl_easy_getinfo(ch->cp, CURLINFO_CERTINFO, &ci) == CURLE_OK) {
create_certinfo(ci, return_value TSRMLS_CC);
} else {
@@ -2586,6 +3123,61 @@ PHP_FUNCTION(curl_getinfo)
break;
}
#endif
+ default: {
+ int type = CURLINFO_TYPEMASK & option;
+ switch (type) {
+ case CURLINFO_STRING:
+ {
+ char *s_code = NULL;
+
+ if (curl_easy_getinfo(ch->cp, option, &s_code) == CURLE_OK && s_code) {
+ RETURN_STRING(s_code, 1);
+ } else {
+ RETURN_FALSE;
+ }
+ break;
+ }
+ case CURLINFO_LONG:
+ {
+ long code = 0;
+
+ if (curl_easy_getinfo(ch->cp, option, &code) == CURLE_OK) {
+ RETURN_LONG(code);
+ } else {
+ RETURN_FALSE;
+ }
+ break;
+ }
+ case CURLINFO_DOUBLE:
+ {
+ double code = 0.0;
+
+ if (curl_easy_getinfo(ch->cp, option, &code) == CURLE_OK) {
+ RETURN_DOUBLE(code);
+ } else {
+ RETURN_FALSE;
+ }
+ break;
+ }
+ case CURLINFO_SLIST:
+ {
+ struct curl_slist *slist;
+ array_init(return_value);
+ if (curl_easy_getinfo(ch->cp, option, &slist) == CURLE_OK) {
+ while (slist) {
+ add_next_index_string(return_value, slist->data, 1);
+ slist = slist->next;
+ }
+ curl_slist_free_all(slist);
+ } else {
+ RETURN_FALSE;
+ }
+ break;
+ }
+ default:
+ RETURN_FALSE;
+ }
+ }
}
}
}
@@ -2644,11 +3236,7 @@ PHP_FUNCTION(curl_close)
return;
}
- if (ch->uses) {
- ch->uses--;
- } else {
- zend_list_delete(Z_LVAL_P(zid));
- }
+ zend_list_delete(Z_LVAL_P(zid));
}
/* }}} */
@@ -2662,16 +3250,16 @@ static void _php_curl_close_ex(php_curl *ch TSRMLS_DC)
_php_curl_verify_handlers(ch, 0 TSRMLS_CC);
- /*
+ /*
* Libcurl is doing connection caching. When easy handle is cleaned up,
- * if the handle was previously used by the curl_multi_api, the connection
+ * if the handle was previously used by the curl_multi_api, the connection
* remains open un the curl multi handle is cleaned up. Some protocols are
- * sending content like the FTP one, and libcurl try to use the
+ * sending content like the FTP one, and libcurl try to use the
* WRITEFUNCTION or the HEADERFUNCTION. Since structures used in those
* callback are freed, we need to use an other callback to which avoid
* segfaults.
*
- * Libcurl commit d021f2e8a00 fix this issue and should be part of 7.28.2
+ * Libcurl commit d021f2e8a00 fix this issue and should be part of 7.28.2
*/
curl_easy_setopt(ch->cp, CURLOPT_HEADERFUNCTION, curl_write_nothing);
curl_easy_setopt(ch->cp, CURLOPT_WRITEFUNCTION, curl_write_nothing);
@@ -2702,12 +3290,11 @@ static void _php_curl_close_ex(php_curl *ch TSRMLS_DC)
if (ch->handlers->write_header->func_name) {
zval_ptr_dtor(&ch->handlers->write_header->func_name);
}
- if (ch->handlers->progress->func_name) {
- zval_ptr_dtor(&ch->handlers->progress->func_name);
- }
+#if CURLOPT_PASSWDFUNCTION != 0
if (ch->handlers->passwd) {
zval_ptr_dtor(&ch->handlers->passwd);
}
+#endif
if (ch->handlers->std_err) {
zval_ptr_dtor(&ch->handlers->std_err);
}
@@ -2728,7 +3315,23 @@ static void _php_curl_close_ex(php_curl *ch TSRMLS_DC)
efree(ch->handlers->write);
efree(ch->handlers->write_header);
efree(ch->handlers->read);
- efree(ch->handlers->progress);
+
+ if (ch->handlers->progress) {
+ if (ch->handlers->progress->func_name) {
+ zval_ptr_dtor(&ch->handlers->progress->func_name);
+ }
+ efree(ch->handlers->progress);
+ }
+
+#if LIBCURL_VERSION_NUM >= 0x071500 /* Available since 7.21.0 */
+ if (ch->handlers->fnmatch) {
+ if (ch->handlers->fnmatch->func_name) {
+ zval_ptr_dtor(&ch->handlers->fnmatch->func_name);
+ }
+ efree(ch->handlers->fnmatch);
+ }
+#endif
+
efree(ch->handlers);
efree(ch);
}
@@ -2743,6 +3346,176 @@ static void _php_curl_close(zend_rsrc_list_entry *rsrc TSRMLS_DC)
}
/* }}} */
+#if LIBCURL_VERSION_NUM >= 0x070c00 /* Available since 7.12.0 */
+/* {{{ proto bool curl_strerror(int code)
+ return string describing error code */
+PHP_FUNCTION(curl_strerror)
+{
+ long code;
+ const char *str;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &code) == FAILURE) {
+ return;
+ }
+
+ str = curl_easy_strerror(code);
+ if (str) {
+ RETURN_STRING(str, 1);
+ } else {
+ RETURN_NULL();
+ }
+}
+/* }}} */
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x070c01 /* 7.12.1 */
+/* {{{ _php_curl_reset_handlers()
+ Reset all handlers of a given php_curl */
+static void _php_curl_reset_handlers(php_curl *ch)
+{
+ if (ch->handlers->write->stream) {
+ Z_DELREF_P(ch->handlers->write->stream);
+ ch->handlers->write->stream = NULL;
+ }
+ ch->handlers->write->fp = NULL;
+ ch->handlers->write->method = PHP_CURL_STDOUT;
+
+ if (ch->handlers->write_header->stream) {
+ Z_DELREF_P(ch->handlers->write_header->stream);
+ ch->handlers->write_header->stream = NULL;
+ }
+ ch->handlers->write_header->fp = NULL;
+ ch->handlers->write_header->method = PHP_CURL_IGNORE;
+
+ if (ch->handlers->read->stream) {
+ Z_DELREF_P(ch->handlers->read->stream);
+ ch->handlers->read->stream = NULL;
+ }
+ ch->handlers->read->fp = NULL;
+ ch->handlers->read->fd = 0;
+ ch->handlers->read->method = PHP_CURL_DIRECT;
+
+ if (ch->handlers->std_err) {
+ zval_ptr_dtor(&ch->handlers->std_err);
+ ch->handlers->std_err = NULL;
+ }
+
+ if (ch->handlers->progress) {
+ if (ch->handlers->progress->func_name) {
+ zval_ptr_dtor(&ch->handlers->progress->func_name);
+ }
+ efree(ch->handlers->progress);
+ ch->handlers->progress = NULL;
+ }
+
+#if LIBCURL_VERSION_NUM >= 0x071500 /* Available since 7.21.0 */
+ if (ch->handlers->fnmatch) {
+ if (ch->handlers->fnmatch->func_name) {
+ zval_ptr_dtor(&ch->handlers->fnmatch->func_name);
+ }
+ efree(ch->handlers->fnmatch);
+ ch->handlers->fnmatch = NULL;
+ }
+#endif
+
+}
+/* }}} */
+
+/* {{{ proto void curl_reset(resource ch)
+ Reset all options of a libcurl session handle */
+PHP_FUNCTION(curl_reset)
+{
+ zval *zid;
+ php_curl *ch;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zid) == FAILURE) {
+ return;
+ }
+
+ ZEND_FETCH_RESOURCE(ch, php_curl *, &zid, -1, le_curl_name, le_curl);
+
+ if (ch->in_callback) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attempt to reset cURL handle from a callback");
+ return;
+ }
+
+ curl_easy_reset(ch->cp);
+ _php_curl_reset_handlers(ch);
+ _php_curl_set_default_options(ch);
+}
+/* }}} */
+#endif
+
+#if LIBCURL_VERSION_NUM > 0x070f03 /* 7.15.4 */
+/* {{{ proto void curl_escape(resource ch, string str)
+ URL encodes the given string */
+PHP_FUNCTION(curl_escape)
+{
+ char *str = NULL, *res = NULL;
+ int str_len = 0;
+ zval *zid;
+ php_curl *ch;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &zid, &str, &str_len) == FAILURE) {
+ return;
+ }
+
+ ZEND_FETCH_RESOURCE(ch, php_curl *, &zid, -1, le_curl_name, le_curl);
+
+ if ((res = curl_easy_escape(ch->cp, str, str_len))) {
+ RETVAL_STRING(res, 1);
+ curl_free(res);
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
+/* {{{ proto void curl_unescape(resource ch, string str)
+ URL decodes the given string */
+PHP_FUNCTION(curl_unescape)
+{
+ char *str = NULL, *out = NULL;
+ int str_len = 0, out_len;
+ zval *zid;
+ php_curl *ch;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &zid, &str, &str_len) == FAILURE) {
+ return;
+ }
+
+ ZEND_FETCH_RESOURCE(ch, php_curl *, &zid, -1, le_curl_name, le_curl);
+
+ if ((out = curl_easy_unescape(ch->cp, str, str_len, &out_len))) {
+ RETVAL_STRINGL(out, out_len, 1);
+ curl_free(out);
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x071200 /* 7.18.0 */
+/* {{{ proto void curl_pause(resource ch, int bitmask)
+ pause and unpause a connection */
+PHP_FUNCTION(curl_pause)
+{
+ long bitmask;
+ zval *zid;
+ php_curl *ch;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &zid, &bitmask) == FAILURE) {
+ return;
+ }
+
+ ZEND_FETCH_RESOURCE(ch, php_curl *, &zid, -1, le_curl_name, le_curl);
+
+ RETURN_LONG(curl_easy_pause(ch->cp, bitmask));
+}
+/* }}} */
+#endif
+
#endif /* HAVE_CURL */
/*
diff --git a/ext/curl/multi.c b/ext/curl/multi.c
index a990dad2f2..e5c026a513 100644
--- a/ext/curl/multi.c
+++ b/ext/curl/multi.c
@@ -86,7 +86,6 @@ PHP_FUNCTION(curl_multi_add_handle)
ZEND_FETCH_RESOURCE(ch, php_curl *, &z_ch, -1, le_curl_name, le_curl);
_php_curl_cleanup_handle(ch);
- ch->uses++;
/* we want to create a copy of this zval that we store in the multihandle structure element "easyh" */
tmp_val = *z_ch;
@@ -113,11 +112,7 @@ void _php_curl_multi_cleanup_list(void *data) /* {{{ */
return;
}
- if (ch->uses) {
- ch->uses--;
- } else {
- zend_list_delete(Z_LVAL_P(z_ch));
- }
+ zend_list_delete(Z_LVAL_P(z_ch));
}
/* }}} */
@@ -125,8 +120,8 @@ void _php_curl_multi_cleanup_list(void *data) /* {{{ */
static int curl_compare_resources( zval *z1, zval **z2 ) /* {{{ */
{
return (Z_TYPE_P( z1 ) == Z_TYPE_PP( z2 ) &&
- Z_TYPE_P( z1 ) == IS_RESOURCE &&
- Z_LVAL_P( z1 ) == Z_LVAL_PP( z2 ) );
+ Z_TYPE_P( z1 ) == IS_RESOURCE &&
+ Z_LVAL_P( z1 ) == Z_LVAL_PP( z2 ) );
}
/* }}} */
@@ -146,12 +141,12 @@ PHP_FUNCTION(curl_multi_remove_handle)
ZEND_FETCH_RESOURCE(mh, php_curlm *, &z_mh, -1, le_curl_multi_handle_name, le_curl_multi_handle);
ZEND_FETCH_RESOURCE(ch, php_curl *, &z_ch, -1, le_curl_name, le_curl);
- --ch->uses;
+
+ RETVAL_LONG((long) curl_multi_remove_handle(mh->multi, ch->cp));
zend_llist_del_element( &mh->easyh, &z_ch,
(int (*)(void *, void *)) curl_compare_resources );
-
- RETURN_LONG((long) curl_multi_remove_handle(mh->multi, ch->cp));
+
}
/* }}} */
@@ -359,6 +354,81 @@ void _php_curl_multi_close(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
}
/* }}} */
+#if LIBCURL_VERSION_NUM >= 0x070c00 /* Available since 7.12.0 */
+/* {{{ proto bool curl_multi_strerror(int code)
+ return string describing error code */
+PHP_FUNCTION(curl_multi_strerror)
+{
+ long code;
+ const char *str;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &code) == FAILURE) {
+ return;
+ }
+
+ str = curl_multi_strerror(code);
+ if (str) {
+ RETURN_STRING(str, 1);
+ } else {
+ RETURN_NULL();
+ }
+}
+/* }}} */
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x070f04 /* 7.15.4 */
+static int _php_curl_multi_setopt(php_curlm *mh, long option, zval **zvalue, zval *return_value TSRMLS_DC) /* {{{ */
+{
+ CURLMcode error = CURLM_OK;
+
+ switch (option) {
+#if LIBCURL_VERSION_NUM >= 0x071000 /* 7.16.0 */
+ case CURLMOPT_PIPELINING:
+#endif
+#if LIBCURL_VERSION_NUM >= 0x071003 /* 7.16.3 */
+ case CURLMOPT_MAXCONNECTS:
+#endif
+ convert_to_long_ex(zvalue);
+ error = curl_multi_setopt(mh->multi, option, Z_LVAL_PP(zvalue));
+ break;
+
+ default:
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid curl multi configuration option");
+ error = CURLM_UNKNOWN_OPTION;
+ break;
+ }
+
+ if (error != CURLM_OK) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+/* }}} */
+
+/* {{{ proto int curl_multi_setopt(resource mh, int option, mixed value)
+ Set an option for the curl multi handle */
+PHP_FUNCTION(curl_multi_setopt)
+{
+ zval *z_mh, **zvalue;
+ long options;
+ php_curlm *mh;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlZ", &z_mh, &options, &zvalue) == FAILURE) {
+ return;
+ }
+
+ ZEND_FETCH_RESOURCE(mh, php_curlm *, &z_mh, -1, le_curl_multi_handle_name, le_curl_multi_handle);
+
+ if (!_php_curl_multi_setopt(mh, options, zvalue, return_value TSRMLS_CC)) {
+ RETURN_TRUE;
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+#endif
+
#endif
/*
diff --git a/ext/curl/package.xml b/ext/curl/package.xml
index 85cb634c63..c14321738d 100644
--- a/ext/curl/package.xml
+++ b/ext/curl/package.xml
@@ -39,6 +39,7 @@ package.xml added to support installation using pear installer
<file role="src" name="curl.dsp"/>
<file role="src" name="interface.c"/>
<file role="src" name="multi.c"/>
+ <file role="src" name="share.c"/>
<file role="src" name="streams.c"/>
<file role="src" name="php_curl.h"/>
</filelist>
diff --git a/ext/curl/php_curl.h b/ext/curl/php_curl.h
index c613da1dc6..e02a890b0b 100644
--- a/ext/curl/php_curl.h
+++ b/ext/curl/php_curl.h
@@ -34,6 +34,14 @@
#define PHP_CURL_DEBUG 0
+#ifdef PHP_WIN32
+# define PHP_CURL_API __declspec(dllexport)
+#elif defined(__GNUC__) && __GNUC__ >= 4
+# define PHP_CURL_API __attribute__ ((visibility("default")))
+#else
+# define PHP_CURL_API
+#endif
+
#include <curl/curl.h>
#include <curl/multi.h>
@@ -41,43 +49,73 @@ extern zend_module_entry curl_module_entry;
#define curl_module_ptr &curl_module_entry
#define CURLOPT_RETURNTRANSFER 19913
-#define CURLOPT_BINARYTRANSFER 19914
+#define CURLOPT_BINARYTRANSFER 19914 /* For Backward compatibility */
#define PHP_CURL_STDOUT 0
#define PHP_CURL_FILE 1
#define PHP_CURL_USER 2
#define PHP_CURL_DIRECT 3
#define PHP_CURL_RETURN 4
-#define PHP_CURL_ASCII 5
-#define PHP_CURL_BINARY 6
#define PHP_CURL_IGNORE 7
extern int le_curl;
#define le_curl_name "cURL handle"
extern int le_curl_multi_handle;
#define le_curl_multi_handle_name "cURL Multi Handle"
+extern int le_curl_share_handle;
+#define le_curl_share_handle_name "cURL Share Handle"
PHP_MINIT_FUNCTION(curl);
PHP_MSHUTDOWN_FUNCTION(curl);
PHP_MINFO_FUNCTION(curl);
-PHP_FUNCTION(curl_version);
-PHP_FUNCTION(curl_init);
+
+PHP_FUNCTION(curl_close);
PHP_FUNCTION(curl_copy_handle);
-PHP_FUNCTION(curl_setopt);
-PHP_FUNCTION(curl_setopt_array);
+PHP_FUNCTION(curl_errno);
+PHP_FUNCTION(curl_error);
PHP_FUNCTION(curl_exec);
PHP_FUNCTION(curl_getinfo);
-PHP_FUNCTION(curl_error);
-PHP_FUNCTION(curl_errno);
-PHP_FUNCTION(curl_close);
-PHP_FUNCTION(curl_multi_init);
+PHP_FUNCTION(curl_init);
+PHP_FUNCTION(curl_setopt);
+PHP_FUNCTION(curl_setopt_array);
+PHP_FUNCTION(curl_version);
+
PHP_FUNCTION(curl_multi_add_handle);
-PHP_FUNCTION(curl_multi_remove_handle);
-PHP_FUNCTION(curl_multi_select);
+PHP_FUNCTION(curl_multi_close);
PHP_FUNCTION(curl_multi_exec);
PHP_FUNCTION(curl_multi_getcontent);
PHP_FUNCTION(curl_multi_info_read);
-PHP_FUNCTION(curl_multi_close);
+PHP_FUNCTION(curl_multi_init);
+PHP_FUNCTION(curl_multi_remove_handle);
+PHP_FUNCTION(curl_multi_select);
+
+PHP_FUNCTION(curl_share_close);
+PHP_FUNCTION(curl_share_init);
+PHP_FUNCTION(curl_share_setopt);
+
+#if LIBCURL_VERSION_NUM >= 0x070c00 /* 7.12.0 */
+PHP_FUNCTION(curl_strerror);
+PHP_FUNCTION(curl_multi_strerror);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x070c01 /* 7.12.1 */
+PHP_FUNCTION(curl_reset);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x070f04 /* 7.15.4 */
+PHP_FUNCTION(curl_escape);
+PHP_FUNCTION(curl_unescape);
+
+PHP_FUNCTION(curl_multi_setopt);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x071200 /* 7.18.0 */
+PHP_FUNCTION(curl_pause);
+#endif
+PHP_FUNCTION(curl_file_create);
+
+
void _php_curl_multi_close(zend_rsrc_list_entry * TSRMLS_DC);
+void _php_curl_share_close(zend_rsrc_list_entry * TSRMLS_DC);
typedef struct {
zval *func_name;
@@ -85,7 +123,6 @@ typedef struct {
FILE *fp;
smart_str buf;
int method;
- int type;
zval *stream;
} php_curl_write;
@@ -102,15 +139,20 @@ typedef struct {
zval *func_name;
zend_fcall_info_cache fci_cache;
int method;
-} php_curl_progress;
+} php_curl_progress, php_curl_fnmatch;
typedef struct {
php_curl_write *write;
php_curl_write *write_header;
php_curl_read *read;
+#if CURLOPT_PASSWDFUNCTION != 0
zval *passwd;
+#endif
zval *std_err;
php_curl_progress *progress;
+#if LIBCURL_VERSION_NUM >= 0x071500 /* Available since 7.21.0 */
+ php_curl_fnmatch *fnmatch;
+#endif
} php_curl_handlers;
struct _php_curl_error {
@@ -137,53 +179,29 @@ typedef struct {
CURL *cp;
php_curl_handlers *handlers;
long id;
- unsigned int uses;
zend_bool in_callback;
zval *clone;
+ zend_bool safe_upload;
} php_curl;
+#define CURLOPT_SAFE_UPLOAD -1
+
typedef struct {
int still_running;
CURLM *multi;
zend_llist easyh;
} php_curlm;
+typedef struct {
+ CURLSH *share;
+} php_curlsh;
+
void _php_curl_cleanup_handle(php_curl *);
void _php_curl_multi_cleanup_list(void *data);
int _php_curl_verify_handlers(php_curl *ch, int reporterror TSRMLS_DC);
-/* streams support */
-
-extern php_stream_ops php_curl_stream_ops;
-#define PHP_STREAM_IS_CURL &php_curl_stream_ops
-
-php_stream *php_curl_stream_opener(php_stream_wrapper *wrapper, char *filename, char *mode,
- int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC);
-
-extern php_stream_wrapper php_curl_wrapper;
-
-struct php_curl_buffer {
- off_t readpos, writepos;
- php_stream *buf;
-};
-
-typedef struct {
- CURL *curl;
- CURLM *multi;
- char *url;
- struct php_curl_buffer readbuffer; /* holds downloaded data */
- struct php_curl_buffer writebuffer; /* holds data to upload */
-
- fd_set readfds, writefds, excfds;
- int maxfd;
-
- char errstr[CURL_ERROR_SIZE + 1];
- CURLMcode mcode;
- int pending;
- zval *headers;
- struct curl_slist *headers_slist; /* holds custom headers sent out in the request */
-} php_curl_stream;
-
+void curlfile_register_class(TSRMLS_D);
+PHP_CURL_API extern zend_class_entry *curl_CURLFile_class;
#else
#define curl_module_ptr NULL
diff --git a/ext/curl/share.c b/ext/curl/share.c
new file mode 100644
index 0000000000..d46361e0ae
--- /dev/null
+++ b/ext/curl/share.c
@@ -0,0 +1,136 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2014 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: Pierrick Charron <pierrick@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#define ZEND_INCLUDE_FULL_WINDOWS_HEADERS
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+
+#if HAVE_CURL
+
+#include "php_curl.h"
+
+#include <curl/curl.h>
+
+/* {{{ proto void curl_share_init()
+ Initialize a share curl handle */
+PHP_FUNCTION(curl_share_init)
+{
+ php_curlsh *sh;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ sh = ecalloc(1, sizeof(php_curlsh));
+
+ sh->share = curl_share_init();
+
+ ZEND_REGISTER_RESOURCE(return_value, sh, le_curl_share_handle);
+}
+/* }}} */
+
+/* {{{ proto void curl_share_close(resource sh)
+ Close a set of cURL handles */
+PHP_FUNCTION(curl_share_close)
+{
+ zval *z_sh;
+ php_curlsh *sh;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_sh) == FAILURE) {
+ return;
+ }
+
+ ZEND_FETCH_RESOURCE(sh, php_curlsh *, &z_sh, -1, le_curl_share_handle_name, le_curl_share_handle);
+ zend_list_delete(Z_LVAL_P(z_sh));
+}
+/* }}} */
+
+static int _php_curl_share_setopt(php_curlsh *sh, long option, zval **zvalue, zval *return_value TSRMLS_DC) /* {{{ */
+{
+ CURLSHcode error = CURLSHE_OK;
+
+ switch (option) {
+ case CURLSHOPT_SHARE:
+ case CURLSHOPT_UNSHARE:
+ convert_to_long_ex(zvalue);
+ error = curl_share_setopt(sh->share, option, Z_LVAL_PP(zvalue));
+ break;
+
+ default:
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid curl share configuration option");
+ error = CURLSHE_BAD_OPTION;
+ break;
+ }
+
+ if (error != CURLSHE_OK) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+/* }}} */
+
+/* {{{ proto bool curl_share_setopt(resource sh, int option, mixed value)
+ Set an option for a cURL transfer */
+PHP_FUNCTION(curl_share_setopt)
+{
+ zval *zid, **zvalue;
+ long options;
+ php_curlsh *sh;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlZ", &zid, &options, &zvalue) == FAILURE) {
+ return;
+ }
+
+ ZEND_FETCH_RESOURCE(sh, php_curlsh *, &zid, -1, le_curl_share_handle_name, le_curl_share_handle);
+
+ if (!_php_curl_share_setopt(sh, options, zvalue, return_value TSRMLS_CC)) {
+ RETURN_TRUE;
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
+void _php_curl_share_close(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
+{
+ php_curlsh *sh = (php_curlsh *) rsrc->ptr;
+ if (sh) {
+ curl_share_cleanup(sh->share);
+ efree(sh);
+ rsrc->ptr = NULL;
+ }
+}
+/* }}} */
+
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/curl/streams.c b/ext/curl/streams.c
deleted file mode 100644
index 9681e197ac..0000000000
--- a/ext/curl/streams.c
+++ /dev/null
@@ -1,542 +0,0 @@
-/*
- +----------------------------------------------------------------------+
- | PHP Version 5 |
- +----------------------------------------------------------------------+
- | Copyright (c) 1997-2014 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 <wez@thebrainroom.com> |
- +----------------------------------------------------------------------+
-*/
-
-/* $Id$ */
-
-/* This file implements cURL based wrappers.
- * NOTE: If you are implementing your own streams that are intended to
- * work independently of wrappers, this is not a good example to follow!
- **/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "php.h"
-#include "php_memory_streams.h"
-
-#if HAVE_CURL
-
-#include <stdio.h>
-#include <string.h>
-
-#ifdef PHP_WIN32
-#include <winsock2.h>
-#include <sys/types.h>
-#endif
-
-#include <curl/curl.h>
-#include <curl/easy.h>
-
-#define SMART_STR_PREALLOC 4096
-
-#include "ext/standard/php_smart_str.h"
-#include "ext/standard/info.h"
-#include "ext/standard/file.h"
-#include "ext/standard/php_string.h"
-#include "php_curl.h"
-
-static size_t on_data_available(char *data, size_t size, size_t nmemb, void *ctx)
-{
- php_stream *stream = (php_stream *) ctx;
- php_curl_stream *curlstream = (php_curl_stream *) stream->abstract;
- size_t wrote;
- TSRMLS_FETCH();
-
- /* TODO: I'd like to deprecate this.
- * This code is here because until we start getting real data, we don't know
- * if we have had all of the headers
- * */
- if (curlstream->readbuffer.writepos == 0) {
- zval *sym;
-
- if (!EG(active_symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
- }
- MAKE_STD_ZVAL(sym);
- *sym = *curlstream->headers;
- zval_copy_ctor(sym);
- ZEND_SET_SYMBOL(EG(active_symbol_table), "http_response_header", sym);
- }
-
- php_stream_seek(curlstream->readbuffer.buf, curlstream->readbuffer.writepos, SEEK_SET);
- wrote = php_stream_write(curlstream->readbuffer.buf, data, size * nmemb);
- curlstream->readbuffer.writepos = php_stream_tell(curlstream->readbuffer.buf);
-
- return wrote;
-}
-
-/* cURL guarantees that headers are written as complete lines, with this function
- * called once for each header */
-static size_t on_header_available(char *data, size_t size, size_t nmemb, void *ctx)
-{
- size_t length = size * nmemb;
- zval *header;
- php_stream *stream = (php_stream *) ctx;
- php_curl_stream *curlstream = (php_curl_stream *) stream->abstract;
- TSRMLS_FETCH();
-
- if (length < 2) {
- /* invalid header ? */
- return length;
- }
-
- if (!(length == 2 && data[0] == '\r' && data[1] == '\n')) {
- MAKE_STD_ZVAL(header);
- Z_STRLEN_P(header) = length;
- Z_STRVAL_P(header) = estrndup(data, length);
- if (Z_STRVAL_P(header)[length-1] == '\n') {
- Z_STRVAL_P(header)[length-1] = '\0';
- Z_STRLEN_P(header)--;
-
- if (Z_STRVAL_P(header)[length-2] == '\r') {
- Z_STRVAL_P(header)[length-2] = '\0';
- Z_STRLEN_P(header)--;
- }
- }
- Z_TYPE_P(header) = IS_STRING;
- zend_hash_next_index_insert(Z_ARRVAL_P(curlstream->headers), &header, sizeof(zval *), NULL);
-
- /* based on the header, we might need to trigger a notification */
- if (!strncasecmp(data, "Location: ", 10)) {
- php_stream_notify_info(stream->context, PHP_STREAM_NOTIFY_REDIRECTED, data + 10, 0);
- } else if (!strncasecmp(data, "Content-Type: ", 14)) {
- php_stream_notify_info(stream->context, PHP_STREAM_NOTIFY_MIME_TYPE_IS, data + 14, 0);
- } else if (!strncasecmp(data, "Context-Length: ", 16)) {
- php_stream_notify_file_size(stream->context, atoi(data + 16), data, 0);
- php_stream_notify_progress_init(stream->context, 0, 0);
- }
- }
- return length;
-
-}
-
-static int on_progress_avail(php_stream *stream, double dltotal, double dlnow, double ultotal, double ulnow)
-{
- TSRMLS_FETCH();
-
- /* our notification system only works in a single direction; we should detect which
- * direction is important and use the correct values in this call */
- php_stream_notify_progress(stream->context, (size_t) dlnow, (size_t) dltotal);
- return 0;
-}
-
-static size_t php_curl_stream_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC)
-{
- php_curl_stream *curlstream = (php_curl_stream *) stream->abstract;
-
- if (curlstream->writebuffer.buf) {
- return php_stream_write(curlstream->writebuffer.buf, buf, count);
- }
-
- return 0;
-}
-
-static size_t php_curl_stream_read(php_stream *stream, char *buf, size_t count TSRMLS_DC)
-{
- php_curl_stream *curlstream = (php_curl_stream *) stream->abstract;
- size_t didread = 0;
-
- if (curlstream->readbuffer.readpos >= curlstream->readbuffer.writepos && curlstream->pending) {
- /* we need to read some more data */
- struct timeval tv;
-
- /* fire up the connection */
- if (curlstream->readbuffer.writepos == 0) {
- while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(curlstream->multi, &curlstream->pending));
- }
-
- do {
- FD_ZERO(&curlstream->readfds);
- FD_ZERO(&curlstream->writefds);
- FD_ZERO(&curlstream->excfds);
-
- /* get the descriptors from curl */
- curl_multi_fdset(curlstream->multi, &curlstream->readfds, &curlstream->writefds, &curlstream->excfds, &curlstream->maxfd);
-
- /* if we are in blocking mode, set a timeout */
- tv.tv_usec = 0;
- tv.tv_sec = 15; /* TODO: allow this to be configured from the script */
-
- /* wait for data */
- switch ((curlstream->maxfd < 0) ? 1 :
- select(curlstream->maxfd + 1, &curlstream->readfds, &curlstream->writefds, &curlstream->excfds, &tv)) {
- case -1:
- /* error */
- return 0;
- case 0:
- /* no data yet: timed-out */
- return 0;
- default:
- /* fetch the data */
- do {
- curlstream->mcode = curl_multi_perform(curlstream->multi, &curlstream->pending);
- } while (curlstream->mcode == CURLM_CALL_MULTI_PERFORM);
- }
- } while (curlstream->maxfd >= 0 &&
- curlstream->readbuffer.readpos >= curlstream->readbuffer.writepos && curlstream->pending > 0);
-
- }
-
- /* if there is data in the buffer, try and read it */
- if (curlstream->readbuffer.writepos > 0 && curlstream->readbuffer.readpos < curlstream->readbuffer.writepos) {
- php_stream_seek(curlstream->readbuffer.buf, curlstream->readbuffer.readpos, SEEK_SET);
- didread = php_stream_read(curlstream->readbuffer.buf, buf, count);
- curlstream->readbuffer.readpos = php_stream_tell(curlstream->readbuffer.buf);
- }
-
- if (didread == 0) {
- stream->eof = 1;
- }
-
- return didread;
-}
-
-static int php_curl_stream_close(php_stream *stream, int close_handle TSRMLS_DC)
-{
- php_curl_stream *curlstream = (php_curl_stream *) stream->abstract;
-
- /* TODO: respect the close_handle flag here, so that casting to a FILE* on
- * systems without fopencookie will work properly */
-
- curl_multi_remove_handle(curlstream->multi, curlstream->curl);
- curl_easy_cleanup(curlstream->curl);
- curl_multi_cleanup(curlstream->multi);
-
- if (curlstream->headers_slist) {
- curl_slist_free_all(curlstream->headers_slist);
- }
-
- /* we are not closing curlstream->readbuf here, because we export
- * it as a zval with the wrapperdata - the engine will garbage collect it */
-
- efree(curlstream->url);
- efree(curlstream);
-
- return 0;
-}
-
-static int php_curl_stream_flush(php_stream *stream TSRMLS_DC)
-{
-#ifdef ilia_0
- php_curl_stream *curlstream = (php_curl_stream *) stream->abstract;
-#endif
- return 0;
-}
-
-static int php_curl_stream_stat(php_stream *stream, php_stream_statbuf *ssb TSRMLS_DC)
-{
- /* TODO: fill in details based on Data: and Content-Length: headers, and/or data
- * from curl_easy_getinfo().
- * For now, return -1 to indicate that it doesn't make sense to stat this stream */
- return -1;
-}
-
-static int php_curl_stream_cast(php_stream *stream, int castas, void **ret TSRMLS_DC)
-{
- php_curl_stream *curlstream = (php_curl_stream *) stream->abstract;
- /* delegate to the readbuffer stream */
- return php_stream_cast(curlstream->readbuffer.buf, castas, ret, 0);
-}
-
-php_stream_ops php_curl_stream_ops = {
- php_curl_stream_write,
- php_curl_stream_read,
- php_curl_stream_close,
- php_curl_stream_flush,
- "cURL",
- NULL, /* seek */
- php_curl_stream_cast, /* cast */
- php_curl_stream_stat /* stat */
-};
-
-
-php_stream *php_curl_stream_opener(php_stream_wrapper *wrapper, char *filename, char *mode,
- int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC)
-{
- php_stream *stream;
- php_curl_stream *curlstream;
- zval *tmp, **ctx_opt = NULL;
-
- curlstream = emalloc(sizeof(php_curl_stream));
- memset(curlstream, 0, sizeof(php_curl_stream));
-
- stream = php_stream_alloc(&php_curl_stream_ops, curlstream, 0, mode);
- php_stream_context_set(stream, context);
-
- curlstream->curl = curl_easy_init();
- curlstream->multi = curl_multi_init();
- curlstream->pending = 1;
- curlstream->headers_slist = NULL;
-
- /* if opening for an include statement, ensure that the local storage will
- * have a FILE* associated with it.
- * Otherwise, use the "smart" memory stream that will turn itself into a file
- * when it gets large */
-#ifndef HAVE_FOPENCOOKIE
- if (options & STREAM_WILL_CAST) {
- curlstream->readbuffer.buf = php_stream_fopen_tmpfile();
- } else
-#endif
- {
- curlstream->readbuffer.buf = php_stream_temp_new();
- }
-
- /* curl requires the URL to be valid throughout it's operation, so dup it */
- curlstream->url = estrdup(filename);
- curl_easy_setopt(curlstream->curl, CURLOPT_URL, curlstream->url);
-
- /* feed curl data into our read buffer */
- curl_easy_setopt(curlstream->curl, CURLOPT_WRITEFUNCTION, on_data_available);
- curl_easy_setopt(curlstream->curl, CURLOPT_FILE, stream);
-
- /* feed headers */
- curl_easy_setopt(curlstream->curl, CURLOPT_HEADERFUNCTION, on_header_available);
- curl_easy_setopt(curlstream->curl, CURLOPT_WRITEHEADER, stream);
-
- curl_easy_setopt(curlstream->curl, CURLOPT_ERRORBUFFER, curlstream->errstr);
- curl_easy_setopt(curlstream->curl, CURLOPT_VERBOSE, 0);
-
- /* enable progress notification */
- curl_easy_setopt(curlstream->curl, CURLOPT_PROGRESSFUNCTION, on_progress_avail);
- curl_easy_setopt(curlstream->curl, CURLOPT_PROGRESSDATA, stream);
- curl_easy_setopt(curlstream->curl, CURLOPT_NOPROGRESS, 0);
-
- curl_easy_setopt(curlstream->curl, CURLOPT_USERAGENT, FG(user_agent) ? FG(user_agent) : "PHP/" PHP_VERSION);
-
- /* TODO: read cookies and options from context */
- if (context && !strncasecmp(filename, "http", sizeof("http")-1)) {
- /* Protocol version */
- if (SUCCESS == php_stream_context_get_option(context, "http", "protocol_version", &ctx_opt) && Z_TYPE_PP(ctx_opt) == IS_DOUBLE) {
- if (Z_DVAL_PP(ctx_opt) == 1.1) {
- curl_easy_setopt(curlstream->curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
- } else {
- curl_easy_setopt(curlstream->curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
- }
- }
-
- if (SUCCESS == php_stream_context_get_option(context, "http", "curl_verify_ssl_host", &ctx_opt) && Z_TYPE_PP(ctx_opt) == IS_BOOL && Z_LVAL_PP(ctx_opt) == 1) {
- curl_easy_setopt(curlstream->curl, CURLOPT_SSL_VERIFYHOST, 2);
- } else {
- curl_easy_setopt(curlstream->curl, CURLOPT_SSL_VERIFYHOST, 0);
- }
- if (SUCCESS == php_stream_context_get_option(context, "http", "curl_verify_ssl_peer", &ctx_opt) && Z_TYPE_PP(ctx_opt) == IS_BOOL && Z_LVAL_PP(ctx_opt) == 1) {
- curl_easy_setopt(curlstream->curl, CURLOPT_SSL_VERIFYPEER, 1);
- } else {
- curl_easy_setopt(curlstream->curl, CURLOPT_SSL_VERIFYPEER, 0);
- }
-
- /* HTTP(S) */
- if (SUCCESS == php_stream_context_get_option(context, "http", "user_agent", &ctx_opt) && Z_TYPE_PP(ctx_opt) == IS_STRING) {
- curl_easy_setopt(curlstream->curl, CURLOPT_USERAGENT, Z_STRVAL_PP(ctx_opt));
- }
- if (SUCCESS == php_stream_context_get_option(context, "http", "header", &ctx_opt)) {
- if (Z_TYPE_PP(ctx_opt) == IS_ARRAY) {
- HashPosition pos;
- zval **header = NULL;
-
- for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(ctx_opt), &pos);
- SUCCESS == zend_hash_get_current_data_ex(Z_ARRVAL_PP(ctx_opt), (void *)&header, &pos);
- zend_hash_move_forward_ex(Z_ARRVAL_PP(ctx_opt), &pos)
- ) {
- if (Z_TYPE_PP(header) == IS_STRING) {
- curlstream->headers_slist = curl_slist_append(curlstream->headers_slist, Z_STRVAL_PP(header));
- }
- }
- } else if (Z_TYPE_PP(ctx_opt) == IS_STRING && Z_STRLEN_PP(ctx_opt)) {
- char *p, *token, *trimmed, *copy_ctx_opt;
-
- copy_ctx_opt = php_trim(Z_STRVAL_PP(ctx_opt), Z_STRLEN_PP(ctx_opt), NULL, 0, NULL, 3 TSRMLS_CC);
- p = php_strtok_r(copy_ctx_opt, "\r\n", &token);
- while (p) {
- trimmed = php_trim(p, strlen(p), NULL, 0, NULL, 3 TSRMLS_CC);
- curlstream->headers_slist = curl_slist_append(curlstream->headers_slist, trimmed);
- efree(trimmed);
- p = php_strtok_r(NULL, "\r\n", &token);
- }
- efree(copy_ctx_opt);
- }
- if (curlstream->headers_slist) {
- curl_easy_setopt(curlstream->curl, CURLOPT_HTTPHEADER, curlstream->headers_slist);
- }
- }
- if (SUCCESS == php_stream_context_get_option(context, "http", "method", &ctx_opt) && Z_TYPE_PP(ctx_opt) == IS_STRING) {
- if (strcasecmp(Z_STRVAL_PP(ctx_opt), "get")) {
- if (!strcasecmp(Z_STRVAL_PP(ctx_opt), "head")) {
- curl_easy_setopt(curlstream->curl, CURLOPT_NOBODY, 1);
- } else {
- if (!strcasecmp(Z_STRVAL_PP(ctx_opt), "post")) {
- curl_easy_setopt(curlstream->curl, CURLOPT_POST, 1);
- } else {
- curl_easy_setopt(curlstream->curl, CURLOPT_CUSTOMREQUEST, Z_STRVAL_PP(ctx_opt));
- }
- if (SUCCESS == php_stream_context_get_option(context, "http", "content", &ctx_opt) && Z_TYPE_PP(ctx_opt) == IS_STRING) {
- curl_easy_setopt(curlstream->curl, CURLOPT_POSTFIELDS, Z_STRVAL_PP(ctx_opt));
- curl_easy_setopt(curlstream->curl, CURLOPT_POSTFIELDSIZE, (long)Z_STRLEN_PP(ctx_opt));
- }
- }
- }
- }
- if (SUCCESS == php_stream_context_get_option(context, "http", "proxy", &ctx_opt) && Z_TYPE_PP(ctx_opt) == IS_STRING) {
- curl_easy_setopt(curlstream->curl, CURLOPT_PROXY, Z_STRVAL_PP(ctx_opt));
- }
- if (SUCCESS == php_stream_context_get_option(context, "http", "max_redirects", &ctx_opt)) {
- long mr = 20;
- if (Z_TYPE_PP(ctx_opt) != IS_STRING || !is_numeric_string(Z_STRVAL_PP(ctx_opt), Z_STRLEN_PP(ctx_opt), &mr, NULL, 1)) {
- if (Z_TYPE_PP(ctx_opt) == IS_LONG) {
- mr = Z_LVAL_PP(ctx_opt);
- }
- }
- if (mr > 1) {
- if (PG(open_basedir) && *PG(open_basedir)) {
- curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 0);
- } else {
- curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 1);
- }
- curl_easy_setopt(curlstream->curl, CURLOPT_MAXREDIRS, mr);
- }
- } else {
- if (PG(open_basedir) && *PG(open_basedir)) {
- curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 0);
- } else {
- curl_easy_setopt(curlstream->curl, CURLOPT_FOLLOWLOCATION, 1);
- }
- curl_easy_setopt(curlstream->curl, CURLOPT_MAXREDIRS, 20L);
- }
- } else if (context && !strncasecmp(filename, "ftps", sizeof("ftps")-1)) {
- if (SUCCESS == php_stream_context_get_option(context, "ftp", "curl_verify_ssl_host", &ctx_opt) && Z_TYPE_PP(ctx_opt) == IS_BOOL && Z_LVAL_PP(ctx_opt) == 1) {
- curl_easy_setopt(curlstream->curl, CURLOPT_SSL_VERIFYHOST, 2);
- } else {
- curl_easy_setopt(curlstream->curl, CURLOPT_SSL_VERIFYHOST, 0);
- }
- if (SUCCESS == php_stream_context_get_option(context, "ftp", "curl_verify_ssl_peer", &ctx_opt) && Z_TYPE_PP(ctx_opt) == IS_BOOL && Z_LVAL_PP(ctx_opt) == 1) {
- curl_easy_setopt(curlstream->curl, CURLOPT_SSL_VERIFYPEER, 1);
- } else {
- curl_easy_setopt(curlstream->curl, CURLOPT_SSL_VERIFYPEER, 0);
- }
- }
-
- /* prepare for "pull" mode */
- curl_multi_add_handle(curlstream->multi, curlstream->curl);
-
- /* Prepare stuff for file_get_wrapper_data: the data is an array:
- *
- * data = array(
- * "headers" => array("Content-Type: text/html", "Xxx: Yyy"),
- * "readbuf" => resource (equivalent to curlstream->readbuffer)
- * );
- * */
- MAKE_STD_ZVAL(stream->wrapperdata);
- array_init(stream->wrapperdata);
-
- MAKE_STD_ZVAL(curlstream->headers);
- array_init(curlstream->headers);
-
- add_assoc_zval(stream->wrapperdata, "headers", curlstream->headers);
-
- MAKE_STD_ZVAL(tmp);
- php_stream_to_zval(curlstream->readbuffer.buf, tmp);
- add_assoc_zval(stream->wrapperdata, "readbuf", tmp);
-
-#ifndef HAVE_FOPENCOOKIE
- if (options & STREAM_WILL_CAST) {
- /* we will need to download the whole resource now,
- * since we cannot get the actual FD for the download,
- * so we won't be able to drive curl via stdio. */
-
-/* TODO: this needs finishing */
-
- curl_easy_perform(curlstream->curl);
- }
- else
-#endif
- {
- /* fire up the connection; we need to detect a connection error here,
- * otherwise the curlstream we return ends up doing nothing useful. */
- CURLMcode m;
- CURLMsg *msg;
- int msgs_left, msg_found = 0;
-
- while (CURLM_CALL_MULTI_PERFORM == (m = curl_multi_perform(curlstream->multi, &curlstream->pending))) {
- ; /* spin */
- }
-
- if (m != CURLM_OK) {
-#if HAVE_CURL_MULTI_STRERROR
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", curl_multi_strerror(m));
-#else
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "There was an error mcode=%d", m);
-#endif
- goto exit_fail;
- }
-
- /* we have only one curl handle here, even though we use multi syntax,
- * so it's ok to fail on any error */
- while ((msg = curl_multi_info_read(curlstream->multi, &msgs_left))) {
- if (msg->data.result == CURLE_OK) {
- continue;
- } else {
-#if HAVE_CURL_EASY_STRERROR
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", curl_easy_strerror(msg->data.result));
-#else
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "There was an error mcode=%d", msg->data.result);
-#endif
- msg_found++;
- }
- }
- if (msg_found) {
- goto exit_fail;
- }
- }
-
- return stream;
-
-exit_fail:
- php_stream_close(stream);
- return NULL;
-}
-
-static php_stream_wrapper_ops php_curl_wrapper_ops = {
- php_curl_stream_opener,
- NULL, /* stream_close: curl streams know how to clean themselves up */
- NULL, /* stream_stat: curl streams know how to stat themselves */
- NULL, /* stat url */
- NULL, /* opendir */
- "cURL", /* label */
- NULL, /* unlink */
- NULL, /* rename */
- NULL, /* mkdir */
- NULL /* rmdir */
-};
-
-php_stream_wrapper php_curl_wrapper = {
- &php_curl_wrapper_ops,
- NULL,
- 1 /* is_url */
-};
-
-#endif
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim600: noet sw=4 ts=4 fdm=marker
- * vim<600: noet sw=4 ts=4
- */
diff --git a/ext/curl/tests/bug27023.phpt b/ext/curl/tests/bug27023.phpt
index b738c956e9..62effec990 100644
--- a/ext/curl/tests/bug27023.phpt
+++ b/ext/curl/tests/bug27023.phpt
@@ -1,5 +1,7 @@
--TEST--
Bug #27023 (CURLOPT_POSTFIELDS does not parse content types for files)
+--INI--
+error_reporting = E_ALL & ~E_DEPRECATED
--SKIPIF--
<?php
if (!extension_loaded("curl")) {
diff --git a/ext/curl/tests/bug54995.phpt b/ext/curl/tests/bug54995.phpt
new file mode 100644
index 0000000000..0f3f50f344
--- /dev/null
+++ b/ext/curl/tests/bug54995.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Bug #54995 (Missing CURLINFO_RESPONSE_CODE support)
+--SKIPIF--
+<?php
+if (!extension_loaded("curl")) {
+ exit("skip curl extension not loaded");
+}
+if ($curl_version['version_number'] > 0x070a08) {
+ exit("skip: tests works a versions of curl >= 7.10.8");
+}
+if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) {
+ exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined");
+}
+?>
+--FILE--
+<?php
+
+$host = getenv('PHP_CURL_HTTP_REMOTE_SERVER');
+$ch = curl_init();
+curl_setopt($ch, CURLOPT_URL, "{$host}/get.php");
+curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+
+var_dump(curl_getinfo($ch, CURLINFO_HTTP_CODE) == curl_getinfo($ch, CURLINFO_RESPONSE_CODE));
+
+curl_exec($ch);
+curl_close($ch);
+
+?>
+--EXPECTF--
+bool(true)
diff --git a/ext/curl/tests/check_win_config.phpt b/ext/curl/tests/check_win_config.phpt
new file mode 100644
index 0000000000..103f1cf692
--- /dev/null
+++ b/ext/curl/tests/check_win_config.phpt
@@ -0,0 +1,48 @@
+--TEST--
+Check libcurl config on windows
+--SKIPIF--
+<?php
+if (!extension_loaded("curl")) {
+ die('skip - curl extension not available in this build');
+}
+if(substr(PHP_OS, 0, 3) != 'WIN' )
+ die("skip for windows only");
+?>
+--FILE--
+<?php
+ ob_start();
+ phpinfo();
+ $s = ob_get_contents();
+ ob_end_clean();
+ preg_match('/curl\n\n(.+)\n\n/siU', $s, $m);
+
+ echo $m[1], "\n";
+
+?>
+DONE
+--EXPECTF--
+cURL support => enabled
+cURL Information => %s
+Age => %d
+Features
+AsynchDNS => Yes
+CharConv => No
+Debug => No
+GSS-Negotiate => Yes
+IDN => Yes
+IPv6 => Yes
+krb4 => No
+Largefile => Yes
+libz => Yes
+NTLM => Yes
+NTLMWB => No
+SPNEGO => Yes
+SSL => Yes
+SSPI => Yes
+TLS-SRP => No
+Protocols => dict, file, ftp, ftps, gopher, http, https, imap, imaps, ldap, pop3, pop3s, rtsp, scp, sftp, smtp, smtps, telnet, tftp
+Host => %s-pc-win32
+SSL Version => OpenSSL/%s
+ZLib Version => %s
+libSSH Version => libssh2/%s
+DONE
diff --git a/ext/curl/tests/curl_basic_022.phpt b/ext/curl/tests/curl_basic_022.phpt
new file mode 100644
index 0000000000..d4277a3f89
--- /dev/null
+++ b/ext/curl/tests/curl_basic_022.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Test curl_getinfo() function with CURLINFO_COOKIELIST parameter
+--SKIPIF--
+<?php if (!extension_loaded("curl")) print "skip";
+$curl_version = curl_version();
+if ($curl_version['version_number'] < 0x070e01) {
+ exit("skip: test works only with curl >= 7.14.1");
+}
+?>
+--FILE--
+<?php
+
+$ch = curl_init();
+curl_setopt($ch, CURLOPT_COOKIELIST, 'Set-Cookie: C1=v1; expires=Thu, 31-Dec-2037 23:59:59 GMT; path=/; domain=.php.net');
+curl_setopt($ch, CURLOPT_COOKIELIST, 'Set-Cookie: C2=v2; expires=Thu, 31-Dec-2037 23:59:59 GMT; path=/; domain=.php.net');
+var_dump(curl_getinfo($ch, CURLINFO_COOKIELIST));
+
+?>
+--EXPECT--
+array(2) {
+ [0]=>
+ string(38) ".php.net TRUE / FALSE 2145916799 C1 v1"
+ [1]=>
+ string(38) ".php.net TRUE / FALSE 2145916799 C2 v2"
+}
diff --git a/ext/curl/tests/curl_escape.phpt b/ext/curl/tests/curl_escape.phpt
new file mode 100644
index 0000000000..e759144c8a
--- /dev/null
+++ b/ext/curl/tests/curl_escape.phpt
Binary files differ
diff --git a/ext/curl/tests/curl_file_serialize.phpt b/ext/curl/tests/curl_file_serialize.phpt
new file mode 100644
index 0000000000..43b272ad64
--- /dev/null
+++ b/ext/curl/tests/curl_file_serialize.phpt
@@ -0,0 +1,21 @@
+--TEST--
+CURL file uploading
+--SKIPIF--
+<?php
+if (!extension_loaded("curl")) {
+ exit("skip curl extension not loaded");
+}
+?>
+--FILE--
+<?php
+$data = 'a:2:{s:4:"file";O:8:"CURLFile":3:{s:4:"name";s:13:"testdata1.txt";s:4:"mime";s:0:"";s:8:"postname";s:0:"";}s:4:"data";s:3:"foo";}';
+var_dump(unserialize($data));
+?>
+--EXPECTF--
+Fatal error: Uncaught exception 'Exception' with message 'Unserialization of CURLFile instances is not allowed' in %s
+Stack trace:
+#0 [internal function]: CURLFile->__wakeup()
+#1 %s
+#2 {main}
+ thrown in %s on line %d
+
diff --git a/ext/curl/tests/curl_file_upload.phpt b/ext/curl/tests/curl_file_upload.phpt
new file mode 100644
index 0000000000..d3168e578a
--- /dev/null
+++ b/ext/curl/tests/curl_file_upload.phpt
@@ -0,0 +1,85 @@
+--TEST--
+CURL file uploading
+--SKIPIF--
+<?php
+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--
+<?php
+
+function testcurl($ch, $name, $mime = '', $postname = '')
+{
+ if(!empty($postname)) {
+ $file = new CurlFile($name, $mime, $postname);
+ } else if(!empty($mime)) {
+ $file = new CurlFile($name, $mime);
+ } else {
+ $file = new CurlFile($name);
+ }
+ curl_setopt($ch, CURLOPT_POSTFIELDS, array("file" => $file));
+ var_dump(curl_exec($ch));
+}
+
+$host = getenv('PHP_CURL_HTTP_REMOTE_SERVER');
+$ch = curl_init();
+curl_setopt($ch, CURLOPT_URL, "{$host}/get.php?test=file");
+curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+
+testcurl($ch, __DIR__ . '/curl_testdata1.txt');
+testcurl($ch, __DIR__ . '/curl_testdata1.txt', 'text/plain');
+testcurl($ch, __DIR__ . '/curl_testdata1.txt', '', 'foo.txt');
+testcurl($ch, __DIR__ . '/curl_testdata1.txt', 'text/plain', 'foo.txt');
+
+$file = new CurlFile(__DIR__ . '/curl_testdata1.txt');
+$file->setMimeType('text/plain');
+var_dump($file->getMimeType());
+var_dump($file->getFilename());
+curl_setopt($ch, CURLOPT_POSTFIELDS, array("file" => $file));
+var_dump(curl_exec($ch));
+
+$file = curl_file_create(__DIR__ . '/curl_testdata1.txt');
+$file->setPostFilename('foo.txt');
+var_dump($file->getPostFilename());
+curl_setopt($ch, CURLOPT_POSTFIELDS, array("file" => $file));
+var_dump(curl_exec($ch));
+
+$params = array('file' => '@' . __DIR__ . '/curl_testdata1.txt');
+curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
+var_dump(curl_exec($ch));
+
+curl_setopt($ch, CURLOPT_SAFE_UPLOAD, true);
+$params = array('file' => '@' . __DIR__ . '/curl_testdata1.txt');
+curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
+var_dump(curl_exec($ch));
+
+curl_setopt($ch, CURLOPT_URL, "{$host}/get.php?test=post");
+$params = array('file' => '@' . __DIR__ . '/curl_testdata1.txt');
+curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
+var_dump(curl_exec($ch));
+
+curl_close($ch);
+?>
+--EXPECTF--
+string(%d) "curl_testdata1.txt|application/octet-stream"
+string(%d) "curl_testdata1.txt|text/plain"
+string(%d) "foo.txt|application/octet-stream"
+string(%d) "foo.txt|text/plain"
+string(%d) "text/plain"
+string(%d) "%s/curl_testdata1.txt"
+string(%d) "curl_testdata1.txt|text/plain"
+string(%d) "foo.txt"
+string(%d) "foo.txt|application/octet-stream"
+
+Deprecated: curl_setopt(): The usage of the @filename API for file uploading is deprecated. Please use the CURLFile class instead in %s on line %d
+string(%d) "curl_testdata1.txt|application/octet-stream"
+string(0) ""
+string(%d) "array(1) {
+ ["file"]=>
+ string(%d) "@%s/curl_testdata1.txt"
+}
+"
diff --git a/ext/curl/tests/curl_multi_setopt_basic001.phpt b/ext/curl/tests/curl_multi_setopt_basic001.phpt
new file mode 100644
index 0000000000..a13cf6d716
--- /dev/null
+++ b/ext/curl/tests/curl_multi_setopt_basic001.phpt
@@ -0,0 +1,25 @@
+--TEST--
+curl_multi_setopt basic test
+--SKIPIF--
+<?php
+if (!extension_loaded("curl")) {
+ exit("skip curl extension not loaded");
+}
+$curl_version = curl_version();
+if ($curl_version['version_number'] < 0x071000) {
+ exit("skip: test works only with curl >= 7.16.0");
+}
+?>
+--FILE--
+<?php
+
+$mh = curl_multi_init();
+var_dump(curl_multi_setopt($mh, CURLMOPT_PIPELINING, 0));
+var_dump(curl_multi_setopt($mh, -1, 0));
+
+?>
+--EXPECTF--
+bool(true)
+
+Warning: curl_multi_setopt(): Invalid curl multi configuration option in %s on line %d
+bool(false)
diff --git a/ext/curl/tests/curl_multi_strerror_001.phpt b/ext/curl/tests/curl_multi_strerror_001.phpt
new file mode 100644
index 0000000000..ac330acaee
--- /dev/null
+++ b/ext/curl/tests/curl_multi_strerror_001.phpt
@@ -0,0 +1,22 @@
+--TEST--
+curl_multi_strerror basic test
+--SKIPIF--
+<?php
+if (!extension_loaded("curl")) {
+ exit("skip curl extension not loaded");
+}
+$curl_version = curl_version();
+if ($curl_version['version_number'] < 0x070c00) {
+ exit("skip: test works only with curl >= 7.12.0");
+}
+?>
+--FILE--
+<?php
+
+var_dump(strtolower(curl_multi_strerror(CURLM_OK)));
+var_dump(strtolower(curl_multi_strerror(CURLM_BAD_HANDLE)));
+
+?>
+--EXPECTF--
+string(8) "no error"
+string(20) "invalid multi handle"
diff --git a/ext/curl/tests/curl_reset.phpt b/ext/curl/tests/curl_reset.phpt
new file mode 100644
index 0000000000..c78a8e0953
--- /dev/null
+++ b/ext/curl/tests/curl_reset.phpt
@@ -0,0 +1,40 @@
+--TEST--
+Test curl_reset
+--SKIPIF--
+<?php if (!extension_loaded("curl")) print "skip";
+if (!function_exists("curl_reset")) exit("skip curl_reset doesn't exists (require libcurl >= 7.12.1)");
+?>
+--FILE--
+<?php
+
+$test_file = tempnam(sys_get_temp_dir(), 'php-curl-test');
+$log_file = tempnam(sys_get_temp_dir(), 'php-curl-test');
+
+$fp = fopen($log_file, 'w+');
+fwrite($fp, "test");
+fclose($fp);
+
+$testfile_fp = fopen($test_file, 'w+');
+
+$ch = curl_init();
+curl_setopt($ch, CURLOPT_FILE, $testfile_fp);
+curl_setopt($ch, CURLOPT_URL, 'file://' . $log_file);
+curl_exec($ch);
+
+curl_reset($ch);
+curl_setopt($ch, CURLOPT_URL, 'file://' . $log_file);
+curl_exec($ch);
+
+curl_close($ch);
+
+fclose($testfile_fp);
+
+echo file_get_contents($test_file);
+
+// cleanup
+unlink($test_file);
+unlink($log_file);
+
+?>
+--EXPECT--
+testtest
diff --git a/ext/curl/tests/curl_setopt_basic003.phpt b/ext/curl/tests/curl_setopt_basic003.phpt
index 7849140766..aa225c6e33 100644
--- a/ext/curl/tests/curl_setopt_basic003.phpt
+++ b/ext/curl/tests/curl_setopt_basic003.phpt
@@ -38,6 +38,6 @@ var_dump( $curl_content );
--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
+Warning: curl_setopt(): You must pass either an object or an array with the CURLOPT_HTTPHEADER argument in %s on line %d
bool(false)
bool(true)
diff --git a/ext/curl/tests/curl_setopt_error.phpt b/ext/curl/tests/curl_setopt_error.phpt
index ad73318f1c..01593aff22 100644
--- a/ext/curl/tests/curl_setopt_error.phpt
+++ b/ext/curl/tests/curl_setopt_error.phpt
@@ -14,14 +14,14 @@ curl_setopt(false);
curl_setopt($ch);
curl_setopt($ch, false);
-curl_setopt($ch, -1);
+curl_setopt($ch, -10);
curl_setopt($ch, '');
curl_setopt($ch, 1, false);
curl_setopt(false, false, false);
curl_setopt($ch, '', false);
curl_setopt($ch, 1, '');
-curl_setopt($ch, -1, 0);
+curl_setopt($ch, -10, 0);
?>
--EXPECTF--
*** curl_setopt() call with incorrect parameters
diff --git a/ext/curl/tests/curl_share_setopt_basic001.phpt b/ext/curl/tests/curl_share_setopt_basic001.phpt
new file mode 100644
index 0000000000..33c03e3337
--- /dev/null
+++ b/ext/curl/tests/curl_share_setopt_basic001.phpt
@@ -0,0 +1,23 @@
+--TEST--
+curl_share_setopt basic test
+--SKIPIF--
+<?php
+if (!extension_loaded("curl")) {
+ exit("skip curl extension not loaded");
+}
+?>
+--FILE--
+<?php
+
+$sh = curl_share_init();
+var_dump(curl_share_setopt($sh, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE));
+var_dump(curl_share_setopt($sh, CURLSHOPT_UNSHARE, CURL_LOCK_DATA_DNS));
+var_dump(curl_share_setopt($sh, -1, 0));
+
+?>
+--EXPECTF--
+bool(true)
+bool(true)
+
+Warning: curl_share_setopt(): Invalid curl share configuration option in %s on line %d
+bool(false)
diff --git a/ext/curl/tests/curl_strerror_001.phpt b/ext/curl/tests/curl_strerror_001.phpt
new file mode 100644
index 0000000000..f8a0de311b
--- /dev/null
+++ b/ext/curl/tests/curl_strerror_001.phpt
@@ -0,0 +1,24 @@
+--TEST--
+curl_strerror basic test
+--SKIPIF--
+<?php
+if (!extension_loaded("curl")) {
+ exit("skip curl extension not loaded");
+}
+$curl_version = curl_version();
+if ($curl_version['version_number'] < 0x070c00) {
+ exit("skip: test works only with curl >= 7.12.0");
+}
+?>
+--FILE--
+<?php
+
+var_dump(strtolower(curl_strerror(CURLE_OK)));
+var_dump(strtolower(curl_strerror(CURLE_UNSUPPORTED_PROTOCOL)));
+var_dump(strtolower(curl_strerror(-1)));
+
+?>
+--EXPECTF--
+string(8) "no error"
+string(20) "unsupported protocol"
+string(13) "unknown error"
diff --git a/ext/date/TODO b/ext/date/TODO
index 4b1237c4a9..a585b05516 100644
--- a/ext/date/TODO
+++ b/ext/date/TODO
@@ -1,6 +1,5 @@
- Port over my 200 test cases to .phpt format.
- Write an error handler for unexpected characters while parsing dates.
- Cache lookups for timezone information.
-- Optimize parsing @ with a negative timestamp.
- Make sure that date_default_timezone_set() validates the passed timezone
identifier.
diff --git a/ext/date/lib/parse_date.c b/ext/date/lib/parse_date.c
index 258c61855d..e8dec50292 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 Sun Aug 25 14:46:08 2013 */
+/* Generated by re2c 0.13.5 on Sun Aug 25 15:12:48 2013 */
#line 1 "ext/date/lib/parse_date.re"
/*
+----------------------------------------------------------------------+
@@ -170,8 +170,6 @@ typedef struct _timelib_relunit {
int multiplier;
} timelib_relunit;
-#define HOUR(a) (int)(a * 60)
-
/* The timezone table. */
const static timelib_tz_lookup_table timelib_timezone_lookup[] = {
#include "timezonemap.h"
@@ -532,39 +530,6 @@ static timelib_ull timelib_get_unsigned_nr(char **ptr, int max_length)
return dir * timelib_get_nr(ptr, max_length);
}
-static long timelib_parse_tz_cor(char **ptr)
-{
- char *begin = *ptr, *end;
- long tmp;
-
- while (isdigit(**ptr) || **ptr == ':') {
- ++*ptr;
- }
- end = *ptr;
- switch (end - begin) {
- case 1:
- case 2:
- return HOUR(strtol(begin, NULL, 10));
- break;
- case 3:
- case 4:
- if (begin[1] == ':') {
- tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 2, NULL, 10);
- return tmp;
- } else if (begin[2] == ':') {
- tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 3, NULL, 10);
- return tmp;
- } else {
- tmp = strtol(begin, NULL, 10);
- return HOUR(tmp / 100) + tmp % 100;
- }
- case 5:
- tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 3, NULL, 10);
- return tmp;
- }
- return 0;
-}
-
static timelib_sll timelib_lookup_relative_text(char **ptr, int *behavior)
{
char *word;
@@ -872,11 +837,11 @@ static int scan(Scanner *s, timelib_tz_get_wrapper tz_get_wrapper)
std:
s->tok = cursor;
s->len = 0;
-#line 998 "ext/date/lib/parse_date.re"
+#line 963 "ext/date/lib/parse_date.re"
-#line 880 "ext/date/lib/parse_date.c"
+#line 845 "ext/date/lib/parse_date.c"
{
YYCTYPE yych;
unsigned int yyaccept = 0;
@@ -996,7 +961,7 @@ std:
}
yy2:
YYDEBUG(2, *YYCURSOR);
-#line 1084 "ext/date/lib/parse_date.re"
+#line 1049 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("firstdayof | lastdayof");
TIMELIB_INIT;
@@ -1012,7 +977,7 @@ yy2:
TIMELIB_DEINIT;
return TIMELIB_LF_DAY_OF_MONTH;
}
-#line 1016 "ext/date/lib/parse_date.c"
+#line 981 "ext/date/lib/parse_date.c"
yy3:
YYDEBUG(3, *YYCURSOR);
++YYCURSOR;
@@ -1035,7 +1000,7 @@ yy3:
}
yy4:
YYDEBUG(4, *YYCURSOR);
-#line 1678 "ext/date/lib/parse_date.re"
+#line 1643 "ext/date/lib/parse_date.re"
{
int tz_not_found;
DEBUG_OUTPUT("tzcorrection | tz");
@@ -1048,7 +1013,7 @@ yy4:
TIMELIB_DEINIT;
return TIMELIB_TIMEZONE;
}
-#line 1052 "ext/date/lib/parse_date.c"
+#line 1017 "ext/date/lib/parse_date.c"
yy5:
YYDEBUG(5, *YYCURSOR);
yych = *++YYCURSOR;
@@ -1359,12 +1324,12 @@ yy12:
if (yych <= '9') goto yy1385;
yy13:
YYDEBUG(13, *YYCURSOR);
-#line 1773 "ext/date/lib/parse_date.re"
+#line 1738 "ext/date/lib/parse_date.re"
{
add_error(s, "Unexpected character");
goto std;
}
-#line 1368 "ext/date/lib/parse_date.c"
+#line 1333 "ext/date/lib/parse_date.c"
yy14:
YYDEBUG(14, *YYCURSOR);
yych = *++YYCURSOR;
@@ -2421,11 +2386,11 @@ yy49:
if (yych <= '9') goto yy55;
yy50:
YYDEBUG(50, *YYCURSOR);
-#line 1762 "ext/date/lib/parse_date.re"
+#line 1727 "ext/date/lib/parse_date.re"
{
goto std;
}
-#line 2429 "ext/date/lib/parse_date.c"
+#line 2394 "ext/date/lib/parse_date.c"
yy51:
YYDEBUG(51, *YYCURSOR);
yych = *++YYCURSOR;
@@ -2434,12 +2399,12 @@ yy52:
YYDEBUG(52, *YYCURSOR);
++YYCURSOR;
YYDEBUG(53, *YYCURSOR);
-#line 1767 "ext/date/lib/parse_date.re"
+#line 1732 "ext/date/lib/parse_date.re"
{
s->pos = cursor; s->line++;
goto std;
}
-#line 2443 "ext/date/lib/parse_date.c"
+#line 2408 "ext/date/lib/parse_date.c"
yy54:
YYDEBUG(54, *YYCURSOR);
yych = *++YYCURSOR;
@@ -2826,7 +2791,7 @@ yy72:
if (yych == 's') goto yy74;
yy73:
YYDEBUG(73, *YYCURSOR);
-#line 1746 "ext/date/lib/parse_date.re"
+#line 1711 "ext/date/lib/parse_date.re"
{
timelib_ull i;
DEBUG_OUTPUT("relative");
@@ -2841,7 +2806,7 @@ yy73:
TIMELIB_DEINIT;
return TIMELIB_RELATIVE;
}
-#line 2845 "ext/date/lib/parse_date.c"
+#line 2810 "ext/date/lib/parse_date.c"
yy74:
YYDEBUG(74, *YYCURSOR);
yych = *++YYCURSOR;
@@ -3603,7 +3568,7 @@ yy166:
}
yy167:
YYDEBUG(167, *YYCURSOR);
-#line 1609 "ext/date/lib/parse_date.re"
+#line 1574 "ext/date/lib/parse_date.re"
{
const timelib_relunit* relunit;
DEBUG_OUTPUT("daytext");
@@ -3620,7 +3585,7 @@ yy167:
TIMELIB_DEINIT;
return TIMELIB_WEEKDAY;
}
-#line 3624 "ext/date/lib/parse_date.c"
+#line 3589 "ext/date/lib/parse_date.c"
yy168:
YYDEBUG(168, *YYCURSOR);
yych = *++YYCURSOR;
@@ -4140,7 +4105,7 @@ yy193:
}
yy194:
YYDEBUG(194, *YYCURSOR);
-#line 1668 "ext/date/lib/parse_date.re"
+#line 1633 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("monthtext");
TIMELIB_INIT;
@@ -4149,7 +4114,7 @@ yy194:
TIMELIB_DEINIT;
return TIMELIB_DATE_TEXT;
}
-#line 4153 "ext/date/lib/parse_date.c"
+#line 4118 "ext/date/lib/parse_date.c"
yy195:
YYDEBUG(195, *YYCURSOR);
++YYCURSOR;
@@ -4200,7 +4165,7 @@ yy198:
}
yy199:
YYDEBUG(199, *YYCURSOR);
-#line 1414 "ext/date/lib/parse_date.re"
+#line 1379 "ext/date/lib/parse_date.re"
{
int length = 0;
DEBUG_OUTPUT("datetextual | datenoyear");
@@ -4213,7 +4178,7 @@ yy199:
TIMELIB_DEINIT;
return TIMELIB_DATE_TEXT;
}
-#line 4217 "ext/date/lib/parse_date.c"
+#line 4182 "ext/date/lib/parse_date.c"
yy200:
YYDEBUG(200, *YYCURSOR);
yyaccept = 6;
@@ -4482,7 +4447,7 @@ yy222:
}
yy223:
YYDEBUG(223, *YYCURSOR);
-#line 1716 "ext/date/lib/parse_date.re"
+#line 1681 "ext/date/lib/parse_date.re"
{
int tz_not_found;
DEBUG_OUTPUT("dateshortwithtimeshort | dateshortwithtimelong | dateshortwithtimelongtz");
@@ -4511,7 +4476,7 @@ yy223:
TIMELIB_DEINIT;
return TIMELIB_SHORTDATE_WITH_TIME;
}
-#line 4515 "ext/date/lib/parse_date.c"
+#line 4480 "ext/date/lib/parse_date.c"
yy224:
YYDEBUG(224, *YYCURSOR);
yyaccept = 7;
@@ -5209,7 +5174,7 @@ yy278:
YYDEBUG(278, *YYCURSOR);
++YYCURSOR;
YYDEBUG(279, *YYCURSOR);
-#line 1692 "ext/date/lib/parse_date.re"
+#line 1657 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("dateshortwithtimeshort12 | dateshortwithtimelong12");
TIMELIB_INIT;
@@ -5232,7 +5197,7 @@ yy278:
TIMELIB_DEINIT;
return TIMELIB_SHORTDATE_WITH_TIME;
}
-#line 5236 "ext/date/lib/parse_date.c"
+#line 5201 "ext/date/lib/parse_date.c"
yy280:
YYDEBUG(280, *YYCURSOR);
yych = *++YYCURSOR;
@@ -5410,7 +5375,7 @@ yy294:
++YYCURSOR;
yy295:
YYDEBUG(295, *YYCURSOR);
-#line 1386 "ext/date/lib/parse_date.re"
+#line 1351 "ext/date/lib/parse_date.re"
{
int length = 0;
DEBUG_OUTPUT("datenoday");
@@ -5423,7 +5388,7 @@ yy295:
TIMELIB_DEINIT;
return TIMELIB_DATE_NO_DAY;
}
-#line 5427 "ext/date/lib/parse_date.c"
+#line 5392 "ext/date/lib/parse_date.c"
yy296:
YYDEBUG(296, *YYCURSOR);
yych = *++YYCURSOR;
@@ -6643,7 +6608,7 @@ yy362:
if (yych <= '9') goto yy365;
yy364:
YYDEBUG(364, *YYCURSOR);
-#line 1530 "ext/date/lib/parse_date.re"
+#line 1495 "ext/date/lib/parse_date.re"
{
int length = 0;
DEBUG_OUTPUT("pgtextshort");
@@ -6656,7 +6621,7 @@ yy364:
TIMELIB_DEINIT;
return TIMELIB_PG_TEXT;
}
-#line 6660 "ext/date/lib/parse_date.c"
+#line 6625 "ext/date/lib/parse_date.c"
yy365:
YYDEBUG(365, *YYCURSOR);
yych = *++YYCURSOR;
@@ -7294,7 +7259,7 @@ yy392:
}
yy393:
YYDEBUG(393, *YYCURSOR);
-#line 1588 "ext/date/lib/parse_date.re"
+#line 1553 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("ago");
TIMELIB_INIT;
@@ -7314,7 +7279,7 @@ yy393:
TIMELIB_DEINIT;
return TIMELIB_AGO;
}
-#line 7318 "ext/date/lib/parse_date.c"
+#line 7283 "ext/date/lib/parse_date.c"
yy394:
YYDEBUG(394, *YYCURSOR);
yyaccept = 5;
@@ -9064,7 +9029,7 @@ yy454:
++YYCURSOR;
yy455:
YYDEBUG(455, *YYCURSOR);
-#line 1291 "ext/date/lib/parse_date.re"
+#line 1256 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("iso8601date4 | iso8601date2 | iso8601dateslash | dateslash");
TIMELIB_INIT;
@@ -9075,7 +9040,7 @@ yy455:
TIMELIB_DEINIT;
return TIMELIB_ISO_DATE;
}
-#line 9079 "ext/date/lib/parse_date.c"
+#line 9044 "ext/date/lib/parse_date.c"
yy456:
YYDEBUG(456, *YYCURSOR);
yyaccept = 0;
@@ -9635,7 +9600,7 @@ yy475:
}
yy476:
YYDEBUG(476, *YYCURSOR);
-#line 1428 "ext/date/lib/parse_date.re"
+#line 1393 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("datenoyearrev");
TIMELIB_INIT;
@@ -9646,7 +9611,7 @@ yy476:
TIMELIB_DEINIT;
return TIMELIB_DATE_TEXT;
}
-#line 9650 "ext/date/lib/parse_date.c"
+#line 9615 "ext/date/lib/parse_date.c"
yy477:
YYDEBUG(477, *YYCURSOR);
yyaccept = 10;
@@ -9787,7 +9752,7 @@ yy488:
YYDEBUG(488, *YYCURSOR);
++YYCURSOR;
YYDEBUG(489, *YYCURSOR);
-#line 1146 "ext/date/lib/parse_date.re"
+#line 1111 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("timetiny12 | timeshort12 | timelong12");
TIMELIB_INIT;
@@ -9803,7 +9768,7 @@ yy488:
TIMELIB_DEINIT;
return TIMELIB_TIME12;
}
-#line 9807 "ext/date/lib/parse_date.c"
+#line 9772 "ext/date/lib/parse_date.c"
yy490:
YYDEBUG(490, *YYCURSOR);
yyaccept = 11;
@@ -9816,7 +9781,7 @@ yy490:
}
yy491:
YYDEBUG(491, *YYCURSOR);
-#line 1183 "ext/date/lib/parse_date.re"
+#line 1148 "ext/date/lib/parse_date.re"
{
int tz_not_found;
DEBUG_OUTPUT("timeshort24 | timelong24 | iso8601long");
@@ -9841,7 +9806,7 @@ yy491:
TIMELIB_DEINIT;
return TIMELIB_TIME24_WITH_ZONE;
}
-#line 9845 "ext/date/lib/parse_date.c"
+#line 9810 "ext/date/lib/parse_date.c"
yy492:
YYDEBUG(492, *YYCURSOR);
yyaccept = 11;
@@ -10151,7 +10116,7 @@ yy523:
YYDEBUG(523, *YYCURSOR);
++YYCURSOR;
YYDEBUG(524, *YYCURSOR);
-#line 1163 "ext/date/lib/parse_date.re"
+#line 1128 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("mssqltime");
TIMELIB_INIT;
@@ -10170,7 +10135,7 @@ yy523:
TIMELIB_DEINIT;
return TIMELIB_TIME24_WITH_ZONE;
}
-#line 10174 "ext/date/lib/parse_date.c"
+#line 10139 "ext/date/lib/parse_date.c"
yy525:
YYDEBUG(525, *YYCURSOR);
yyaccept = 11;
@@ -10276,7 +10241,7 @@ yy534:
if (yych <= '9') goto yy541;
yy535:
YYDEBUG(535, *YYCURSOR);
-#line 1345 "ext/date/lib/parse_date.re"
+#line 1310 "ext/date/lib/parse_date.re"
{
int length = 0;
DEBUG_OUTPUT("datefull");
@@ -10290,7 +10255,7 @@ yy535:
TIMELIB_DEINIT;
return TIMELIB_DATE_FULL;
}
-#line 10294 "ext/date/lib/parse_date.c"
+#line 10259 "ext/date/lib/parse_date.c"
yy536:
YYDEBUG(536, *YYCURSOR);
yych = *++YYCURSOR;
@@ -11027,7 +10992,7 @@ yy605:
YYDEBUG(606, *YYCURSOR);
++YYCURSOR;
YYDEBUG(607, *YYCURSOR);
-#line 1360 "ext/date/lib/parse_date.re"
+#line 1325 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("pointed date YYYY");
TIMELIB_INIT;
@@ -11038,7 +11003,7 @@ yy605:
TIMELIB_DEINIT;
return TIMELIB_DATE_FULL_POINTED;
}
-#line 11042 "ext/date/lib/parse_date.c"
+#line 11007 "ext/date/lib/parse_date.c"
yy608:
YYDEBUG(608, *YYCURSOR);
yyaccept = 11;
@@ -11074,7 +11039,7 @@ yy611:
if (yych <= '9') goto yy605;
yy612:
YYDEBUG(612, *YYCURSOR);
-#line 1372 "ext/date/lib/parse_date.re"
+#line 1337 "ext/date/lib/parse_date.re"
{
int length = 0;
DEBUG_OUTPUT("pointed date YY");
@@ -11087,7 +11052,7 @@ yy612:
TIMELIB_DEINIT;
return TIMELIB_DATE_FULL_POINTED;
}
-#line 11091 "ext/date/lib/parse_date.c"
+#line 11056 "ext/date/lib/parse_date.c"
yy613:
YYDEBUG(613, *YYCURSOR);
yyaccept = 11;
@@ -11728,7 +11693,7 @@ yy656:
}
yy657:
YYDEBUG(657, *YYCURSOR);
-#line 1331 "ext/date/lib/parse_date.re"
+#line 1296 "ext/date/lib/parse_date.re"
{
int length = 0;
DEBUG_OUTPUT("gnudateshort");
@@ -11741,7 +11706,7 @@ yy657:
TIMELIB_DEINIT;
return TIMELIB_ISO_DATE;
}
-#line 11745 "ext/date/lib/parse_date.c"
+#line 11710 "ext/date/lib/parse_date.c"
yy658:
YYDEBUG(658, *YYCURSOR);
yyaccept = 13;
@@ -11847,7 +11812,7 @@ yy666:
}
yy667:
YYDEBUG(667, *YYCURSOR);
-#line 1275 "ext/date/lib/parse_date.re"
+#line 1240 "ext/date/lib/parse_date.re"
{
int length = 0;
DEBUG_OUTPUT("americanshort | american");
@@ -11862,7 +11827,7 @@ yy667:
TIMELIB_DEINIT;
return TIMELIB_AMERICAN;
}
-#line 11866 "ext/date/lib/parse_date.c"
+#line 11831 "ext/date/lib/parse_date.c"
yy668:
YYDEBUG(668, *YYCURSOR);
yyaccept = 14;
@@ -12095,7 +12060,7 @@ yy700:
if (yych <= ':') goto yy704;
yy701:
YYDEBUG(701, *YYCURSOR);
-#line 1558 "ext/date/lib/parse_date.re"
+#line 1523 "ext/date/lib/parse_date.re"
{
int tz_not_found;
DEBUG_OUTPUT("clf");
@@ -12115,7 +12080,7 @@ yy701:
TIMELIB_DEINIT;
return TIMELIB_CLF;
}
-#line 12119 "ext/date/lib/parse_date.c"
+#line 12084 "ext/date/lib/parse_date.c"
yy702:
YYDEBUG(702, *YYCURSOR);
yych = *++YYCURSOR;
@@ -12667,7 +12632,7 @@ yy763:
}
yy764:
YYDEBUG(764, *YYCURSOR);
-#line 1303 "ext/date/lib/parse_date.re"
+#line 1268 "ext/date/lib/parse_date.re"
{
int length = 0;
DEBUG_OUTPUT("iso8601date2");
@@ -12680,7 +12645,7 @@ yy764:
TIMELIB_DEINIT;
return TIMELIB_ISO_DATE;
}
-#line 12684 "ext/date/lib/parse_date.c"
+#line 12649 "ext/date/lib/parse_date.c"
yy765:
YYDEBUG(765, *YYCURSOR);
yych = *++YYCURSOR;
@@ -12719,7 +12684,7 @@ yy771:
YYDEBUG(771, *YYCURSOR);
++YYCURSOR;
YYDEBUG(772, *YYCURSOR);
-#line 1544 "ext/date/lib/parse_date.re"
+#line 1509 "ext/date/lib/parse_date.re"
{
int length = 0;
DEBUG_OUTPUT("pgtextreverse");
@@ -12732,7 +12697,7 @@ yy771:
TIMELIB_DEINIT;
return TIMELIB_PG_TEXT;
}
-#line 12736 "ext/date/lib/parse_date.c"
+#line 12701 "ext/date/lib/parse_date.c"
yy773:
YYDEBUG(773, *YYCURSOR);
yych = *++YYCURSOR;
@@ -12870,7 +12835,7 @@ yy783:
}
yy784:
YYDEBUG(784, *YYCURSOR);
-#line 1579 "ext/date/lib/parse_date.re"
+#line 1544 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("year4");
TIMELIB_INIT;
@@ -12878,7 +12843,7 @@ yy784:
TIMELIB_DEINIT;
return TIMELIB_CLF;
}
-#line 12882 "ext/date/lib/parse_date.c"
+#line 12847 "ext/date/lib/parse_date.c"
yy785:
YYDEBUG(785, *YYCURSOR);
yych = *++YYCURSOR;
@@ -13029,7 +12994,7 @@ yy793:
}
yy794:
YYDEBUG(794, *YYCURSOR);
-#line 1400 "ext/date/lib/parse_date.re"
+#line 1365 "ext/date/lib/parse_date.re"
{
int length = 0;
DEBUG_OUTPUT("datenodayrev");
@@ -13042,7 +13007,7 @@ yy794:
TIMELIB_DEINIT;
return TIMELIB_DATE_NO_DAY;
}
-#line 13046 "ext/date/lib/parse_date.c"
+#line 13011 "ext/date/lib/parse_date.c"
yy795:
YYDEBUG(795, *YYCURSOR);
yych = *++YYCURSOR;
@@ -13257,7 +13222,7 @@ yy814:
if (yych <= '7') goto yy817;
yy815:
YYDEBUG(815, *YYCURSOR);
-#line 1511 "ext/date/lib/parse_date.re"
+#line 1476 "ext/date/lib/parse_date.re"
{
timelib_sll w, d;
DEBUG_OUTPUT("isoweek");
@@ -13275,7 +13240,7 @@ yy815:
TIMELIB_DEINIT;
return TIMELIB_ISO_WEEK;
}
-#line 13279 "ext/date/lib/parse_date.c"
+#line 13244 "ext/date/lib/parse_date.c"
yy816:
YYDEBUG(816, *YYCURSOR);
yych = *++YYCURSOR;
@@ -13285,7 +13250,7 @@ yy817:
YYDEBUG(817, *YYCURSOR);
++YYCURSOR;
YYDEBUG(818, *YYCURSOR);
-#line 1492 "ext/date/lib/parse_date.re"
+#line 1457 "ext/date/lib/parse_date.re"
{
timelib_sll w, d;
DEBUG_OUTPUT("isoweekday");
@@ -13303,7 +13268,7 @@ yy817:
TIMELIB_DEINIT;
return TIMELIB_ISO_WEEK;
}
-#line 13307 "ext/date/lib/parse_date.c"
+#line 13272 "ext/date/lib/parse_date.c"
yy819:
YYDEBUG(819, *YYCURSOR);
yych = *++YYCURSOR;
@@ -13367,7 +13332,7 @@ yy821:
}
yy822:
YYDEBUG(822, *YYCURSOR);
-#line 1478 "ext/date/lib/parse_date.re"
+#line 1443 "ext/date/lib/parse_date.re"
{
int length = 0;
DEBUG_OUTPUT("pgydotd");
@@ -13380,7 +13345,7 @@ yy822:
TIMELIB_DEINIT;
return TIMELIB_PG_YEARDAY;
}
-#line 13384 "ext/date/lib/parse_date.c"
+#line 13349 "ext/date/lib/parse_date.c"
yy823:
YYDEBUG(823, *YYCURSOR);
yych = *++YYCURSOR;
@@ -13483,7 +13448,7 @@ yy842:
++YYCURSOR;
yy843:
YYDEBUG(843, *YYCURSOR);
-#line 1452 "ext/date/lib/parse_date.re"
+#line 1417 "ext/date/lib/parse_date.re"
{
int tz_not_found;
DEBUG_OUTPUT("xmlrpc | xmlrpcnocolon | soap | wddx | exif");
@@ -13508,7 +13473,7 @@ yy843:
TIMELIB_DEINIT;
return TIMELIB_XMLRPC_SOAP;
}
-#line 13512 "ext/date/lib/parse_date.c"
+#line 13477 "ext/date/lib/parse_date.c"
yy844:
YYDEBUG(844, *YYCURSOR);
yych = *++YYCURSOR;
@@ -13770,7 +13735,7 @@ yy848:
}
yy849:
YYDEBUG(849, *YYCURSOR);
-#line 1440 "ext/date/lib/parse_date.re"
+#line 1405 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("datenocolon");
TIMELIB_INIT;
@@ -13781,7 +13746,7 @@ yy849:
TIMELIB_DEINIT;
return TIMELIB_DATE_NOCOLON;
}
-#line 13785 "ext/date/lib/parse_date.c"
+#line 13750 "ext/date/lib/parse_date.c"
yy850:
YYDEBUG(850, *YYCURSOR);
yych = *++YYCURSOR;
@@ -14701,7 +14666,7 @@ yy973:
if (yych <= '9') goto yy996;
yy974:
YYDEBUG(974, *YYCURSOR);
-#line 1317 "ext/date/lib/parse_date.re"
+#line 1282 "ext/date/lib/parse_date.re"
{
int length = 0;
DEBUG_OUTPUT("gnudateshorter");
@@ -14714,7 +14679,7 @@ yy974:
TIMELIB_DEINIT;
return TIMELIB_ISO_DATE;
}
-#line 14718 "ext/date/lib/parse_date.c"
+#line 14683 "ext/date/lib/parse_date.c"
yy975:
YYDEBUG(975, *YYCURSOR);
yyaccept = 22;
@@ -15723,7 +15688,7 @@ yy1066:
}
yy1068:
YYDEBUG(1068, *YYCURSOR);
-#line 1209 "ext/date/lib/parse_date.re"
+#line 1174 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("gnunocolon");
TIMELIB_INIT;
@@ -15745,7 +15710,7 @@ yy1068:
TIMELIB_DEINIT;
return TIMELIB_GNU_NOCOLON;
}
-#line 15749 "ext/date/lib/parse_date.c"
+#line 15714 "ext/date/lib/parse_date.c"
yy1069:
YYDEBUG(1069, *YYCURSOR);
yych = *++YYCURSOR;
@@ -15837,7 +15802,7 @@ yy1075:
}
yy1076:
YYDEBUG(1076, *YYCURSOR);
-#line 1255 "ext/date/lib/parse_date.re"
+#line 1220 "ext/date/lib/parse_date.re"
{
int tz_not_found;
DEBUG_OUTPUT("iso8601nocolon");
@@ -15856,7 +15821,7 @@ yy1076:
TIMELIB_DEINIT;
return TIMELIB_ISO_NOCOLON;
}
-#line 15860 "ext/date/lib/parse_date.c"
+#line 15825 "ext/date/lib/parse_date.c"
yy1077:
YYDEBUG(1077, *YYCURSOR);
yyaccept = 25;
@@ -16754,7 +16719,7 @@ yy1117:
}
yy1118:
YYDEBUG(1118, *YYCURSOR);
-#line 1651 "ext/date/lib/parse_date.re"
+#line 1616 "ext/date/lib/parse_date.re"
{
timelib_sll i;
int behavior = 0;
@@ -16770,7 +16735,7 @@ yy1118:
TIMELIB_DEINIT;
return TIMELIB_RELATIVE;
}
-#line 16774 "ext/date/lib/parse_date.c"
+#line 16739 "ext/date/lib/parse_date.c"
yy1119:
YYDEBUG(1119, *YYCURSOR);
++YYCURSOR;
@@ -16821,7 +16786,7 @@ yy1126:
YYDEBUG(1126, *YYCURSOR);
++YYCURSOR;
YYDEBUG(1127, *YYCURSOR);
-#line 1124 "ext/date/lib/parse_date.re"
+#line 1089 "ext/date/lib/parse_date.re"
{
timelib_sll i;
int behavior = 0;
@@ -16842,7 +16807,7 @@ yy1126:
TIMELIB_DEINIT;
return TIMELIB_WEEK_DAY_OF_MONTH;
}
-#line 16846 "ext/date/lib/parse_date.c"
+#line 16811 "ext/date/lib/parse_date.c"
yy1128:
YYDEBUG(1128, *YYCURSOR);
yyaccept = 26;
@@ -16950,7 +16915,7 @@ yy1141:
}
yy1142:
YYDEBUG(1142, *YYCURSOR);
-#line 1627 "ext/date/lib/parse_date.re"
+#line 1592 "ext/date/lib/parse_date.re"
{
timelib_sll i;
int behavior = 0;
@@ -16973,7 +16938,7 @@ yy1142:
TIMELIB_DEINIT;
return TIMELIB_RELATIVE;
}
-#line 16977 "ext/date/lib/parse_date.c"
+#line 16942 "ext/date/lib/parse_date.c"
yy1143:
YYDEBUG(1143, *YYCURSOR);
yych = *++YYCURSOR;
@@ -19650,7 +19615,7 @@ yy1294:
goto yy1298;
yy1295:
YYDEBUG(1295, *YYCURSOR);
-#line 1101 "ext/date/lib/parse_date.re"
+#line 1066 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("backof | frontof");
TIMELIB_INIT;
@@ -19672,7 +19637,7 @@ yy1295:
TIMELIB_DEINIT;
return TIMELIB_LF_DAY_OF_MONTH;
}
-#line 19676 "ext/date/lib/parse_date.c"
+#line 19641 "ext/date/lib/parse_date.c"
yy1296:
YYDEBUG(1296, *YYCURSOR);
yyaccept = 28;
@@ -21363,7 +21328,7 @@ yy1385:
if (yych <= '9') goto yy1385;
yy1387:
YYDEBUG(1387, *YYCURSOR);
-#line 1058 "ext/date/lib/parse_date.re"
+#line 1023 "ext/date/lib/parse_date.re"
{
timelib_ull i;
@@ -21388,7 +21353,7 @@ yy1387:
TIMELIB_DEINIT;
return TIMELIB_RELATIVE;
}
-#line 21392 "ext/date/lib/parse_date.c"
+#line 21357 "ext/date/lib/parse_date.c"
yy1388:
YYDEBUG(1388, *YYCURSOR);
yych = *++YYCURSOR;
@@ -21824,7 +21789,7 @@ yy1416:
++YYCURSOR;
yy1417:
YYDEBUG(1417, *YYCURSOR);
-#line 1046 "ext/date/lib/parse_date.re"
+#line 1011 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("tomorrow");
TIMELIB_INIT;
@@ -21835,7 +21800,7 @@ yy1417:
TIMELIB_DEINIT;
return TIMELIB_RELATIVE;
}
-#line 21839 "ext/date/lib/parse_date.c"
+#line 21804 "ext/date/lib/parse_date.c"
yy1418:
YYDEBUG(1418, *YYCURSOR);
yych = *++YYCURSOR;
@@ -21870,7 +21835,7 @@ yy1419:
}
yy1420:
YYDEBUG(1420, *YYCURSOR);
-#line 1036 "ext/date/lib/parse_date.re"
+#line 1001 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("midnight | today");
TIMELIB_INIT;
@@ -21879,7 +21844,7 @@ yy1420:
TIMELIB_DEINIT;
return TIMELIB_RELATIVE;
}
-#line 21883 "ext/date/lib/parse_date.c"
+#line 21848 "ext/date/lib/parse_date.c"
yy1421:
YYDEBUG(1421, *YYCURSOR);
yych = *++YYCURSOR;
@@ -23891,7 +23856,7 @@ yy1499:
}
yy1500:
YYDEBUG(1500, *YYCURSOR);
-#line 1015 "ext/date/lib/parse_date.re"
+#line 980 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("now");
TIMELIB_INIT;
@@ -23899,7 +23864,7 @@ yy1500:
TIMELIB_DEINIT;
return TIMELIB_RELATIVE;
}
-#line 23903 "ext/date/lib/parse_date.c"
+#line 23868 "ext/date/lib/parse_date.c"
yy1501:
YYDEBUG(1501, *YYCURSOR);
yych = *++YYCURSOR;
@@ -24038,7 +24003,7 @@ yy1507:
}
yy1508:
YYDEBUG(1508, *YYCURSOR);
-#line 1024 "ext/date/lib/parse_date.re"
+#line 989 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("noon");
TIMELIB_INIT;
@@ -24049,7 +24014,7 @@ yy1508:
TIMELIB_DEINIT;
return TIMELIB_RELATIVE;
}
-#line 24053 "ext/date/lib/parse_date.c"
+#line 24018 "ext/date/lib/parse_date.c"
yy1509:
YYDEBUG(1509, *YYCURSOR);
yyaccept = 0;
@@ -24582,7 +24547,7 @@ yy1530:
++YYCURSOR;
yy1531:
YYDEBUG(1531, *YYCURSOR);
-#line 1003 "ext/date/lib/parse_date.re"
+#line 968 "ext/date/lib/parse_date.re"
{
DEBUG_OUTPUT("yesterday");
TIMELIB_INIT;
@@ -24593,7 +24558,7 @@ yy1531:
TIMELIB_DEINIT;
return TIMELIB_RELATIVE;
}
-#line 24597 "ext/date/lib/parse_date.c"
+#line 24562 "ext/date/lib/parse_date.c"
yy1532:
YYDEBUG(1532, *YYCURSOR);
yyaccept = 0;
@@ -24766,7 +24731,7 @@ yy1537:
goto yy1531;
}
}
-#line 1777 "ext/date/lib/parse_date.re"
+#line 1742 "ext/date/lib/parse_date.re"
}
@@ -24825,6 +24790,7 @@ timelib_time* timelib_strtotime(char *s, int len, struct timelib_error_container
in.tzdb = tzdb;
in.time->is_localtime = 0;
in.time->zone_type = 0;
+ in.time->relative.days = TIMELIB_UNSET;
do {
t = scan(&in, tz_get_wrapper);
@@ -25124,7 +25090,7 @@ timelib_time *timelib_parse_from_format(char *format, char *string, int len, tim
break;
case '\\': /* escaped char */
- fptr++;
+ ++fptr;
if (*ptr == *fptr) {
++ptr;
} else {
diff --git a/ext/date/lib/parse_date.re b/ext/date/lib/parse_date.re
index df33508f50..6d91d9ada9 100644
--- a/ext/date/lib/parse_date.re
+++ b/ext/date/lib/parse_date.re
@@ -168,8 +168,6 @@ typedef struct _timelib_relunit {
int multiplier;
} timelib_relunit;
-#define HOUR(a) (int)(a * 60)
-
/* The timezone table. */
const static timelib_tz_lookup_table timelib_timezone_lookup[] = {
#include "timezonemap.h"
@@ -530,39 +528,6 @@ static timelib_ull timelib_get_unsigned_nr(char **ptr, int max_length)
return dir * timelib_get_nr(ptr, max_length);
}
-static long timelib_parse_tz_cor(char **ptr)
-{
- char *begin = *ptr, *end;
- long tmp;
-
- while (isdigit(**ptr) || **ptr == ':') {
- ++*ptr;
- }
- end = *ptr;
- switch (end - begin) {
- case 1:
- case 2:
- return HOUR(strtol(begin, NULL, 10));
- break;
- case 3:
- case 4:
- if (begin[1] == ':') {
- tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 2, NULL, 10);
- return tmp;
- } else if (begin[2] == ':') {
- tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 3, NULL, 10);
- return tmp;
- } else {
- tmp = strtol(begin, NULL, 10);
- return HOUR(tmp / 100) + tmp % 100;
- }
- case 5:
- tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 3, NULL, 10);
- return tmp;
- }
- return 0;
-}
-
static timelib_sll timelib_lookup_relative_text(char **ptr, int *behavior)
{
char *word;
@@ -1832,6 +1797,7 @@ timelib_time* timelib_strtotime(char *s, int len, struct timelib_error_container
in.tzdb = tzdb;
in.time->is_localtime = 0;
in.time->zone_type = 0;
+ in.time->relative.days = TIMELIB_UNSET;
do {
t = scan(&in, tz_get_wrapper);
@@ -2131,7 +2097,7 @@ timelib_time *timelib_parse_from_format(char *format, char *string, int len, tim
break;
case '\\': /* escaped char */
- fptr++;
+ ++fptr;
if (*ptr == *fptr) {
++ptr;
} else {
diff --git a/ext/date/lib/parse_iso_intervals.c b/ext/date/lib/parse_iso_intervals.c
index f6b4d838c8..c14a07465a 100644
--- a/ext/date/lib/parse_iso_intervals.c
+++ b/ext/date/lib/parse_iso_intervals.c
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.13.5 on Wed Nov 27 11:10:58 2013 */
+/* Generated by re2c 0.13.5 on Wed Nov 27 11:14:23 2013 */
#line 1 "ext/date/lib/parse_iso_intervals.re"
/*
+----------------------------------------------------------------------+
@@ -104,8 +104,6 @@ typedef struct Scanner {
int have_end_date;
} Scanner;
-#define HOUR(a) (int)(a * 60)
-
static void add_warning(Scanner *s, char *error)
{
s->errors->warning_count++;
@@ -178,39 +176,6 @@ static timelib_ull timelib_get_unsigned_nr(char **ptr, int max_length)
return dir * timelib_get_nr(ptr, max_length);
}
-static long timelib_parse_tz_cor(char **ptr)
-{
- char *begin = *ptr, *end;
- long tmp;
-
- while (isdigit(**ptr) || **ptr == ':') {
- ++*ptr;
- }
- end = *ptr;
- switch (end - begin) {
- case 1:
- case 2:
- return HOUR(strtol(begin, NULL, 10));
- break;
- case 3:
- case 4:
- if (begin[1] == ':') {
- tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 2, NULL, 10);
- return tmp;
- } else if (begin[2] == ':') {
- tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 3, NULL, 10);
- return tmp;
- } else {
- tmp = strtol(begin, NULL, 10);
- return HOUR(tmp / 100) + tmp % 100;
- }
- case 5:
- tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 3, NULL, 10);
- return tmp;
- }
- return 0;
-}
-
static void timelib_eat_spaces(char **ptr)
{
while (**ptr == ' ' || **ptr == '\t') {
@@ -283,11 +248,11 @@ static int scan(Scanner *s)
std:
s->tok = cursor;
s->len = 0;
-#line 311 "ext/date/lib/parse_iso_intervals.re"
+#line 276 "ext/date/lib/parse_iso_intervals.re"
-#line 291 "ext/date/lib/parse_iso_intervals.c"
+#line 256 "ext/date/lib/parse_iso_intervals.c"
{
YYCTYPE yych;
unsigned int yyaccept = 0;
@@ -357,12 +322,12 @@ std:
if (yych <= '9') goto yy98;
yy3:
YYDEBUG(3, *YYCURSOR);
-#line 424 "ext/date/lib/parse_iso_intervals.re"
+#line 389 "ext/date/lib/parse_iso_intervals.re"
{
add_error(s, "Unexpected character");
goto std;
}
-#line 366 "ext/date/lib/parse_iso_intervals.c"
+#line 331 "ext/date/lib/parse_iso_intervals.c"
yy4:
YYDEBUG(4, *YYCURSOR);
yyaccept = 0;
@@ -379,7 +344,7 @@ yy5:
if (yych == 'T') goto yy14;
yy6:
YYDEBUG(6, *YYCURSOR);
-#line 351 "ext/date/lib/parse_iso_intervals.re"
+#line 316 "ext/date/lib/parse_iso_intervals.re"
{
timelib_sll nr;
int in_time = 0;
@@ -420,26 +385,26 @@ yy6:
TIMELIB_DEINIT;
return TIMELIB_PERIOD;
}
-#line 424 "ext/date/lib/parse_iso_intervals.c"
+#line 389 "ext/date/lib/parse_iso_intervals.c"
yy7:
YYDEBUG(7, *YYCURSOR);
++YYCURSOR;
YYDEBUG(8, *YYCURSOR);
-#line 413 "ext/date/lib/parse_iso_intervals.re"
+#line 378 "ext/date/lib/parse_iso_intervals.re"
{
goto std;
}
-#line 433 "ext/date/lib/parse_iso_intervals.c"
+#line 398 "ext/date/lib/parse_iso_intervals.c"
yy9:
YYDEBUG(9, *YYCURSOR);
++YYCURSOR;
YYDEBUG(10, *YYCURSOR);
-#line 418 "ext/date/lib/parse_iso_intervals.re"
+#line 383 "ext/date/lib/parse_iso_intervals.re"
{
s->pos = cursor; s->line++;
goto std;
}
-#line 443 "ext/date/lib/parse_iso_intervals.c"
+#line 408 "ext/date/lib/parse_iso_intervals.c"
yy11:
YYDEBUG(11, *YYCURSOR);
yych = *++YYCURSOR;
@@ -769,7 +734,7 @@ yy51:
YYDEBUG(57, *YYCURSOR);
++YYCURSOR;
YYDEBUG(58, *YYCURSOR);
-#line 393 "ext/date/lib/parse_iso_intervals.re"
+#line 358 "ext/date/lib/parse_iso_intervals.re"
{
DEBUG_OUTPUT("combinedrep");
TIMELIB_INIT;
@@ -788,7 +753,7 @@ yy51:
TIMELIB_DEINIT;
return TIMELIB_PERIOD;
}
-#line 792 "ext/date/lib/parse_iso_intervals.c"
+#line 757 "ext/date/lib/parse_iso_intervals.c"
yy59:
YYDEBUG(59, *YYCURSOR);
yych = *++YYCURSOR;
@@ -917,7 +882,7 @@ yy83:
YYDEBUG(83, *YYCURSOR);
++YYCURSOR;
YYDEBUG(84, *YYCURSOR);
-#line 327 "ext/date/lib/parse_iso_intervals.re"
+#line 292 "ext/date/lib/parse_iso_intervals.re"
{
timelib_time *current;
@@ -940,7 +905,7 @@ yy83:
TIMELIB_DEINIT;
return TIMELIB_ISO_DATE;
}
-#line 944 "ext/date/lib/parse_iso_intervals.c"
+#line 909 "ext/date/lib/parse_iso_intervals.c"
yy85:
YYDEBUG(85, *YYCURSOR);
yych = *++YYCURSOR;
@@ -1018,7 +983,7 @@ yy98:
if (yych <= '9') goto yy98;
yy100:
YYDEBUG(100, *YYCURSOR);
-#line 316 "ext/date/lib/parse_iso_intervals.re"
+#line 281 "ext/date/lib/parse_iso_intervals.re"
{
DEBUG_OUTPUT("recurrences");
TIMELIB_INIT;
@@ -1028,9 +993,9 @@ yy100:
s->have_recurrences = 1;
return TIMELIB_PERIOD;
}
-#line 1032 "ext/date/lib/parse_iso_intervals.c"
+#line 997 "ext/date/lib/parse_iso_intervals.c"
}
-#line 428 "ext/date/lib/parse_iso_intervals.re"
+#line 393 "ext/date/lib/parse_iso_intervals.re"
}
#ifdef PHP_WIN32
diff --git a/ext/date/lib/parse_iso_intervals.re b/ext/date/lib/parse_iso_intervals.re
index c5e9f677ba..cbbf8781bf 100644
--- a/ext/date/lib/parse_iso_intervals.re
+++ b/ext/date/lib/parse_iso_intervals.re
@@ -102,8 +102,6 @@ typedef struct Scanner {
int have_end_date;
} Scanner;
-#define HOUR(a) (int)(a * 60)
-
static void add_warning(Scanner *s, char *error)
{
s->errors->warning_count++;
@@ -176,39 +174,6 @@ static timelib_ull timelib_get_unsigned_nr(char **ptr, int max_length)
return dir * timelib_get_nr(ptr, max_length);
}
-static long timelib_parse_tz_cor(char **ptr)
-{
- char *begin = *ptr, *end;
- long tmp;
-
- while (isdigit(**ptr) || **ptr == ':') {
- ++*ptr;
- }
- end = *ptr;
- switch (end - begin) {
- case 1:
- case 2:
- return HOUR(strtol(begin, NULL, 10));
- break;
- case 3:
- case 4:
- if (begin[1] == ':') {
- tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 2, NULL, 10);
- return tmp;
- } else if (begin[2] == ':') {
- tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 3, NULL, 10);
- return tmp;
- } else {
- tmp = strtol(begin, NULL, 10);
- return HOUR(tmp / 100) + tmp % 100;
- }
- case 5:
- tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 3, NULL, 10);
- return tmp;
- }
- return 0;
-}
-
static void timelib_eat_spaces(char **ptr)
{
while (**ptr == ' ' || **ptr == '\t') {
diff --git a/ext/date/lib/timelib.c b/ext/date/lib/timelib.c
index 039d3cedbe..bf7c55a735 100644
--- a/ext/date/lib/timelib.c
+++ b/ext/date/lib/timelib.c
@@ -30,6 +30,8 @@
#define TIMELIB_LLABS(y) (y < 0 ? (y * -1) : y)
+#define HOUR(a) (int)(a * 60)
+
timelib_time* timelib_time_ctor(void)
{
timelib_time *t;
@@ -284,3 +286,35 @@ void timelib_dump_rel_time(timelib_rel_time *d)
printf("\n");
}
+long timelib_parse_tz_cor(char **ptr)
+{
+ char *begin = *ptr, *end;
+ long tmp;
+
+ while (isdigit(**ptr) || **ptr == ':') {
+ ++*ptr;
+ }
+ end = *ptr;
+ switch (end - begin) {
+ case 1:
+ case 2:
+ return HOUR(strtol(begin, NULL, 10));
+ break;
+ case 3:
+ case 4:
+ if (begin[1] == ':') {
+ tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 2, NULL, 10);
+ return tmp;
+ } else if (begin[2] == ':') {
+ tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 3, NULL, 10);
+ return tmp;
+ } else {
+ tmp = strtol(begin, NULL, 10);
+ return HOUR(tmp / 100) + tmp % 100;
+ }
+ case 5:
+ tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 3, NULL, 10);
+ return tmp;
+ }
+ return 0;
+}
diff --git a/ext/date/lib/timelib.h b/ext/date/lib/timelib.h
index 0396e62cab..f5e7597835 100644
--- a/ext/date/lib/timelib.h
+++ b/ext/date/lib/timelib.h
@@ -73,6 +73,7 @@ timelib_time *timelib_parse_from_format(char *format, char *s, int len, timelib_
void timelib_fill_holes(timelib_time *parsed, timelib_time *now, int options);
char *timelib_timezone_id_from_abbr(const char *abbr, long gmtoffset, int isdst);
const timelib_tz_lookup_table *timelib_timezone_abbreviations_list(void);
+long timelib_parse_tz_cor(char**);
/* From parse_iso_intervals.re */
void timelib_strtointerval(char *s, int len,
@@ -129,6 +130,7 @@ void timelib_dump_date(timelib_time *d, int options);
void timelib_dump_rel_time(timelib_rel_time *d);
void timelib_decimal_hour_to_hms(double h, int *hour, int *min, int *sec);
+long timelib_parse_tz_cor(char **ptr);
/* from astro.c */
double timelib_ts_to_juliandate(timelib_sll ts);
diff --git a/ext/date/lib/tm2unixtime.c b/ext/date/lib/tm2unixtime.c
index f1756e4791..5fc84a5ff7 100644
--- a/ext/date/lib/tm2unixtime.c
+++ b/ext/date/lib/tm2unixtime.c
@@ -220,55 +220,52 @@ static void do_adjust_relative(timelib_time* time)
static void do_adjust_special_weekday(timelib_time* time)
{
- timelib_sll current_dow, count;
+ timelib_sll count, dow, rem;
count = time->relative.special.amount;
+ dow = timelib_day_of_week(time->y, time->m, time->d);
- current_dow = timelib_day_of_week(time->y, time->m, time->d);
- if (count == 0) {
- /* skip over saturday and sunday */
- if (current_dow == 6) {
- time->d += 2;
- }
- /* skip over sunday */
- if (current_dow == 0) {
- time->d += 1;
- }
- } else if (count > 0) {
- /* skip over saturday and sunday */
- if (current_dow == 5) {
- time->d += 2;
- }
- /* skip over sunday */
- if (current_dow == 6) {
+ /* Add increments of 5 weekdays as a week, leaving the DOW unchanged. */
+ time->d += (count / 5) * 7;
+
+ /* Deal with the remainder. */
+ rem = (count % 5);
+
+ if (count > 0) {
+ if (rem == 0) {
+ /* Head back to Friday if we stop on the weekend. */
+ if (dow == 0) {
+ time->d -= 2;
+ } else if (dow == 6) {
+ time->d -= 1;
+ }
+ } else if (dow == 6) {
+ /* We ended up on Saturday, but there's still work to do, so move
+ * to Sunday and continue from there. */
time->d += 1;
- }
- /* add increments of 5 weekdays as a week */
- time->d += (count / 5) * 7;
- /* if current DOW plus the remainder > 5, add two days */
- current_dow = timelib_day_of_week(time->y, time->m, time->d);
- time->d += (count % 5);
- if ((count % 5) + current_dow > 5) {
+ } else if (dow + rem > 5) {
+ /* We're on a weekday, but we're going past Friday, so skip right
+ * over the weekend. */
time->d += 2;
}
- } else if (count < 0) {
- /* skip over sunday and saturday */
- if (current_dow == 1) {
- time->d -= 2;
- }
- /* skip over satruday */
- if (current_dow == 0 ) {
+ } else {
+ /* Completely mirror the forward direction. This also covers the 0
+ * case, since if we start on the weekend, we want to move forward as
+ * if we stopped there while going backwards. */
+ if (rem == 0) {
+ if (dow == 6) {
+ time->d += 2;
+ } else if (dow == 0) {
+ time->d += 1;
+ }
+ } else if (dow == 0) {
time->d -= 1;
- }
- /* subtract increments of 5 weekdays as a week */
- time->d += (count / 5) * 7;
- /* if current DOW minus the remainder < 0, subtract two days */
- current_dow = timelib_day_of_week(time->y, time->m, time->d);
- time->d += (count % 5);
- if ((count % 5) + current_dow < 1) {
+ } else if (dow + rem < 1) {
time->d -= 2;
}
}
+
+ time->d += rem;
}
static void do_adjust_special(timelib_time* time)
diff --git a/ext/date/php_date.c b/ext/date/php_date.c
index 1655057212..c069e0ccae 100644
--- a/ext/date/php_date.c
+++ b/ext/date/php_date.c
@@ -399,7 +399,9 @@ const zend_function_entry date_functions[] = {
/* Advanced Interface */
PHP_FE(date_create, arginfo_date_create)
+ PHP_FE(date_create_immutable, arginfo_date_create)
PHP_FE(date_create_from_format, arginfo_date_create_from_format)
+ PHP_FE(date_create_immutable_from_format, arginfo_date_create_from_format)
PHP_FE(date_parse, arginfo_date_parse)
PHP_FE(date_parse_from_format, arginfo_date_parse_from_format)
PHP_FE(date_get_last_errors, arginfo_date_get_last_errors)
@@ -442,6 +444,16 @@ const zend_function_entry date_functions[] = {
PHP_FE_END
};
+static const zend_function_entry date_funcs_interface[] = {
+ PHP_ABSTRACT_ME(DateTimeInterface, format, arginfo_date_method_format)
+ PHP_ABSTRACT_ME(DateTimeInterface, getTimezone, arginfo_date_method_timezone_get)
+ PHP_ABSTRACT_ME(DateTimeInterface, getOffset, arginfo_date_method_offset_get)
+ PHP_ABSTRACT_ME(DateTimeInterface, getTimestamp, arginfo_date_method_timestamp_get)
+ PHP_ABSTRACT_ME(DateTimeInterface, diff, arginfo_date_method_diff)
+ PHP_ABSTRACT_ME(DateTimeInterface, __wakeup, NULL)
+ PHP_FE_END
+};
+
const zend_function_entry date_funcs_date[] = {
PHP_ME(DateTime, __construct, arginfo_date_create, ZEND_ACC_CTOR|ZEND_ACC_PUBLIC)
PHP_ME(DateTime, __wakeup, NULL, ZEND_ACC_PUBLIC)
@@ -464,8 +476,32 @@ const zend_function_entry date_funcs_date[] = {
PHP_FE_END
};
+const zend_function_entry date_funcs_immutable[] = {
+ PHP_ME(DateTimeImmutable, __construct, arginfo_date_create, ZEND_ACC_CTOR|ZEND_ACC_PUBLIC)
+ PHP_ME(DateTime, __wakeup, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(DateTimeImmutable, __set_state, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+ PHP_ME_MAPPING(createFromFormat, date_create_immutable_from_format, arginfo_date_create_from_format, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+ PHP_ME_MAPPING(getLastErrors, date_get_last_errors, arginfo_date_get_last_errors, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+ PHP_ME_MAPPING(format, date_format, arginfo_date_method_format, 0)
+ PHP_ME_MAPPING(getTimezone, date_timezone_get, arginfo_date_method_timezone_get, 0)
+ PHP_ME_MAPPING(getOffset, date_offset_get, arginfo_date_method_offset_get, 0)
+ PHP_ME_MAPPING(getTimestamp, date_timestamp_get, arginfo_date_method_timestamp_get, 0)
+ PHP_ME_MAPPING(diff, date_diff, arginfo_date_method_diff, 0)
+ PHP_ME(DateTimeImmutable, modify, arginfo_date_method_modify, 0)
+ PHP_ME(DateTimeImmutable, add, arginfo_date_method_add, 0)
+ PHP_ME(DateTimeImmutable, sub, arginfo_date_method_sub, 0)
+ PHP_ME(DateTimeImmutable, setTimezone, arginfo_date_method_timezone_set, 0)
+ PHP_ME(DateTimeImmutable, setTime, arginfo_date_method_time_set, 0)
+ PHP_ME(DateTimeImmutable, setDate, arginfo_date_method_date_set, 0)
+ PHP_ME(DateTimeImmutable, setISODate, arginfo_date_method_isodate_set, 0)
+ PHP_ME(DateTimeImmutable, setTimestamp, arginfo_date_method_timestamp_set, 0)
+ PHP_FE_END
+};
+
const zend_function_entry date_funcs_timezone[] = {
PHP_ME(DateTimeZone, __construct, arginfo_timezone_open, ZEND_ACC_CTOR|ZEND_ACC_PUBLIC)
+ PHP_ME(DateTimeZone, __wakeup, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(DateTimeZone, __set_state, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_ME_MAPPING(getName, timezone_name_get, arginfo_timezone_method_name_get, 0)
PHP_ME_MAPPING(getOffset, timezone_offset_get, arginfo_timezone_method_offset_get, 0)
PHP_ME_MAPPING(getTransitions, timezone_transitions_get, arginfo_timezone_method_transitions_get, 0)
@@ -524,6 +560,7 @@ PHP_INI_END()
/* }}} */
zend_class_entry *date_ce_date, *date_ce_timezone, *date_ce_interval, *date_ce_period;
+zend_class_entry *date_ce_immutable, *date_ce_interface;
PHPAPI zend_class_entry *php_date_get_date_ce(void)
@@ -531,12 +568,18 @@ PHPAPI zend_class_entry *php_date_get_date_ce(void)
return date_ce_date;
}
+PHPAPI zend_class_entry *php_date_get_immutable_ce(void)
+{
+ return date_ce_immutable;
+}
+
PHPAPI zend_class_entry *php_date_get_timezone_ce(void)
{
return date_ce_timezone;
}
static zend_object_handlers date_object_handlers_date;
+static zend_object_handlers date_object_handlers_immutable;
static zend_object_handlers date_object_handlers_timezone;
static zend_object_handlers date_object_handlers_interval;
static zend_object_handlers date_object_handlers_period;
@@ -587,6 +630,8 @@ static HashTable *date_object_get_gc_interval(zval *object, zval ***table, int *
static HashTable *date_object_get_properties_interval(zval *object TSRMLS_DC);
static HashTable *date_object_get_gc_period(zval *object, zval ***table, int *n TSRMLS_DC);
static HashTable *date_object_get_properties_period(zval *object TSRMLS_DC);
+static HashTable *date_object_get_properties_timezone(zval *object TSRMLS_DC);
+static HashTable *date_object_get_gc_timezone(zval *object, zval ***table, int *n TSRMLS_DC);
zval *date_interval_read_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC);
void date_interval_write_property(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC);
@@ -771,7 +816,6 @@ PHP_RSHUTDOWN_FUNCTION(date)
#define SUNFUNCS_RET_STRING 1
#define SUNFUNCS_RET_DOUBLE 2
-
/* {{{ PHP_MINIT_FUNCTION */
PHP_MINIT_FUNCTION(date)
{
@@ -1385,7 +1429,6 @@ PHPAPI signed long php_parse_date(char *string, signed long *now)
}
/* }}} */
-
/* {{{ proto int strtotime(string time [, int now ])
Convert string representation of date and time to a timestamp */
PHP_FUNCTION(strtotime)
@@ -1446,7 +1489,6 @@ PHP_FUNCTION(strtotime)
}
/* }}} */
-
/* {{{ php_mktime - (gm)mktime helper */
PHPAPI void php_mktime(INTERNAL_FUNCTION_PARAMETERS, int gmt)
{
@@ -1555,7 +1597,6 @@ PHP_FUNCTION(gmmktime)
}
/* }}} */
-
/* {{{ proto bool checkdate(int month, int day, int year)
Returns true(1) if it is a valid date in gregorian calendar */
PHP_FUNCTION(checkdate)
@@ -1582,7 +1623,7 @@ PHPAPI void php_strftime(INTERNAL_FUNCTION_PARAMETERS, int gmt)
long timestamp = 0;
struct tm ta;
int max_reallocs = 5;
- size_t buf_len = 64, real_len;
+ size_t buf_len = 256, real_len;
timelib_time *ts;
timelib_tzinfo *tzi;
timelib_time_offset *offset = NULL;
@@ -1635,6 +1676,9 @@ PHPAPI void php_strftime(INTERNAL_FUNCTION_PARAMETERS, int gmt)
#endif
}
+ /* VS2012 crt has a bug where strftime crash with %z and %Z format when the
+ initial buffer is too small. See
+ http://connect.microsoft.com/VisualStudio/feedback/details/759720/vs2012-strftime-crash-with-z-formatting-code */
buf = (char *) emalloc(buf_len);
while ((real_len=strftime(buf, buf_len, format, &ta))==buf_len || real_len==0) {
buf_len *= 2;
@@ -1643,6 +1687,13 @@ PHPAPI void php_strftime(INTERNAL_FUNCTION_PARAMETERS, int gmt)
break;
}
}
+#if defined(PHP_WIN32) && _MSC_VER >= 1700
+ /* VS2012 strftime() returns number of characters, not bytes.
+ See VC++11 bug id 766205. */
+ if (real_len > 0) {
+ real_len = strlen(buf);
+ }
+#endif
timelib_time_dtor(ts);
if (!gmt) {
@@ -1855,7 +1906,7 @@ static void date_period_it_current_data(zend_object_iterator *iter, zval ***data
/* Create new object */
MAKE_STD_ZVAL(iterator->current);
- php_date_instantiate(date_ce_date, iterator->current TSRMLS_CC);
+ php_date_instantiate(object->start_ce, iterator->current TSRMLS_CC);
newdateobj = (php_date_obj *) zend_object_store_get_object(iterator->current TSRMLS_CC);
newdateobj->time = timelib_time_ctor();
*newdateobj->time = *it_time;
@@ -1872,11 +1923,10 @@ static void date_period_it_current_data(zend_object_iterator *iter, zval ***data
/* {{{ date_period_it_current_key */
-static int date_period_it_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
+static void date_period_it_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC)
{
- date_period_it *iterator = (date_period_it *)iter;
- *int_key = iterator->current_index;
- return HASH_KEY_IS_LONG;
+ date_period_it *iterator = (date_period_it *)iter;
+ ZVAL_LONG(key, iterator->current_index);
}
/* }}} */
@@ -1939,9 +1989,25 @@ zend_object_iterator *date_object_period_get_iterator(zend_class_entry *ce, zval
return (zend_object_iterator*)iterator;
}
+static int implement_date_interface_handler(zend_class_entry *interface, zend_class_entry *implementor TSRMLS_DC)
+{
+ if (implementor->type == ZEND_USER_CLASS &&
+ !instanceof_function(implementor, date_ce_date TSRMLS_CC) &&
+ !instanceof_function(implementor, date_ce_immutable TSRMLS_CC)
+ ) {
+ zend_error(E_ERROR, "DateTimeInterface can't be implemented by user classes");
+ }
+
+ return SUCCESS;
+}
+
static void date_register_classes(TSRMLS_D)
{
- zend_class_entry ce_date, ce_timezone, ce_interval, ce_period;
+ zend_class_entry ce_date, ce_immutable, ce_timezone, ce_interval, ce_period, ce_interface;
+
+ INIT_CLASS_ENTRY(ce_interface, "DateTimeInterface", date_funcs_interface);
+ date_ce_interface = zend_register_internal_interface(&ce_interface TSRMLS_CC);
+ date_ce_interface->interface_gets_implemented = implement_date_interface_handler;
INIT_CLASS_ENTRY(ce_date, "DateTime", date_funcs_date);
ce_date.create_object = date_object_new_date;
@@ -1951,6 +2017,7 @@ static void date_register_classes(TSRMLS_D)
date_object_handlers_date.compare_objects = date_object_compare_date;
date_object_handlers_date.get_properties = date_object_get_properties;
date_object_handlers_date.get_gc = date_object_get_gc;
+ zend_class_implements(date_ce_date TSRMLS_CC, 1, date_ce_interface);
#define REGISTER_DATE_CLASS_CONST_STRING(const_name, value) \
zend_declare_class_constant_stringl(date_ce_date, const_name, sizeof(const_name)-1, value, sizeof(value)-1 TSRMLS_CC);
@@ -1967,12 +2034,22 @@ static void date_register_classes(TSRMLS_D)
REGISTER_DATE_CLASS_CONST_STRING("RSS", DATE_FORMAT_RFC1123);
REGISTER_DATE_CLASS_CONST_STRING("W3C", DATE_FORMAT_RFC3339);
+ INIT_CLASS_ENTRY(ce_immutable, "DateTimeImmutable", date_funcs_immutable);
+ ce_immutable.create_object = date_object_new_date;
+ date_ce_immutable = zend_register_internal_class_ex(&ce_immutable, NULL, NULL TSRMLS_CC);
+ memcpy(&date_object_handlers_immutable, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ date_object_handlers_immutable.clone_obj = date_object_clone_date;
+ date_object_handlers_immutable.compare_objects = date_object_compare_date;
+ date_object_handlers_immutable.get_properties = date_object_get_properties;
+ zend_class_implements(date_ce_immutable TSRMLS_CC, 1, date_ce_interface);
INIT_CLASS_ENTRY(ce_timezone, "DateTimeZone", date_funcs_timezone);
ce_timezone.create_object = date_object_new_timezone;
date_ce_timezone = zend_register_internal_class_ex(&ce_timezone, NULL, NULL TSRMLS_CC);
memcpy(&date_object_handlers_timezone, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
date_object_handlers_timezone.clone_obj = date_object_clone_timezone;
+ date_object_handlers_timezone.get_properties = date_object_get_properties_timezone;
+ date_object_handlers_timezone.get_gc = date_object_get_gc_timezone;
#define REGISTER_TIMEZONE_CLASS_CONST_STRING(const_name, value) \
zend_declare_class_constant_long(date_ce_timezone, const_name, sizeof(const_name)-1, value TSRMLS_CC);
@@ -2072,29 +2149,36 @@ static zend_object_value date_object_clone_date(zval *this_ptr TSRMLS_DC)
return new_ov;
}
+static zval* date_clone_immutable(zval *object TSRMLS_DC)
+{
+ zval *new_object;
+
+ ALLOC_ZVAL(new_object);
+ Z_OBJVAL_P(new_object) = date_object_clone_date(object TSRMLS_CC);
+ Z_SET_REFCOUNT_P(new_object, 1);
+ Z_SET_ISREF_P(new_object);
+ Z_TYPE_P(new_object) = IS_OBJECT;
+
+ return new_object;
+}
+
static int date_object_compare_date(zval *d1, zval *d2 TSRMLS_DC)
{
- if (Z_TYPE_P(d1) == IS_OBJECT && Z_TYPE_P(d2) == IS_OBJECT &&
- instanceof_function(Z_OBJCE_P(d1), date_ce_date TSRMLS_CC) &&
- instanceof_function(Z_OBJCE_P(d2), date_ce_date TSRMLS_CC)) {
- php_date_obj *o1 = zend_object_store_get_object(d1 TSRMLS_CC);
- php_date_obj *o2 = zend_object_store_get_object(d2 TSRMLS_CC);
+ php_date_obj *o1 = zend_object_store_get_object(d1 TSRMLS_CC);
+ php_date_obj *o2 = zend_object_store_get_object(d2 TSRMLS_CC);
- if (!o1->time || !o2->time) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Trying to compare an incomplete DateTime object");
- return 1;
- }
- if (!o1->time->sse_uptodate) {
- timelib_update_ts(o1->time, o1->time->tz_info);
- }
- if (!o2->time->sse_uptodate) {
- timelib_update_ts(o2->time, o2->time->tz_info);
- }
-
- return (o1->time->sse == o2->time->sse) ? 0 : ((o1->time->sse < o2->time->sse) ? -1 : 1);
+ if (!o1->time || !o2->time) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Trying to compare an incomplete DateTime or DateTimeImmutable object");
+ return 1;
+ }
+ if (!o1->time->sse_uptodate) {
+ timelib_update_ts(o1->time, o1->time->tz_info);
+ }
+ if (!o2->time->sse_uptodate) {
+ timelib_update_ts(o2->time, o2->time->tz_info);
}
- return 1;
+ return (o1->time->sse == o2->time->sse) ? 0 : ((o1->time->sse < o2->time->sse) ? -1 : 1);
}
static HashTable *date_object_get_gc(zval *object, zval ***table, int *n TSRMLS_DC)
@@ -2104,6 +2188,14 @@ static HashTable *date_object_get_gc(zval *object, zval ***table, int *n TSRMLS_
return zend_std_get_properties(object TSRMLS_CC);
}
+static HashTable *date_object_get_gc_timezone(zval *object, zval ***table, int *n TSRMLS_DC)
+{
+
+ *table = NULL;
+ *n = 0;
+ return zend_std_get_properties(object TSRMLS_CC);
+}
+
static HashTable *date_object_get_properties(zval *object TSRMLS_DC)
{
HashTable *props;
@@ -2212,6 +2304,50 @@ static zend_object_value date_object_clone_timezone(zval *this_ptr TSRMLS_DC)
return new_ov;
}
+static HashTable *date_object_get_properties_timezone(zval *object TSRMLS_DC)
+{
+ HashTable *props;
+ zval *zv;
+ php_timezone_obj *tzobj;
+
+
+ tzobj = (php_timezone_obj *) zend_object_store_get_object(object TSRMLS_CC);
+
+ props = zend_std_get_properties(object TSRMLS_CC);
+
+ if (!tzobj->initialized) {
+ return props;
+ }
+
+ MAKE_STD_ZVAL(zv);
+ ZVAL_LONG(zv, tzobj->type);
+ zend_hash_update(props, "timezone_type", 14, &zv, sizeof(zv), NULL);
+
+ MAKE_STD_ZVAL(zv);
+ switch (tzobj->type) {
+ case TIMELIB_ZONETYPE_ID:
+ ZVAL_STRING(zv, tzobj->tzi.tz->name, 1);
+ break;
+ case TIMELIB_ZONETYPE_OFFSET: {
+ char *tmpstr = emalloc(sizeof("UTC+05:00"));
+
+ snprintf(tmpstr, sizeof("+05:00"), "%c%02d:%02d",
+ tzobj->tzi.utc_offset > 0 ? '-' : '+',
+ abs(tzobj->tzi.utc_offset / 60),
+ abs((tzobj->tzi.utc_offset % 60)));
+
+ ZVAL_STRING(zv, tmpstr, 0);
+ }
+ break;
+ case TIMELIB_ZONETYPE_ABBR:
+ ZVAL_STRING(zv, tzobj->tzi.z.abbr, 1);
+ break;
+ }
+ zend_hash_update(props, "timezone", 9, &zv, sizeof(zv), NULL);
+
+ return props;
+}
+
static inline zend_object_value date_object_new_interval_ex(zend_class_entry *class_type, php_interval_obj **ptr TSRMLS_DC)
{
php_interval_obj *intern;
@@ -2516,6 +2652,26 @@ PHP_FUNCTION(date_create)
}
/* }}} */
+/* {{{ proto DateTime date_create_immutable([string time[, DateTimeZone object]])
+ Returns new DateTime object
+*/
+PHP_FUNCTION(date_create_immutable)
+{
+ zval *timezone_object = NULL;
+ char *time_str = NULL;
+ int time_str_len = 0;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sO!", &time_str, &time_str_len, &timezone_object, date_ce_timezone) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ php_date_instantiate(date_ce_immutable, return_value TSRMLS_CC);
+ if (!php_date_initialize(zend_object_store_get_object(return_value TSRMLS_CC), time_str, time_str_len, NULL, timezone_object, 0 TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
/* {{{ proto DateTime date_create_from_format(string format, string time[, DateTimeZone object])
Returns new DateTime object formatted according to the specified format
*/
@@ -2536,6 +2692,26 @@ PHP_FUNCTION(date_create_from_format)
}
/* }}} */
+/* {{{ proto DateTime date_create_immutable_from_format(string format, string time[, DateTimeZone object])
+ Returns new DateTime object formatted according to the specified format
+*/
+PHP_FUNCTION(date_create_immutable_from_format)
+{
+ zval *timezone_object = NULL;
+ char *time_str = NULL, *format_str = NULL;
+ int time_str_len = 0, format_str_len = 0;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|O", &format_str, &format_str_len, &time_str, &time_str_len, &timezone_object, date_ce_timezone) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ php_date_instantiate(date_ce_immutable, return_value TSRMLS_CC);
+ if (!php_date_initialize(zend_object_store_get_object(return_value TSRMLS_CC), time_str, time_str_len, format_str, timezone_object, 0 TSRMLS_CC)) {
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
/* {{{ proto DateTime::__construct([string time[, DateTimeZone object]])
Creates new DateTime object
*/
@@ -2554,6 +2730,24 @@ PHP_METHOD(DateTime, __construct)
}
/* }}} */
+/* {{{ proto DateTimeImmutable::__construct([string time[, DateTimeZone object]])
+ Creates new DateTimeImmutable object
+*/
+PHP_METHOD(DateTimeImmutable, __construct)
+{
+ zval *timezone_object = NULL;
+ char *time_str = NULL;
+ int time_str_len = 0;
+ zend_error_handling error_handling;
+
+ zend_replace_error_handling(EH_THROW, NULL, &error_handling TSRMLS_CC);
+ if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sO!", &time_str, &time_str_len, &timezone_object, date_ce_timezone)) {
+ php_date_initialize(zend_object_store_get_object(getThis() TSRMLS_CC), time_str, time_str_len, NULL, timezone_object, 1 TSRMLS_CC);
+ }
+ zend_restore_error_handling(&error_handling TSRMLS_CC);
+}
+/* }}} */
+
static int php_date_initialize_from_hash(zval **return_value, php_date_obj **dateobj, HashTable *myht TSRMLS_DC)
{
zval **z_date = NULL;
@@ -2626,6 +2820,28 @@ PHP_METHOD(DateTime, __set_state)
}
/* }}} */
+/* {{{ proto DateTimeImmutable::__set_state()
+*/
+PHP_METHOD(DateTimeImmutable, __set_state)
+{
+ php_date_obj *dateobj;
+ zval *array;
+ HashTable *myht;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ myht = HASH_OF(array);
+
+ php_date_instantiate(date_ce_immutable, return_value TSRMLS_CC);
+ dateobj = (php_date_obj *) zend_object_store_get_object(return_value TSRMLS_CC);
+ if (!php_date_initialize_from_hash(&return_value, &dateobj, myht TSRMLS_CC)) {
+ php_error(E_ERROR, "Invalid serialization data for DateTimeImmutable object");
+ }
+}
+/* }}} */
+
/* {{{ proto DateTime::__wakeup()
*/
PHP_METHOD(DateTime, __wakeup)
@@ -2794,7 +3010,7 @@ PHP_FUNCTION(date_parse_from_format)
}
/* }}} */
-/* {{{ proto string date_format(DateTime object, string format)
+/* {{{ proto string date_format(DateTimeInterface object, string format)
Returns date formatted according to given format
*/
PHP_FUNCTION(date_format)
@@ -2804,7 +3020,7 @@ PHP_FUNCTION(date_format)
char *format;
int format_len;
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &object, date_ce_date, &format, &format_len) == FAILURE) {
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &object, date_ce_interface, &format, &format_len) == FAILURE) {
RETURN_FALSE;
}
dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
@@ -2813,23 +3029,18 @@ PHP_FUNCTION(date_format)
}
/* }}} */
-/* {{{ proto DateTime date_modify(DateTime object, string modify)
- Alters the timestamp.
-*/
-PHP_FUNCTION(date_modify)
+static int php_date_modify(zval *object, char *modify, int modify_len TSRMLS_DC)
{
- zval *object;
php_date_obj *dateobj;
- char *modify;
- int modify_len;
timelib_time *tmp_time;
timelib_error_container *err = NULL;
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &object, date_ce_date, &modify, &modify_len) == FAILURE) {
- RETURN_FALSE;
- }
dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
- DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
+
+ if (!(dateobj->time)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "The DateTime object has not been correctly initialized by its constructor");
+ return 0;
+ }
tmp_time = timelib_strtotime(modify, modify_len, &err, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper);
@@ -2840,7 +3051,7 @@ PHP_FUNCTION(date_modify)
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to parse time string (%s) at position %d (%c): %s", modify,
err->error_messages[0].position, err->error_messages[0].character, err->error_messages[0].message);
timelib_time_dtor(tmp_time);
- RETURN_FALSE;
+ return 0;
}
memcpy(&dateobj->time->relative, &tmp_time->relative, sizeof(struct timelib_rel_time));
@@ -2876,24 +3087,58 @@ PHP_FUNCTION(date_modify)
timelib_update_ts(dateobj->time, NULL);
timelib_update_from_sse(dateobj->time);
dateobj->time->have_relative = 0;
+
+ return 1;
+}
- RETURN_ZVAL(object, 1, 0);
+/* {{{ proto DateTime date_modify(DateTime object, string modify)
+ Alters the timestamp.
+*/
+PHP_FUNCTION(date_modify)
+{
+ zval *object;
+ char *modify;
+ int modify_len;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &object, date_ce_date, &modify, &modify_len) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ if (php_date_modify(object, modify, modify_len TSRMLS_CC)) {
+ RETURN_ZVAL(object, 1, 0);
+ }
+
+ RETURN_FALSE;
}
/* }}} */
-/* {{{ proto DateTime date_add(DateTime object, DateInterval interval)
- Adds an interval to the current date in object.
+/* {{{ proto DateTimeImmutable::modify()
*/
-PHP_FUNCTION(date_add)
+PHP_METHOD(DateTimeImmutable, modify)
{
- zval *object, *interval;
- php_date_obj *dateobj;
- php_interval_obj *intobj;
- timelib_time *new_time;
+ zval *object, *new_object;
+ char *modify;
+ int modify_len;
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &object, date_ce_date, &interval, date_ce_interval) == FAILURE) {
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &object, date_ce_immutable, &modify, &modify_len) == FAILURE) {
RETURN_FALSE;
}
+
+ new_object = date_clone_immutable(object TSRMLS_CC);
+ if (php_date_modify(new_object, modify, modify_len TSRMLS_CC)) {
+ RETURN_ZVAL(new_object, 0, 1);
+ }
+
+ RETURN_FALSE;
+}
+/* }}} */
+
+static void php_date_add(zval *object, zval *interval, zval *return_value TSRMLS_DC)
+{
+ php_date_obj *dateobj;
+ php_interval_obj *intobj;
+ timelib_time *new_time;
+
dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
intobj = (php_interval_obj *) zend_object_store_get_object(interval TSRMLS_CC);
@@ -2902,24 +3147,48 @@ PHP_FUNCTION(date_add)
new_time = timelib_add(dateobj->time, intobj->diff);
timelib_time_dtor(dateobj->time);
dateobj->time = new_time;
+}
+
+/* {{{ proto DateTime date_add(DateTime object, DateInterval interval)
+ Adds an interval to the current date in object.
+*/
+PHP_FUNCTION(date_add)
+{
+ zval *object, *interval;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &object, date_ce_date, &interval, date_ce_interval) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ php_date_add(object, interval, return_value TSRMLS_CC);
RETURN_ZVAL(object, 1, 0);
}
/* }}} */
-/* {{{ proto DateTime date_sub(DateTime object, DateInterval interval)
- Subtracts an interval to the current date in object.
+/* {{{ proto DateTimeImmutable::add()
*/
-PHP_FUNCTION(date_sub)
+PHP_METHOD(DateTimeImmutable, add)
{
- zval *object, *interval;
- php_date_obj *dateobj;
- php_interval_obj *intobj;
- timelib_time *new_time;
+ zval *object, *interval, *new_object;
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &object, date_ce_date, &interval, date_ce_interval) == FAILURE) {
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &object, date_ce_immutable, &interval, date_ce_interval) == FAILURE) {
RETURN_FALSE;
}
+
+ new_object = date_clone_immutable(object TSRMLS_CC);
+ php_date_add(new_object, interval, return_value TSRMLS_CC);
+
+ RETURN_ZVAL(new_object, 0, 1);
+}
+/* }}} */
+
+static void php_date_sub(zval *object, zval *interval, zval *return_value TSRMLS_DC)
+{
+ php_date_obj *dateobj;
+ php_interval_obj *intobj;
+ timelib_time *new_time;
+
dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
intobj = (php_interval_obj *) zend_object_store_get_object(interval TSRMLS_CC);
@@ -2933,12 +3202,43 @@ PHP_FUNCTION(date_sub)
new_time = timelib_sub(dateobj->time, intobj->diff);
timelib_time_dtor(dateobj->time);
dateobj->time = new_time;
+}
+
+/* {{{ proto DateTime date_sub(DateTime object, DateInterval interval)
+ Subtracts an interval to the current date in object.
+*/
+PHP_FUNCTION(date_sub)
+{
+ zval *object, *interval;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &object, date_ce_date, &interval, date_ce_interval) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ php_date_sub(object, interval, return_value TSRMLS_CC);
RETURN_ZVAL(object, 1, 0);
}
/* }}} */
-/* {{{ proto DateTimeZone date_timezone_get(DateTime object)
+/* {{{ proto DateTimeImmutable::sub()
+*/
+PHP_METHOD(DateTimeImmutable, sub)
+{
+ zval *object, *interval, *new_object;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &object, date_ce_immutable, &interval, date_ce_interval) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ new_object = date_clone_immutable(object TSRMLS_CC);
+ php_date_sub(new_object, interval, return_value TSRMLS_CC);
+
+ RETURN_ZVAL(new_object, 0, 1);
+}
+/* }}} */
+
+/* {{{ proto DateTimeZone date_timezone_get(DateTimeInterface object)
Return new DateTimeZone object relative to give DateTime
*/
PHP_FUNCTION(date_timezone_get)
@@ -2947,7 +3247,7 @@ PHP_FUNCTION(date_timezone_get)
php_date_obj *dateobj;
php_timezone_obj *tzobj;
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, date_ce_date) == FAILURE) {
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, date_ce_interface) == FAILURE) {
RETURN_FALSE;
}
dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
@@ -2976,19 +3276,11 @@ PHP_FUNCTION(date_timezone_get)
}
/* }}} */
-/* {{{ proto DateTime date_timezone_set(DateTime object, DateTimeZone object)
- Sets the timezone for the DateTime object.
-*/
-PHP_FUNCTION(date_timezone_set)
+static void php_date_timezone_set(zval *object, zval *timezone_object, zval *return_value TSRMLS_DC)
{
- zval *object;
- zval *timezone_object;
php_date_obj *dateobj;
php_timezone_obj *tzobj;
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &object, date_ce_date, &timezone_object, date_ce_timezone) == FAILURE) {
- RETURN_FALSE;
- }
dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
tzobj = (php_timezone_obj *) zend_object_store_get_object(timezone_object TSRMLS_CC);
@@ -2998,12 +3290,45 @@ PHP_FUNCTION(date_timezone_set)
}
timelib_set_timezone(dateobj->time, tzobj->tzi.tz);
timelib_unixtime2local(dateobj->time, dateobj->time->sse);
+}
+
+/* {{{ proto DateTime date_timezone_set(DateTime object, DateTimeZone object)
+ Sets the timezone for the DateTime object.
+*/
+PHP_FUNCTION(date_timezone_set)
+{
+ zval *object;
+ zval *timezone_object;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &object, date_ce_date, &timezone_object, date_ce_timezone) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ php_date_timezone_set(object, timezone_object, return_value TSRMLS_CC);
RETURN_ZVAL(object, 1, 0);
}
/* }}} */
-/* {{{ proto long date_offset_get(DateTime object)
+/* {{{ proto DateTimeImmutable::setTimezone()
+*/
+PHP_METHOD(DateTimeImmutable, setTimezone)
+{
+ zval *object, *new_object;
+ zval *timezone_object;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &object, date_ce_immutable, &timezone_object, date_ce_timezone) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ new_object = date_clone_immutable(object TSRMLS_CC);
+ php_date_timezone_set(new_object, timezone_object, return_value TSRMLS_CC);
+
+ RETURN_ZVAL(new_object, 0, 1);
+}
+/* }}} */
+
+/* {{{ proto long date_offset_get(DateTimeInterface object)
Returns the DST offset.
*/
PHP_FUNCTION(date_offset_get)
@@ -3012,7 +3337,7 @@ PHP_FUNCTION(date_offset_get)
php_date_obj *dateobj;
timelib_time_offset *offset;
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, date_ce_date) == FAILURE) {
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, date_ce_interface) == FAILURE) {
RETURN_FALSE;
}
dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
@@ -3038,64 +3363,106 @@ PHP_FUNCTION(date_offset_get)
}
/* }}} */
-/* {{{ proto DateTime date_time_set(DateTime object, long hour, long minute[, long second])
- Sets the time.
-*/
-PHP_FUNCTION(date_time_set)
+static void php_date_time_set(zval *object, long h, long i, long s, zval *return_value TSRMLS_DC)
{
- zval *object;
php_date_obj *dateobj;
- long h, i, s = 0;
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll|l", &object, date_ce_date, &h, &i, &s) == FAILURE) {
- RETURN_FALSE;
- }
dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
dateobj->time->h = h;
dateobj->time->i = i;
dateobj->time->s = s;
timelib_update_ts(dateobj->time, NULL);
+}
+
+/* {{{ proto DateTime date_time_set(DateTime object, long hour, long minute[, long second])
+ Sets the time.
+*/
+PHP_FUNCTION(date_time_set)
+{
+ zval *object;
+ long h, i, s = 0;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll|l", &object, date_ce_date, &h, &i, &s) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ php_date_time_set(object, h, i, s, return_value TSRMLS_CC);
RETURN_ZVAL(object, 1, 0);
}
/* }}} */
-/* {{{ proto DateTime date_date_set(DateTime object, long year, long month, long day)
- Sets the date.
+/* {{{ proto DateTimeImmutable::setTime()
*/
-PHP_FUNCTION(date_date_set)
+PHP_METHOD(DateTimeImmutable, setTime)
{
- zval *object;
- php_date_obj *dateobj;
- long y, m, d;
+ zval *object, *new_object;
+ long h, i, s = 0;
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Olll", &object, date_ce_date, &y, &m, &d) == FAILURE) {
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll|l", &object, date_ce_immutable, &h, &i, &s) == FAILURE) {
RETURN_FALSE;
}
+
+ new_object = date_clone_immutable(object TSRMLS_CC);
+ php_date_time_set(new_object, h, i, s, return_value TSRMLS_CC);
+
+ RETURN_ZVAL(new_object, 0, 1);
+}
+/* }}} */
+
+static void php_date_date_set(zval *object, long y, long m, long d, zval *return_value TSRMLS_DC)
+{
+ php_date_obj *dateobj;
+
dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
dateobj->time->y = y;
dateobj->time->m = m;
dateobj->time->d = d;
timelib_update_ts(dateobj->time, NULL);
+}
+
+/* {{{ proto DateTime date_date_set(DateTime object, long year, long month, long day)
+ Sets the date.
+*/
+PHP_FUNCTION(date_date_set)
+{
+ zval *object;
+ long y, m, d;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Olll", &object, date_ce_date, &y, &m, &d) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ php_date_date_set(object, y, m, d, return_value TSRMLS_CC);
RETURN_ZVAL(object, 1, 0);
}
/* }}} */
-/* {{{ proto DateTime date_isodate_set(DateTime object, long year, long week[, long day])
- Sets the ISO date.
+/* {{{ proto DateTimeImmutable::setDate()
*/
-PHP_FUNCTION(date_isodate_set)
+PHP_METHOD(DateTimeImmutable, setDate)
{
- zval *object;
- php_date_obj *dateobj;
- long y, w, d = 1;
+ zval *object, *new_object;
+ long y, m, d;
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll|l", &object, date_ce_date, &y, &w, &d) == FAILURE) {
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Olll", &object, date_ce_immutable, &y, &m, &d) == FAILURE) {
RETURN_FALSE;
}
+
+ new_object = date_clone_immutable(object TSRMLS_CC);
+ php_date_date_set(new_object, y, m, d, return_value TSRMLS_CC);
+
+ RETURN_ZVAL(new_object, 0, 1);
+}
+/* }}} */
+
+static void php_date_isodate_set(zval *object, long y, long w, long d, zval *return_value TSRMLS_DC)
+{
+ php_date_obj *dateobj;
+
dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
dateobj->time->y = y;
@@ -3106,33 +3473,91 @@ PHP_FUNCTION(date_isodate_set)
dateobj->time->have_relative = 1;
timelib_update_ts(dateobj->time, NULL);
+}
+
+/* {{{ proto DateTime date_isodate_set(DateTime object, long year, long week[, long day])
+ Sets the ISO date.
+*/
+PHP_FUNCTION(date_isodate_set)
+{
+ zval *object;
+ long y, w, d = 1;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll|l", &object, date_ce_date, &y, &w, &d) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ php_date_isodate_set(object, y, w, d, return_value TSRMLS_CC);
RETURN_ZVAL(object, 1, 0);
}
/* }}} */
-/* {{{ proto DateTime date_timestamp_set(DateTime object, long unixTimestamp)
- Sets the date and time based on an Unix timestamp.
+/* {{{ proto DateTimeImmutable::setISODate()
*/
-PHP_FUNCTION(date_timestamp_set)
+PHP_METHOD(DateTimeImmutable, setISODate)
{
- zval *object;
- php_date_obj *dateobj;
- long timestamp;
+ zval *object, *new_object;
+ long y, w, d = 1;
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &object, date_ce_date, &timestamp) == FAILURE) {
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll|l", &object, date_ce_immutable, &y, &w, &d) == FAILURE) {
RETURN_FALSE;
}
+
+ new_object = date_clone_immutable(object TSRMLS_CC);
+ php_date_isodate_set(new_object, y, w, d, return_value TSRMLS_CC);
+
+ RETURN_ZVAL(new_object, 0, 1);
+}
+/* }}} */
+
+static void php_date_timestamp_set(zval *object, long timestamp, zval *return_value TSRMLS_DC)
+{
+ php_date_obj *dateobj;
+
dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
DATE_CHECK_INITIALIZED(dateobj->time, DateTime);
timelib_unixtime2local(dateobj->time, (timelib_sll)timestamp);
timelib_update_ts(dateobj->time, NULL);
+}
+
+/* {{{ proto DateTime date_timestamp_set(DateTime object, long unixTimestamp)
+ Sets the date and time based on an Unix timestamp.
+*/
+PHP_FUNCTION(date_timestamp_set)
+{
+ zval *object;
+ long timestamp;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &object, date_ce_date, &timestamp) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ php_date_timestamp_set(object, timestamp, return_value TSRMLS_CC);
RETURN_ZVAL(object, 1, 0);
}
/* }}} */
-/* {{{ proto long date_timestamp_get(DateTime object)
+/* {{{ proto DateTimeImmutable::setTimestamp()
+*/
+PHP_METHOD(DateTimeImmutable, setTimestamp)
+{
+ zval *object, *new_object;
+ long timestamp;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol", &object, date_ce_immutable, &timestamp) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ new_object = date_clone_immutable(object TSRMLS_CC);
+ php_date_timestamp_set(new_object, timestamp, return_value TSRMLS_CC);
+
+ RETURN_ZVAL(new_object, 0, 1);
+}
+/* }}} */
+
+/* {{{ proto long date_timestamp_get(DateTimeInterface object)
Gets the Unix timestamp.
*/
PHP_FUNCTION(date_timestamp_get)
@@ -3142,7 +3567,7 @@ PHP_FUNCTION(date_timestamp_get)
long timestamp;
int error;
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, date_ce_date) == FAILURE) {
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, date_ce_interface) == FAILURE) {
RETURN_FALSE;
}
dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC);
@@ -3168,13 +3593,13 @@ PHP_FUNCTION(date_diff)
php_interval_obj *interval;
long absolute = 0;
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO|l", &object1, date_ce_date, &object2, date_ce_date, &absolute) == FAILURE) {
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO|l", &object1, date_ce_interface, &object2, date_ce_interface, &absolute) == FAILURE) {
RETURN_FALSE;
}
dateobj1 = (php_date_obj *) zend_object_store_get_object(object1 TSRMLS_CC);
dateobj2 = (php_date_obj *) zend_object_store_get_object(object2 TSRMLS_CC);
- DATE_CHECK_INITIALIZED(dateobj1->time, DateTime);
- DATE_CHECK_INITIALIZED(dateobj2->time, DateTime);
+ DATE_CHECK_INITIALIZED(dateobj1->time, DateTimeInterface);
+ DATE_CHECK_INITIALIZED(dateobj2->time, DateTimeInterface);
timelib_update_ts(dateobj1->time, NULL);
timelib_update_ts(dateobj2->time, NULL);
@@ -3257,6 +3682,85 @@ PHP_METHOD(DateTimeZone, __construct)
}
/* }}} */
+static int php_date_timezone_initialize_from_hash(zval **return_value, php_timezone_obj **tzobj, HashTable *myht TSRMLS_DC)
+{
+ zval **z_timezone = NULL;
+ zval **z_timezone_type = NULL;
+ timelib_tzinfo *tzi;
+
+ if (zend_hash_find(myht, "timezone_type", 14, (void**) &z_timezone_type) == SUCCESS) {
+ if (zend_hash_find(myht, "timezone", 9, (void**) &z_timezone) == SUCCESS) {
+ convert_to_long(*z_timezone_type);
+ switch (Z_LVAL_PP(z_timezone_type)) {
+ case TIMELIB_ZONETYPE_OFFSET: {
+ char *offset, *offset_start;
+
+ offset = emalloc(sizeof(char) * (Z_STRLEN_PP(z_timezone) + 1));
+ memmove(offset, Z_STRVAL_PP(z_timezone), Z_STRLEN_PP(z_timezone)+1);
+ offset_start = offset;
+
+ ++offset;
+ if(*offset_start == '+'){
+ (*tzobj)->tzi.utc_offset = -1 * timelib_parse_tz_cor(&offset);
+ } else {
+ (*tzobj)->tzi.utc_offset = timelib_parse_tz_cor(&offset);
+ }
+ efree(offset_start);
+ (*tzobj)->type = TIMELIB_ZONETYPE_OFFSET;
+ (*tzobj)->initialized = 1;
+ return SUCCESS;
+ break;
+ }
+ case TIMELIB_ZONETYPE_ABBR:
+ case TIMELIB_ZONETYPE_ID:
+ if (SUCCESS == timezone_initialize(&tzi, Z_STRVAL_PP(z_timezone) TSRMLS_CC)) {
+ (*tzobj)->type = TIMELIB_ZONETYPE_ID;
+ (*tzobj)->tzi.tz = tzi;
+ (*tzobj)->initialized = 1;
+ return SUCCESS;
+ }
+ }
+ }
+ }
+ return FAILURE;
+}
+
+/* {{{ proto DateTimeZone::__set_state()
+ * */
+PHP_METHOD(DateTimeZone, __set_state)
+{
+ php_timezone_obj *tzobj;
+ zval *array;
+ HashTable *myht;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ myht = HASH_OF(array);
+
+ php_date_instantiate(date_ce_timezone, return_value TSRMLS_CC);
+ tzobj = (php_timezone_obj *) zend_object_store_get_object(return_value TSRMLS_CC);
+ php_date_timezone_initialize_from_hash(&return_value, &tzobj, myht TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto DateTimeZone::__wakeup()
+ * */
+PHP_METHOD(DateTimeZone, __wakeup)
+{
+ zval *object = getThis();
+ php_timezone_obj *tzobj;
+ HashTable *myht;
+
+ tzobj = (php_timezone_obj *) zend_object_store_get_object(object TSRMLS_CC);
+
+ myht = Z_OBJPROP_P(object);
+
+ php_date_timezone_initialize_from_hash(&return_value, &tzobj, myht TSRMLS_CC);
+}
+/* }}} */
+
/* {{{ proto string timezone_name_get(DateTimeZone object)
Returns the name of the timezone.
*/
@@ -3872,10 +4376,10 @@ PHP_METHOD(DatePeriod, __construct)
zend_error_handling error_handling;
zend_replace_error_handling(EH_THROW, NULL, &error_handling TSRMLS_CC);
- if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "OOl|l", &start, date_ce_date, &interval, date_ce_interval, &recurrences, &options) == FAILURE) {
- if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "OOO|l", &start, date_ce_date, &interval, date_ce_interval, &end, date_ce_date, &options) == FAILURE) {
+ if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "OOl|l", &start, date_ce_interface, &interval, date_ce_interval, &recurrences, &options) == FAILURE) {
+ if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "OOO|l", &start, date_ce_interface, &interval, date_ce_interval, &end, date_ce_interface, &options) == FAILURE) {
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &isostr, &isostr_len, &options) == FAILURE) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "This constructor accepts either (DateTime, DateInterval, int) OR (DateTime, DateInterval, DateTime) OR (string) as arguments.");
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "This constructor accepts either (DateTimeInterface, DateInterval, int) OR (DateTimeInterface, DateInterval, DateTime) OR (string) as arguments.");
zend_restore_error_handling(&error_handling TSRMLS_CC);
return;
}
@@ -3903,6 +4407,7 @@ PHP_METHOD(DatePeriod, __construct)
if (dpobj->end) {
timelib_update_ts(dpobj->end, NULL);
}
+ dpobj->start_ce = date_ce_date;
} else {
/* init */
intobj = (php_interval_obj *) zend_object_store_get_object(interval TSRMLS_CC);
@@ -3918,6 +4423,7 @@ PHP_METHOD(DatePeriod, __construct)
clone->tz_info = dateobj->time->tz_info;
}
dpobj->start = clone;
+ dpobj->start_ce = Z_OBJCE_P(start);
/* interval */
dpobj->interval = timelib_rel_time_clone(intobj->diff);
@@ -4377,6 +4883,7 @@ static int php_date_period_initialize_from_hash(php_period_obj *period_obj, Hash
php_date_obj *date_obj;
date_obj = zend_object_store_get_object(*ht_entry TSRMLS_CC);
period_obj->start = timelib_time_clone(date_obj->time);
+ period_obj->start_ce = Z_OBJCE_PP(ht_entry);
} else if (Z_TYPE_PP(ht_entry) != IS_NULL) {
return 0;
}
diff --git a/ext/date/php_date.h b/ext/date/php_date.h
index 1d6a94d0ae..d4204ebd79 100644
--- a/ext/date/php_date.h
+++ b/ext/date/php_date.h
@@ -51,7 +51,9 @@ PHP_METHOD(DateTime, __construct);
PHP_METHOD(DateTime, __wakeup);
PHP_METHOD(DateTime, __set_state);
PHP_FUNCTION(date_create);
+PHP_FUNCTION(date_create_immutable);
PHP_FUNCTION(date_create_from_format);
+PHP_FUNCTION(date_create_immutable_from_format);
PHP_FUNCTION(date_parse);
PHP_FUNCTION(date_parse_from_format);
PHP_FUNCTION(date_get_last_errors);
@@ -70,7 +72,20 @@ PHP_FUNCTION(date_isodate_set);
PHP_FUNCTION(date_timestamp_set);
PHP_FUNCTION(date_timestamp_get);
+PHP_METHOD(DateTimeImmutable, __construct);
+PHP_METHOD(DateTimeImmutable, __set_state);
+PHP_METHOD(DateTimeImmutable, modify);
+PHP_METHOD(DateTimeImmutable, add);
+PHP_METHOD(DateTimeImmutable, sub);
+PHP_METHOD(DateTimeImmutable, setTimezone);
+PHP_METHOD(DateTimeImmutable, setTime);
+PHP_METHOD(DateTimeImmutable, setDate);
+PHP_METHOD(DateTimeImmutable, setISODate);
+PHP_METHOD(DateTimeImmutable, setTimestamp);
+
PHP_METHOD(DateTimeZone, __construct);
+PHP_METHOD(DateTimeZone, __wakeup);
+PHP_METHOD(DateTimeZone, __set_state);
PHP_FUNCTION(timezone_open);
PHP_FUNCTION(timezone_name_get);
PHP_FUNCTION(timezone_name_from_abbr);
@@ -131,6 +146,7 @@ struct _php_timezone_obj {
int dst;
} z;
} tzi;
+ HashTable *props;
};
struct _php_interval_obj {
@@ -143,6 +159,7 @@ struct _php_interval_obj {
struct _php_period_obj {
zend_object std;
timelib_time *start;
+ zend_class_entry *start_ce;
timelib_time *current;
timelib_time *end;
timelib_rel_time *interval;
diff --git a/ext/date/tests/014.phpt b/ext/date/tests/014.phpt
index be0847777f..5e609c8685 100644
--- a/ext/date/tests/014.phpt
+++ b/ext/date/tests/014.phpt
@@ -26,7 +26,11 @@ object(DateTime)#%d (3) {
["timezone"]=>
string(3) "UTC"
}
-object(DateTimeZone)#%d (0) {
+object(DateTimeZone)#%d (2) {
+ ["timezone_type"]=>
+ int(3)
+ ["timezone"]=>
+ string(3) "UTC"
}
Warning: timezone_offset_get() expects exactly 2 parameters, 0 given in %s on line %d
diff --git a/ext/date/tests/DatePeriod_wrong_constructor.phpt b/ext/date/tests/DatePeriod_wrong_constructor.phpt
index 62e6aa98ac..744ca26c87 100644
--- a/ext/date/tests/DatePeriod_wrong_constructor.phpt
+++ b/ext/date/tests/DatePeriod_wrong_constructor.phpt
@@ -10,8 +10,8 @@ date.timezone=UTC
new DatePeriod();
?>
--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
+Fatal error: Uncaught exception 'Exception' with message 'DatePeriod::__construct(): This constructor accepts either (DateTimeInterface, DateInterval, int) OR (DateTimeInterface, 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
+ thrown in %s on line %d
diff --git a/ext/date/tests/DateTimeZone_clone_basic1.phpt b/ext/date/tests/DateTimeZone_clone_basic1.phpt
index 6de5d4b463..a89005aaec 100644
--- a/ext/date/tests/DateTimeZone_clone_basic1.phpt
+++ b/ext/date/tests/DateTimeZone_clone_basic1.phpt
@@ -29,9 +29,17 @@ if ($clone != $orig) {
===DONE===
--EXPECTF--
*** Testing clone on DateTime objects ***
-object(DateTimeZone)#%d (0) {
+object(DateTimeZone)#%d (2) {
+ ["timezone_type"]=>
+ int(3)
+ ["timezone"]=>
+ string(3) "UTC"
}
-object(DateTimeZone)#%d (0) {
+object(DateTimeZone)#%d (2) {
+ ["timezone_type"]=>
+ int(3)
+ ["timezone"]=>
+ string(3) "UTC"
}
TEST PASSED : Objects equal but not indetical
===DONE===
diff --git a/ext/date/tests/DateTimeZone_clone_basic2.phpt b/ext/date/tests/DateTimeZone_clone_basic2.phpt
index a499510ff9..92f833082f 100644
--- a/ext/date/tests/DateTimeZone_clone_basic2.phpt
+++ b/ext/date/tests/DateTimeZone_clone_basic2.phpt
@@ -31,19 +31,27 @@ var_dump($d2_clone);
===DONE===
--EXPECTF--
*** Testing clone on objects whoose class derived from DateTimeZone class ***
-object(DateTimeZoneExt1)#%d (2) {
+object(DateTimeZoneExt1)#%d (4) {
["property1"]=>
int(99)
["property2"]=>
string(5) "Hello"
+ ["timezone_type"]=>
+ int(3)
+ ["timezone"]=>
+ string(13) "Europe/London"
}
-object(DateTimeZoneExt1)#%d (2) {
+object(DateTimeZoneExt1)#%d (4) {
["property1"]=>
int(99)
["property2"]=>
string(5) "Hello"
+ ["timezone_type"]=>
+ int(3)
+ ["timezone"]=>
+ string(13) "Europe/London"
}
-object(DateTimeZoneExt2)#%d (4) {
+object(DateTimeZoneExt2)#%d (6) {
["property3"]=>
bool(true)
["property4"]=>
@@ -52,8 +60,12 @@ object(DateTimeZoneExt2)#%d (4) {
int(99)
["property2"]=>
string(5) "Hello"
+ ["timezone_type"]=>
+ int(3)
+ ["timezone"]=>
+ string(13) "Europe/London"
}
-object(DateTimeZoneExt2)#%d (4) {
+object(DateTimeZoneExt2)#%d (6) {
["property3"]=>
bool(true)
["property4"]=>
@@ -62,5 +74,9 @@ object(DateTimeZoneExt2)#%d (4) {
int(99)
["property2"]=>
string(5) "Hello"
+ ["timezone_type"]=>
+ int(3)
+ ["timezone"]=>
+ string(13) "Europe/London"
}
===DONE===
diff --git a/ext/date/tests/DateTimeZone_clone_basic3.phpt b/ext/date/tests/DateTimeZone_clone_basic3.phpt
index e85f42e876..128c8ff40b 100644
--- a/ext/date/tests/DateTimeZone_clone_basic3.phpt
+++ b/ext/date/tests/DateTimeZone_clone_basic3.phpt
@@ -30,11 +30,19 @@ var_dump($d2_clone);
*** Testing clone on DateTime objects ***
-- Create a DateTimeZone object --
-object(DateTimeZone)#%d (0) {
+object(DateTimeZone)#%d (2) {
+ ["timezone_type"]=>
+ int(3)
+ ["timezone"]=>
+ string(13) "Europe/London"
}
-- Add some properties --
-object(DateTimeZone)#%d (2) {
+object(DateTimeZone)#%d (4) {
+ ["timezone_type"]=>
+ int(3)
+ ["timezone"]=>
+ string(13) "Europe/London"
["property1"]=>
int(99)
["property2"]=>
@@ -42,7 +50,11 @@ object(DateTimeZone)#%d (2) {
}
-- clone it --
-object(DateTimeZone)#%d (2) {
+object(DateTimeZone)#%d (4) {
+ ["timezone_type"]=>
+ int(3)
+ ["timezone"]=>
+ string(13) "Europe/London"
["property1"]=>
int(99)
["property2"]=>
@@ -50,7 +62,11 @@ object(DateTimeZone)#%d (2) {
}
-- Add some more properties --
-object(DateTimeZone)#%d (4) {
+object(DateTimeZone)#%d (6) {
+ ["timezone_type"]=>
+ int(3)
+ ["timezone"]=>
+ string(13) "Europe/London"
["property1"]=>
int(99)
["property2"]=>
@@ -62,7 +78,11 @@ object(DateTimeZone)#%d (4) {
}
-- clone it --
-object(DateTimeZone)#%d (4) {
+object(DateTimeZone)#%d (6) {
+ ["timezone_type"]=>
+ int(3)
+ ["timezone"]=>
+ string(13) "Europe/London"
["property1"]=>
int(99)
["property2"]=>
diff --git a/ext/date/tests/DateTimeZone_construct_basic.phpt b/ext/date/tests/DateTimeZone_construct_basic.phpt
index b681e8f9c3..2f18f81c03 100644
--- a/ext/date/tests/DateTimeZone_construct_basic.phpt
+++ b/ext/date/tests/DateTimeZone_construct_basic.phpt
@@ -21,10 +21,22 @@ var_dump( new DateTimeZone("America/Los_Angeles") );
===DONE===
--EXPECTF--
*** Testing new DateTimeZone() : basic functionality ***
-object(DateTimeZone)#%d (0) {
+object(DateTimeZone)#%d (2) {
+ ["timezone_type"]=>
+ int(3)
+ ["timezone"]=>
+ string(3) "UTC"
}
-object(DateTimeZone)#%d (0) {
+object(DateTimeZone)#%d (2) {
+ ["timezone_type"]=>
+ int(3)
+ ["timezone"]=>
+ string(13) "Europe/London"
}
-object(DateTimeZone)#%d (0) {
+object(DateTimeZone)#%d (2) {
+ ["timezone_type"]=>
+ int(3)
+ ["timezone"]=>
+ string(19) "America/Los_Angeles"
}
===DONE===
diff --git a/ext/date/tests/DateTimeZone_serialize_type_1.phpt b/ext/date/tests/DateTimeZone_serialize_type_1.phpt
new file mode 100644
index 0000000000..51a5c53b23
--- /dev/null
+++ b/ext/date/tests/DateTimeZone_serialize_type_1.phpt
@@ -0,0 +1,35 @@
+--TEST--
+Test serialization of DateTimeZone objects
+--FILE--
+<?php
+//Set the default time zone
+date_default_timezone_set("Europe/London");
+
+$tz1 = date_create("2012-01-01 10:00 +1:00")->getTimezone();
+var_dump( $tz1 );
+$serialized = serialize($tz1);
+var_dump($serialized);
+
+$tz2 = unserialize($serialized);
+var_dump($tz2);
+// Try to use unserialzied object
+var_dump( $tz2->getName() );
+
+?>
+===DONE===
+--EXPECTF--
+object(DateTimeZone)#%d (2) {
+ ["timezone_type"]=>
+ int(1)
+ ["timezone"]=>
+ string(6) "+01:00"
+}
+string(77) "O:12:"DateTimeZone":2:{s:13:"timezone_type";i:1;s:8:"timezone";s:6:"+01:00";}"
+object(DateTimeZone)#%d (2) {
+ ["timezone_type"]=>
+ int(1)
+ ["timezone"]=>
+ string(6) "+01:00"
+}
+string(6) "+01:00"
+===DONE===
diff --git a/ext/date/tests/DateTimeZone_serialize_type_2.phpt b/ext/date/tests/DateTimeZone_serialize_type_2.phpt
new file mode 100644
index 0000000000..a264322f3e
--- /dev/null
+++ b/ext/date/tests/DateTimeZone_serialize_type_2.phpt
@@ -0,0 +1,35 @@
+--TEST--
+Test serialization of DateTimeZone objects
+--FILE--
+<?php
+//Set the default time zone
+date_default_timezone_set("Europe/London");
+
+$tz1 = new DateTimeZone("EST");
+var_dump( $tz1 );
+$serialized = serialize($tz1);
+var_dump($serialized);
+
+$tz2 = unserialize($serialized);
+var_dump($tz2);
+// Try to use unserialzied object
+var_dump( $tz2->getName() );
+
+?>
+===DONE===
+--EXPECTF--
+object(DateTimeZone)#%d (2) {
+ ["timezone_type"]=>
+ int(3)
+ ["timezone"]=>
+ string(16) "America/New_York"
+}
+string(88) "O:12:"DateTimeZone":2:{s:13:"timezone_type";i:3;s:8:"timezone";s:16:"America/New_York";}"
+object(DateTimeZone)#%d (2) {
+ ["timezone_type"]=>
+ int(3)
+ ["timezone"]=>
+ string(16) "America/New_York"
+}
+string(16) "America/New_York"
+===DONE===
diff --git a/ext/date/tests/DateTimeZone_serialize.phpt b/ext/date/tests/DateTimeZone_serialize_type_3.phpt
index 08dd934466..49b9349bb8 100644
--- a/ext/date/tests/DateTimeZone_serialize.phpt
+++ b/ext/date/tests/DateTimeZone_serialize_type_3.phpt
@@ -18,12 +18,18 @@ var_dump( $tz2->getName() );
?>
===DONE===
--EXPECTF--
-object(DateTimeZone)#%d (0) {
+object(DateTimeZone)#%d (2) {
+ ["timezone_type"]=>
+ int(3)
+ ["timezone"]=>
+ string(16) "America/New_York"
}
-string(24) "O:12:"DateTimeZone":0:{}"
-object(DateTimeZone)#%d (0) {
+string(88) "O:12:"DateTimeZone":2:{s:13:"timezone_type";i:3;s:8:"timezone";s:16:"America/New_York";}"
+object(DateTimeZone)#%d (2) {
+ ["timezone_type"]=>
+ int(3)
+ ["timezone"]=>
+ string(16) "America/New_York"
}
-
-Warning: DateTimeZone::getName(): The DateTimeZone object has not been correctly initialized by its constructor in %s on line %d
-bool(false)
-===DONE=== \ No newline at end of file
+string(16) "America/New_York"
+===DONE===
diff --git a/ext/date/tests/DateTimeZone_verify.phpt b/ext/date/tests/DateTimeZone_verify.phpt
index 3ca09131a7..241d91e665 100644
--- a/ext/date/tests/DateTimeZone_verify.phpt
+++ b/ext/date/tests/DateTimeZone_verify.phpt
@@ -26,7 +26,7 @@ object(ReflectionClass)#%d (1) {
string(12) "DateTimeZone"
}
..and get names of all its methods
-array(7) {
+array(9) {
[0]=>
&object(ReflectionMethod)#%d (2) {
["name"]=>
@@ -37,41 +37,55 @@ array(7) {
[1]=>
&object(ReflectionMethod)#%d (2) {
["name"]=>
- string(7) "getName"
+ string(8) "__wakeup"
["class"]=>
string(12) "DateTimeZone"
}
[2]=>
&object(ReflectionMethod)#%d (2) {
["name"]=>
- string(9) "getOffset"
+ string(11) "__set_state"
["class"]=>
string(12) "DateTimeZone"
}
[3]=>
&object(ReflectionMethod)#%d (2) {
["name"]=>
- string(14) "getTransitions"
+ string(7) "getName"
["class"]=>
string(12) "DateTimeZone"
}
[4]=>
&object(ReflectionMethod)#%d (2) {
["name"]=>
- string(11) "getLocation"
+ string(9) "getOffset"
["class"]=>
string(12) "DateTimeZone"
}
[5]=>
&object(ReflectionMethod)#%d (2) {
["name"]=>
- string(17) "listAbbreviations"
+ string(14) "getTransitions"
["class"]=>
string(12) "DateTimeZone"
}
[6]=>
&object(ReflectionMethod)#%d (2) {
["name"]=>
+ string(11) "getLocation"
+ ["class"]=>
+ string(12) "DateTimeZone"
+ }
+ [7]=>
+ &object(ReflectionMethod)#%d (2) {
+ ["name"]=>
+ string(17) "listAbbreviations"
+ ["class"]=>
+ string(12) "DateTimeZone"
+ }
+ [8]=>
+ &object(ReflectionMethod)#%d (2) {
+ ["name"]=>
string(15) "listIdentifiers"
["class"]=>
string(12) "DateTimeZone"
@@ -108,4 +122,4 @@ array(14) {
["PER_COUNTRY"]=>
int(4096)
}
-===DONE=== \ No newline at end of file
+===DONE===
diff --git a/ext/date/tests/bug60774.phpt b/ext/date/tests/bug60774.phpt
new file mode 100644
index 0000000000..7045cd7781
--- /dev/null
+++ b/ext/date/tests/bug60774.phpt
@@ -0,0 +1,44 @@
+--TEST--
+Bug #60774 (DateInterval::format("%a") is always zero when an interval is created using the createFromDateString method)
+--FILE--
+<?php
+$i= DateInterval::createFromDateString('2 days');
+var_dump($i);
+echo $i->format("%d"), "\n";
+echo $i->format("%a"), "\n";
+?>
+--EXPECTF--
+object(DateInterval)#1 (%d) {
+ ["y"]=>
+ int(0)
+ ["m"]=>
+ int(0)
+ ["d"]=>
+ int(2)
+ ["h"]=>
+ int(0)
+ ["i"]=>
+ int(0)
+ ["s"]=>
+ int(0)
+ ["weekday"]=>
+ int(0)
+ ["weekday_behavior"]=>
+ int(0)
+ ["first_last_day_of"]=>
+ int(0)
+ ["invert"]=>
+ int(0)
+ ["days"]=>
+ bool(false)
+ ["special_type"]=>
+ int(0)
+ ["special_amount"]=>
+ int(0)
+ ["have_weekday_relative"]=>
+ int(0)
+ ["have_special_relative"]=>
+ int(0)
+}
+2
+(unknown)
diff --git a/ext/date/tests/bug61642.phpt b/ext/date/tests/bug61642.phpt
new file mode 100644
index 0000000000..d03a814d88
--- /dev/null
+++ b/ext/date/tests/bug61642.phpt
@@ -0,0 +1,62 @@
+--TEST--
+Bug #61642 (modify("+5 weekdays") returns Sunday)
+--INI--
+date.timezone=UTC
+--FILE--
+<?php
+// ±5 and ±10 (and any non-zero multiple of 5) is broken, but everything else
+// should already work correctly.
+$weekdays = range(-11, 11);
+$dates = array('2012-03-29', '2012-03-30', '2012-03-31', '2012-04-01', '2012-04-02', '2012-04-03', '2012-04-04', '2012-04-05');
+
+$header = array();
+
+foreach ($dates as $startdate) {
+ $date = new DateTime($startdate);
+
+ $header[] = $date->format('Y-m-d D');
+}
+
+echo '### ', implode(' ', $header), "\n\n";
+
+foreach ($weekdays as $days) {
+ $line = array();
+
+ printf('%+3d ', $days);
+
+ foreach ($dates as $startdate) {
+ $date = new DateTime($startdate);
+ $date->modify("{$days} weekdays");
+
+ $line[] = $date->format('Y-m-d D');
+ }
+
+ echo implode(' ', $line), "\n";
+}
+?>
+--EXPECTF--
+### 2012-03-29 Thu 2012-03-30 Fri 2012-03-31 Sat 2012-04-01 Sun 2012-04-02 Mon 2012-04-03 Tue 2012-04-04 Wed 2012-04-05 Thu
+
+-11 2012-03-14 Wed 2012-03-15 Thu 2012-03-16 Fri 2012-03-16 Fri 2012-03-16 Fri 2012-03-19 Mon 2012-03-20 Tue 2012-03-21 Wed
+-10 2012-03-15 Thu 2012-03-16 Fri 2012-03-19 Mon 2012-03-19 Mon 2012-03-19 Mon 2012-03-20 Tue 2012-03-21 Wed 2012-03-22 Thu
+ -9 2012-03-16 Fri 2012-03-19 Mon 2012-03-20 Tue 2012-03-20 Tue 2012-03-20 Tue 2012-03-21 Wed 2012-03-22 Thu 2012-03-23 Fri
+ -8 2012-03-19 Mon 2012-03-20 Tue 2012-03-21 Wed 2012-03-21 Wed 2012-03-21 Wed 2012-03-22 Thu 2012-03-23 Fri 2012-03-26 Mon
+ -7 2012-03-20 Tue 2012-03-21 Wed 2012-03-22 Thu 2012-03-22 Thu 2012-03-22 Thu 2012-03-23 Fri 2012-03-26 Mon 2012-03-27 Tue
+ -6 2012-03-21 Wed 2012-03-22 Thu 2012-03-23 Fri 2012-03-23 Fri 2012-03-23 Fri 2012-03-26 Mon 2012-03-27 Tue 2012-03-28 Wed
+ -5 2012-03-22 Thu 2012-03-23 Fri 2012-03-26 Mon 2012-03-26 Mon 2012-03-26 Mon 2012-03-27 Tue 2012-03-28 Wed 2012-03-29 Thu
+ -4 2012-03-23 Fri 2012-03-26 Mon 2012-03-27 Tue 2012-03-27 Tue 2012-03-27 Tue 2012-03-28 Wed 2012-03-29 Thu 2012-03-30 Fri
+ -3 2012-03-26 Mon 2012-03-27 Tue 2012-03-28 Wed 2012-03-28 Wed 2012-03-28 Wed 2012-03-29 Thu 2012-03-30 Fri 2012-04-02 Mon
+ -2 2012-03-27 Tue 2012-03-28 Wed 2012-03-29 Thu 2012-03-29 Thu 2012-03-29 Thu 2012-03-30 Fri 2012-04-02 Mon 2012-04-03 Tue
+ -1 2012-03-28 Wed 2012-03-29 Thu 2012-03-30 Fri 2012-03-30 Fri 2012-03-30 Fri 2012-04-02 Mon 2012-04-03 Tue 2012-04-04 Wed
+ +0 2012-03-29 Thu 2012-03-30 Fri 2012-04-02 Mon 2012-04-02 Mon 2012-04-02 Mon 2012-04-03 Tue 2012-04-04 Wed 2012-04-05 Thu
+ +1 2012-03-30 Fri 2012-04-02 Mon 2012-04-02 Mon 2012-04-02 Mon 2012-04-03 Tue 2012-04-04 Wed 2012-04-05 Thu 2012-04-06 Fri
+ +2 2012-04-02 Mon 2012-04-03 Tue 2012-04-03 Tue 2012-04-03 Tue 2012-04-04 Wed 2012-04-05 Thu 2012-04-06 Fri 2012-04-09 Mon
+ +3 2012-04-03 Tue 2012-04-04 Wed 2012-04-04 Wed 2012-04-04 Wed 2012-04-05 Thu 2012-04-06 Fri 2012-04-09 Mon 2012-04-10 Tue
+ +4 2012-04-04 Wed 2012-04-05 Thu 2012-04-05 Thu 2012-04-05 Thu 2012-04-06 Fri 2012-04-09 Mon 2012-04-10 Tue 2012-04-11 Wed
+ +5 2012-04-05 Thu 2012-04-06 Fri 2012-04-06 Fri 2012-04-06 Fri 2012-04-09 Mon 2012-04-10 Tue 2012-04-11 Wed 2012-04-12 Thu
+ +6 2012-04-06 Fri 2012-04-09 Mon 2012-04-09 Mon 2012-04-09 Mon 2012-04-10 Tue 2012-04-11 Wed 2012-04-12 Thu 2012-04-13 Fri
+ +7 2012-04-09 Mon 2012-04-10 Tue 2012-04-10 Tue 2012-04-10 Tue 2012-04-11 Wed 2012-04-12 Thu 2012-04-13 Fri 2012-04-16 Mon
+ +8 2012-04-10 Tue 2012-04-11 Wed 2012-04-11 Wed 2012-04-11 Wed 2012-04-12 Thu 2012-04-13 Fri 2012-04-16 Mon 2012-04-17 Tue
+ +9 2012-04-11 Wed 2012-04-12 Thu 2012-04-12 Thu 2012-04-12 Thu 2012-04-13 Fri 2012-04-16 Mon 2012-04-17 Tue 2012-04-18 Wed
++10 2012-04-12 Thu 2012-04-13 Fri 2012-04-13 Fri 2012-04-13 Fri 2012-04-16 Mon 2012-04-17 Tue 2012-04-18 Wed 2012-04-19 Thu
++11 2012-04-13 Fri 2012-04-16 Mon 2012-04-16 Mon 2012-04-16 Mon 2012-04-17 Tue 2012-04-18 Wed 2012-04-19 Thu 2012-04-20 Fri
diff --git a/ext/date/tests/bug65184.phpt b/ext/date/tests/bug65184.phpt
new file mode 100644
index 0000000000..9bb68558aa
--- /dev/null
+++ b/ext/date/tests/bug65184.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Test bug #65184 strftime() returns insufficient-length string under multibyte locales
+--SKIPIF--
+<?php
+if (strtoupper(substr(PHP_OS, 0, 3)) != 'WIN') {
+ die("skip Test is valid for Windows");
+}
+?>
+--INI--
+date.timezone = UTC
+--FILE--
+<?php
+ setlocale(LC_ALL, 'Japanese_Japan.932');
+ /* timestamp has to be some wednesday */
+ $s = strftime('%A', 1372884126);
+
+ for ($i = 0; $i < strlen($s); $i++) {
+ printf("%x ", ord($s[$i]));
+ }
+ echo "\n";
+
+ echo strlen(strftime('%A')), "\n";
+?>
+===DONE===
+--EXPECT--
+90 85 97 6a 93 fa
+6
+===DONE===
diff --git a/ext/date/tests/bug65502.phpt b/ext/date/tests/bug65502.phpt
new file mode 100644
index 0000000000..8819c1ff74
--- /dev/null
+++ b/ext/date/tests/bug65502.phpt
@@ -0,0 +1,12 @@
+--TEST--
+Test for bug #65502: DateTimeImmutable::createFromFormat returns DateTime
+--CREDITS--
+Boro Sitnikovski <buritomath@yahoo.com>
+--INI--
+date.timezone = UTC
+--FILE--
+<?php
+echo get_class(DateTimeImmutable::createFromFormat('j-M-Y', '12-Sep-2013'));
+?>
+--EXPECT--
+DateTimeImmutable
diff --git a/ext/date/tests/bug65548.phpt b/ext/date/tests/bug65548.phpt
new file mode 100644
index 0000000000..53f2519f6d
--- /dev/null
+++ b/ext/date/tests/bug65548.phpt
@@ -0,0 +1,34 @@
+--TEST--
+Test for bug #65548: Comparison for DateTimeImmutable doesn't work
+--CREDITS--
+Boro Sitnikovski <buritomath@yahoo.com>
+--INI--
+date.timezone = UTC
+--FILE--
+<?php
+$iToday = new DateTimeImmutable('today');
+$iTomorrow = new DateTimeImmutable('tomorrow');
+
+$mToday = new DateTime('today');
+$mTomorrow = new DateTime('tomorrow');
+
+var_dump($iToday < $iTomorrow);
+var_dump($iToday == $iTomorrow);
+var_dump($iToday > $iTomorrow);
+
+var_dump($iToday == $mToday);
+var_dump($iToday === $mToday);
+
+var_dump($iToday < $mTomorrow);
+var_dump($iToday == $mTomorrow);
+var_dump($iToday > $mTomorrow);
+?>
+--EXPECT--
+bool(true)
+bool(false)
+bool(false)
+bool(true)
+bool(false)
+bool(true)
+bool(false)
+bool(false)
diff --git a/ext/date/tests/date_format_error.phpt b/ext/date/tests/date_format_error.phpt
index 967695a86d..a563d0d974 100644
--- a/ext/date/tests/date_format_error.phpt
+++ b/ext/date/tests/date_format_error.phpt
@@ -56,12 +56,12 @@ bool(false)
-- Testing date_create() function with an invalid values for $object argument --
-Warning: date_format() expects parameter 1 to be DateTime, object given in %sp on line %d
+Warning: date_format() expects parameter 1 to be DateTimeInterface, object given in %sp on line %d
bool(false)
-Warning: date_format() expects parameter 1 to be DateTime, integer given in %s on line %d
+Warning: date_format() expects parameter 1 to be DateTimeInterface, integer given in %s on line %d
bool(false)
-Warning: date_format() expects parameter 1 to be DateTime, null given in %s on line %d
+Warning: date_format() expects parameter 1 to be DateTimeInterface, null given in %s on line %d
bool(false)
===DONE===
diff --git a/ext/date/tests/date_format_variation1.phpt b/ext/date/tests/date_format_variation1.phpt
index 025b7d332f..e5efc07356 100644
--- a/ext/date/tests/date_format_variation1.phpt
+++ b/ext/date/tests/date_format_variation1.phpt
@@ -2,10 +2,10 @@
Test date_format() function : usage variation - Passing unexpected values to first argument $object.
--FILE--
<?php
-/* Prototype : string date_format ( DateTime $object , string $format )
+/* Prototype : string date_format ( DateTimeInterface $object , string $format )
* Description: Returns date formatted according to given format
* Source code: ext/date/php_date.c
- * Alias to functions: DateTime::format
+ * Alias to functions: DateTimeInterface::format
*/
echo "*** Testing date_format() : usage variation - unexpected values to first argument \$object***\n";
@@ -112,141 +112,141 @@ fclose( $file_handle );
-- int 0 --
-Warning: date_format() expects parameter 1 to be DateTime, integer given in %s on line %d
+Warning: date_format() expects parameter 1 to be DateTimeInterface, integer given in %s on line %d
bool(false)
-- int 1 --
-Warning: date_format() expects parameter 1 to be DateTime, integer given in %s on line %d
+Warning: date_format() expects parameter 1 to be DateTimeInterface, integer given in %s on line %d
bool(false)
-- int 12345 --
-Warning: date_format() expects parameter 1 to be DateTime, integer given in %s on line %d
+Warning: date_format() expects parameter 1 to be DateTimeInterface, integer given in %s on line %d
bool(false)
-- int -12345 --
-Warning: date_format() expects parameter 1 to be DateTime, integer given in %s on line %d
+Warning: date_format() expects parameter 1 to be DateTimeInterface, integer given in %s on line %d
bool(false)
-- float 10.5 --
-Warning: date_format() expects parameter 1 to be DateTime, double given in %s on line %d
+Warning: date_format() expects parameter 1 to be DateTimeInterface, double given in %s on line %d
bool(false)
-- float -10.5 --
-Warning: date_format() expects parameter 1 to be DateTime, double given in %s on line %d
+Warning: date_format() expects parameter 1 to be DateTimeInterface, double given in %s on line %d
bool(false)
-- float .5 --
-Warning: date_format() expects parameter 1 to be DateTime, double given in %s on line %d
+Warning: date_format() expects parameter 1 to be DateTimeInterface, double given in %s on line %d
bool(false)
-- empty array --
-Warning: date_format() expects parameter 1 to be DateTime, array given in %s on line %d
+Warning: date_format() expects parameter 1 to be DateTimeInterface, array given in %s on line %d
bool(false)
-- int indexed array --
-Warning: date_format() expects parameter 1 to be DateTime, array given in %s on line %d
+Warning: date_format() expects parameter 1 to be DateTimeInterface, array given in %s on line %d
bool(false)
-- associative array --
-Warning: date_format() expects parameter 1 to be DateTime, array given in %s on line %d
+Warning: date_format() expects parameter 1 to be DateTimeInterface, array given in %s on line %d
bool(false)
-- nested arrays --
-Warning: date_format() expects parameter 1 to be DateTime, array given in %s on line %d
+Warning: date_format() expects parameter 1 to be DateTimeInterface, array given in %s on line %d
bool(false)
-- uppercase NULL --
-Warning: date_format() expects parameter 1 to be DateTime, null given in %s on line %d
+Warning: date_format() expects parameter 1 to be DateTimeInterface, null given in %s on line %d
bool(false)
-- lowercase null --
-Warning: date_format() expects parameter 1 to be DateTime, null given in %s on line %d
+Warning: date_format() expects parameter 1 to be DateTimeInterface, null given in %s on line %d
bool(false)
-- lowercase true --
-Warning: date_format() expects parameter 1 to be DateTime, boolean given in %s on line %d
+Warning: date_format() expects parameter 1 to be DateTimeInterface, boolean given in %s on line %d
bool(false)
-- lowercase false --
-Warning: date_format() expects parameter 1 to be DateTime, boolean given in %s on line %d
+Warning: date_format() expects parameter 1 to be DateTimeInterface, boolean given in %s on line %d
bool(false)
-- uppercase TRUE --
-Warning: date_format() expects parameter 1 to be DateTime, boolean given in %s on line %d
+Warning: date_format() expects parameter 1 to be DateTimeInterface, boolean given in %s on line %d
bool(false)
-- uppercase FALSE --
-Warning: date_format() expects parameter 1 to be DateTime, boolean given in %s on line %d
+Warning: date_format() expects parameter 1 to be DateTimeInterface, boolean given in %s on line %d
bool(false)
-- empty string DQ --
-Warning: date_format() expects parameter 1 to be DateTime, string given in %s on line %d
+Warning: date_format() expects parameter 1 to be DateTimeInterface, string given in %s on line %d
bool(false)
-- empty string SQ --
-Warning: date_format() expects parameter 1 to be DateTime, string given in %s on line %d
+Warning: date_format() expects parameter 1 to be DateTimeInterface, string given in %s on line %d
bool(false)
-- string DQ --
-Warning: date_format() expects parameter 1 to be DateTime, string given in %s on line %d
+Warning: date_format() expects parameter 1 to be DateTimeInterface, string given in %s on line %d
bool(false)
-- string SQ --
-Warning: date_format() expects parameter 1 to be DateTime, string given in %s on line %d
+Warning: date_format() expects parameter 1 to be DateTimeInterface, string given in %s on line %d
bool(false)
-- mixed case string --
-Warning: date_format() expects parameter 1 to be DateTime, string given in %s on line %d
+Warning: date_format() expects parameter 1 to be DateTimeInterface, string given in %s on line %d
bool(false)
-- heredoc --
-Warning: date_format() expects parameter 1 to be DateTime, string given in %s on line %d
+Warning: date_format() expects parameter 1 to be DateTimeInterface, string given in %s on line %d
bool(false)
-- instance of classWithToString --
-Warning: date_format() expects parameter 1 to be DateTime, object given in %s on line %d
+Warning: date_format() expects parameter 1 to be DateTimeInterface, object given in %s on line %d
bool(false)
-- instance of classWithoutToString --
-Warning: date_format() expects parameter 1 to be DateTime, object given in %s on line %d
+Warning: date_format() expects parameter 1 to be DateTimeInterface, object given in %s on line %d
bool(false)
-- undefined var --
-Warning: date_format() expects parameter 1 to be DateTime, null given in %s on line %d
+Warning: date_format() expects parameter 1 to be DateTimeInterface, null given in %s on line %d
bool(false)
-- unset var --
-Warning: date_format() expects parameter 1 to be DateTime, null given in %s on line %d
+Warning: date_format() expects parameter 1 to be DateTimeInterface, null given in %s on line %d
bool(false)
-- resource --
-Warning: date_format() expects parameter 1 to be DateTime, resource given in %s on line %d
+Warning: date_format() expects parameter 1 to be DateTimeInterface, resource given in %s on line %d
bool(false)
===DONE===
diff --git a/ext/date/tests/date_offset_get_error.phpt b/ext/date/tests/date_offset_get_error.phpt
index bd4e429225..8531845ca7 100644
--- a/ext/date/tests/date_offset_get_error.phpt
+++ b/ext/date/tests/date_offset_get_error.phpt
@@ -3,10 +3,10 @@ Test date_offset_get() function : error conditions
--FILE--
<?php
-/* Prototype : int date_offset_get ( DateTime $object )
+/* Prototype : int date_offset_get ( DateTimeInterface $object )
* Description: Returns the daylight saving time offset
* Source code: ext/date/php_date.c
- * Alias to functions: DateTime::getOffset
+ * Alias to functions: DateTimeInterface::getOffset
*/
//Set the default time zone
@@ -46,12 +46,12 @@ bool(false)
-- Testing date_offset_get() function with an invalid values for $object argument --
-Warning: date_offset_get() expects parameter 1 to be DateTime, object given in %s on line %d
+Warning: date_offset_get() expects parameter 1 to be DateTimeInterface, object given in %s on line %d
bool(false)
-Warning: date_offset_get() expects parameter 1 to be DateTime, integer given in %s on line %d
+Warning: date_offset_get() expects parameter 1 to be DateTimeInterface, integer given in %s on line %d
bool(false)
-Warning: date_offset_get() expects parameter 1 to be DateTime, null given in %s on line %d
+Warning: date_offset_get() expects parameter 1 to be DateTimeInterface, null given in %s on line %d
bool(false)
===DONE===
diff --git a/ext/date/tests/date_offset_get_variation1.phpt b/ext/date/tests/date_offset_get_variation1.phpt
index 9df6e2d16b..4b67b90646 100644
--- a/ext/date/tests/date_offset_get_variation1.phpt
+++ b/ext/date/tests/date_offset_get_variation1.phpt
@@ -2,10 +2,10 @@
Test date_offset_get() function : usage variation - Passing unexpected values to first argument $object.
--FILE--
<?php
-/* Prototype : int date_offset_get ( DateTime $object )
+/* Prototype : int date_offset_get ( DateTimeInterface $object )
* Description: Returns the daylight saving time offset
* Source code: ext/date/php_date.c
- * Alias to functions: DateTime::getOffset
+ * Alias to functions: DateTimeInterface::getOffset
*/
echo "*** Testing date_offset_get() : usage variation - unexpected values to first argument \$object***\n";
@@ -110,141 +110,141 @@ fclose( $file_handle );
-- int 0 --
-Warning: date_offset_get() expects parameter 1 to be DateTime, integer given in %s on line %d
+Warning: date_offset_get() expects parameter 1 to be DateTimeInterface, integer given in %s on line %d
bool(false)
-- int 1 --
-Warning: date_offset_get() expects parameter 1 to be DateTime, integer given in %s on line %d
+Warning: date_offset_get() expects parameter 1 to be DateTimeInterface, integer given in %s on line %d
bool(false)
-- int 12345 --
-Warning: date_offset_get() expects parameter 1 to be DateTime, integer given in %s on line %d
+Warning: date_offset_get() expects parameter 1 to be DateTimeInterface, integer given in %s on line %d
bool(false)
-- int -12345 --
-Warning: date_offset_get() expects parameter 1 to be DateTime, integer given in %s on line %d
+Warning: date_offset_get() expects parameter 1 to be DateTimeInterface, integer given in %s on line %d
bool(false)
-- float 10.5 --
-Warning: date_offset_get() expects parameter 1 to be DateTime, double given in %s on line %d
+Warning: date_offset_get() expects parameter 1 to be DateTimeInterface, double given in %s on line %d
bool(false)
-- float -10.5 --
-Warning: date_offset_get() expects parameter 1 to be DateTime, double given in %s on line %d
+Warning: date_offset_get() expects parameter 1 to be DateTimeInterface, double given in %s on line %d
bool(false)
-- float .5 --
-Warning: date_offset_get() expects parameter 1 to be DateTime, double given in %s on line %d
+Warning: date_offset_get() expects parameter 1 to be DateTimeInterface, double given in %s on line %d
bool(false)
-- empty array --
-Warning: date_offset_get() expects parameter 1 to be DateTime, array given in %s on line %d
+Warning: date_offset_get() expects parameter 1 to be DateTimeInterface, array given in %s on line %d
bool(false)
-- int indexed array --
-Warning: date_offset_get() expects parameter 1 to be DateTime, array given in %s on line %d
+Warning: date_offset_get() expects parameter 1 to be DateTimeInterface, array given in %s on line %d
bool(false)
-- associative array --
-Warning: date_offset_get() expects parameter 1 to be DateTime, array given in %s on line %d
+Warning: date_offset_get() expects parameter 1 to be DateTimeInterface, array given in %s on line %d
bool(false)
-- nested arrays --
-Warning: date_offset_get() expects parameter 1 to be DateTime, array given in %s on line %d
+Warning: date_offset_get() expects parameter 1 to be DateTimeInterface, array given in %s on line %d
bool(false)
-- uppercase NULL --
-Warning: date_offset_get() expects parameter 1 to be DateTime, null given in %s on line %d
+Warning: date_offset_get() expects parameter 1 to be DateTimeInterface, null given in %s on line %d
bool(false)
-- lowercase null --
-Warning: date_offset_get() expects parameter 1 to be DateTime, null given in %s on line %d
+Warning: date_offset_get() expects parameter 1 to be DateTimeInterface, null given in %s on line %d
bool(false)
-- lowercase true --
-Warning: date_offset_get() expects parameter 1 to be DateTime, boolean given in %s on line %d
+Warning: date_offset_get() expects parameter 1 to be DateTimeInterface, boolean given in %s on line %d
bool(false)
-- lowercase false --
-Warning: date_offset_get() expects parameter 1 to be DateTime, boolean given in %s on line %d
+Warning: date_offset_get() expects parameter 1 to be DateTimeInterface, boolean given in %s on line %d
bool(false)
-- uppercase TRUE --
-Warning: date_offset_get() expects parameter 1 to be DateTime, boolean given in %s on line %d
+Warning: date_offset_get() expects parameter 1 to be DateTimeInterface, boolean given in %s on line %d
bool(false)
-- uppercase FALSE --
-Warning: date_offset_get() expects parameter 1 to be DateTime, boolean given in %s on line %d
+Warning: date_offset_get() expects parameter 1 to be DateTimeInterface, boolean given in %s on line %d
bool(false)
-- empty string DQ --
-Warning: date_offset_get() expects parameter 1 to be DateTime, string given in %s on line %d
+Warning: date_offset_get() expects parameter 1 to be DateTimeInterface, string given in %s on line %d
bool(false)
-- empty string SQ --
-Warning: date_offset_get() expects parameter 1 to be DateTime, string given in %s on line %d
+Warning: date_offset_get() expects parameter 1 to be DateTimeInterface, string given in %s on line %d
bool(false)
-- string DQ --
-Warning: date_offset_get() expects parameter 1 to be DateTime, string given in %s on line %d
+Warning: date_offset_get() expects parameter 1 to be DateTimeInterface, string given in %s on line %d
bool(false)
-- string SQ --
-Warning: date_offset_get() expects parameter 1 to be DateTime, string given in %s on line %d
+Warning: date_offset_get() expects parameter 1 to be DateTimeInterface, string given in %s on line %d
bool(false)
-- mixed case string --
-Warning: date_offset_get() expects parameter 1 to be DateTime, string given in %s on line %d
+Warning: date_offset_get() expects parameter 1 to be DateTimeInterface, string given in %s on line %d
bool(false)
-- heredoc --
-Warning: date_offset_get() expects parameter 1 to be DateTime, string given in %s on line %d
+Warning: date_offset_get() expects parameter 1 to be DateTimeInterface, string given in %s on line %d
bool(false)
-- instance of classWithToString --
-Warning: date_offset_get() expects parameter 1 to be DateTime, object given in %s on line %d
+Warning: date_offset_get() expects parameter 1 to be DateTimeInterface, object given in %s on line %d
bool(false)
-- instance of classWithoutToString --
-Warning: date_offset_get() expects parameter 1 to be DateTime, object given in %s on line %d
+Warning: date_offset_get() expects parameter 1 to be DateTimeInterface, object given in %s on line %d
bool(false)
-- undefined var --
-Warning: date_offset_get() expects parameter 1 to be DateTime, null given in %s on line %d
+Warning: date_offset_get() expects parameter 1 to be DateTimeInterface, null given in %s on line %d
bool(false)
-- unset var --
-Warning: date_offset_get() expects parameter 1 to be DateTime, null given in %s on line %d
+Warning: date_offset_get() expects parameter 1 to be DateTimeInterface, null given in %s on line %d
bool(false)
-- resource --
-Warning: date_offset_get() expects parameter 1 to be DateTime, resource given in %s on line %d
+Warning: date_offset_get() expects parameter 1 to be DateTimeInterface, resource given in %s on line %d
bool(false)
===DONE===
diff --git a/ext/date/tests/date_period-immutable.phpt b/ext/date/tests/date_period-immutable.phpt
new file mode 100644
index 0000000000..0ec4b4a130
--- /dev/null
+++ b/ext/date/tests/date_period-immutable.phpt
@@ -0,0 +1,56 @@
+--TEST--
+DatePeriod
+--FILE--
+<?php
+date_default_timezone_set('UTC');
+$db1 = new DateTimeImmutable( '2008-01-01' );
+$db2 = new DateTime( '2008-01-01' );
+$de = new DateTime( '2008-03-31' );
+$di = DateInterval::createFromDateString( 'first day of next month' );
+
+foreach ( new DatePeriod( $db1, $di, $de ) as $dt )
+{
+ echo get_class( $dt ), "\n";
+ echo $dt->format( "l Y-m-d\n" );
+ echo $dt->modify( "3 tuesday" )->format( "l Y-m-d\n" );
+ echo $dt->format( "l Y-m-d\n\n" );
+}
+
+foreach ( new DatePeriod( $db2, $di, $de ) as $dt )
+{
+ echo get_class( $dt ), "\n";
+ echo $dt->format( "l Y-m-d\n" );
+ echo $dt->modify( "3 tuesday" )->format( "l Y-m-d\n" );
+ echo $dt->format( "l Y-m-d\n\n" );
+}
+?>
+--EXPECT--
+DateTimeImmutable
+Tuesday 2008-01-01
+Tuesday 2008-01-15
+Tuesday 2008-01-01
+
+DateTimeImmutable
+Friday 2008-02-01
+Tuesday 2008-02-19
+Friday 2008-02-01
+
+DateTimeImmutable
+Saturday 2008-03-01
+Tuesday 2008-03-18
+Saturday 2008-03-01
+
+DateTime
+Tuesday 2008-01-01
+Tuesday 2008-01-15
+Tuesday 2008-01-15
+
+DateTime
+Friday 2008-02-01
+Tuesday 2008-02-19
+Tuesday 2008-02-19
+
+DateTime
+Saturday 2008-03-01
+Tuesday 2008-03-18
+Tuesday 2008-03-18
diff --git a/ext/date/tests/date_time_immutable-inherited.phpt b/ext/date/tests/date_time_immutable-inherited.phpt
new file mode 100644
index 0000000000..ad8b7edb84
--- /dev/null
+++ b/ext/date/tests/date_time_immutable-inherited.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Tests for DateTimeImmutable.
+--INI--
+date.timezone=Europe/London
+--FILE--
+<?php
+$tz = new DateTimeZone("Asia/Tokyo");
+$current = "2012-12-27 16:24:08";
+
+echo "\ngetTimezone():\n";
+$v = date_create_immutable($current);
+$x = $v->getTimezone();
+var_dump($x->getName());
+
+echo "\ngetTimestamp():\n";
+$v = date_create_immutable($current);
+$x = $v->getTimestamp();
+var_dump($x);
+?>
+--EXPECT--
+getTimezone():
+string(13) "Europe/London"
+
+getTimestamp():
+int(1356625448)
diff --git a/ext/date/tests/date_time_immutable.phpt b/ext/date/tests/date_time_immutable.phpt
new file mode 100644
index 0000000000..b4a576570e
--- /dev/null
+++ b/ext/date/tests/date_time_immutable.phpt
@@ -0,0 +1,167 @@
+--TEST--
+Tests for DateTimeImmutable.
+--INI--
+date.timezone=Europe/London
+--FILE--
+<?php
+$tz = new DateTimeZone("Asia/Tokyo");
+$current = "2012-12-27 16:24:08";
+
+function dump($a, $b, $c)
+{
+ echo 'orig: ', $a->format('Y-m-d H:i:s e'), "\n";
+ echo 'copy: ', $b->format('Y-m-d H:i:s e'), "\n";
+ echo 'changed: ', $c->format('Y-m-d H:i:s e'), "\n";
+}
+
+echo "modify():\n";
+$v = date_create_immutable($current);
+$z = $v;
+$x = $z->modify("+2 days");
+dump($v, $z, $x);
+$v = date_create($current);
+$z = $v;
+$x = $z->modify("+2 days");
+dump($v, $z, $x);
+
+echo "\nadd():\n";
+$v = date_create_immutable($current);
+$z = $v;
+$x = $z->add(new DateInterval("P2DT2S"));
+dump($v, $z, $x);
+$v = date_create($current);
+$z = $v;
+$x = $z->add(new DateInterval("P2DT2S"));
+dump($v, $z, $x);
+
+echo "\nsub():\n";
+$v = date_create_immutable($current);
+$z = $v;
+$x = $z->sub(new DateInterval("P2DT2S"));
+dump($v, $z, $x);
+$v = date_create($current);
+$z = $v;
+$x = $z->sub(new DateInterval("P2DT2S"));
+dump($v, $z, $x);
+
+echo "\nsetTimezone():\n";
+$v = date_create_immutable($current);
+$z = $v;
+$x = $z->setTimezone($tz);
+dump($v, $z, $x);
+$v = date_create($current);
+$z = $v;
+$x = $z->setTimezone($tz);
+dump($v, $z, $x);
+$v = new DateTimeImmutable($current);
+$z = $v;
+$x = $z->setTimezone($tz);
+dump($v, $z, $x);
+
+echo "\nsetTime():\n";
+$v = date_create_immutable($current);
+$z = $v;
+$x = $z->setTime(5, 7, 19);
+dump($v, $z, $x);
+$v = date_create($current);
+$z = $v;
+$x = $z->setTime(5, 7, 19);
+dump($v, $z, $x);
+
+echo "\nsetDate():\n";
+$v = date_create_immutable($current);
+$z = $v;
+$x = $z->setDate(5, 7, 19);
+dump($v, $z, $x);
+$v = date_create($current);
+$z = $v;
+$x = $z->setDate(5, 7, 19);
+dump($v, $z, $x);
+
+echo "\nsetIsoDate():\n";
+$v = date_create_immutable($current);
+$z = $v;
+$x = $z->setIsoDate(2012, 2, 6);
+dump($v, $z, $x);
+$v = date_create($current);
+$z = $v;
+$x = $z->setIsoDate(2012, 2, 6);
+dump($v, $z, $x);
+
+echo "\nsetTimestamp():\n";
+$v = date_create_immutable($current);
+$z = $v;
+$x = $z->setTimestamp(2012234222);
+dump($v, $z, $x);
+$v = date_create($current);
+$z = $v;
+$x = $z->setTimestamp(2012234222);
+dump($v, $z, $x);
+?>
+--EXPECT--
+modify():
+orig: 2012-12-27 16:24:08 Europe/London
+copy: 2012-12-27 16:24:08 Europe/London
+changed: 2012-12-29 16:24:08 Europe/London
+orig: 2012-12-29 16:24:08 Europe/London
+copy: 2012-12-29 16:24:08 Europe/London
+changed: 2012-12-29 16:24:08 Europe/London
+
+add():
+orig: 2012-12-27 16:24:08 Europe/London
+copy: 2012-12-27 16:24:08 Europe/London
+changed: 2012-12-29 16:24:10 Europe/London
+orig: 2012-12-29 16:24:10 Europe/London
+copy: 2012-12-29 16:24:10 Europe/London
+changed: 2012-12-29 16:24:10 Europe/London
+
+sub():
+orig: 2012-12-27 16:24:08 Europe/London
+copy: 2012-12-27 16:24:08 Europe/London
+changed: 2012-12-25 16:24:06 Europe/London
+orig: 2012-12-25 16:24:06 Europe/London
+copy: 2012-12-25 16:24:06 Europe/London
+changed: 2012-12-25 16:24:06 Europe/London
+
+setTimezone():
+orig: 2012-12-27 16:24:08 Europe/London
+copy: 2012-12-27 16:24:08 Europe/London
+changed: 2012-12-28 01:24:08 Asia/Tokyo
+orig: 2012-12-28 01:24:08 Asia/Tokyo
+copy: 2012-12-28 01:24:08 Asia/Tokyo
+changed: 2012-12-28 01:24:08 Asia/Tokyo
+orig: 2012-12-27 16:24:08 Europe/London
+copy: 2012-12-27 16:24:08 Europe/London
+changed: 2012-12-28 01:24:08 Asia/Tokyo
+
+setTime():
+orig: 2012-12-27 16:24:08 Europe/London
+copy: 2012-12-27 16:24:08 Europe/London
+changed: 2012-12-27 05:07:19 Europe/London
+orig: 2012-12-27 05:07:19 Europe/London
+copy: 2012-12-27 05:07:19 Europe/London
+changed: 2012-12-27 05:07:19 Europe/London
+
+setDate():
+orig: 2012-12-27 16:24:08 Europe/London
+copy: 2012-12-27 16:24:08 Europe/London
+changed: 0005-07-19 16:24:08 Europe/London
+orig: 0005-07-19 16:24:08 Europe/London
+copy: 0005-07-19 16:24:08 Europe/London
+changed: 0005-07-19 16:24:08 Europe/London
+
+setIsoDate():
+orig: 2012-12-27 16:24:08 Europe/London
+copy: 2012-12-27 16:24:08 Europe/London
+changed: 2012-01-14 16:24:08 Europe/London
+orig: 2012-01-14 16:24:08 Europe/London
+copy: 2012-01-14 16:24:08 Europe/London
+changed: 2012-01-14 16:24:08 Europe/London
+
+setTimestamp():
+orig: 2012-12-27 16:24:08 Europe/London
+copy: 2012-12-27 16:24:08 Europe/London
+changed: 2033-10-06 18:57:02 Europe/London
+orig: 2033-10-06 18:57:02 Europe/London
+copy: 2033-10-06 18:57:02 Europe/London
+changed: 2033-10-06 18:57:02 Europe/London
diff --git a/ext/date/tests/date_timestamp_get.phpt b/ext/date/tests/date_timestamp_get.phpt
index bdd4d047ea..ec0258bdc0 100644
--- a/ext/date/tests/date_timestamp_get.phpt
+++ b/ext/date/tests/date_timestamp_get.phpt
@@ -17,4 +17,4 @@ 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
+Warning: date_timestamp_get() expects parameter 1 to be DateTimeInterface, integer given in %s on line %d
diff --git a/ext/date/tests/date_timezone_get_error.phpt b/ext/date/tests/date_timezone_get_error.phpt
index 1310cbe9d6..01963c8224 100644
--- a/ext/date/tests/date_timezone_get_error.phpt
+++ b/ext/date/tests/date_timezone_get_error.phpt
@@ -2,10 +2,10 @@
Test date_timezone_get() function : error conditions
--FILE--
<?php
-/* Prototype : DateTimeZone date_timezone_get ( DateTime $object )
- * Description: Return time zone relative to given DateTime
+/* Prototype : DateTimeZone date_timezone_get ( DateTimeInterface $object )
+ * Description: Return time zone relative to given DateTimeInterface
* Source code: ext/date/php_date.c
- * Alias to functions: DateTime::getTimezone
+ * Alias to functions: DateTimeInterface::getTimezone
*/
// Set timezone
@@ -45,12 +45,12 @@ bool(false)
-- Testing date_timezone_get() function with an invalid values for $object argument --
-Warning: date_timezone_get() expects parameter 1 to be DateTime, object given in %s on line %d
+Warning: date_timezone_get() expects parameter 1 to be DateTimeInterface, object given in %s on line %d
bool(false)
-Warning: date_timezone_get() expects parameter 1 to be DateTime, integer given in %s on line %d
+Warning: date_timezone_get() expects parameter 1 to be DateTimeInterface, integer given in %s on line %d
bool(false)
-Warning: date_timezone_get() expects parameter 1 to be DateTime, null given in %s on line %d
+Warning: date_timezone_get() expects parameter 1 to be DateTimeInterface, null given in %s on line %d
bool(false)
===DONE===
diff --git a/ext/date/tests/date_timezone_get_variation1.phpt b/ext/date/tests/date_timezone_get_variation1.phpt
index 3b2034ecc2..dd346e9d92 100644
--- a/ext/date/tests/date_timezone_get_variation1.phpt
+++ b/ext/date/tests/date_timezone_get_variation1.phpt
@@ -2,10 +2,10 @@
Test date_timezone_get() function : usage variation - Passing unexpected values to first argument $object.
--FILE--
<?php
-/* Prototype : DateTimeZone date_timezone_get ( DateTime $object )
- * Description: Return time zone relative to given DateTime
+/* Prototype : DateTimeZone date_timezone_get ( DateTimeInterface $object )
+ * Description: Return time zone relative to given DateTimeInterface
* Source code: ext/date/php_date.c
- * Alias to functions: DateTime::getTimezone
+ * Alias to functions: DateTimeInterface::getTimezone
*/
echo "*** Testing date_timezone_get() : usage variation - unexpected values to first argument \$object***\n";
@@ -110,141 +110,141 @@ fclose( $file_handle );
-- int 0 --
-Warning: date_timezone_get() expects parameter 1 to be DateTime, integer given in %s on line %d
+Warning: date_timezone_get() expects parameter 1 to be DateTimeInterface, integer given in %s on line %d
bool(false)
-- int 1 --
-Warning: date_timezone_get() expects parameter 1 to be DateTime, integer given in %s on line %d
+Warning: date_timezone_get() expects parameter 1 to be DateTimeInterface, integer given in %s on line %d
bool(false)
-- int 12345 --
-Warning: date_timezone_get() expects parameter 1 to be DateTime, integer given in %s on line %d
+Warning: date_timezone_get() expects parameter 1 to be DateTimeInterface, integer given in %s on line %d
bool(false)
-- int -12345 --
-Warning: date_timezone_get() expects parameter 1 to be DateTime, integer given in %s on line %d
+Warning: date_timezone_get() expects parameter 1 to be DateTimeInterface, integer given in %s on line %d
bool(false)
-- float 10.5 --
-Warning: date_timezone_get() expects parameter 1 to be DateTime, double given in %s on line %d
+Warning: date_timezone_get() expects parameter 1 to be DateTimeInterface, double given in %s on line %d
bool(false)
-- float -10.5 --
-Warning: date_timezone_get() expects parameter 1 to be DateTime, double given in %s on line %d
+Warning: date_timezone_get() expects parameter 1 to be DateTimeInterface, double given in %s on line %d
bool(false)
-- float .5 --
-Warning: date_timezone_get() expects parameter 1 to be DateTime, double given in %s on line %d
+Warning: date_timezone_get() expects parameter 1 to be DateTimeInterface, double given in %s on line %d
bool(false)
-- empty array --
-Warning: date_timezone_get() expects parameter 1 to be DateTime, array given in %s on line %d
+Warning: date_timezone_get() expects parameter 1 to be DateTimeInterface, array given in %s on line %d
bool(false)
-- int indexed array --
-Warning: date_timezone_get() expects parameter 1 to be DateTime, array given in %s on line %d
+Warning: date_timezone_get() expects parameter 1 to be DateTimeInterface, array given in %s on line %d
bool(false)
-- associative array --
-Warning: date_timezone_get() expects parameter 1 to be DateTime, array given in %s on line %d
+Warning: date_timezone_get() expects parameter 1 to be DateTimeInterface, array given in %s on line %d
bool(false)
-- nested arrays --
-Warning: date_timezone_get() expects parameter 1 to be DateTime, array given in %s on line %d
+Warning: date_timezone_get() expects parameter 1 to be DateTimeInterface, array given in %s on line %d
bool(false)
-- uppercase NULL --
-Warning: date_timezone_get() expects parameter 1 to be DateTime, null given in %s on line %d
+Warning: date_timezone_get() expects parameter 1 to be DateTimeInterface, null given in %s on line %d
bool(false)
-- lowercase null --
-Warning: date_timezone_get() expects parameter 1 to be DateTime, null given in %s on line %d
+Warning: date_timezone_get() expects parameter 1 to be DateTimeInterface, null given in %s on line %d
bool(false)
-- lowercase true --
-Warning: date_timezone_get() expects parameter 1 to be DateTime, boolean given in %s on line %d
+Warning: date_timezone_get() expects parameter 1 to be DateTimeInterface, boolean given in %s on line %d
bool(false)
-- lowercase false --
-Warning: date_timezone_get() expects parameter 1 to be DateTime, boolean given in %s on line %d
+Warning: date_timezone_get() expects parameter 1 to be DateTimeInterface, boolean given in %s on line %d
bool(false)
-- uppercase TRUE --
-Warning: date_timezone_get() expects parameter 1 to be DateTime, boolean given in %s on line %d
+Warning: date_timezone_get() expects parameter 1 to be DateTimeInterface, boolean given in %s on line %d
bool(false)
-- uppercase FALSE --
-Warning: date_timezone_get() expects parameter 1 to be DateTime, boolean given in %s on line %d
+Warning: date_timezone_get() expects parameter 1 to be DateTimeInterface, boolean given in %s on line %d
bool(false)
-- empty string DQ --
-Warning: date_timezone_get() expects parameter 1 to be DateTime, string given in %s on line %d
+Warning: date_timezone_get() expects parameter 1 to be DateTimeInterface, string given in %s on line %d
bool(false)
-- empty string SQ --
-Warning: date_timezone_get() expects parameter 1 to be DateTime, string given in %s on line %d
+Warning: date_timezone_get() expects parameter 1 to be DateTimeInterface, string given in %s on line %d
bool(false)
-- string DQ --
-Warning: date_timezone_get() expects parameter 1 to be DateTime, string given in %s on line %d
+Warning: date_timezone_get() expects parameter 1 to be DateTimeInterface, string given in %s on line %d
bool(false)
-- string SQ --
-Warning: date_timezone_get() expects parameter 1 to be DateTime, string given in %s on line %d
+Warning: date_timezone_get() expects parameter 1 to be DateTimeInterface, string given in %s on line %d
bool(false)
-- mixed case string --
-Warning: date_timezone_get() expects parameter 1 to be DateTime, string given in %s on line %d
+Warning: date_timezone_get() expects parameter 1 to be DateTimeInterface, string given in %s on line %d
bool(false)
-- heredoc --
-Warning: date_timezone_get() expects parameter 1 to be DateTime, string given in %s on line %d
+Warning: date_timezone_get() expects parameter 1 to be DateTimeInterface, string given in %s on line %d
bool(false)
-- instance of classWithToString --
-Warning: date_timezone_get() expects parameter 1 to be DateTime, object given in %s on line %d
+Warning: date_timezone_get() expects parameter 1 to be DateTimeInterface, object given in %s on line %d
bool(false)
-- instance of classWithoutToString --
-Warning: date_timezone_get() expects parameter 1 to be DateTime, object given in %s on line %d
+Warning: date_timezone_get() expects parameter 1 to be DateTimeInterface, object given in %s on line %d
bool(false)
-- undefined var --
-Warning: date_timezone_get() expects parameter 1 to be DateTime, null given in %s on line %d
+Warning: date_timezone_get() expects parameter 1 to be DateTimeInterface, null given in %s on line %d
bool(false)
-- unset var --
-Warning: date_timezone_get() expects parameter 1 to be DateTime, null given in %s on line %d
+Warning: date_timezone_get() expects parameter 1 to be DateTimeInterface, null given in %s on line %d
bool(false)
-- resource --
-Warning: date_timezone_get() expects parameter 1 to be DateTime, resource given in %s on line %d
+Warning: date_timezone_get() expects parameter 1 to be DateTimeInterface, resource given in %s on line %d
bool(false)
===DONE===
diff --git a/ext/date/tests/timezone_open_basic1.phpt b/ext/date/tests/timezone_open_basic1.phpt
index 7a989362b0..7fcfcb34cb 100644
--- a/ext/date/tests/timezone_open_basic1.phpt
+++ b/ext/date/tests/timezone_open_basic1.phpt
@@ -18,10 +18,22 @@ var_dump( timezone_open("America/Los_Angeles") );
===DONE===
--EXPECTF--
*** Testing timezone_open() : basic functionality ***
-object(DateTimeZone)#%d (0) {
+object(DateTimeZone)#%d (2) {
+ ["timezone_type"]=>
+ int(3)
+ ["timezone"]=>
+ string(3) "UTC"
}
-object(DateTimeZone)#%d (0) {
+object(DateTimeZone)#%d (2) {
+ ["timezone_type"]=>
+ int(3)
+ ["timezone"]=>
+ string(13) "Europe/London"
}
-object(DateTimeZone)#%d (0) {
+object(DateTimeZone)#%d (2) {
+ ["timezone_type"]=>
+ int(3)
+ ["timezone"]=>
+ string(19) "America/Los_Angeles"
}
===DONE=== \ No newline at end of file
diff --git a/ext/dba/config.m4 b/ext/dba/config.m4
index 4b123518b4..5442bb1415 100644
--- a/ext/dba/config.m4
+++ b/ext/dba/config.m4
@@ -557,10 +557,10 @@ PHP_ARG_WITH(cdb,,
[ --without-cdb[=DIR] DBA: CDB support (bundled)], $php_dba_enable, no)
PHP_ARG_ENABLE(inifile,,
-[ --disable-inifile DBA: INI support (bundled)], $php_dba_enable, no)
+[ --disable-inifile DBA: INI support (bundled)], $php_dba_enable, no)
PHP_ARG_ENABLE(flatfile,,
-[ --disable-flatfile DBA: FlatFile support (bundled)], $php_dba_enable, no)
+[ --disable-flatfile DBA: FlatFile support (bundled)], $php_dba_enable, no)
# CDB
if test "$PHP_CDB" = "yes"; then
diff --git a/ext/dba/dba_flatfile.c b/ext/dba/dba_flatfile.c
index aa99d01283..ee8eefa652 100644
--- a/ext/dba/dba_flatfile.c
+++ b/ext/dba/dba_flatfile.c
@@ -88,15 +88,16 @@ DBA_UPDATE_FUNC(flatfile)
gval.dsize = vallen;
switch(flatfile_store(dba, gkey, gval, mode==1 ? FLATFILE_INSERT : FLATFILE_REPLACE TSRMLS_CC)) {
- case -1:
- php_error_docref1(NULL TSRMLS_CC, key, E_WARNING, "Operation not possible");
- return FAILURE;
- default:
- case 0:
- return SUCCESS;
- case 1:
- php_error_docref1(NULL TSRMLS_CC, key, E_WARNING, "Key already exists");
- return FAILURE;
+ case 0:
+ return SUCCESS;
+ case 1:
+ return FAILURE;
+ case -1:
+ php_error_docref1(NULL TSRMLS_CC, key, E_WARNING, "Operation not possible");
+ return FAILURE;
+ default:
+ php_error_docref2(NULL TSRMLS_CC, key, val, E_WARNING, "Unknown return value");
+ return FAILURE;
}
}
diff --git a/ext/dba/dba_gdbm.c b/ext/dba/dba_gdbm.c
index d8ca97e209..345687fcf7 100644
--- a/ext/dba/dba_gdbm.c
+++ b/ext/dba/dba_gdbm.c
@@ -104,11 +104,18 @@ DBA_UPDATE_FUNC(gdbm)
gval.dptr = (char *) val;
gval.dsize = vallen;
- if(gdbm_store(dba->dbf, gkey, gval,
- mode == 1 ? GDBM_INSERT : GDBM_REPLACE) == 0)
- return SUCCESS;
- php_error_docref2(NULL TSRMLS_CC, key, val, E_WARNING, "%s", gdbm_strerror(gdbm_errno));
- return FAILURE;
+ switch (gdbm_store(dba->dbf, gkey, gval, mode == 1 ? GDBM_INSERT : GDBM_REPLACE)) {
+ case 0:
+ return SUCCESS;
+ case 1:
+ return FAILURE;
+ case -1:
+ php_error_docref2(NULL TSRMLS_CC, key, val, E_WARNING, "%s", gdbm_strerror(gdbm_errno));
+ return FAILURE;
+ default:
+ php_error_docref2(NULL TSRMLS_CC, key, val, E_WARNING, "Unknown return value");
+ return FAILURE;
+ }
}
DBA_EXISTS_FUNC(gdbm)
diff --git a/ext/dba/dba_inifile.c b/ext/dba/dba_inifile.c
index 5ca5d302bc..4d8eae73ac 100644
--- a/ext/dba/dba_inifile.c
+++ b/ext/dba/dba_inifile.c
@@ -101,7 +101,6 @@ DBA_UPDATE_FUNC(inifile)
case 0:
return SUCCESS;
case 1:
- php_error_docref1(NULL TSRMLS_CC, key, E_WARNING, "Key already exists");
return FAILURE;
}
}
diff --git a/ext/dba/dba_qdbm.c b/ext/dba/dba_qdbm.c
index 4e5d69dfa2..a32b7e9e97 100644
--- a/ext/dba/dba_qdbm.c
+++ b/ext/dba/dba_qdbm.c
@@ -96,13 +96,15 @@ DBA_FETCH_FUNC(qdbm)
DBA_UPDATE_FUNC(qdbm)
{
QDBM_DATA;
- int result;
- result = dpput(dba->dbf, key, keylen, val, vallen, mode == 1 ? DP_DKEEP : DP_DOVER);
- if (result)
+ if (dpput(dba->dbf, key, keylen, val, vallen, mode == 1 ? DP_DKEEP : DP_DOVER)) {
return SUCCESS;
+ }
+
+ if (dpecode != DP_EKEEP) {
+ php_error_docref2(NULL TSRMLS_CC, key, val, E_WARNING, "%s", dperrmsg(dpecode));
+ }
- php_error_docref2(NULL TSRMLS_CC, key, val, E_WARNING, "%s", dperrmsg(dpecode));
return FAILURE;
}
diff --git a/ext/dba/libinifile/inifile.c b/ext/dba/libinifile/inifile.c
index 0dd17da31e..8c771beba4 100644
--- a/ext/dba/libinifile/inifile.c
+++ b/ext/dba/libinifile/inifile.c
@@ -402,7 +402,7 @@ static int inifile_copy_to(inifile *dba, size_t pos_start, size_t pos_end, inifi
return FAILURE;
}
php_stream_seek(dba->fp, pos_start, SEEK_SET);
- if (!php_stream_copy_to_stream(dba->fp, fp, pos_end - pos_start)) {
+ if (!php_stream_copy_to_stream_ex(dba->fp, fp, pos_end - pos_start, NULL)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not copy group [%zu - %zu] to temporary stream", pos_start, pos_end);
return FAILURE;
}
@@ -427,7 +427,7 @@ static int inifile_filter(inifile *dba, inifile *from, const key_type *key TSRML
pos_curr = php_stream_tell(from->fp);
if (pos_start != pos_next) {
php_stream_seek(from->fp, pos_start, SEEK_SET);
- if (!php_stream_copy_to_stream(from->fp, dba->fp, pos_next - pos_start)) {
+ if (!php_stream_copy_to_stream_ex(from->fp, dba->fp, pos_next - pos_start, NULL)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not copy [%zu - %zu] from temporary stream", pos_next, pos_start);
ret = FAILURE;
}
@@ -446,13 +446,13 @@ static int inifile_filter(inifile *dba, inifile *from, const key_type *key TSRML
}
if (pos_start != pos_next) {
php_stream_seek(from->fp, pos_start, SEEK_SET);
- if (!php_stream_copy_to_stream(from->fp, dba->fp, pos_next - pos_start)) {
+ if (!php_stream_copy_to_stream_ex(from->fp, dba->fp, pos_next - pos_start, NULL)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not copy [%zu - %zu] from temporary stream", pos_next, pos_start);
ret = FAILURE;
}
}
inifile_line_free(&ln);
- return SUCCESS;
+ return ret;
}
/* }}} */
@@ -460,7 +460,7 @@ static int inifile_filter(inifile *dba, inifile *from, const key_type *key TSRML
*/
static int inifile_delete_replace_append(inifile *dba, const key_type *key, const val_type *value, int append TSRMLS_DC)
{
- size_t pos_grp_start = 0, pos_grp_next;
+ size_t pos_grp_start=0, pos_grp_next;
inifile *ini_tmp = NULL;
php_stream *fp_tmp = NULL;
int ret;
@@ -497,7 +497,7 @@ static int inifile_delete_replace_append(inifile *dba, const key_type *key, cons
php_stream_seek(dba->fp, 0, SEEK_END);
if (pos_grp_next != (size_t)php_stream_tell(dba->fp)) {
php_stream_seek(dba->fp, pos_grp_next, SEEK_SET);
- if (!php_stream_copy_to_stream(dba->fp, fp_tmp, PHP_STREAM_COPY_ALL)) {
+ if (!php_stream_copy_to_stream_ex(dba->fp, fp_tmp, PHP_STREAM_COPY_ALL, NULL)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not copy remainder to temporary stream");
ret = FAILURE;
}
@@ -538,7 +538,7 @@ static int inifile_delete_replace_append(inifile *dba, const key_type *key, cons
if (fp_tmp && php_stream_tell(fp_tmp)) {
php_stream_seek(fp_tmp, 0, SEEK_SET);
php_stream_seek(dba->fp, 0, SEEK_END);
- if (!php_stream_copy_to_stream(fp_tmp, dba->fp, PHP_STREAM_COPY_ALL)) {
+ if (!php_stream_copy_to_stream_ex(fp_tmp, dba->fp, PHP_STREAM_COPY_ALL, NULL)) {
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "Could not copy from temporary stream - ini file truncated");
ret = FAILURE;
}
diff --git a/ext/dba/tests/dba_db1.phpt b/ext/dba/tests/dba_db1.phpt
index a24600350f..d0e530e026 100644
--- a/ext/dba/tests/dba_db1.phpt
+++ b/ext/dba/tests/dba_db1.phpt
@@ -18,6 +18,8 @@ database handler: db1
Content String 2
Content 2 replaced
Read during write: not allowed
+"key number 6" written
+Failed to write "key number 6" 2nd time
Content 2 replaced 2nd time
The 6th value
array(3) {
@@ -33,6 +35,8 @@ array(3) {
Content String 2
Content 2 replaced
Read during write: not allowed
+"key number 6" written
+Failed to write "key number 6" 2nd time
Content 2 replaced 2nd time
The 6th value
array(3) {
diff --git a/ext/dba/tests/dba_db2.phpt b/ext/dba/tests/dba_db2.phpt
index 89d8a926e1..1cfbb3e340 100644
--- a/ext/dba/tests/dba_db2.phpt
+++ b/ext/dba/tests/dba_db2.phpt
@@ -18,6 +18,8 @@ database handler: db2
Content String 2
Content 2 replaced
Read during write: not allowed
+"key number 6" written
+Failed to write "key number 6" 2nd time
Content 2 replaced 2nd time
The 6th value
array(3) {
@@ -33,6 +35,8 @@ array(3) {
Content String 2
Content 2 replaced
Read during write: not allowed
+"key number 6" written
+Failed to write "key number 6" 2nd time
Content 2 replaced 2nd time
The 6th value
array(3) {
diff --git a/ext/dba/tests/dba_db3.phpt b/ext/dba/tests/dba_db3.phpt
index 257c882175..5de7e5a041 100644
--- a/ext/dba/tests/dba_db3.phpt
+++ b/ext/dba/tests/dba_db3.phpt
@@ -18,6 +18,8 @@ database handler: db3
Content String 2
Content 2 replaced
Read during write: not allowed
+"key number 6" written
+Failed to write "key number 6" 2nd time
Content 2 replaced 2nd time
The 6th value
array(3) {
@@ -33,6 +35,8 @@ array(3) {
Content String 2
Content 2 replaced
Read during write: not allowed
+"key number 6" written
+Failed to write "key number 6" 2nd time
Content 2 replaced 2nd time
The 6th value
array(3) {
diff --git a/ext/dba/tests/dba_db4_000.phpt b/ext/dba/tests/dba_db4_000.phpt
index bbbc52c9f1..17db4bb62d 100644
--- a/ext/dba/tests/dba_db4_000.phpt
+++ b/ext/dba/tests/dba_db4_000.phpt
@@ -22,6 +22,8 @@ database handler: db4
Content String 2
Content 2 replaced
Read during write: not allowed
+"key number 6" written
+Failed to write "key number 6" 2nd time
Content 2 replaced 2nd time
The 6th value
array(3) {
@@ -37,6 +39,8 @@ array(3) {
Content String 2
Content 2 replaced
Read during write: not allowed
+"key number 6" written
+Failed to write "key number 6" 2nd time
Content 2 replaced 2nd time
The 6th value
array(3) {
diff --git a/ext/dba/tests/dba_dbm.phpt b/ext/dba/tests/dba_dbm.phpt
index dd1fe1e31c..8bea8463da 100644
--- a/ext/dba/tests/dba_dbm.phpt
+++ b/ext/dba/tests/dba_dbm.phpt
@@ -18,6 +18,8 @@ database handler: dbm
Content String 2
Content 2 replaced
Read during write: not allowed
+"key number 6" written
+Failed to write "key number 6" 2nd time
Content 2 replaced 2nd time
The 6th value
array(3) {
@@ -33,6 +35,8 @@ array(3) {
Content String 2
Content 2 replaced
Read during write: not allowed
+"key number 6" written
+Failed to write "key number 6" 2nd time
Content 2 replaced 2nd time
The 6th value
array(3) {
diff --git a/ext/dba/tests/dba_flatfile.phpt b/ext/dba/tests/dba_flatfile.phpt
index 8e1ca6a933..ac7f86ebda 100644
--- a/ext/dba/tests/dba_flatfile.phpt
+++ b/ext/dba/tests/dba_flatfile.phpt
@@ -22,6 +22,8 @@ database handler: flatfile
Content String 2
Content 2 replaced
Read during write: not allowed
+"key number 6" written
+Failed to write "key number 6" 2nd time
Content 2 replaced 2nd time
The 6th value
array(3) {
@@ -37,6 +39,8 @@ array(3) {
Content String 2
Content 2 replaced
Read during write: not allowed
+"key number 6" written
+Failed to write "key number 6" 2nd time
Content 2 replaced 2nd time
The 6th value
array(3) {
diff --git a/ext/dba/tests/dba_gdbm.phpt b/ext/dba/tests/dba_gdbm.phpt
index 8ac3f6474d..d8fde4b628 100644
--- a/ext/dba/tests/dba_gdbm.phpt
+++ b/ext/dba/tests/dba_gdbm.phpt
@@ -21,6 +21,8 @@ database handler: gdbm
Content String 2
Content 2 replaced
Read during write:%sallowed
+"key number 6" written
+Failed to write "key number 6" 2nd time
Content 2 replaced 2nd time
The 6th value
array(3) {
diff --git a/ext/dba/tests/dba_handler.inc b/ext/dba/tests/dba_handler.inc
index 1c3f5127ef..a950e903af 100644
--- a/ext/dba/tests/dba_handler.inc
+++ b/ext/dba/tests/dba_handler.inc
@@ -46,8 +46,16 @@ do {
echo "Read during write: allowed\n";
}
if ($db_writer!==FALSE) {
- dba_insert("key number 6", "The 6th value", $db_writer);
- @dba_insert("key number 6", "The 6th value inserted again would be an error", $db_writer);
+ if (dba_insert("key number 6", "The 6th value", $db_writer)) {
+ echo '"key number 6" written' . "\n";
+ } else {
+ echo 'Failed to write "key number 6"' . "\n";
+ }
+ if (dba_insert("key number 6", "The 6th value inserted again would be an error", $db_writer)) {
+ echo '"key number 6" written 2nd time' . "\n";
+ } else {
+ echo 'Failed to write "key number 6" 2nd time' . "\n";
+ }
dba_replace("key2", "Content 2 replaced 2nd time", $db_writer);
dba_delete("key4", $db_writer);
echo dba_fetch("key2", $db_writer)."\n";
diff --git a/ext/dba/tests/dba_inifile.phpt b/ext/dba/tests/dba_inifile.phpt
index 81ab738796..5975d25f4d 100644
--- a/ext/dba/tests/dba_inifile.phpt
+++ b/ext/dba/tests/dba_inifile.phpt
@@ -18,6 +18,8 @@ database handler: inifile
Content String 2
Content 2 replaced
Read during write: not allowed
+"key number 6" written
+Failed to write "key number 6" 2nd time
Content 2 replaced 2nd time
The 6th value
array(3) {
@@ -33,6 +35,8 @@ array(3) {
Content String 2
Content 2 replaced
Read during write: not allowed
+"key number 6" written
+Failed to write "key number 6" 2nd time
Content 2 replaced 2nd time
The 6th value
array(3) {
diff --git a/ext/dba/tests/dba_ndbm.phpt b/ext/dba/tests/dba_ndbm.phpt
index b0f5542de4..193db6f94d 100644
--- a/ext/dba/tests/dba_ndbm.phpt
+++ b/ext/dba/tests/dba_ndbm.phpt
@@ -18,6 +18,8 @@ database handler: ndbm
Content String 2
Content 2 replaced
Read during write: not allowed
+"key number 6" written
+Failed to write "key number 6" 2nd time
Content 2 replaced 2nd time
The 6th value
array(3) {
@@ -33,6 +35,8 @@ array(3) {
Content String 2
Content 2 replaced
Read during write: not allowed
+"key number 6" written
+Failed to write "key number 6" 2nd time
Content 2 replaced 2nd time
The 6th value
array(3) {
diff --git a/ext/dba/tests/dba_qdbm.phpt b/ext/dba/tests/dba_qdbm.phpt
index ef216d9258..e2205baa26 100644
--- a/ext/dba/tests/dba_qdbm.phpt
+++ b/ext/dba/tests/dba_qdbm.phpt
@@ -19,6 +19,8 @@ database handler: qdbm
Content String 2
Content 2 replaced
Read during write:%sallowed
+"key number 6" written
+Failed to write "key number 6" 2nd time
Content 2 replaced 2nd time
The 6th value
array(3) {
diff --git a/ext/dba/tests/dba_tcadb.phpt b/ext/dba/tests/dba_tcadb.phpt
index 52dd4de336..28b6dd8f0b 100644
--- a/ext/dba/tests/dba_tcadb.phpt
+++ b/ext/dba/tests/dba_tcadb.phpt
@@ -22,6 +22,8 @@ database handler: tcadb
Content String 2
Content 2 replaced
Read during write: not allowed
+"key number 6" written
+Failed to write "key number 6" 2nd time
Content 2 replaced 2nd time
The 6th value
array(3) {
@@ -37,6 +39,8 @@ array(3) {
Content String 2
Content 2 replaced
Read during write: not allowed
+"key number 6" written
+Failed to write "key number 6" 2nd time
Content 2 replaced 2nd time
The 6th value
array(3) {
diff --git a/ext/dom/document.c b/ext/dom/document.c
index 19acff7468..73bc8c1c62 100644
--- a/ext/dom/document.c
+++ b/ext/dom/document.c
@@ -1973,14 +1973,15 @@ static void _dom_document_schema_validate(INTERNAL_FUNCTION_PARAMETERS, int type
xmlDoc *docp;
dom_object *intern;
char *source = NULL, *valid_file = NULL;
- int source_len = 0;
+ int source_len = 0, valid_opts = 0;
+ long flags = 0;
xmlSchemaParserCtxtPtr parser;
xmlSchemaPtr sptr;
xmlSchemaValidCtxtPtr vptr;
int is_valid;
char resolved_path[MAXPATHLEN + 1];
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Op", &id, dom_document_class_entry, &source, &source_len) == FAILURE) {
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Op|l", &id, dom_document_class_entry, &source, &source_len, &flags) == FAILURE) {
return;
}
@@ -2029,6 +2030,13 @@ static void _dom_document_schema_validate(INTERNAL_FUNCTION_PARAMETERS, int type
RETURN_FALSE;
}
+#if LIBXML_VERSION >= 20614
+ if (flags & XML_SCHEMA_VAL_VC_I_CREATE) {
+ valid_opts |= XML_SCHEMA_VAL_VC_I_CREATE;
+ }
+#endif
+
+ xmlSchemaSetValidOptions(vptr, valid_opts);
xmlSchemaSetValidErrors(vptr, php_libxml_error_handler, php_libxml_error_handler, vptr);
is_valid = xmlSchemaValidateDoc(vptr, docp);
xmlSchemaFree(sptr);
@@ -2042,14 +2050,14 @@ static void _dom_document_schema_validate(INTERNAL_FUNCTION_PARAMETERS, int type
}
/* }}} */
-/* {{{ proto boolean dom_document_schema_validate_file(string filename); */
+/* {{{ proto boolean dom_document_schema_validate_file(string filename, int flags); */
PHP_FUNCTION(dom_document_schema_validate_file)
{
_dom_document_schema_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_FILE);
}
/* }}} end dom_document_schema_validate_file */
-/* {{{ proto boolean dom_document_schema_validate(string source); */
+/* {{{ proto boolean dom_document_schema_validate(string source, int flags); */
PHP_FUNCTION(dom_document_schema_validate_xml)
{
_dom_document_schema_validate(INTERNAL_FUNCTION_PARAM_PASSTHRU, DOM_LOAD_STRING);
diff --git a/ext/dom/dom_iterators.c b/ext/dom/dom_iterators.c
index f5772e5a99..987d54de25 100644
--- a/ext/dom/dom_iterators.c
+++ b/ext/dom/dom_iterators.c
@@ -157,35 +157,22 @@ static void php_dom_iterator_current_data(zend_object_iterator *iter, zval ***da
}
/* }}} */
-static int php_dom_iterator_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) /* {{{ */
+static void php_dom_iterator_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC) /* {{{ */
{
- zval *curobj;
- xmlNodePtr curnode = NULL;
- dom_object *intern;
- zval *object;
- int namelen;
-
php_dom_iterator *iterator = (php_dom_iterator *)iter;
-
- object = (zval *)iterator->intern.data;
+ zval *object = (zval *)iterator->intern.data;
if (instanceof_function(Z_OBJCE_P(object), dom_nodelist_class_entry TSRMLS_CC)) {
- *int_key = iter->index;
- return HASH_KEY_IS_LONG;
+ ZVAL_LONG(key, iter->index);
} else {
- curobj = iterator->curobj;
+ dom_object *intern = (dom_object *)zend_object_store_get_object(iterator->curobj TSRMLS_CC);
- intern = (dom_object *)zend_object_store_get_object(curobj TSRMLS_CC);
if (intern != NULL && intern->ptr != NULL) {
- curnode = (xmlNodePtr)((php_libxml_node_ptr *)intern->ptr)->node;
+ xmlNodePtr curnode = (xmlNodePtr)((php_libxml_node_ptr *)intern->ptr)->node;
+ ZVAL_STRINGL(key, (char *) curnode->name, xmlStrlen(curnode->name), 1);
} else {
- return HASH_KEY_NON_EXISTANT;
+ ZVAL_NULL(key);
}
-
- namelen = xmlStrlen(curnode->name);
- *str_key = estrndup(curnode->name, namelen);
- *str_key_len = namelen + 1;
- return HASH_KEY_IS_STRING;
}
}
/* }}} */
diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c
index dda638abd0..0623dbdcde 100644
--- a/ext/dom/php_dom.c
+++ b/ext/dom/php_dom.c
@@ -176,9 +176,9 @@ dom_doc_propsptr dom_get_doc_props(php_libxml_ref_obj *document)
static void dom_copy_doc_props(php_libxml_ref_obj *source_doc, php_libxml_ref_obj *dest_doc)
{
dom_doc_propsptr source, dest;
-
+
if (source_doc && dest_doc) {
-
+
source = dom_get_doc_props(source_doc);
dest = dom_get_doc_props(dest_doc);
@@ -224,7 +224,7 @@ zend_class_entry *dom_get_doc_classmap(php_libxml_ref_obj *document, zend_class_
{
dom_doc_propsptr doc_props;
zend_class_entry **ce = NULL;
-
+
if (document) {
doc_props = dom_get_doc_props(document);
if (doc_props->classmap) {
@@ -296,14 +296,14 @@ static int dom_write_na(dom_object *obj, zval *newval TSRMLS_DC)
static void dom_register_prop_handler(HashTable *prop_handler, char *name, dom_read_t read_func, dom_write_t write_func TSRMLS_DC)
{
dom_prop_handler hnd;
-
+
hnd.read_func = read_func ? read_func : dom_read_na;
hnd.write_func = write_func ? write_func : dom_write_na;
zend_hash_add(prop_handler, name, strlen(name)+1, &hnd, sizeof(dom_prop_handler), NULL);
}
/* }}} */
-static zval **dom_get_property_ptr_ptr(zval *object, zval *member, const zend_literal *key TSRMLS_DC) /* {{{ */
+static zval **dom_get_property_ptr_ptr(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */
{
dom_object *obj;
zval tmp_member;
@@ -326,7 +326,7 @@ static zval **dom_get_property_ptr_ptr(zval *object, zval *member, const zend_li
}
if (ret == FAILURE) {
std_hnd = zend_get_std_object_handlers();
- retval = std_hnd->get_property_ptr_ptr(object, member, key TSRMLS_CC);
+ retval = std_hnd->get_property_ptr_ptr(object, member, type, key TSRMLS_CC);
}
if (member == &tmp_member) {
@@ -557,7 +557,7 @@ void *php_dom_export_node(zval *object TSRMLS_DC) /* {{{ */
nodep = intern->node->node;
}
- return nodep;
+ return nodep;
}
/* }}} */
@@ -596,10 +596,10 @@ zend_object_value dom_objects_store_clone_obj(zval *zobject TSRMLS_DC) /* {{{ */
zend_object_handle handle = Z_OBJ_HANDLE_P(zobject);
obj = &EG(objects_store).object_buckets[handle].bucket.obj;
-
+
if (obj->clone == NULL) {
php_error(E_ERROR, "Trying to clone an uncloneable object of class %s", Z_OBJCE_P(zobject)->name);
- }
+ }
obj->clone(obj->object, &new_object TSRMLS_CC);
@@ -607,7 +607,7 @@ zend_object_value dom_objects_store_clone_obj(zval *zobject TSRMLS_DC) /* {{{ */
intern = (dom_object *) new_object;
intern->handle = retval.handle;
retval.handlers = Z_OBJ_HT_P(zobject);
-
+
old_object = (dom_object *) obj->object;
zend_objects_clone_members(&intern->std, retval, &old_object->std, intern->handle TSRMLS_CC);
@@ -676,19 +676,19 @@ PHP_MINIT_FUNCTION(dom)
zend_declare_property_long(dom_domexception_class_entry, "code", sizeof("code")-1, 0, ZEND_ACC_PUBLIC TSRMLS_CC);
REGISTER_DOM_CLASS(ce, "DOMStringList", NULL, php_dom_domstringlist_class_functions, dom_domstringlist_class_entry);
-
+
zend_hash_init(&dom_domstringlist_prop_handlers, 0, NULL, NULL, 1);
dom_register_prop_handler(&dom_domstringlist_prop_handlers, "length", dom_domstringlist_length_read, NULL TSRMLS_CC);
zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_domstringlist_prop_handlers, sizeof(dom_domstringlist_prop_handlers), NULL);
REGISTER_DOM_CLASS(ce, "DOMNameList", NULL, php_dom_namelist_class_functions, dom_namelist_class_entry);
-
+
zend_hash_init(&dom_namelist_prop_handlers, 0, NULL, NULL, 1);
dom_register_prop_handler(&dom_namelist_prop_handlers, "length", dom_namelist_length_read, NULL TSRMLS_CC);
zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_namelist_prop_handlers, sizeof(dom_namelist_prop_handlers), NULL);
REGISTER_DOM_CLASS(ce, "DOMImplementationList", NULL, php_dom_domimplementationlist_class_functions, dom_domimplementationlist_class_entry);
-
+
zend_hash_init(&dom_domimplementationlist_prop_handlers, 0, NULL, NULL, 1);
dom_register_prop_handler(&dom_domimplementationlist_prop_handlers, "length", dom_domimplementationlist_length_read, NULL TSRMLS_CC);
zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_domimplementationlist_prop_handlers, sizeof(dom_domimplementationlist_prop_handlers), NULL);
@@ -697,7 +697,7 @@ PHP_MINIT_FUNCTION(dom)
REGISTER_DOM_CLASS(ce, "DOMImplementation", NULL, php_dom_domimplementation_class_functions, dom_domimplementation_class_entry);
REGISTER_DOM_CLASS(ce, "DOMNode", NULL, php_dom_node_class_functions, dom_node_class_entry);
-
+
zend_hash_init(&dom_node_prop_handlers, 0, NULL, NULL, 1);
dom_register_prop_handler(&dom_node_prop_handlers, "nodeName", dom_node_node_name_read, NULL TSRMLS_CC);
dom_register_prop_handler(&dom_node_prop_handlers, "nodeValue", dom_node_node_value_read, dom_node_node_value_write TSRMLS_CC);
@@ -732,7 +732,7 @@ PHP_MINIT_FUNCTION(dom)
REGISTER_DOM_CLASS(ce, "DOMDocumentFragment", dom_node_class_entry, php_dom_documentfragment_class_functions, dom_documentfragment_class_entry);
zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_node_prop_handlers, sizeof(dom_node_prop_handlers), NULL);
-
+
REGISTER_DOM_CLASS(ce, "DOMDocument", dom_node_class_entry, php_dom_document_class_functions, dom_document_class_entry);
zend_hash_init(&dom_document_prop_handlers, 0, NULL, NULL, 1);
dom_register_prop_handler(&dom_document_prop_handlers, "doctype", dom_document_doctype_read, NULL TSRMLS_CC);
@@ -779,7 +779,7 @@ PHP_MINIT_FUNCTION(dom)
zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_namednodemap_prop_handlers, sizeof(dom_namednodemap_prop_handlers), NULL);
REGISTER_DOM_CLASS(ce, "DOMCharacterData", dom_node_class_entry, php_dom_characterdata_class_functions, dom_characterdata_class_entry);
-
+
zend_hash_init(&dom_characterdata_prop_handlers, 0, NULL, NULL, 1);
dom_register_prop_handler(&dom_characterdata_prop_handlers, "data", dom_characterdata_data_read, dom_characterdata_data_write TSRMLS_CC);
dom_register_prop_handler(&dom_characterdata_prop_handlers, "length", dom_characterdata_length_read, NULL TSRMLS_CC);
@@ -787,7 +787,7 @@ PHP_MINIT_FUNCTION(dom)
zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_characterdata_prop_handlers, sizeof(dom_characterdata_prop_handlers), NULL);
REGISTER_DOM_CLASS(ce, "DOMAttr", dom_node_class_entry, php_dom_attr_class_functions, dom_attr_class_entry);
-
+
zend_hash_init(&dom_attr_prop_handlers, 0, NULL, NULL, 1);
dom_register_prop_handler(&dom_attr_prop_handlers, "name", dom_attr_name_read, NULL TSRMLS_CC);
dom_register_prop_handler(&dom_attr_prop_handlers, "specified", dom_attr_specified_read, NULL TSRMLS_CC);
@@ -798,7 +798,7 @@ PHP_MINIT_FUNCTION(dom)
zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_attr_prop_handlers, sizeof(dom_attr_prop_handlers), NULL);
REGISTER_DOM_CLASS(ce, "DOMElement", dom_node_class_entry, php_dom_element_class_functions, dom_element_class_entry);
-
+
zend_hash_init(&dom_element_prop_handlers, 0, NULL, NULL, 1);
dom_register_prop_handler(&dom_element_prop_handlers, "tagName", dom_element_tag_name_read, NULL TSRMLS_CC);
dom_register_prop_handler(&dom_element_prop_handlers, "schemaTypeInfo", dom_element_schema_type_info_read, NULL TSRMLS_CC);
@@ -806,7 +806,7 @@ PHP_MINIT_FUNCTION(dom)
zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_element_prop_handlers, sizeof(dom_element_prop_handlers), NULL);
REGISTER_DOM_CLASS(ce, "DOMText", dom_characterdata_class_entry, php_dom_text_class_functions, dom_text_class_entry);
-
+
zend_hash_init(&dom_text_prop_handlers, 0, NULL, NULL, 1);
dom_register_prop_handler(&dom_text_prop_handlers, "wholeText", dom_text_whole_text_read, NULL TSRMLS_CC);
zend_hash_merge(&dom_text_prop_handlers, &dom_characterdata_prop_handlers, NULL, NULL, sizeof(dom_prop_handler), 0);
@@ -816,7 +816,7 @@ PHP_MINIT_FUNCTION(dom)
zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_characterdata_prop_handlers, sizeof(dom_typeinfo_prop_handlers), NULL);
REGISTER_DOM_CLASS(ce, "DOMTypeinfo", NULL, php_dom_typeinfo_class_functions, dom_typeinfo_class_entry);
-
+
zend_hash_init(&dom_typeinfo_prop_handlers, 0, NULL, NULL, 1);
dom_register_prop_handler(&dom_typeinfo_prop_handlers, "typeName", dom_typeinfo_type_name_read, NULL TSRMLS_CC);
dom_register_prop_handler(&dom_typeinfo_prop_handlers, "typeNamespace", dom_typeinfo_type_namespace_read, NULL TSRMLS_CC);
@@ -824,7 +824,7 @@ PHP_MINIT_FUNCTION(dom)
REGISTER_DOM_CLASS(ce, "DOMUserDataHandler", NULL, php_dom_userdatahandler_class_functions, dom_userdatahandler_class_entry);
REGISTER_DOM_CLASS(ce, "DOMDomError", NULL, php_dom_domerror_class_functions, dom_domerror_class_entry);
-
+
zend_hash_init(&dom_domerror_prop_handlers, 0, NULL, NULL, 1);
dom_register_prop_handler(&dom_domerror_prop_handlers, "severity", dom_domerror_severity_read, NULL TSRMLS_CC);
dom_register_prop_handler(&dom_domerror_prop_handlers, "message", dom_domerror_message_read, NULL TSRMLS_CC);
@@ -836,7 +836,7 @@ PHP_MINIT_FUNCTION(dom)
REGISTER_DOM_CLASS(ce, "DOMErrorHandler", NULL, php_dom_domerrorhandler_class_functions, dom_domerrorhandler_class_entry);
REGISTER_DOM_CLASS(ce, "DOMLocator", NULL, php_dom_domlocator_class_functions, dom_domlocator_class_entry);
-
+
zend_hash_init(&dom_domlocator_prop_handlers, 0, NULL, NULL, 1);
dom_register_prop_handler(&dom_domlocator_prop_handlers, "lineNumber", dom_domlocator_line_number_read, NULL TSRMLS_CC);
dom_register_prop_handler(&dom_domlocator_prop_handlers, "columnNumber", dom_domlocator_column_number_read, NULL TSRMLS_CC);
@@ -850,7 +850,7 @@ PHP_MINIT_FUNCTION(dom)
zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_text_prop_handlers, sizeof(dom_documenttype_prop_handlers), NULL);
REGISTER_DOM_CLASS(ce, "DOMDocumentType", dom_node_class_entry, php_dom_documenttype_class_functions, dom_documenttype_class_entry);
-
+
zend_hash_init(&dom_documenttype_prop_handlers, 0, NULL, NULL, 1);
dom_register_prop_handler(&dom_documenttype_prop_handlers, "name", dom_documenttype_name_read, NULL TSRMLS_CC);
dom_register_prop_handler(&dom_documenttype_prop_handlers, "entities", dom_documenttype_entities_read, NULL TSRMLS_CC);
@@ -862,7 +862,7 @@ PHP_MINIT_FUNCTION(dom)
zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_documenttype_prop_handlers, sizeof(dom_documenttype_prop_handlers), NULL);
REGISTER_DOM_CLASS(ce, "DOMNotation", dom_node_class_entry, php_dom_notation_class_functions, dom_notation_class_entry);
-
+
zend_hash_init(&dom_notation_prop_handlers, 0, NULL, NULL, 1);
dom_register_prop_handler(&dom_notation_prop_handlers, "publicId", dom_notation_public_id_read, NULL TSRMLS_CC);
dom_register_prop_handler(&dom_notation_prop_handlers, "systemId", dom_notation_system_id_read, NULL TSRMLS_CC);
@@ -870,7 +870,7 @@ PHP_MINIT_FUNCTION(dom)
zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_notation_prop_handlers, sizeof(dom_notation_prop_handlers), NULL);
REGISTER_DOM_CLASS(ce, "DOMEntity", dom_node_class_entry, php_dom_entity_class_functions, dom_entity_class_entry);
-
+
zend_hash_init(&dom_entity_prop_handlers, 0, NULL, NULL, 1);
dom_register_prop_handler(&dom_entity_prop_handlers, "publicId", dom_entity_public_id_read, NULL TSRMLS_CC);
dom_register_prop_handler(&dom_entity_prop_handlers, "systemId", dom_entity_system_id_read, NULL TSRMLS_CC);
@@ -886,7 +886,7 @@ PHP_MINIT_FUNCTION(dom)
zend_hash_add(&classes, ce.name, ce.name_length + 1, &dom_node_prop_handlers, sizeof(dom_entity_prop_handlers), NULL);
REGISTER_DOM_CLASS(ce, "DOMProcessingInstruction", dom_node_class_entry, php_dom_processinginstruction_class_functions, dom_processinginstruction_class_entry);
-
+
zend_hash_init(&dom_processinginstruction_prop_handlers, 0, NULL, NULL, 1);
dom_register_prop_handler(&dom_processinginstruction_prop_handlers, "target", dom_processinginstruction_target_read, NULL TSRMLS_CC);
dom_register_prop_handler(&dom_processinginstruction_prop_handlers, "data", dom_processinginstruction_data_read, dom_processinginstruction_data_write TSRMLS_CC);
@@ -1011,7 +1011,7 @@ PHP_MSHUTDOWN_FUNCTION(dom) /* {{{ */
zend_hash_destroy(&dom_xpath_prop_handlers);
#endif
zend_hash_destroy(&classes);
-
+
/* If you want do find memleaks in this module, compile libxml2 with --with-mem-debug and
uncomment the following line, this will tell you the amount of not freed memory
and the total used memory into apaches error_log */
@@ -1074,7 +1074,7 @@ void dom_xpath_objects_free_storage(void *object TSRMLS_DC)
zend_hash_destroy(intern->registered_phpfunctions);
FREE_HASHTABLE(intern->registered_phpfunctions);
}
-
+
if (intern->node_list) {
zend_hash_destroy(intern->node_list);
FREE_HASHTABLE(intern->node_list);
@@ -1204,7 +1204,7 @@ zend_object_value dom_objects_new(zend_class_entry *class_type TSRMLS_DC)
{
zend_object_value retval;
dom_object *intern;
-
+
intern = dom_objects_set_class(class_type, 1 TSRMLS_CC);
retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t)dom_objects_free_storage, dom_objects_clone TSRMLS_CC);
@@ -1284,7 +1284,7 @@ zend_object_value dom_nnodemap_objects_new(zend_class_entry *class_type TSRMLS_D
zend_object_value retval;
dom_object *intern;
dom_nnodemap_object *objmap;
-
+
intern = dom_objects_set_class(class_type, 1 TSRMLS_CC);
intern->ptr = emalloc(sizeof(dom_nnodemap_object));
objmap = (dom_nnodemap_object *)intern->ptr;
@@ -1442,7 +1442,7 @@ void php_dom_create_implementation(zval **retval TSRMLS_DC) {
}
/* {{{ int dom_hierarchy(xmlNodePtr parent, xmlNodePtr child) */
-int dom_hierarchy(xmlNodePtr parent, xmlNodePtr child)
+int dom_hierarchy(xmlNodePtr parent, xmlNodePtr child)
{
xmlNodePtr nodep;
@@ -1509,7 +1509,7 @@ void dom_normalize (xmlNodePtr nodep TSRMLS_DC)
{
xmlNodePtr child, nextp, newnextp;
xmlAttrPtr attr;
- xmlChar *strContent;
+ xmlChar *strContent;
child = nodep->children;
while(child != NULL) {
@@ -1564,8 +1564,8 @@ void dom_set_old_ns(xmlDoc *doc, xmlNs *ns) {
}
memset(doc->oldNs, 0, sizeof(xmlNs));
doc->oldNs->type = XML_LOCAL_NAMESPACE;
- doc->oldNs->href = xmlStrdup(XML_XML_NAMESPACE);
- doc->oldNs->prefix = xmlStrdup((const xmlChar *)"xml");
+ doc->oldNs->href = xmlStrdup(XML_XML_NAMESPACE);
+ doc->oldNs->prefix = xmlStrdup((const xmlChar *)"xml");
}
cur = doc->oldNs;
@@ -1590,7 +1590,7 @@ int dom_check_qname(char *qname, char **localname, char **prefix, int uri_len, i
if (name_len == 0) {
return NAMESPACE_ERR;
}
-
+
*localname = (char *)xmlSplitQName2((xmlChar *)qname, (xmlChar **) prefix);
if (*localname == NULL) {
*localname = (char *)xmlStrdup((xmlChar *)qname);
diff --git a/ext/dom/tests/DOMDocument_loadXML_basic.phpt b/ext/dom/tests/DOMDocument_loadXML_basic.phpt
new file mode 100644
index 0000000000..569593c007
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_loadXML_basic.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Test DOMDocument::loadXML() basic behavior
+--DESCRIPTION--
+This test verifies the basic behaviour of the method
+Environment variables used in the test:
+- XML_FILE: the xml file to load
+- LOAD_OPTIONS: the second parameter to pass to the method
+- EXPECTED_RESULT: the expected result
+--CREDITS--
+Antonio Diaz Ruiz <dejalatele@gmail.com>
+--INI--
+assert.bail=true
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--ENV--
+XML_FILE=/book.xml
+LOAD_OPTIONS=0
+EXPECTED_RESULT=1
+--FILE_EXTERNAL--
+domdocumentloadxml_test_method.php
+--EXPECT--
diff --git a/ext/dom/tests/DOMDocument_loadXML_error1.phpt b/ext/dom/tests/DOMDocument_loadXML_error1.phpt
new file mode 100644
index 0000000000..52d44ea291
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_loadXML_error1.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Test DOMDocument::loadXML() detects not-well formed XML
+--DESCRIPTION--
+This test verifies the method detects an opening and ending tag mismatch
+Environment variables used in the test:
+- XML_FILE: the xml file to load
+- LOAD_OPTIONS: the second parameter to pass to the method
+- EXPECTED_RESULT: the expected result
+--CREDITS--
+Antonio Diaz Ruiz <dejalatele@gmail.com>
+--INI--
+assert.bail=true
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--ENV--
+XML_FILE=/not_well_formed.xml
+LOAD_OPTIONS=0
+EXPECTED_RESULT=0
+--FILE_EXTERNAL--
+domdocumentloadxml_test_method.php
+--EXPECTF--
+Warning: DOMDocument::load%r(XML){0,1}%r(): Opening and ending tag mismatch: title line 5 and book %s
+
+Warning: DOMDocument::load%r(XML){0,1}%r(): expected '>' %s
+
+Warning: DOMDocument::load%r(XML){0,1}%r(): Premature end of data in tag books %s
diff --git a/ext/dom/tests/DOMDocument_loadXML_error2.phpt b/ext/dom/tests/DOMDocument_loadXML_error2.phpt
new file mode 100644
index 0000000000..6ac4193daf
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_loadXML_error2.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Test DOMDocument::loadXML() detects not-well formed XML
+--DESCRIPTION--
+This test verifies the method detects attributes values not closed between " or '
+Environment variables used in the test:
+- XML_FILE: the xml file to load
+- LOAD_OPTIONS: the second parameter to pass to the method
+- EXPECTED_RESULT: the expected result
+--CREDITS--
+Antonio Diaz Ruiz <dejalatele@gmail.com>
+--INI--
+assert.bail=true
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--ENV--
+XML_FILE=/not_well_formed2.xml
+LOAD_OPTIONS=0
+EXPECTED_RESULT=0
+--FILE_EXTERNAL--
+domdocumentloadxml_test_method.php
+--EXPECTF--
+Warning: DOMDocument::load%r(XML){0,1}%r(): AttValue: " or ' expected %s
+
+Warning: DOMDocument::load%r(XML){0,1}%r(): attributes construct error %s
+
+Warning: DOMDocument::load%r(XML){0,1}%r(): Couldn't find end of Start Tag book %s
+
+Warning: DOMDocument::load%r(XML){0,1}%r(): Opening and ending tag mismatch: books %s
+
+Warning: DOMDocument::load%r(XML){0,1}%r(): Extra content at the end of the document %s
diff --git a/ext/dom/tests/DOMDocument_loadXML_error3.phpt b/ext/dom/tests/DOMDocument_loadXML_error3.phpt
new file mode 100644
index 0000000000..07f7ca7738
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_loadXML_error3.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Test DOMDocument::loadXML() detects not-well formed XML
+--DESCRIPTION--
+This test verifies the method detects a typo in tag names
+Environment variables used in the test:
+- XML_FILE: the xml file to load
+- LOAD_OPTIONS: the second parameter to pass to the method
+- EXPECTED_RESULT: the expected result
+--CREDITS--
+Antonio Diaz Ruiz <dejalatele@gmail.com>
+--INI--
+assert.bail=true
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--ENV--
+XML_FILE=/not_well_formed3.xml
+LOAD_OPTIONS=0
+EXPECTED_RESULT=0
+--FILE_EXTERNAL--
+domdocumentloadxml_test_method.php
+--EXPECTF--
+Warning: DOMDocument::load%r(XML){0,1}%r(): Opening and ending tag mismatch: boOk line 8 and book %s
diff --git a/ext/dom/tests/DOMDocument_loadXML_error4.phpt b/ext/dom/tests/DOMDocument_loadXML_error4.phpt
new file mode 100644
index 0000000000..e35d3dcea5
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_loadXML_error4.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Test DOMDocument::loadXML() detects not-well formed XML
+--DESCRIPTION--
+This test verifies the method detects an unsupported xml version
+Environment variables used in the test:
+- XML_FILE: the xml file to load
+- LOAD_OPTIONS: the second parameter to pass to the method
+- EXPECTED_RESULT: the expected result
+--CREDITS--
+Antonio Diaz Ruiz <dejalatele@gmail.com>
+--INI--
+assert.bail=true
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--ENV--
+XML_FILE=/not_well_formed4.xml
+LOAD_OPTIONS=0
+EXPECTED_RESULT=0
+--FILE_EXTERNAL--
+domdocumentloadxml_test_method.php
+--EXPECTF--
+Warning: DOMDocument::load%r(XML){0,1}%r(): Unsupported version '3.1' %s
diff --git a/ext/dom/tests/DOMDocument_loadXML_error5.phpt b/ext/dom/tests/DOMDocument_loadXML_error5.phpt
new file mode 100644
index 0000000000..a4aa1858f5
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_loadXML_error5.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Test DOMDocument::loadXML() detects not-well formed XML
+--DESCRIPTION--
+This test verifies the method detects extra content at the end of the document
+Environment variables used in the test:
+- XML_FILE: the xml file to load
+- LOAD_OPTIONS: the second parameter to pass to the method
+- EXPECTED_RESULT: the expected result
+--CREDITS--
+Antonio Diaz Ruiz <dejalatele@gmail.com>
+--INI--
+assert.bail=true
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--ENV--
+XML_FILE=/not_well_formed5.xml
+LOAD_OPTIONS=0
+EXPECTED_RESULT=0
+--FILE_EXTERNAL--
+domdocumentloadxml_test_method.php
+--EXPECTF--
+Warning: DOMDocument::load%r(XML){0,1}%r(): Extra content at the end of the document %s
diff --git a/ext/dom/tests/DOMDocument_loadXML_variation1.phpt b/ext/dom/tests/DOMDocument_loadXML_variation1.phpt
new file mode 100644
index 0000000000..558137526f
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_loadXML_variation1.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Test DOMDocument::loadXML() with LIBXML_DTDLOAD option
+--DESCRIPTION--
+This test verifies the right behaviour of the LIBXML_DTDLOAD constant
+Environment variables used in the test:
+- XML_FILE: the xml file to load
+- LOAD_OPTIONS: the second parameter to pass to the method
+- EXPECTED_RESULT: the expected result
+--CREDITS--
+Antonio Diaz Ruiz <dejalatele@gmail.com>
+--INI--
+assert.bail=true
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--ENV--
+XML_FILE=/book_with_dtd2.xml
+LOAD_OPTIONS=LIBXML_DTDLOAD
+EXPECTED_RESULT=1
+--FILE_EXTERNAL--
+domdocumentloadxml_test_method.php
+--EXPECT--
diff --git a/ext/dom/tests/DOMDocument_loadXML_variation2.phpt b/ext/dom/tests/DOMDocument_loadXML_variation2.phpt
new file mode 100644
index 0000000000..71f638efc1
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_loadXML_variation2.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Test DOMDocument::loadXML() with LIBXML_DTDVALID option
+--DESCRIPTION--
+This test verifies the right behaviour of the LIBXML_DTDVALID constant
+Environment variables used in the test:
+- XML_FILE: the xml file to load
+- LOAD_OPTIONS: the second parameter to pass to the method
+- EXPECTED_RESULT: the expected result
+--CREDITS--
+Antonio Diaz Ruiz <dejalatele@gmail.com>
+--INI--
+assert.bail=true
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--ENV--
+XML_FILE=/wrong_book_with_dtd2.xml
+LOAD_OPTIONS=LIBXML_DTDVALID
+EXPECTED_RESULT=1
+--FILE_EXTERNAL--
+domdocumentloadxml_test_method.php
+--EXPECTF--
+Warning: DOMDocument::load%r(XML){0,1}%r(): Element book content does not follow the DTD, expecting (title , author), got (title author author ) %s
diff --git a/ext/dom/tests/DOMDocument_loadXML_variation3.phpt b/ext/dom/tests/DOMDocument_loadXML_variation3.phpt
new file mode 100644
index 0000000000..8e61ec4dbc
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_loadXML_variation3.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Test DOMDocument::loadXML() with LIBXML_DTDVALID and LIBXML_NOERROR options
+--DESCRIPTION--
+This test vrifies the right behaviour of the LIBXML_NOERROR constant
+which avoids the display of the warning message
+Environment variables used in the test:
+- XML_FILE: the xml file to load
+- LOAD_OPTIONS: the second parameter to pass to the method
+- EXPECTED_RESULT: the expected result
+--CREDITS--
+Antonio Diaz Ruiz <dejalatele@gmail.com>
+--INI--
+assert.bail=true
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--ENV--
+XML_FILE=/wrong_book_with_dtd.xml
+LOAD_OPTIONS=LIBXML_DTDVALID | LIBXML_NOERROR
+EXPECTED_RESULT=1
+--FILE_EXTERNAL--
+domdocumentloadxml_test_method.php
+--EXPECT--
diff --git a/ext/dom/tests/DOMDocument_loadXML_variation4.phpt b/ext/dom/tests/DOMDocument_loadXML_variation4.phpt
new file mode 100644
index 0000000000..4f1ea37c19
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_loadXML_variation4.phpt
@@ -0,0 +1,32 @@
+--TEST--
+Test DOMDocument::loadXML() with LIBXML_DTDATTR, LIBXML_NOCDATA, LIBXML_NOENT, LIBXML_NOBLANKS
+--DESCRIPTION--
+This test verifies the right behaviour of the following constants:
+LIBXML_DTDATTR, LIBXML_NOCDATA, LIBXML_NOENT and LIBXML_NOBLANKS
+Environment variables used in the test:
+- XML_FILE: the xml file to load
+- LOAD_OPTIONS: the second parameter to pass to the method
+- EXPECTED_RESULT: the expected result
+--CREDITS--
+Antonio Diaz Ruiz <dejalatele@gmail.com>
+--INI--
+assert.bail=true
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--ENV--
+XML_FILE=/book_with_dtd2.xml
+LOAD_OPTIONS=LIBXML_DTDATTR|LIBXML_NOCDATA|LIBXML_NOENT|LIBXML_NOBLANKS
+EXPECTED_RESULT=1
+--FILE_EXTERNAL--
+domdocumentloadxml_test_method_savexml.php
+--EXPECT--
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE books [
+<!ENTITY entitest "entity is only for test purposes">
+<!ATTLIST title default CDATA "default title">
+<!ELEMENT books (book)*>
+<!ELEMENT book (title , author)>
+<!ELEMENT title (#PCDATA)>
+<!ELEMENT author (#PCDATA)>
+]>
+<books><book><title default="default title">The Grapes of Wrath</title><author>John Steinbeck</author></book><book><title default="default title">The Pearl</title><author>John Steinbeck</author></book><book><title default="default title">entity is only for test purposes</title><author>data for test</author></book></books>
diff --git a/ext/dom/tests/DOMDocument_load_basic.phpt b/ext/dom/tests/DOMDocument_load_basic.phpt
new file mode 100644
index 0000000000..6d70ed4522
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_load_basic.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Test DOMDocument::load() basic behavior
+--DESCRIPTION--
+This test verifies the basic behaviour of the method
+Environment variables used in the test:
+- XML_FILE: the xml file to load
+- LOAD_OPTIONS: the second parameter to pass to the method
+- EXPECTED_RESULT: the expected result
+--CREDITS--
+Antonio Diaz Ruiz <dejalatele@gmail.com>
+--INI--
+assert.bail=true
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--ENV--
+XML_FILE=/book.xml
+LOAD_OPTIONS=0
+EXPECTED_RESULT=1
+--FILE_EXTERNAL--
+domdocumentload_test_method.php
+--EXPECT--
diff --git a/ext/dom/tests/DOMDocument_load_error1.phpt b/ext/dom/tests/DOMDocument_load_error1.phpt
new file mode 100644
index 0000000000..2ac3f50979
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_load_error1.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Test DOMDocument::load() detects not-well formed XML
+--DESCRIPTION--
+This test verifies the method detects an opening and ending tag mismatch
+Environment variables used in the test:
+- XML_FILE: the xml file to load
+- LOAD_OPTIONS: the second parameter to pass to the method
+- EXPECTED_RESULT: the expected result
+--CREDITS--
+Antonio Diaz Ruiz <dejalatele@gmail.com>
+--INI--
+assert.bail=true
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--ENV--
+XML_FILE=/not_well_formed.xml
+LOAD_OPTIONS=0
+EXPECTED_RESULT=0
+--FILE_EXTERNAL--
+domdocumentload_test_method.php
+--EXPECTF--
+Warning: DOMDocument::load%r(XML){0,1}%r(): Opening and ending tag mismatch: title line 5 and book %s
+
+Warning: DOMDocument::load%r(XML){0,1}%r(): expected '>' %s
+
+Warning: DOMDocument::load%r(XML){0,1}%r(): Premature end of data in tag books %s
diff --git a/ext/dom/tests/DOMDocument_load_error2.phpt b/ext/dom/tests/DOMDocument_load_error2.phpt
new file mode 100644
index 0000000000..23a5e4827d
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_load_error2.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Test DOMDocument::load() detects not-well formed XML
+--DESCRIPTION--
+This test verifies the method detects attributes values not closed between " or '
+Environment variables used in the test:
+- XML_FILE: the xml file to load
+- LOAD_OPTIONS: the second parameter to pass to the method
+- EXPECTED_RESULT: the expected result
+--CREDITS--
+Antonio Diaz Ruiz <dejalatele@gmail.com>
+--INI--
+assert.bail=true
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--ENV--
+XML_FILE=/not_well_formed2.xml
+LOAD_OPTIONS=0
+EXPECTED_RESULT=0
+--FILE_EXTERNAL--
+domdocumentload_test_method.php
+--EXPECTF--
+Warning: DOMDocument::load%r(XML){0,1}%r(): AttValue: " or ' expected %s
+
+Warning: DOMDocument::load%r(XML){0,1}%r(): attributes construct error %s
+
+Warning: DOMDocument::load%r(XML){0,1}%r(): Couldn't find end of Start Tag book %s
+
+Warning: DOMDocument::load%r(XML){0,1}%r(): Opening and ending tag mismatch: books %s
+
+Warning: DOMDocument::load%r(XML){0,1}%r(): Extra content at the end of the document %s
diff --git a/ext/dom/tests/DOMDocument_load_error3.phpt b/ext/dom/tests/DOMDocument_load_error3.phpt
new file mode 100644
index 0000000000..b9ac49c466
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_load_error3.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Test DOMDocument::load() detects not-well formed XML
+--DESCRIPTION--
+This test verifies the method detects and opening and ending tag mismatch
+Environment variables used in the test:
+- XML_FILE: the xml file to load
+- LOAD_OPTIONS: the second parameter to pass to the method
+- EXPECTED_RESULT: the expected result
+--CREDITS--
+Antonio Diaz Ruiz <dejalatele@gmail.com>
+--INI--
+assert.bail=true
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--ENV--
+XML_FILE=/not_well_formed3.xml
+LOAD_OPTIONS=0
+EXPECTED_RESULT=0
+--FILE_EXTERNAL--
+domdocumentload_test_method.php
+--EXPECTF--
+Warning: DOMDocument::load%r(XML){0,1}%r(): Opening and ending tag mismatch: boOk line 8 and book %s
diff --git a/ext/dom/tests/DOMDocument_load_error4.phpt b/ext/dom/tests/DOMDocument_load_error4.phpt
new file mode 100644
index 0000000000..ca9ed79a3e
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_load_error4.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Test DOMDocument::load() detects not-well formed XML
+--DESCRIPTION--
+This test verifies the method detects an unsupported xml version
+Environment variables used in the test:
+- XML_FILE: the xml file to load
+- LOAD_OPTIONS: the second parameter to pass to the method
+- EXPECTED_RESULT: the expected result
+--CREDITS--
+Antonio Diaz Ruiz <dejalatele@gmail.com>
+--INI--
+assert.bail=true
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--ENV--
+XML_FILE=/not_well_formed4.xml
+LOAD_OPTIONS=0
+EXPECTED_RESULT=0
+--FILE_EXTERNAL--
+domdocumentload_test_method.php
+--EXPECTF--
+Warning: DOMDocument::load%r(XML){0,1}%r(): Unsupported version '3.1' %s
diff --git a/ext/dom/tests/DOMDocument_load_error5.phpt b/ext/dom/tests/DOMDocument_load_error5.phpt
new file mode 100644
index 0000000000..a374f9474d
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_load_error5.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Test DOMDocument::load() detects not-well formed XML
+--DESCRIPTION--
+This test verifies the method detects extra content at the end of the document
+Environment variables used in the test:
+- XML_FILE: the xml file to load
+- LOAD_OPTIONS: the second parameter to pass to the method
+- EXPECTED_RESULT: the expected result
+--CREDITS--
+Antonio Diaz Ruiz <dejalatele@gmail.com>
+--INI--
+assert.bail=true
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--ENV--
+XML_FILE=/not_well_formed5.xml
+LOAD_OPTIONS=0
+EXPECTED_RESULT=0
+--FILE_EXTERNAL--
+domdocumentload_test_method.php
+--EXPECTF--
+Warning: DOMDocument::load%r(XML){0,1}%r(): Extra content at the end of the document %s
diff --git a/ext/dom/tests/DOMDocument_load_variation1.phpt b/ext/dom/tests/DOMDocument_load_variation1.phpt
new file mode 100644
index 0000000000..b2b99e74c7
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_load_variation1.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Test DOMDocument::load() with LIBXML_DTDLOAD option
+--DESCRIPTION--
+This test verifies the right behaviour of the LIBXML_DTDLOAD constant
+Environment variables used in the test:
+- XML_FILE: the xml file to load
+- LOAD_OPTIONS: the second parameter to pass to the method
+- EXPECTED_RESULT: the expected result
+--CREDITS--
+Antonio Diaz Ruiz <dejalatele@gmail.com>
+--INI--
+assert.bail=true
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--ENV--
+XML_FILE=/book_with_dtd.xml
+LOAD_OPTIONS=LIBXML_DTDLOAD
+EXPECTED_RESULT=1
+--FILE_EXTERNAL--
+domdocumentload_test_method.php
+--EXPECT--
diff --git a/ext/dom/tests/DOMDocument_load_variation2.phpt b/ext/dom/tests/DOMDocument_load_variation2.phpt
new file mode 100644
index 0000000000..c8460e55eb
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_load_variation2.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Test DOMDocument::load() with LIBXML_DTDVALID option
+--DESCRIPTION--
+This test verifies the right behaviour of the LIBXML_DTDVALID constant
+Environment variables used in the test:
+- XML_FILE: the xml file to load
+- LOAD_OPTIONS: the second parameter to pass to the method
+- EXPECTED_RESULT: the expected result
+--CREDITS--
+Antonio Diaz Ruiz <dejalatele@gmail.com>
+--INI--
+assert.bail=true
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--ENV--
+XML_FILE=/wrong_book_with_dtd.xml
+LOAD_OPTIONS=LIBXML_DTDVALID
+EXPECTED_RESULT=1
+--FILE_EXTERNAL--
+domdocumentload_test_method.php
+--EXPECTF--
+Warning: DOMDocument::load%r(XML){0,1}%r(): Element book content does not follow the DTD, expecting (title , author), got (title author author ) %s
diff --git a/ext/dom/tests/DOMDocument_load_variation3.phpt b/ext/dom/tests/DOMDocument_load_variation3.phpt
new file mode 100644
index 0000000000..77801d475e
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_load_variation3.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Test DOMDocument::load() with LIBXML_DTDVALID and LIBXML_NOERROR options
+--DESCRIPTION--
+This test vrifies the right behaviour of the LIBXML_NOERROR constant
+which avoids the display of the warning message
+Environment variables used in the test:
+- XML_FILE: the xml file to load
+- LOAD_OPTIONS: the second parameter to pass to the method
+- EXPECTED_RESULT: the expected result
+--CREDITS--
+Antonio Diaz Ruiz <dejalatele@gmail.com>
+--INI--
+assert.bail=true
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--ENV--
+XML_FILE=/wrong_book_with_dtd.xml
+LOAD_OPTIONS=LIBXML_DTDVALID | LIBXML_NOERROR
+EXPECTED_RESULT=1
+--FILE_EXTERNAL--
+domdocumentload_test_method.php
+--EXPECT--
diff --git a/ext/dom/tests/DOMDocument_load_variation4.phpt b/ext/dom/tests/DOMDocument_load_variation4.phpt
new file mode 100644
index 0000000000..3bf7ccc04d
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_load_variation4.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Test DOMDocument::load() with LIBXML_DTDATTR, LIBXML_NOCDATA, LIBXML_NOENT, LIBXML_NOBLANKS
+--DESCRIPTION--
+This test verifies the right behaviour of the following constants:
+LIBXML_DTDATTR, LIBXML_NOCDATA, LIBXML_NOENT and LIBXML_NOBLANKS
+Environment variables used in the test:
+- XML_FILE: the xml file to load
+- LOAD_OPTIONS: the second parameter to pass to the method
+- EXPECTED_RESULT: the expected result
+--CREDITS--
+Antonio Diaz Ruiz <dejalatele@gmail.com>
+--INI--
+assert.bail=true
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--ENV--
+XML_FILE=/book_with_dtd.xml
+LOAD_OPTIONS=LIBXML_DTDATTR|LIBXML_NOCDATA|LIBXML_NOENT|LIBXML_NOBLANKS
+EXPECTED_RESULT=1
+--FILE_EXTERNAL--
+domdocumentload_test_method_savexml.php
+--EXPECT--
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE books SYSTEM "books.dtd">
+<books><book><title default="default title">The Grapes of Wrath</title><author>John Steinbeck</author></book><book><title default="default title">The Pearl</title><author>John Steinbeck</author></book><book><title default="default title">entity is only for test purposes</title><author>data for test</author></book></books>
diff --git a/ext/dom/tests/DOMDocument_schemaValidateSource_addAttrs.phpt b/ext/dom/tests/DOMDocument_schemaValidateSource_addAttrs.phpt
new file mode 100644
index 0000000000..994b94d0c8
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_schemaValidateSource_addAttrs.phpt
@@ -0,0 +1,25 @@
+--TEST--
+DomDocument::schemaValidateSource() - Add missing attribute default values from schema
+--CREDITS--
+Chris Wright <info@daverandom.com>
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$doc = new DOMDocument;
+
+$doc->load(dirname(__FILE__)."/book-attr.xml");
+
+$xsd = file_get_contents(dirname(__FILE__)."/book.xsd");
+
+$doc->schemaValidateSource($xsd, LIBXML_SCHEMA_CREATE);
+
+foreach ($doc->getElementsByTagName('book') as $book) {
+ var_dump($book->getAttribute('is-hardback'));
+}
+
+?>
+--EXPECT--
+string(5) "false"
+string(4) "true"
diff --git a/ext/dom/tests/DOMDocument_schemaValidateSource_error4.phpt b/ext/dom/tests/DOMDocument_schemaValidateSource_error4.phpt
index 65c8d8678f..f841b87428 100644
--- a/ext/dom/tests/DOMDocument_schemaValidateSource_error4.phpt
+++ b/ext/dom/tests/DOMDocument_schemaValidateSource_error4.phpt
@@ -17,5 +17,5 @@ var_dump($result);
?>
--EXPECTF--
-Warning: DOMDocument::schemaValidateSource() expects exactly 1 parameter, 0 given in %s.php on line %d
+Warning: DOMDocument::schemaValidateSource() expects at least 1 parameter, 0 given in %s.php on line %d
NULL
diff --git a/ext/dom/tests/DOMDocument_schemaValidateSource_missingAttrs.phpt b/ext/dom/tests/DOMDocument_schemaValidateSource_missingAttrs.phpt
new file mode 100644
index 0000000000..7c98a74b1d
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_schemaValidateSource_missingAttrs.phpt
@@ -0,0 +1,25 @@
+--TEST--
+DomDocument::schemaValidateSource() - Don't add missing attribute default values from schema
+--CREDITS--
+Chris Wright <info@daverandom.com>
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$doc = new DOMDocument;
+
+$doc->load(dirname(__FILE__)."/book-attr.xml");
+
+$xsd = file_get_contents(dirname(__FILE__)."/book.xsd");
+
+$doc->schemaValidateSource($xsd);
+
+foreach ($doc->getElementsByTagName('book') as $book) {
+ var_dump($book->getAttribute('is-hardback'));
+}
+
+?>
+--EXPECT--
+string(0) ""
+string(4) "true"
diff --git a/ext/dom/tests/DOMDocument_schemaValidate_addAttrs.phpt b/ext/dom/tests/DOMDocument_schemaValidate_addAttrs.phpt
new file mode 100644
index 0000000000..e0b5251b23
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_schemaValidate_addAttrs.phpt
@@ -0,0 +1,23 @@
+--TEST--
+DomDocument::schemaValidate() - Add missing attribute default values from schema
+--CREDITS--
+Chris Wright <info@daverandom.com>
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$doc = new DOMDocument;
+
+$doc->load(dirname(__FILE__)."/book-attr.xml");
+
+$doc->schemaValidate(dirname(__FILE__)."/book.xsd", LIBXML_SCHEMA_CREATE);
+
+foreach ($doc->getElementsByTagName('book') as $book) {
+ var_dump($book->getAttribute('is-hardback'));
+}
+
+?>
+--EXPECT--
+string(5) "false"
+string(4) "true"
diff --git a/ext/dom/tests/DOMDocument_schemaValidate_error4.phpt b/ext/dom/tests/DOMDocument_schemaValidate_error4.phpt
index d4817deca0..9e4b6c4b7c 100644
--- a/ext/dom/tests/DOMDocument_schemaValidate_error4.phpt
+++ b/ext/dom/tests/DOMDocument_schemaValidate_error4.phpt
@@ -17,5 +17,5 @@ var_dump($result);
?>
--EXPECTF--
-Warning: DOMDocument::schemaValidate() expects exactly 1 parameter, 0 given in %s.php on line %d
+Warning: DOMDocument::schemaValidate() expects at least 1 parameter, 0 given in %s.php on line %d
NULL
diff --git a/ext/dom/tests/DOMDocument_schemaValidate_missingAttrs.phpt b/ext/dom/tests/DOMDocument_schemaValidate_missingAttrs.phpt
new file mode 100644
index 0000000000..d253ad9690
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_schemaValidate_missingAttrs.phpt
@@ -0,0 +1,23 @@
+--TEST--
+DomDocument::schemaValidate() - Don't add missing attribute default values from schema
+--CREDITS--
+Chris Wright <info@daverandom.com>
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+$doc = new DOMDocument;
+
+$doc->load(dirname(__FILE__)."/book-attr.xml");
+
+$doc->schemaValidate(dirname(__FILE__)."/book.xsd");
+
+foreach ($doc->getElementsByTagName('book') as $book) {
+ var_dump($book->getAttribute('is-hardback'));
+}
+
+?>
+--EXPECT--
+string(0) ""
+string(4) "true"
diff --git a/ext/dom/tests/book-attr.xml b/ext/dom/tests/book-attr.xml
new file mode 100644
index 0000000000..ba4298d098
--- /dev/null
+++ b/ext/dom/tests/book-attr.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" ?>
+<books>
+ <book>
+ <title>The Grapes of Wrath</title>
+ <author>John Steinbeck</author>
+ </book>
+ <book is-hardback="true">
+ <title>The Pearl</title>
+ <author>John Steinbeck</author>
+ </book>
+</books>
diff --git a/ext/dom/tests/book.xsd b/ext/dom/tests/book.xsd
index 45986fc4b3..6b4a8ea545 100755
--- a/ext/dom/tests/book.xsd
+++ b/ext/dom/tests/book.xsd
@@ -9,6 +9,7 @@
<xs:element name="title" type="xs:string"/>
<xs:element name="author" type="xs:string"/>
</xs:sequence>
+ <xs:attribute name="is-hardback" type="xs:boolean" default="false" use="optional" />
</xs:complexType>
</xs:element>
</xs:sequence>
diff --git a/ext/dom/tests/book_with_dtd.xml b/ext/dom/tests/book_with_dtd.xml
new file mode 100644
index 0000000000..de12e92102
--- /dev/null
+++ b/ext/dom/tests/book_with_dtd.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE books SYSTEM "books.dtd">
+<books>
+ <book>
+ <title>The Grapes of Wrath</title>
+ <author>John Steinbeck</author>
+ </book>
+ <book>
+ <title>The Pearl</title>
+ <author>John Steinbeck</author>
+ </book>
+ <book>
+ <title>&entitest;</title>
+ <author><![CDATA[data for test]]></author>
+ </book>
+</books>
diff --git a/ext/dom/tests/book_with_dtd2.xml b/ext/dom/tests/book_with_dtd2.xml
new file mode 100644
index 0000000000..aeb4f0b800
--- /dev/null
+++ b/ext/dom/tests/book_with_dtd2.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE books [
+<!ENTITY entitest "entity is only for test purposes">
+<!ATTLIST title default CDATA "default title">
+<!ELEMENT books (book*)>
+<!ELEMENT book (title, author)>
+<!ELEMENT title (#PCDATA)>
+<!ELEMENT author (#PCDATA)>
+]>
+<books>
+ <book>
+ <title>The Grapes of Wrath</title>
+ <author>John Steinbeck</author>
+ </book>
+ <book>
+ <title>The Pearl</title>
+ <author>John Steinbeck</author>
+ </book>
+ <book>
+ <title>&entitest;</title>
+ <author><![CDATA[data for test]]></author>
+ </book>
+</books>
diff --git a/ext/dom/tests/books.dtd b/ext/dom/tests/books.dtd
new file mode 100644
index 0000000000..b3f03c1c16
--- /dev/null
+++ b/ext/dom/tests/books.dtd
@@ -0,0 +1,7 @@
+<!ENTITY entitest "entity is only for test purposes">
+<!ATTLIST title
+ default CDATA "default title">
+ <!ELEMENT books (book*)>
+ <!ELEMENT book (title, author)>
+ <!ELEMENT title (#PCDATA)>
+ <!ELEMENT author (#PCDATA)>
diff --git a/ext/dom/tests/domdocumentload_test_method.php b/ext/dom/tests/domdocumentload_test_method.php
new file mode 100644
index 0000000000..7afce15c3a
--- /dev/null
+++ b/ext/dom/tests/domdocumentload_test_method.php
@@ -0,0 +1,12 @@
+<?php
+include(dirname(__FILE__) . '/domdocumentload_utilities.php');
+
+$doc = new DOMDocument();
+
+$libxml_options = libxml_options_to_int(getenv('LOAD_OPTIONS'));
+
+$result = $doc->load(dirname(__FILE__) . getenv('XML_FILE'), $libxml_options);
+
+$expectedResult = (bool) getenv('EXPECTED_RESULT');
+assert('$result === $expectedResult');
+?>
diff --git a/ext/dom/tests/domdocumentload_test_method_savexml.php b/ext/dom/tests/domdocumentload_test_method_savexml.php
new file mode 100644
index 0000000000..8ffd944524
--- /dev/null
+++ b/ext/dom/tests/domdocumentload_test_method_savexml.php
@@ -0,0 +1,14 @@
+<?php
+include(dirname(__FILE__) . '/domdocumentload_utilities.php');
+
+$doc = new DOMDocument();
+
+$libxml_options = libxml_options_to_int(getenv('LOAD_OPTIONS'));
+
+$result = $doc->load(dirname(__FILE__) . getenv('XML_FILE'), $libxml_options);
+
+$expectedResult = (bool) getenv('EXPECTED_RESULT');
+assert('$result === $expectedResult');
+
+echo $doc->saveXML();
+?>
diff --git a/ext/dom/tests/domdocumentload_utilities.php b/ext/dom/tests/domdocumentload_utilities.php
new file mode 100644
index 0000000000..efd1e5a1a5
--- /dev/null
+++ b/ext/dom/tests/domdocumentload_utilities.php
@@ -0,0 +1,16 @@
+<?php
+
+function libxml_options_to_int($libxmlOptions) {
+
+ $defined_constants = get_defined_constants(true);
+ $env_array = explode('|', $libxmlOptions);
+ $libxml_constants = array_intersect_key($defined_constants['libxml'], array_flip($env_array));
+
+ $sum = 0;
+ foreach($libxml_constants as $value) {
+ $sum = $sum|$value;
+ }
+
+ return $sum;
+}
+?>
diff --git a/ext/dom/tests/domdocumentloadxml_test_method.php b/ext/dom/tests/domdocumentloadxml_test_method.php
new file mode 100644
index 0000000000..7c4be85cf1
--- /dev/null
+++ b/ext/dom/tests/domdocumentloadxml_test_method.php
@@ -0,0 +1,12 @@
+<?php
+include(dirname(__FILE__) . '/domdocumentload_utilities.php');
+
+$doc = new DOMDocument();
+
+$libxml_options = libxml_options_to_int(getenv('LOAD_OPTIONS'));
+$result = $doc->loadXML(file_get_contents(dirname(__FILE__) . getenv('XML_FILE')),
+ $libxml_options);
+
+$expectedResult = (bool) getenv('EXPECTED_RESULT');
+assert('$result === $expectedResult');
+?>
diff --git a/ext/dom/tests/domdocumentloadxml_test_method_savexml.php b/ext/dom/tests/domdocumentloadxml_test_method_savexml.php
new file mode 100644
index 0000000000..550219fb78
--- /dev/null
+++ b/ext/dom/tests/domdocumentloadxml_test_method_savexml.php
@@ -0,0 +1,14 @@
+<?php
+include(dirname(__FILE__) . '/domdocumentload_utilities.php');
+
+$doc = new DOMDocument();
+
+$libxml_options = libxml_options_to_int(getenv('LOAD_OPTIONS'));
+$result = $doc->loadXML(file_get_contents(dirname(__FILE__) . getenv('XML_FILE')),
+ $libxml_options);
+
+$expectedResult = (bool) getenv('EXPECTED_RESULT');
+assert('$result === $expectedResult');
+
+echo $doc->saveXML();
+?>
diff --git a/ext/dom/tests/not_well_formed.xml b/ext/dom/tests/not_well_formed.xml
new file mode 100644
index 0000000000..d362e0c4b9
--- /dev/null
+++ b/ext/dom/tests/not_well_formed.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" ?>
+<!-- Opening and ending tag mismatch -->
+<books>
+ <book>
+ <title>The Grapes of Wrath
+ <author>John Steinbeck</author>
+ </book>
+ <book>
+ <title>The Pearl</title>
+ <author>John Steinbeck</author>
+ </book>
+</books>
diff --git a/ext/dom/tests/not_well_formed2.xml b/ext/dom/tests/not_well_formed2.xml
new file mode 100644
index 0000000000..da6b3bccba
--- /dev/null
+++ b/ext/dom/tests/not_well_formed2.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" ?>
+<!-- AttValue: " or ' expected -->
+<books>
+ <book number=nine>
+ <title>The Grapes of Wrath</title>
+ <author>John Steinbeck</author>
+ </book>
+ <book>
+ <title>The Pearl</title>
+ <author>John Steinbeck</author>
+ </book>
+</books>
diff --git a/ext/dom/tests/not_well_formed3.xml b/ext/dom/tests/not_well_formed3.xml
new file mode 100644
index 0000000000..99b2189074
--- /dev/null
+++ b/ext/dom/tests/not_well_formed3.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" ?>
+<!-- Opening and ending tag mismatch -->
+<books>
+ <book>
+ <title>The Grapes of Wrath</title>
+ <author>John Steinbeck</author>
+ </book>
+ <boOk>
+ <title>The Pearl</title>
+ <author>John Steinbeck</author>
+ </book>
+</books>
diff --git a/ext/dom/tests/not_well_formed4.xml b/ext/dom/tests/not_well_formed4.xml
new file mode 100644
index 0000000000..581b8bd962
--- /dev/null
+++ b/ext/dom/tests/not_well_formed4.xml
@@ -0,0 +1,12 @@
+<?xml version="3.1" ?>
+<!-- Unsupported version '3.1' -->
+<books>
+ <book>
+ <title>The Grapes of Wrath</title>
+ <author>John Steinbeck</author>
+ </book>
+ <book>
+ <title>The Pearl</title>
+ <author>John Steinbeck</author>
+ </book>
+</books>
diff --git a/ext/dom/tests/not_well_formed5.xml b/ext/dom/tests/not_well_formed5.xml
new file mode 100644
index 0000000000..f42ead83ab
--- /dev/null
+++ b/ext/dom/tests/not_well_formed5.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" ?>
+<!-- Extra content at the end of the document -->
+ <book>
+ <title>The Grapes of Wrath</title>
+ <author>John Steinbeck</author>
+ </book>
+ <book>
+ <title>The Pearl</title>
+ <author>John Steinbeck</author>
+ </book>
diff --git a/ext/dom/tests/wrong_book_with_dtd.xml b/ext/dom/tests/wrong_book_with_dtd.xml
new file mode 100644
index 0000000000..3a2d48e355
--- /dev/null
+++ b/ext/dom/tests/wrong_book_with_dtd.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE books SYSTEM "books.dtd">
+<books>
+ <book>
+ <title>The Grapes of Wrath</title>
+ <author>John Steinbeck</author>
+ <author>John Steinbeck</author>
+ </book>
+ <book>
+ <title>The Pearl</title>
+ <author>John Steinbeck</author>
+ </book>
+</books>
diff --git a/ext/dom/tests/wrong_book_with_dtd2.xml b/ext/dom/tests/wrong_book_with_dtd2.xml
new file mode 100644
index 0000000000..6c49deb1f5
--- /dev/null
+++ b/ext/dom/tests/wrong_book_with_dtd2.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE books [
+<!ENTITY entitest "entity is only for test purposes">
+<!ATTLIST title default CDATA "default title">
+<!ELEMENT books (book)*>
+<!ELEMENT book (title , author)>
+<!ELEMENT title (#PCDATA)>
+<!ELEMENT author (#PCDATA)>
+]>
+<books>
+ <book>
+ <title>The Grapes of Wrath</title>
+ <author>John Steinbeck</author>
+ <author>John Steinbeck</author>
+ </book>
+ <book>
+ <title>The Pearl</title>
+ <author>John Steinbeck</author>
+ </book>
+</books>
diff --git a/ext/enchant/config.m4 b/ext/enchant/config.m4
index cc40d0bd03..db8a69c5d1 100755
--- a/ext/enchant/config.m4
+++ b/ext/enchant/config.m4
@@ -3,7 +3,7 @@ dnl $Id$
dnl
PHP_ARG_WITH(enchant,for ENCHANT support,
-[ --with-enchant[=DIR] Include enchant support.
+[ --with-enchant[=DIR] Include enchant support.
GNU Aspell version 1.1.3 or higher required.])
if test "$PHP_ENCHANT" != "no"; then
diff --git a/ext/ereg/config0.m4 b/ext/ereg/config0.m4
index f4f8190932..caec39d285 100644
--- a/ext/ereg/config0.m4
+++ b/ext/ereg/config0.m4
@@ -5,7 +5,7 @@ dnl
dnl Check for regex library type
dnl
PHP_ARG_WITH(regex,,
-[ --with-regex=TYPE regex library type: system, php. [TYPE=php]
+[ --with-regex=TYPE Regex library type: system, php. [TYPE=php]
WARNING: Do NOT use unless you know what you are doing!], php, no)
case $PHP_REGEX in
diff --git a/ext/ereg/regex.patch b/ext/ereg/regex.patch
new file mode 100644
index 0000000000..864e6bb6d8
--- /dev/null
+++ b/ext/ereg/regex.patch
@@ -0,0 +1,72 @@
+diff -u regex.orig/regerror.c regex/regerror.c
+--- regex.orig/regerror.c 2011-08-09 19:49:30.000000000 +0800
++++ regex/regerror.c 2011-08-12 10:45:57.000000000 +0800
+@@ -8,6 +8,7 @@
+ #include "regex.h"
+ #include "utils.h"
+ #include "regerror.ih"
++#include "php.h"
+
+ /*
+ = #define REG_OKAY 0
+@@ -74,17 +75,19 @@
+ char convbuf[50];
+
+ if (errcode == REG_ATOI)
+- s = regatoi(preg, convbuf);
++ s = regatoi(preg, convbuf, sizeof(convbuf));
+ else {
+ for (r = rerrs; r->code >= 0; r++)
+ if (r->code == target)
+ break;
+
+ if (errcode&REG_ITOA) {
+- if (r->code >= 0)
+- (void) strcpy(convbuf, r->name);
+- else
+- sprintf(convbuf, "REG_0x%x", target);
++ if (r->code >= 0) {
++ (void) strncpy(convbuf, r->name, sizeof(convbuf) - 1);
++ convbuf[sizeof(convbuf) - 1] = '\0';
++ } else {
++ snprintf(convbuf, sizeof(convbuf), "REG_0x%x", target);
++ }
+ assert(strlen(convbuf) < sizeof(convbuf));
+ s = convbuf;
+ } else
+@@ -106,12 +109,13 @@
+
+ /*
+ - regatoi - internal routine to implement REG_ATOI
+- == static char *regatoi(const regex_t *preg, char *localbuf);
++ == static char *regatoi(const regex_t *preg, char *localbuf, int bufsize);
+ */
+ static char *
+-regatoi(preg, localbuf)
++regatoi(preg, localbuf, bufsize)
+ const regex_t *preg;
+ char *localbuf;
++int bufsize;
+ {
+ register const struct rerr *r;
+
+@@ -121,6 +125,6 @@
+ if (r->code < 0)
+ return("0");
+
+- sprintf(localbuf, "%d", r->code);
++ snprintf(localbuf, bufsize, "%d", r->code);
+ return(localbuf);
+ }
+diff -u regex.orig/regerror.ih regex/regerror.ih
+--- regex.orig/regerror.ih 2011-08-09 19:49:00.000000000 +0800
++++ regex/regerror.ih 2011-08-09 19:41:07.000000000 +0800
+@@ -4,7 +4,7 @@
+ #endif
+
+ /* === regerror.c === */
+-static char *regatoi(const regex_t *preg, char *localbuf);
++static char *regatoi(const regex_t *preg, char *localbuf, int bufsize);
+
+ #ifdef __cplusplus
+ }
diff --git a/ext/ereg/tests/split_variation_004.phpt b/ext/ereg/tests/split_variation_004.phpt
index 1fa71edd38..d3d2de84a3 100644
--- a/ext/ereg/tests/split_variation_004.phpt
+++ b/ext/ereg/tests/split_variation_004.phpt
@@ -18,7 +18,6 @@ $pattern = '[[:space:]]';
$string = '1 2 3 4 5';
var_dump(split($pattern, $string, 0));
var_dump(split($pattern, $string, -10));
-var_dump(split($pattern, $string, 10E20));
echo "Done";
@@ -35,9 +34,4 @@ array(1) {
[0]=>
string(9) "1 2 3 4 5"
}
-Error: 8192 - Function split() is deprecated, %s(18)
-array(1) {
- [0]=>
- string(9) "1 2 3 4 5"
-}
Done
diff --git a/ext/ereg/tests/spliti_variation_004.phpt b/ext/ereg/tests/spliti_variation_004.phpt
index b6bf227ba0..d9afa13892 100644
--- a/ext/ereg/tests/spliti_variation_004.phpt
+++ b/ext/ereg/tests/spliti_variation_004.phpt
@@ -18,7 +18,6 @@ $pattern = '[[:space:]]';
$string = '1 2 3 4 5';
var_dump(spliti($pattern, $string, 0));
var_dump(spliti($pattern, $string, -10));
-var_dump(spliti($pattern, $string, 10E20));
echo "Done";
@@ -35,9 +34,4 @@ array(1) {
[0]=>
string(9) "1 2 3 4 5"
}
-Error: 8192 - Function spliti() is deprecated, %s(18)
-array(1) {
- [0]=>
- string(9) "1 2 3 4 5"
-}
Done
diff --git a/ext/fileinfo/libmagic/print.c b/ext/fileinfo/libmagic/print.c
index 63e34bee0e..eb4e6e8ce4 100644
--- a/ext/fileinfo/libmagic/print.c
+++ b/ext/fileinfo/libmagic/print.c
@@ -28,7 +28,6 @@
/*
* print.c - debugging printout routines
*/
-
#define _GNU_SOURCE
#include "php.h"
diff --git a/ext/fileinfo/php_fileinfo.h b/ext/fileinfo/php_fileinfo.h
index 354ec7b284..d8dec121d6 100644
--- a/ext/fileinfo/php_fileinfo.h
+++ b/ext/fileinfo/php_fileinfo.h
@@ -24,7 +24,7 @@
extern zend_module_entry fileinfo_module_entry;
#define phpext_fileinfo_ptr &fileinfo_module_entry
-#define PHP_FILEINFO_VERSION "1.0.5"
+#define PHP_FILEINFO_VERSION "1.0.5-dev"
#ifdef PHP_WIN32
#define PHP_FILEINFO_API __declspec(dllexport)
diff --git a/ext/filter/config.m4 b/ext/filter/config.m4
index b4e32a21a4..676f5d99ef 100644
--- a/ext/filter/config.m4
+++ b/ext/filter/config.m4
@@ -5,7 +5,7 @@ PHP_ARG_ENABLE(filter, whether to enable input filter support,
[ --disable-filter Disable input filter support], yes)
PHP_ARG_WITH(pcre-dir, pcre install prefix,
-[ --with-pcre-dir FILTER: pcre install prefix], no, no)
+[ --with-pcre-dir FILTER: pcre install prefix], no, no)
if test "$PHP_FILTER" != "no"; then
diff --git a/ext/filter/filter.c b/ext/filter/filter.c
index ad78b4a085..4d3899e089 100644
--- a/ext/filter/filter.c
+++ b/ext/filter/filter.c
@@ -47,6 +47,7 @@ static const filter_list_entry filter_list[] = {
{ "validate_url", FILTER_VALIDATE_URL, php_filter_validate_url },
{ "validate_email", FILTER_VALIDATE_EMAIL, php_filter_validate_email },
{ "validate_ip", FILTER_VALIDATE_IP, php_filter_validate_ip },
+ { "validate_mac", FILTER_VALIDATE_MAC, php_filter_validate_mac },
{ "string", FILTER_SANITIZE_STRING, php_filter_string },
{ "stripped", FILTER_SANITIZE_STRING, php_filter_string },
@@ -233,6 +234,7 @@ PHP_MINIT_FUNCTION(filter)
REGISTER_LONG_CONSTANT("FILTER_VALIDATE_URL", FILTER_VALIDATE_URL, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("FILTER_VALIDATE_EMAIL", FILTER_VALIDATE_EMAIL, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("FILTER_VALIDATE_IP", FILTER_VALIDATE_IP, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("FILTER_VALIDATE_MAC", FILTER_VALIDATE_MAC, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("FILTER_DEFAULT", FILTER_DEFAULT, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("FILTER_UNSAFE_RAW", FILTER_UNSAFE_RAW, CONST_CS | CONST_PERSISTENT);
diff --git a/ext/filter/filter_private.h b/ext/filter/filter_private.h
index 65ebb3622f..fc596f02ca 100644
--- a/ext/filter/filter_private.h
+++ b/ext/filter/filter_private.h
@@ -63,7 +63,8 @@
#define FILTER_VALIDATE_URL 0x0111
#define FILTER_VALIDATE_EMAIL 0x0112
#define FILTER_VALIDATE_IP 0x0113
-#define FILTER_VALIDATE_LAST 0x0113
+#define FILTER_VALIDATE_MAC 0x0114
+#define FILTER_VALIDATE_LAST 0x0114
#define FILTER_VALIDATE_ALL 0x0100
diff --git a/ext/filter/logical_filters.c b/ext/filter/logical_filters.c
index 232a26b91f..923e6f6a39 100644
--- a/ext/filter/logical_filters.c
+++ b/ext/filter/logical_filters.c
@@ -779,6 +779,67 @@ void php_filter_validate_ip(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */
}
/* }}} */
+void php_filter_validate_mac(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */
+{
+ char *input = Z_STRVAL_P(value);
+ int input_len = Z_STRLEN_P(value);
+ int tokens, length, i, offset, exp_separator_set, exp_separator_len;
+ char separator;
+ char *exp_separator;
+ long ret = 0;
+ zval **option_val;
+
+ FETCH_STRING_OPTION(exp_separator, "separator");
+
+ if (exp_separator_set && exp_separator_len != 1) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Separator must be exactly one character long");
+ RETURN_VALIDATION_FAILED;
+ }
+
+ if (14 == input_len) {
+ /* EUI-64 format: Four hexadecimal digits separated by dots. Less
+ * commonly used but valid nonetheless.
+ */
+ tokens = 3;
+ length = 4;
+ separator = '.';
+ } else if (17 == input_len && input[2] == '-') {
+ /* IEEE 802 format: Six hexadecimal digits separated by hyphens. */
+ tokens = 6;
+ length = 2;
+ separator = '-';
+ } else if (17 == input_len && input[2] == ':') {
+ /* IEEE 802 format: Six hexadecimal digits separated by colons. */
+ tokens = 6;
+ length = 2;
+ separator = ':';
+ } else {
+ RETURN_VALIDATION_FAILED;
+ }
+
+ if (exp_separator_set && separator != exp_separator[0]) {
+ RETURN_VALIDATION_FAILED;
+ }
+
+ /* Essentially what we now have is a set of tokens each consisting of
+ * a hexadecimal number followed by a separator character. (With the
+ * exception of the last token which does not have the separator.)
+ */
+ for (i = 0; i < tokens; i++) {
+ offset = i * (length + 1);
+
+ if (i < tokens - 1 && input[offset + length] != separator) {
+ /* The current token did not end with e.g. a "." */
+ RETURN_VALIDATION_FAILED
+ }
+ if (php_filter_parse_hex(input + offset, length, &ret TSRMLS_CC) < 0) {
+ /* The current token is no valid hexadecimal digit */
+ RETURN_VALIDATION_FAILED
+ }
+ }
+}
+/* }}} */
+
/*
* Local variables:
* tab-width: 4
diff --git a/ext/filter/php_filter.h b/ext/filter/php_filter.h
index f658e42fc4..37ccdd23bb 100644
--- a/ext/filter/php_filter.h
+++ b/ext/filter/php_filter.h
@@ -78,6 +78,7 @@ void php_filter_validate_regexp(PHP_INPUT_FILTER_PARAM_DECL);
void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL);
void php_filter_validate_email(PHP_INPUT_FILTER_PARAM_DECL);
void php_filter_validate_ip(PHP_INPUT_FILTER_PARAM_DECL);
+void php_filter_validate_mac(PHP_INPUT_FILTER_PARAM_DECL);
void php_filter_string(PHP_INPUT_FILTER_PARAM_DECL);
void php_filter_encoded(PHP_INPUT_FILTER_PARAM_DECL);
diff --git a/ext/filter/tests/008.phpt b/ext/filter/tests/008.phpt
index 8a4340542f..a499219ee7 100644
--- a/ext/filter/tests/008.phpt
+++ b/ext/filter/tests/008.phpt
@@ -11,7 +11,7 @@ var_dump(filter_list(array()));
echo "Done\n";
?>
--EXPECTF--
-array(19) {
+array(20) {
[0]=>
string(3) "int"
[1]=>
@@ -27,28 +27,30 @@ array(19) {
[6]=>
string(11) "validate_ip"
[7]=>
- string(6) "string"
+ string(12) "validate_mac"
[8]=>
- string(8) "stripped"
+ string(6) "string"
[9]=>
- string(7) "encoded"
+ string(8) "stripped"
[10]=>
- string(13) "special_chars"
+ string(7) "encoded"
[11]=>
- string(18) "full_special_chars"
+ string(13) "special_chars"
[12]=>
- string(10) "unsafe_raw"
+ string(18) "full_special_chars"
[13]=>
- string(5) "email"
+ string(10) "unsafe_raw"
[14]=>
- string(3) "url"
+ string(5) "email"
[15]=>
- string(10) "number_int"
+ string(3) "url"
[16]=>
- string(12) "number_float"
+ string(10) "number_int"
[17]=>
- string(12) "magic_quotes"
+ string(12) "number_float"
[18]=>
+ string(12) "magic_quotes"
+ [19]=>
string(8) "callback"
}
diff --git a/ext/filter/tests/033.phpt b/ext/filter/tests/033.phpt
index 04daa61333..d76f9ab3b8 100644
--- a/ext/filter/tests/033.phpt
+++ b/ext/filter/tests/033.phpt
@@ -10,22 +10,23 @@ default_charset=UTF-8
include dirname(__FILE__) . '/033_run.inc';
?>
--EXPECT--
-int 1 123
-boolean 1
-float 1 123
-validate_regexp O'Henry
-validate_url http://a.b.c
-validate_email foo@bar.com
-validate_ip 1.2.3.4
-string PHP 1 foo@bar.com http://a.b.c 1.2.3.4 123 123abc() O&#39;Henry 하퍼
-stripped PHP 1 foo@bar.com http://a.b.c 1.2.3.4 123 123abc() O&#39;Henry 하퍼
-encoded PHP 1 foo%40bar.com http%3A%2F%2Fa.b.c 1.2.3.4 123 123abc%3C%3E%28%29 O%27Henry %ED%95%98%ED%8D%BC
-special_chars PHP 1 foo@bar.com http://a.b.c 1.2.3.4 123 123abc&#60;&#62;() O&#39;Henry 하퍼
-full_special_chars PHP 1 foo@bar.com http://a.b.c 1.2.3.4 123 123abc&lt;&gt;() O&#039;Henry 하퍼
-unsafe_raw PHP 1 foo@bar.com http://a.b.c 1.2.3.4 123 123abc<>() O'Henry 하퍼
-email PHP 1 foo@bar.com httpa.b.c 1.2.3.4 123 123abc O'Henry
-url PHP 1 foo@bar.com http://a.b.c 1.2.3.4 123 123abc<>() O'Henry
-number_int 1 1234 123 123
-number_float 1 1234 123 123
-magic_quotes PHP 1 foo@bar.com http://a.b.c 1.2.3.4 123 123abc<>() O\'Henry 하퍼
-callback PHP 1 FOO@BAR.COM HTTP://A.B.C 1.2.3.4 123 123ABC<>() O'HENRY 하퍼
+int 1 123
+boolean 1
+float 1 123
+validate_regexp O'Henry
+validate_url http://a.b.c
+validate_email foo@bar.com
+validate_ip 1.2.3.4
+validate_mac aa:bb:cc:dd:ee:ff
+string PHP 1 foo@bar.com http://a.b.c 1.2.3.4 123 123abc() O&#39;Henry 하퍼 aa:bb:cc:dd:ee:ff
+stripped PHP 1 foo@bar.com http://a.b.c 1.2.3.4 123 123abc() O&#39;Henry 하퍼 aa:bb:cc:dd:ee:ff
+encoded PHP 1 foo%40bar.com http%3A%2F%2Fa.b.c 1.2.3.4 123 123abc%3C%3E%28%29 O%27Henry %ED%95%98%ED%8D%BCaa%3Abb%3Acc%3Add%3Aee%3Aff
+special_chars PHP 1 foo@bar.com http://a.b.c 1.2.3.4 123 123abc&#60;&#62;() O&#39;Henry 하퍼 aa:bb:cc:dd:ee:ff
+full_special_chars PHP 1 foo@bar.com http://a.b.c 1.2.3.4 123 123abc&lt;&gt;() O&#039;Henry 하퍼 aa:bb:cc:dd:ee:ff
+unsafe_raw PHP 1 foo@bar.com http://a.b.c 1.2.3.4 123 123abc<>() O'Henry 하퍼 aa:bb:cc:dd:ee:ff
+email PHP 1 foo@bar.com httpa.b.c 1.2.3.4 123 123abc O'Henry aabbccddeeff
+url PHP 1 foo@bar.com http://a.b.c 1.2.3.4 123 123abc<>() O'Henry aa:bb:cc:dd:ee:ff
+number_int 1 1234 123 123
+number_float 1 1234 123 123
+magic_quotes PHP 1 foo@bar.com http://a.b.c 1.2.3.4 123 123abc<>() O\'Henry 하퍼 aa:bb:cc:dd:ee:ff
+callback PHP 1 FOO@BAR.COM HTTP://A.B.C 1.2.3.4 123 123ABC<>() O'HENRY 하퍼 AA:BB:CC:DD:EE:FF \ No newline at end of file
diff --git a/ext/filter/tests/033_run.inc b/ext/filter/tests/033_run.inc
index e3b67387ca..ecb2cf7be1 100644
--- a/ext/filter/tests/033_run.inc
+++ b/ext/filter/tests/033_run.inc
@@ -16,7 +16,8 @@ $data = array(
"123",
"123abc<>()",
"O'Henry",
- "하퍼"
+ "하퍼",
+ "aa:bb:cc:dd:ee:ff",
);
@@ -35,6 +36,7 @@ foreach(filter_list() as $filter) {
printf("%-5s",$result[5]);
printf("%-20s",$result[6]);
printf("%-15s",$result[7]);
- printf("%-10s\n",$result[8]);
+ printf("%-10s",$result[8]);
+ printf("%-10s\n",$result[9]);
}
?>
diff --git a/ext/filter/tests/055.phpt b/ext/filter/tests/055.phpt
new file mode 100644
index 0000000000..688dbb2b54
--- /dev/null
+++ b/ext/filter/tests/055.phpt
@@ -0,0 +1,48 @@
+--TEST--
+filter_var() and FILTER_VALIDATE_MAC
+--SKIPIF--
+<?php if (!extension_loaded("filter")) die("skip"); ?>
+--FILE--
+<?php
+$values = Array(
+ array("01-23-45-67-89-ab", null),
+ array("01-23-45-67-89-ab", array("options" => array("separator" => "-"))),
+ array("01-23-45-67-89-ab", array("options" => array("separator" => "."))),
+ array("01-23-45-67-89-ab", array("options" => array("separator" => ":"))),
+ array("01-23-45-67-89-AB", null),
+ array("01-23-45-67-89-aB", null),
+ array("01:23:45:67:89:ab", null),
+ array("01:23:45:67:89:AB", null),
+ array("01:23:45:67:89:aB", null),
+ array("01:23:45-67:89:aB", null),
+ array("xx:23:45:67:89:aB", null),
+ array("0123.4567.89ab", null),
+ array("01-23-45-67-89-ab", array("options" => array("separator" => "--"))),
+ array("01-23-45-67-89-ab", array("options" => array("separator" => ""))),
+);
+foreach ($values as $value) {
+ var_dump(filter_var($value[0], FILTER_VALIDATE_MAC, $value[1]));
+}
+
+echo "Done\n";
+?>
+--EXPECTF--
+string(17) "01-23-45-67-89-ab"
+string(17) "01-23-45-67-89-ab"
+bool(false)
+bool(false)
+string(17) "01-23-45-67-89-AB"
+string(17) "01-23-45-67-89-aB"
+string(17) "01:23:45:67:89:ab"
+string(17) "01:23:45:67:89:AB"
+string(17) "01:23:45:67:89:aB"
+bool(false)
+bool(false)
+string(14) "0123.4567.89ab"
+
+Warning: filter_var(): Separator must be exactly one character long in %s055.php on line %d
+bool(false)
+
+Warning: filter_var(): Separator must be exactly one character long in %s055.php on line %d
+bool(false)
+Done
diff --git a/ext/ftp/ftp.c b/ext/ftp/ftp.c
index 3ff54ff12f..558463b845 100644
--- a/ext/ftp/ftp.c
+++ b/ext/ftp/ftp.c
@@ -794,7 +794,6 @@ int
ftp_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type, long resumepos TSRMLS_DC)
{
databuf_t *data = NULL;
- int lastch;
size_t rcvd;
char arg[11];
@@ -832,7 +831,6 @@ ftp_get(ftpbuf_t *ftp, php_stream *outstream, const char *path, ftptype_t type,
goto bail;
}
- lastch = 0;
while ((rcvd = my_recv(ftp, data->fd, data->buf, FTP_BUFSIZE))) {
if (rcvd == -1) {
goto bail;
@@ -1191,12 +1189,9 @@ ftp_readline(ftpbuf_t *ftp)
int
ftp_getresp(ftpbuf_t *ftp)
{
- char *buf;
-
if (ftp == NULL) {
return 0;
}
- buf = ftp->inbuf;
ftp->resp = 0;
while (1) {
diff --git a/ext/gd/config.m4 b/ext/gd/config.m4
index 732e14c82e..446c2425ae 100644
--- a/ext/gd/config.m4
+++ b/ext/gd/config.m4
@@ -7,12 +7,11 @@ dnl Configure options
dnl
PHP_ARG_WITH(gd, for GD support,
-[ --with-gd[=DIR] Include GD support. DIR is the GD library base
+[ --with-gd[=DIR] Include GD support. DIR is the GD library base
install directory [BUNDLED]])
-
if test -z "$PHP_VPX_DIR"; then
PHP_ARG_WITH(vpx-dir, for the location of libvpx,
- [ --with-vpx-dir[=DIR] GD: Set the path to libvpx install prefix], no, no)
+ [ --with-vpx-dir[=DIR] GD: Set the path to libvpx install prefix], no, no)
fi
if test -z "$PHP_JPEG_DIR"; then
@@ -40,10 +39,10 @@ PHP_ARG_WITH(t1lib, for T1lib support,
[ --with-t1lib[=DIR] GD: Include T1lib support. T1lib version >= 5.0.0 required], no, no)
PHP_ARG_ENABLE(gd-native-ttf, whether to enable truetype string function in GD,
-[ --enable-gd-native-ttf GD: Enable TrueType string function], no, no)
+[ --enable-gd-native-ttf GD: Enable TrueType string function], no, no)
PHP_ARG_ENABLE(gd-jis-conv, whether to enable JIS-mapped Japanese font support in GD,
-[ --enable-gd-jis-conv GD: Enable JIS-mapped Japanese font support], no, no)
+[ --enable-gd-jis-conv GD: Enable JIS-mapped Japanese font support], no, no)
dnl
dnl Checks for the configure options
@@ -159,18 +158,11 @@ AC_DEFUN([PHP_GD_XPM],[
if test "$PHP_XPM_DIR" != "no"; then
for i in $PHP_XPM_DIR /usr/local /usr/X11R6 /usr; do
- test -f $i/$PHP_LIBDIR/libXpm.$SHLIB_SUFFIX_NAME || test -f $i/$PHP_LIBDIR/libXpm.a && GD_XPM_DIR=$i && break
+ test -f $i/include/xpm.h && GD_XPM_DIR=$i && GD_XPM_INC=$i && break
+ test -f $i/include/X11/xpm.h && GD_XPM_DIR=$i && GD_XPM_INC=$i/X11 && break
done
if test -z "$GD_XPM_DIR"; then
- AC_MSG_ERROR([libXpm.(a|so) not found.])
- fi
-
- for i in include include/X11; do
- test -f $GD_XPM_DIR/$i/xpm.h && GD_XPM_INC=$GD_XPM_DIR/include
- done
-
- if test -z "$GD_XPM_INC"; then
AC_MSG_ERROR([xpm.h not found.])
fi
@@ -254,50 +246,21 @@ AC_DEFUN([PHP_GD_JISX0208],[
])
AC_DEFUN([PHP_GD_CHECK_VERSION],[
- PHP_CHECK_LIBRARY(gd, gdImageString16, [AC_DEFINE(HAVE_LIBGD13, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
- PHP_CHECK_LIBRARY(gd, gdImagePaletteCopy, [AC_DEFINE(HAVE_LIBGD15, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
- PHP_CHECK_LIBRARY(gd, gdImageCreateFromPng, [AC_DEFINE(HAVE_GD_PNG, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
- PHP_CHECK_LIBRARY(gd, gdImageCreateFromGif, [AC_DEFINE(HAVE_GD_GIF_READ, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
- PHP_CHECK_LIBRARY(gd, gdImageGif, [AC_DEFINE(HAVE_GD_GIF_CREATE, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
- PHP_CHECK_LIBRARY(gd, gdImageWBMP, [AC_DEFINE(HAVE_GD_WBMP, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
- PHP_CHECK_LIBRARY(gd, gdImageCreateFromJpeg, [AC_DEFINE(HAVE_GD_JPG, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
- PHP_CHECK_LIBRARY(gd, gdImageCreateFromXpm, [AC_DEFINE(HAVE_GD_XPM, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
- PHP_CHECK_LIBRARY(gd, gdImageCreateFromGd2, [AC_DEFINE(HAVE_GD_GD2, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
- PHP_CHECK_LIBRARY(gd, gdImageCreateTrueColor, [AC_DEFINE(HAVE_LIBGD20, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
- PHP_CHECK_LIBRARY(gd, gdImageSetTile, [AC_DEFINE(HAVE_GD_IMAGESETTILE, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
- PHP_CHECK_LIBRARY(gd, gdImageEllipse, [AC_DEFINE(HAVE_GD_IMAGEELLIPSE, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
- PHP_CHECK_LIBRARY(gd, gdImageSetBrush, [AC_DEFINE(HAVE_GD_IMAGESETBRUSH, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
- PHP_CHECK_LIBRARY(gd, gdImageStringTTF, [AC_DEFINE(HAVE_GD_STRINGTTF, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
- PHP_CHECK_LIBRARY(gd, gdImageStringFT, [AC_DEFINE(HAVE_GD_STRINGFT, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
- PHP_CHECK_LIBRARY(gd, gdImageStringFTEx, [AC_DEFINE(HAVE_GD_STRINGFTEX, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
- PHP_CHECK_LIBRARY(gd, gdImageColorClosestHWB, [AC_DEFINE(HAVE_COLORCLOSESTHWB, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
- PHP_CHECK_LIBRARY(gd, gdImageColorResolve, [AC_DEFINE(HAVE_GDIMAGECOLORRESOLVE, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
- PHP_CHECK_LIBRARY(gd, gdImageGifCtx, [AC_DEFINE(HAVE_GD_GIF_CTX, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
- PHP_CHECK_LIBRARY(gd, gdCacheCreate, [AC_DEFINE(HAVE_GD_CACHE_CREATE, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
- PHP_CHECK_LIBRARY(gd, gdFontCacheShutdown, [AC_DEFINE(HAVE_GD_FONTCACHESHUTDOWN,1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
- PHP_CHECK_LIBRARY(gd, gdFreeFontCache, [AC_DEFINE(HAVE_GD_FREEFONTCACHE, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
- PHP_CHECK_LIBRARY(gd, gdFontCacheMutexSetup, [AC_DEFINE(HAVE_GD_FONTMUTEX, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
- PHP_CHECK_LIBRARY(gd, gdNewDynamicCtxEx, [AC_DEFINE(HAVE_GD_DYNAMIC_CTX_EX, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
- PHP_CHECK_LIBRARY(gd, gdImageConvolution, [AC_DEFINE(HAVE_GD_IMAGE_CONVOLUTION, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
- PHP_CHECK_LIBRARY(gd, gdImagePixelate, [AC_DEFINE(HAVE_GD_IMAGE_PIXELATE, 1, [ ])], [], [ -L$GD_LIB $GD_SHARED_LIBADD ])
+ PHP_CHECK_LIBRARY(gd, gdImageCreateFromPng, [AC_DEFINE(HAVE_GD_PNG, 1, [ ])], [], [ $GD_SHARED_LIBADD ])
+ PHP_CHECK_LIBRARY(gd, gdImageCreateFromWebp, [AC_DEFINE(HAVE_GD_WEBP, 1, [ ])], [], [ $GD_SHARED_LIBADD ])
+ PHP_CHECK_LIBRARY(gd, gdImageCreateFromJpeg, [AC_DEFINE(HAVE_GD_JPG, 1, [ ])], [], [ $GD_SHARED_LIBADD ])
+ PHP_CHECK_LIBRARY(gd, gdImageCreateFromXpm, [AC_DEFINE(HAVE_GD_XPM, 1, [ ])], [], [ $GD_SHARED_LIBADD ])
+ PHP_CHECK_LIBRARY(gd, gdImageStringFT, [AC_DEFINE(HAVE_GD_FREETYPE, 1, [ ])], [], [ $GD_SHARED_LIBADD ])
])
dnl
dnl Main GD configure
dnl
-if test "$PHP_GD" = "yes"; then
- GD_MODULE_TYPE=builtin
- extra_sources="libgd/gd.c libgd/gd_gd.c libgd/gd_gd2.c libgd/gd_io.c libgd/gd_io_dp.c \
- libgd/gd_io_file.c libgd/gd_ss.c libgd/gd_io_ss.c libgd/webpimg.c libgd/gd_webp.c \
- libgd/gd_png.c libgd/gd_jpeg.c libgd/gdxpm.c libgd/gdfontt.c libgd/gdfonts.c \
- libgd/gdfontmb.c libgd/gdfontl.c libgd/gdfontg.c libgd/gdtables.c libgd/gdft.c \
- libgd/gdcache.c libgd/gdkanji.c libgd/wbmp.c libgd/gd_wbmp.c libgd/gdhelpers.c \
- libgd/gd_topal.c libgd/gd_gif_in.c libgd/xbm.c libgd/gd_gif_out.c libgd/gd_security.c \
- libgd/gd_filter.c libgd/gd_pixelate.c libgd/gd_arc.c libgd/gd_rotate.c libgd/gd_color.c"
-
-dnl check for fabsf and floorf which are available since C99
- AC_CHECK_FUNCS(fabsf floorf)
+dnl
+dnl Common for both builtin and external GD
+dnl
+if test "$PHP_GD" != "no"; then
dnl PNG is required by GD library
test "$PHP_PNG_DIR" = "no" && PHP_PNG_DIR=yes
@@ -305,36 +268,33 @@ dnl PNG is required by GD library
dnl Various checks for GD features
PHP_GD_ZLIB
PHP_GD_TTSTR
- PHP_GD_JISX0208
- PHP_GD_JPEG
PHP_GD_VPX
+ PHP_GD_JPEG
PHP_GD_PNG
PHP_GD_XPM
PHP_GD_FREETYPE2
PHP_GD_T1LIB
+ PHP_GD_JISX0208
+fi
+
+if test "$PHP_GD" = "yes"; then
+ GD_MODULE_TYPE=builtin
+ extra_sources="libgd/gd.c libgd/gd_gd.c libgd/gd_gd2.c libgd/gd_io.c libgd/gd_io_dp.c \
+ libgd/gd_io_file.c libgd/gd_ss.c libgd/gd_io_ss.c libgd/webpimg.c libgd/gd_webp.c \
+ libgd/gd_png.c libgd/gd_jpeg.c libgd/gdxpm.c libgd/gdfontt.c libgd/gdfonts.c \
+ libgd/gdfontmb.c libgd/gdfontl.c libgd/gdfontg.c libgd/gdtables.c libgd/gdft.c \
+ libgd/gdcache.c libgd/gdkanji.c libgd/wbmp.c libgd/gd_wbmp.c libgd/gdhelpers.c \
+ libgd/gd_topal.c libgd/gd_gif_in.c libgd/xbm.c libgd/gd_gif_out.c libgd/gd_security.c \
+ libgd/gd_filter.c libgd/gd_pixelate.c libgd/gd_arc.c libgd/gd_rotate.c libgd/gd_color.c \
+ libgd/gd_transform.c libgd/gd_crop.c libgd/gd_interpolation.c libgd/gd_matrix.c"
+
+dnl check for fabsf and floorf which are available since C99
+ AC_CHECK_FUNCS(fabsf floorf)
dnl These are always available with bundled library
- AC_DEFINE(HAVE_LIBGD, 1, [ ])
- AC_DEFINE(HAVE_LIBGD13, 1, [ ])
- AC_DEFINE(HAVE_LIBGD15, 1, [ ])
- AC_DEFINE(HAVE_LIBGD20, 1, [ ])
- AC_DEFINE(HAVE_LIBGD204, 1, [ ])
- AC_DEFINE(HAVE_GD_IMAGESETTILE, 1, [ ])
- AC_DEFINE(HAVE_GD_IMAGESETBRUSH, 1, [ ])
- AC_DEFINE(HAVE_GDIMAGECOLORRESOLVE, 1, [ ])
- AC_DEFINE(HAVE_COLORCLOSESTHWB, 1, [ ])
- AC_DEFINE(HAVE_GD_WBMP, 1, [ ])
- AC_DEFINE(HAVE_GD_GD2, 1, [ ])
- AC_DEFINE(HAVE_GD_PNG, 1, [ ])
- AC_DEFINE(HAVE_GD_XBM, 1, [ ])
AC_DEFINE(HAVE_GD_BUNDLED, 1, [ ])
- AC_DEFINE(HAVE_GD_GIF_READ, 1, [ ])
- AC_DEFINE(HAVE_GD_GIF_CREATE, 1, [ ])
- AC_DEFINE(HAVE_GD_IMAGEELLIPSE, 1, [ ])
- AC_DEFINE(HAVE_GD_FONTCACHESHUTDOWN,1, [ ])
- AC_DEFINE(HAVE_GD_FONTMUTEX, 1, [ ])
- AC_DEFINE(HAVE_GD_DYNAMIC_CTX_EX, 1, [ ])
- AC_DEFINE(HAVE_GD_GIF_CTX, 1, [ ])
+ AC_DEFINE(HAVE_GD_PNG, 1, [ ])
+ AC_DEFINE(HAVE_GD_CACHE_CREATE, 1, [ ])
dnl Make sure the libgd/ is first in the include path
GDLIB_CFLAGS="-DHAVE_LIBPNG"
@@ -358,8 +318,7 @@ dnl enable the support in bundled GD library
fi
if test -n "$FREETYPE2_DIR"; then
- AC_DEFINE(HAVE_GD_STRINGFT, 1, [ ])
- AC_DEFINE(HAVE_GD_STRINGFTEX, 1, [ ])
+ AC_DEFINE(HAVE_GD_FREETYPE, 1, [ ])
AC_DEFINE(ENABLE_GD_TTF, 1, [ ])
GDLIB_CFLAGS="$GDLIB_CFLAGS -DHAVE_LIBFREETYPE -DENABLE_GD_TTF"
fi
@@ -373,8 +332,7 @@ else
if test "$PHP_GD" != "no"; then
GD_MODULE_TYPE=external
- extra_sources="gdcache.c libgd/gd_compat.c libgd/gd_filter.c libgd/gd_pixelate.c libgd/gd_arc.c \
- libgd/gd_rotate.c libgd/gd_color.c"
+ extra_sources="gd_compat.c"
dnl Various checks for GD features
PHP_GD_ZLIB
@@ -387,44 +345,28 @@ dnl Various checks for GD features
PHP_GD_T1LIB
dnl Header path
- for i in include/gd1.3 include/gd include gd1.3 gd ""; do
+ for i in include/gd include gd ""; do
test -f "$PHP_GD/$i/gd.h" && GD_INCLUDE="$PHP_GD/$i"
done
-dnl Library path
- for i in $PHP_LIBDIR/gd1.3 $PHP_LIBDIR/gd $PHP_LIBDIR gd1.3 gd ""; do
- test -f "$PHP_GD/$i/libgd.$SHLIB_SUFFIX_NAME" || test -f "$PHP_GD/$i/libgd.a" && GD_LIB="$PHP_GD/$i"
- done
-
- if test -n "$GD_INCLUDE" && test -n "$GD_LIB"; then
- PHP_ADD_LIBRARY_WITH_PATH(gd, $GD_LIB, GD_SHARED_LIBADD)
- AC_DEFINE(HAVE_LIBGD,1,[ ])
- PHP_GD_CHECK_VERSION
- elif test -z "$GD_INCLUDE"; then
+ if test -z "$GD_INCLUDE"; then
AC_MSG_ERROR([Unable to find gd.h anywhere under $PHP_GD])
- else
- AC_MSG_ERROR([Unable to find libgd.(a|so) anywhere under $PHP_GD])
fi
- PHP_EXPAND_PATH($GD_INCLUDE, GD_INCLUDE)
+dnl Library path
- dnl
- dnl Check for gd 2.0.4 greater availability
- dnl
- old_CPPFLAGS=$CPPFLAGS
- CPPFLAGS=-I$GD_INCLUDE
- AC_TRY_COMPILE([
-#include <gd.h>
-#include <stdlib.h>
- ], [
-gdIOCtx *ctx;
-ctx = malloc(sizeof(gdIOCtx));
-ctx->gd_free = 1;
- ], [
- AC_DEFINE(HAVE_LIBGD204, 1, [ ])
+ PHP_CHECK_LIBRARY(gd, gdSetErrorMethod,
+ [
+ PHP_ADD_LIBRARY_WITH_PATH(gd, $PHP_GD/$PHP_LIBDIR, GD_SHARED_LIBADD)
+ AC_DEFINE(HAVE_LIBGD, 1, [ ])
+ ],[
+ AC_MSG_ERROR([Unable to find libgd.(a|so) >= 2.1.0 anywhere under $PHP_GD])
+ ],[
+ -L$PHP_GD/$PHP_LIBDIR
])
- CPPFLAGS=$old_CPPFLAGS
+ PHP_GD_CHECK_VERSION
+ PHP_EXPAND_PATH($GD_INCLUDE, GD_INCLUDE)
fi
fi
@@ -434,9 +376,8 @@ dnl
if test "$PHP_GD" != "no"; then
PHP_NEW_EXTENSION(gd, gd.c $extra_sources, $ext_shared,, \\$(GDLIB_CFLAGS))
- PHP_ADD_BUILD_DIR($ext_builddir/libgd)
-
- if test "$GD_MODULE_TYPE" = "builtin"; then
+ if test "$GD_MODULE_TYPE" = "builtin"; then
+ PHP_ADD_BUILD_DIR($ext_builddir/libgd)
GDLIB_CFLAGS="-I$ext_srcdir/libgd $GDLIB_CFLAGS"
GD_HEADER_DIRS="ext/gd/ ext/gd/libgd/"
@@ -449,7 +390,7 @@ if test "$PHP_GD" != "no"; then
PHP_ADD_INCLUDE($GD_INCLUDE)
PHP_CHECK_LIBRARY(gd, gdImageCreate, [], [
AC_MSG_ERROR([GD build test failed. Please check the config.log for details.])
- ], [ -L$GD_LIB $GD_SHARED_LIBADD ])
+ ], [ $GD_SHARED_LIBADD ])
fi
PHP_INSTALL_HEADERS([$GD_HEADER_DIRS])
diff --git a/ext/gd/config.w32 b/ext/gd/config.w32
index 8c932a037c..1420b11e6e 100644
--- a/ext/gd/config.w32
+++ b/ext/gd/config.w32
@@ -3,15 +3,16 @@
ARG_WITH("gd", "Bundled GD support", "yes,shared");
ARG_WITH("t1lib", "t1lib support", "yes");
+ARG_WITH("libvpx", "vpx support", "yes");
if (PHP_GD != "no") {
if (
- CHECK_LIB("vpxmt.lib", "gd", PHP_GD) &&
CHECK_LIB("libjpeg_a.lib;libjpeg.lib", "gd", PHP_GD) &&
CHECK_LIB("freetype_a.lib;freetype.lib", "gd", PHP_GD) &&
CHECK_LIB("libpng_a.lib;libpng.lib", "gd", PHP_GD) &&
CHECK_HEADER_ADD_INCLUDE("gd.h", "CFLAGS_GD", PHP_GD + ";ext\\gd\\libgd") &&
- CHECK_HEADER_ADD_INCLUDE("png.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\libpng12") &&
+ (CHECK_HEADER_ADD_INCLUDE("png.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\libpng15") ||
+ CHECK_HEADER_ADD_INCLUDE("png.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\libpng12")) &&
(CHECK_LIB("libiconv_a.lib;libiconv.lib", "gd", PHP_GD) || CHECK_LIB("iconv_a.lib;iconv.lib", "gd", PHP_GD)) &&
CHECK_HEADER_ADD_INCLUDE("iconv.h", "CFLAGS_GD", PHP_GD) &&
(((PHP_ZLIB=="no") && (CHECK_LIB("zlib_a.lib;zlib.lib", "gd", PHP_GD) )) ||
@@ -29,6 +30,14 @@ if (PHP_GD != "no") {
}
}
+ if (PHP_LIBVPX != "no") {
+ if (CHECK_LIB("vpxmt.lib", "gd", PHP_GD) &&
+ CHECK_HEADER_ADD_INCLUDE("vp8.h", "CFLAGS_GD", PHP_GD + ";" + PHP_PHP_BUILD + "\\include\\vpx")) {
+ ADD_FLAG("CFLAGS_GD", "/D HAVE_LIBVPX /D HAVE_GD_WEBP");
+ } else {
+ WARNING("libvpx not enabled; libraries and headers not found");
+ }
+ }
CHECK_LIB("User32.lib", "gd", PHP_GD);
CHECK_LIB("Gdi32.lib", "gd", PHP_GD);
@@ -37,8 +46,9 @@ if (PHP_GD != "no") {
gdcache.c gdfontg.c gdfontl.c gdfontmb.c gdfonts.c gdfontt.c \
gdft.c gd_gd2.c gd_gd.c gd_gif_in.c gd_gif_out.c gdhelpers.c gd_io.c gd_io_dp.c \
gd_io_file.c gd_io_ss.c gd_jpeg.c gdkanji.c gd_png.c gd_ss.c \
- gdtables.c gd_topal.c gd_wbmp.c gdxpm.c wbmp.c xbm.c gd_security.c \
- gd_filter.c gd_pixelate.c gd_arc.c gd_rotate.c gd_color.c webpimg.c gd_webp.c ", "gd");
+ gdtables.c gd_topal.c gd_wbmp.c gdxpm.c wbmp.c xbm.c gd_security.c gd_transform.c \
+ gd_filter.c gd_pixelate.c gd_arc.c gd_rotate.c gd_color.c webpimg.c gd_webp.c \
+ gd_crop.c gd_interpolation.c gd_matrix.c", "gd");
AC_DEFINE('HAVE_LIBGD', 1, 'GD support');
ADD_FLAG("CFLAGS_GD", " \
/D HAVE_GD_DYNAMIC_CTX_EX=1 \
@@ -59,14 +69,12 @@ if (PHP_GD != "no") {
/D HAVE_GD_WBMP \
/D HAVE_GD_XBM \
/D HAVE_GD_XPM \
-/D HAVE_GD_WEBP \
-/D HAVE_LIBFREETYPE=1 \
+/D HAVE_GD_FREETYPE=1 \
/D HAVE_LIBGD13=1 \
/D HAVE_LIBGD15=1 \
/D HAVE_LIBGD20=1 \
/D HAVE_LIBGD204=1 \
/D HAVE_LIBJPEG \
-/D HAVE_LIBVPX \
/D HAVE_LIBPNG \
/D HAVE_XPM \
/D HAVE_COLORCLOSESTHWB \
@@ -76,7 +84,7 @@ if (PHP_GD != "no") {
");
PHP_INSTALL_HEADERS("", "ext/gd ext/gd/libgd" );
- } else {
+ } else {
WARNING("gd not enabled; libraries and headers not found");
}
}
diff --git a/ext/gd/gd.c b/ext/gd/gd.c
index e5657f7424..ab4ab2df56 100644
--- a/ext/gd/gd.c
+++ b/ext/gd/gd.c
@@ -53,11 +53,12 @@
# include <Wingdi.h>
#endif
-#if HAVE_LIBGD
-#if !HAVE_GD_BUNDLED
-# include "libgd/gd_compat.h"
+#ifdef HAVE_GD_XPM
+# include <X11/xpm.h>
#endif
+# include "gd_compat.h"
+
static int le_gd, le_gd_font;
#if HAVE_LIBT1
@@ -74,9 +75,6 @@ static void php_free_ps_enc(zend_rsrc_list_entry *rsrc TSRMLS_DC);
#include <gdfontl.h> /* 4 Large font */
#include <gdfontg.h> /* 5 Giant font */
-#ifdef HAVE_GD_WBMP
-#include "libgd/wbmp.h"
-#endif
#ifdef ENABLE_GD_TTF
# ifdef HAVE_LIBFREETYPE
# include <ft2build.h>
@@ -92,38 +90,7 @@ static void php_free_ps_enc(zend_rsrc_list_entry *rsrc TSRMLS_DC);
static void php_imagettftext_common(INTERNAL_FUNCTION_PARAMETERS, int, int);
#endif
-#if HAVE_LIBGD15
-/* it's >= 1.5, i.e. has IOCtx */
-#define USE_GD_IOCTX 1
-#else
-#undef USE_GD_IOCTX
-#endif
-
-#ifdef USE_GD_IOCTX
#include "gd_ctx.c"
-#else
-#define gdImageCreateFromGdCtx NULL
-#define gdImageCreateFromGd2Ctx NULL
-#define gdImageCreateFromGd2partCtx NULL
-#define gdImageCreateFromGifCtx NULL
-#define gdImageCreateFromJpegCtx NULL
-#define gdImageCreateFromPngCtx NULL
-#define gdImageCreateFromWBMPCtx NULL
-typedef FILE gdIOCtx;
-#define CTX_PUTC(c, fp) fputc(c, fp)
-#endif
-
-#ifndef HAVE_GDIMAGECOLORRESOLVE
-extern int gdImageColorResolve(gdImagePtr, int, int, int);
-#endif
-
-#if HAVE_COLORCLOSESTHWB
-int gdImageColorClosestHWB(gdImagePtr im, int r, int g, int b);
-#endif
-
-#ifndef HAVE_GD_DYNAMIC_CTX_EX
-#define gdNewDynamicCtxEx(len, data, val) gdNewDynamicCtx(len, data)
-#endif
/* Section Filters Declarations */
/* IMPORTANT NOTE FOR NEW FILTER
@@ -195,6 +162,10 @@ ZEND_BEGIN_ARG_INFO(arginfo_imagetruecolortopalette, 0)
ZEND_ARG_INFO(0, colorsWanted)
ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO(arginfo_imagepalettetotruecolor, 0)
+ ZEND_ARG_INFO(0, im)
+ZEND_END_ARG_INFO()
+
ZEND_BEGIN_ARG_INFO(arginfo_imagecolormatch, 0)
ZEND_ARG_INFO(0, im1)
ZEND_ARG_INFO(0, im2)
@@ -236,12 +207,10 @@ ZEND_BEGIN_ARG_INFO(arginfo_imagesavealpha, 0)
ZEND_ARG_INFO(0, save)
ZEND_END_ARG_INFO()
-#if HAVE_GD_BUNDLED
ZEND_BEGIN_ARG_INFO(arginfo_imagelayereffect, 0)
ZEND_ARG_INFO(0, im)
ZEND_ARG_INFO(0, effect)
ZEND_END_ARG_INFO()
-#endif
ZEND_BEGIN_ARG_INFO(arginfo_imagecolorallocatealpha, 0)
ZEND_ARG_INFO(0, im)
@@ -305,19 +274,15 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_imagerotate, 0, 0, 3)
ZEND_ARG_INFO(0, ignoretransparent)
ZEND_END_ARG_INFO()
-#if HAVE_GD_IMAGESETTILE
ZEND_BEGIN_ARG_INFO(arginfo_imagesettile, 0)
ZEND_ARG_INFO(0, im)
ZEND_ARG_INFO(0, tile)
ZEND_END_ARG_INFO()
-#endif
-#if HAVE_GD_IMAGESETBRUSH
ZEND_BEGIN_ARG_INFO(arginfo_imagesetbrush, 0)
ZEND_ARG_INFO(0, im)
ZEND_ARG_INFO(0, brush)
ZEND_END_ARG_INFO()
-#endif
ZEND_BEGIN_ARG_INFO(arginfo_imagecreate, 0)
ZEND_ARG_INFO(0, x_size)
@@ -327,17 +292,13 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_imagetypes, 0)
ZEND_END_ARG_INFO()
-#if HAVE_LIBGD15
ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromstring, 0)
ZEND_ARG_INFO(0, image)
ZEND_END_ARG_INFO()
-#endif
-#ifdef HAVE_GD_GIF_READ
ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromgif, 0)
ZEND_ARG_INFO(0, filename)
ZEND_END_ARG_INFO()
-#endif
#ifdef HAVE_GD_JPG
ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromjpeg, 0)
@@ -357,29 +318,24 @@ ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromwebp, 0)
ZEND_END_ARG_INFO()
#endif
-#ifdef HAVE_GD_XBM
ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromxbm, 0)
ZEND_ARG_INFO(0, filename)
ZEND_END_ARG_INFO()
-#endif
-#if defined(HAVE_GD_XPM) && defined(HAVE_GD_BUNDLED)
+#if defined(HAVE_GD_XPM)
ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromxpm, 0)
ZEND_ARG_INFO(0, filename)
ZEND_END_ARG_INFO()
#endif
-#ifdef HAVE_GD_WBMP
ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromwbmp, 0)
ZEND_ARG_INFO(0, filename)
ZEND_END_ARG_INFO()
-#endif
ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromgd, 0)
ZEND_ARG_INFO(0, filename)
ZEND_END_ARG_INFO()
-#ifdef HAVE_GD_GD2
ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromgd2, 0)
ZEND_ARG_INFO(0, filename)
ZEND_END_ARG_INFO()
@@ -391,22 +347,17 @@ ZEND_BEGIN_ARG_INFO(arginfo_imagecreatefromgd2part, 0)
ZEND_ARG_INFO(0, width)
ZEND_ARG_INFO(0, height)
ZEND_END_ARG_INFO()
-#endif
-#if HAVE_GD_BUNDLED
ZEND_BEGIN_ARG_INFO_EX(arginfo_imagexbm, 0, 0, 2)
ZEND_ARG_INFO(0, im)
ZEND_ARG_INFO(0, filename)
ZEND_ARG_INFO(0, foreground)
ZEND_END_ARG_INFO()
-#endif
-#ifdef HAVE_GD_GIF_CREATE
ZEND_BEGIN_ARG_INFO_EX(arginfo_imagegif, 0, 0, 1)
ZEND_ARG_INFO(0, im)
ZEND_ARG_INFO(0, filename)
ZEND_END_ARG_INFO()
-#endif
#ifdef HAVE_GD_PNG
ZEND_BEGIN_ARG_INFO_EX(arginfo_imagepng, 0, 0, 1)
@@ -430,27 +381,23 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_imagejpeg, 0, 0, 1)
ZEND_END_ARG_INFO()
#endif
-#ifdef HAVE_GD_WBMP
ZEND_BEGIN_ARG_INFO_EX(arginfo_imagewbmp, 0, 0, 1)
ZEND_ARG_INFO(0, im)
ZEND_ARG_INFO(0, filename)
ZEND_ARG_INFO(0, foreground)
ZEND_END_ARG_INFO()
-#endif
ZEND_BEGIN_ARG_INFO_EX(arginfo_imagegd, 0, 0, 1)
ZEND_ARG_INFO(0, im)
ZEND_ARG_INFO(0, filename)
ZEND_END_ARG_INFO()
-#ifdef HAVE_GD_GD2
ZEND_BEGIN_ARG_INFO_EX(arginfo_imagegd2, 0, 0, 1)
ZEND_ARG_INFO(0, im)
ZEND_ARG_INFO(0, filename)
ZEND_ARG_INFO(0, chunk_size)
ZEND_ARG_INFO(0, type)
ZEND_END_ARG_INFO()
-#endif
ZEND_BEGIN_ARG_INFO(arginfo_imagedestroy, 0)
ZEND_ARG_INFO(0, im)
@@ -463,12 +410,10 @@ ZEND_BEGIN_ARG_INFO(arginfo_imagecolorallocate, 0)
ZEND_ARG_INFO(0, blue)
ZEND_END_ARG_INFO()
-#if HAVE_LIBGD15
ZEND_BEGIN_ARG_INFO(arginfo_imagepalettecopy, 0)
ZEND_ARG_INFO(0, dst)
ZEND_ARG_INFO(0, src)
ZEND_END_ARG_INFO()
-#endif
ZEND_BEGIN_ARG_INFO(arginfo_imagecolorat, 0)
ZEND_ARG_INFO(0, im)
@@ -483,14 +428,12 @@ ZEND_BEGIN_ARG_INFO(arginfo_imagecolorclosest, 0)
ZEND_ARG_INFO(0, blue)
ZEND_END_ARG_INFO()
-#if HAVE_COLORCLOSESTHWB
ZEND_BEGIN_ARG_INFO(arginfo_imagecolorclosesthwb, 0)
ZEND_ARG_INFO(0, im)
ZEND_ARG_INFO(0, red)
ZEND_ARG_INFO(0, green)
ZEND_ARG_INFO(0, blue)
ZEND_END_ARG_INFO()
-#endif
ZEND_BEGIN_ARG_INFO(arginfo_imagecolordeallocate, 0)
ZEND_ARG_INFO(0, im)
@@ -692,7 +635,6 @@ ZEND_BEGIN_ARG_INFO(arginfo_imagecopy, 0)
ZEND_ARG_INFO(0, src_h)
ZEND_END_ARG_INFO()
-#if HAVE_LIBGD15
ZEND_BEGIN_ARG_INFO(arginfo_imagecopymerge, 0)
ZEND_ARG_INFO(0, src_im)
ZEND_ARG_INFO(0, dst_im)
@@ -716,7 +658,6 @@ ZEND_BEGIN_ARG_INFO(arginfo_imagecopymergegray, 0)
ZEND_ARG_INFO(0, src_h)
ZEND_ARG_INFO(0, pct)
ZEND_END_ARG_INFO()
-#endif
ZEND_BEGIN_ARG_INFO(arginfo_imagecopyresized, 0)
ZEND_ARG_INFO(0, dst_im)
@@ -740,7 +681,7 @@ ZEND_BEGIN_ARG_INFO(arginfo_imagesy, 0)
ZEND_END_ARG_INFO()
#ifdef ENABLE_GD_TTF
-#if HAVE_LIBFREETYPE && HAVE_GD_STRINGFTEX
+#if HAVE_LIBFREETYPE
ZEND_BEGIN_ARG_INFO_EX(arginfo_imageftbbox, 0, 0, 4)
ZEND_ARG_INFO(0, size)
ZEND_ARG_INFO(0, angle)
@@ -836,15 +777,13 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_imagepsbbox, 0, 0, 3)
ZEND_END_ARG_INFO()
#endif
-#ifdef HAVE_GD_WBMP
ZEND_BEGIN_ARG_INFO_EX(arginfo_image2wbmp, 0, 0, 1)
ZEND_ARG_INFO(0, im)
ZEND_ARG_INFO(0, filename)
ZEND_ARG_INFO(0, threshold)
ZEND_END_ARG_INFO()
-#endif
-#if defined(HAVE_GD_JPG) && defined(HAVE_GD_WBMP)
+#if defined(HAVE_GD_JPG)
ZEND_BEGIN_ARG_INFO(arginfo_jpeg2wbmp, 0)
ZEND_ARG_INFO(0, f_org)
ZEND_ARG_INFO(0, f_dest)
@@ -854,7 +793,7 @@ ZEND_BEGIN_ARG_INFO(arginfo_jpeg2wbmp, 0)
ZEND_END_ARG_INFO()
#endif
-#if defined(HAVE_GD_PNG) && defined(HAVE_GD_WBMP)
+#if defined(HAVE_GD_PNG)
ZEND_BEGIN_ARG_INFO(arginfo_png2wbmp, 0)
ZEND_ARG_INFO(0, f_org)
ZEND_ARG_INFO(0, f_dest)
@@ -880,6 +819,11 @@ ZEND_BEGIN_ARG_INFO(arginfo_imageconvolution, 0)
ZEND_ARG_INFO(0, offset)
ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO(arginfo_imageflip, 0)
+ ZEND_ARG_INFO(0, im)
+ ZEND_ARG_INFO(0, mode)
+ZEND_END_ARG_INFO()
+
#ifdef HAVE_GD_BUNDLED
ZEND_BEGIN_ARG_INFO(arginfo_imageantialias, 0)
ZEND_ARG_INFO(0, im)
@@ -887,6 +831,46 @@ ZEND_BEGIN_ARG_INFO(arginfo_imageantialias, 0)
ZEND_END_ARG_INFO()
#endif
+ZEND_BEGIN_ARG_INFO(arginfo_imagecrop, 0)
+ ZEND_ARG_INFO(0, im)
+ ZEND_ARG_INFO(0, rect)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_imagecropauto, 0, 0, 1)
+ ZEND_ARG_INFO(0, im)
+ ZEND_ARG_INFO(0, mode)
+ ZEND_ARG_INFO(0, threshold)
+ ZEND_ARG_INFO(0, color)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_imagescale, 0, 0, 2)
+ ZEND_ARG_INFO(0, im)
+ ZEND_ARG_INFO(0, new_width)
+ ZEND_ARG_INFO(0, new_height)
+ ZEND_ARG_INFO(0, mode)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_imageaffine, 0, 0, 2)
+ ZEND_ARG_INFO(0, im)
+ ZEND_ARG_INFO(0, affine)
+ ZEND_ARG_INFO(0, clip)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_imageaffinematrixget, 0, 0, 1)
+ ZEND_ARG_INFO(0, type)
+ ZEND_ARG_INFO(0, options)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_imageaffinematrixconcat, 0)
+ ZEND_ARG_INFO(0, m1)
+ ZEND_ARG_INFO(0, m2)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_imagesetinterpolation, 0)
+ ZEND_ARG_INFO(0, im)
+ ZEND_ARG_INFO(0, method)
+ZEND_END_ARG_INFO()
+
/* }}} */
/* {{{ gd_functions[]
@@ -899,14 +883,10 @@ const zend_function_entry gd_functions[] = {
PHP_FE(imagecharup, arginfo_imagecharup)
PHP_FE(imagecolorat, arginfo_imagecolorat)
PHP_FE(imagecolorallocate, arginfo_imagecolorallocate)
-#if HAVE_LIBGD15
PHP_FE(imagepalettecopy, arginfo_imagepalettecopy)
PHP_FE(imagecreatefromstring, arginfo_imagecreatefromstring)
-#endif
PHP_FE(imagecolorclosest, arginfo_imagecolorclosest)
-#if HAVE_COLORCLOSESTHWB
PHP_FE(imagecolorclosesthwb, arginfo_imagecolorclosesthwb)
-#endif
PHP_FE(imagecolordeallocate, arginfo_imagecolordeallocate)
PHP_FE(imagecolorresolve, arginfo_imagecolorresolve)
PHP_FE(imagecolorexact, arginfo_imagecolorexact)
@@ -915,15 +895,14 @@ const zend_function_entry gd_functions[] = {
PHP_FE(imagecolorstotal, arginfo_imagecolorstotal)
PHP_FE(imagecolorsforindex, arginfo_imagecolorsforindex)
PHP_FE(imagecopy, arginfo_imagecopy)
-#if HAVE_LIBGD15
PHP_FE(imagecopymerge, arginfo_imagecopymerge)
PHP_FE(imagecopymergegray, arginfo_imagecopymergegray)
-#endif
PHP_FE(imagecopyresized, arginfo_imagecopyresized)
PHP_FE(imagecreate, arginfo_imagecreate)
PHP_FE(imagecreatetruecolor, arginfo_imagecreatetruecolor)
PHP_FE(imageistruecolor, arginfo_imageistruecolor)
PHP_FE(imagetruecolortopalette, arginfo_imagetruecolortopalette)
+ PHP_FE(imagepalettetotruecolor, arginfo_imagepalettetotruecolor)
PHP_FE(imagesetthickness, arginfo_imagesetthickness)
PHP_FE(imagefilledarc, arginfo_imagefilledarc)
PHP_FE(imagefilledellipse, arginfo_imagefilledellipse)
@@ -941,19 +920,20 @@ const zend_function_entry gd_functions[] = {
#endif
PHP_FE(imagerotate, arginfo_imagerotate)
+ PHP_FE(imageflip, arginfo_imageflip)
#ifdef HAVE_GD_BUNDLED
PHP_FE(imageantialias, arginfo_imageantialias)
#endif
-
-#if HAVE_GD_IMAGESETTILE
+ PHP_FE(imagecrop, arginfo_imagecrop)
+ PHP_FE(imagecropauto, arginfo_imagecropauto)
+ PHP_FE(imagescale, arginfo_imagescale)
+ PHP_FE(imageaffine, arginfo_imageaffine)
+ PHP_FE(imageaffinematrixconcat, arginfo_imageaffinematrixconcat)
+ PHP_FE(imageaffinematrixget, arginfo_imageaffinematrixget)
+ PHP_FE(imagesetinterpolation, arginfo_imagesetinterpolation)
PHP_FE(imagesettile, arginfo_imagesettile)
-#endif
-
-#if HAVE_GD_IMAGESETBRUSH
PHP_FE(imagesetbrush, arginfo_imagesetbrush)
-#endif
-
PHP_FE(imagesetstyle, arginfo_imagesetstyle)
#ifdef HAVE_GD_PNG
@@ -962,45 +942,31 @@ const zend_function_entry gd_functions[] = {
#ifdef HAVE_GD_WEBP
PHP_FE(imagecreatefromwebp, arginfo_imagecreatefromwebp)
#endif
-#ifdef HAVE_GD_GIF_READ
PHP_FE(imagecreatefromgif, arginfo_imagecreatefromgif)
-#endif
#ifdef HAVE_GD_JPG
PHP_FE(imagecreatefromjpeg, arginfo_imagecreatefromjpeg)
#endif
-#ifdef HAVE_GD_WBMP
PHP_FE(imagecreatefromwbmp, arginfo_imagecreatefromwbmp)
-#endif
-#ifdef HAVE_GD_XBM
PHP_FE(imagecreatefromxbm, arginfo_imagecreatefromxbm)
-#endif
-#if defined(HAVE_GD_XPM) && defined(HAVE_GD_BUNDLED)
+#if defined(HAVE_GD_XPM)
PHP_FE(imagecreatefromxpm, arginfo_imagecreatefromxpm)
#endif
PHP_FE(imagecreatefromgd, arginfo_imagecreatefromgd)
-#ifdef HAVE_GD_GD2
PHP_FE(imagecreatefromgd2, arginfo_imagecreatefromgd2)
PHP_FE(imagecreatefromgd2part, arginfo_imagecreatefromgd2part)
-#endif
#ifdef HAVE_GD_PNG
PHP_FE(imagepng, arginfo_imagepng)
#endif
#ifdef HAVE_GD_WEBP
PHP_FE(imagewebp, arginfo_imagewebp)
#endif
-#ifdef HAVE_GD_GIF_CREATE
PHP_FE(imagegif, arginfo_imagegif)
-#endif
#ifdef HAVE_GD_JPG
PHP_FE(imagejpeg, arginfo_imagejpeg)
#endif
-#ifdef HAVE_GD_WBMP
PHP_FE(imagewbmp, arginfo_imagewbmp)
-#endif
PHP_FE(imagegd, arginfo_imagegd)
-#ifdef HAVE_GD_GD2
PHP_FE(imagegd2, arginfo_imagegd2)
-#endif
PHP_FE(imagedestroy, arginfo_imagedestroy)
PHP_FE(imagegammacorrect, arginfo_imagegammacorrect)
@@ -1025,7 +991,7 @@ const zend_function_entry gd_functions[] = {
#ifdef ENABLE_GD_TTF
PHP_FE(imagettfbbox, arginfo_imagettfbbox)
PHP_FE(imagettftext, arginfo_imagettftext)
-#if HAVE_LIBFREETYPE && HAVE_GD_STRINGFTEX
+#if HAVE_GD_FREETYPE && HAVE_LIBFREETYPE
PHP_FE(imageftbbox, arginfo_imageftbbox)
PHP_FE(imagefttext, arginfo_imagefttext)
#endif
@@ -1045,19 +1011,15 @@ const zend_function_entry gd_functions[] = {
#endif
PHP_FE(imagetypes, arginfo_imagetypes)
-#if defined(HAVE_GD_JPG) && defined(HAVE_GD_WBMP)
+#if defined(HAVE_GD_JPG)
PHP_FE(jpeg2wbmp, arginfo_jpeg2wbmp)
#endif
-#if defined(HAVE_GD_PNG) && defined(HAVE_GD_WBMP)
+#if defined(HAVE_GD_PNG)
PHP_FE(png2wbmp, arginfo_png2wbmp)
#endif
-#ifdef HAVE_GD_WBMP
PHP_FE(image2wbmp, arginfo_image2wbmp)
-#endif
-#if HAVE_GD_BUNDLED
PHP_FE(imagelayereffect, arginfo_imagelayereffect)
PHP_FE(imagexbm, arginfo_imagexbm)
-#endif
PHP_FE(imagecolormatch, arginfo_imagecolormatch)
@@ -1074,13 +1036,13 @@ zend_module_entry gd_module_entry = {
"gd",
gd_functions,
PHP_MINIT(gd),
-#if HAVE_LIBT1 || HAVE_GD_FONTMUTEX
+#if HAVE_LIBT1
PHP_MSHUTDOWN(gd),
#else
NULL,
#endif
NULL,
-#if HAVE_GD_STRINGFT && (HAVE_LIBFREETYPE && (HAVE_GD_FONTCACHESHUTDOWN || HAVE_GD_FREEFONTCACHE))
+#if HAVE_GD_FREETYPE && HAVE_LIBFREETYPE
PHP_RSHUTDOWN(gd),
#else
NULL,
@@ -1122,15 +1084,25 @@ static void php_free_gd_font(zend_rsrc_list_entry *rsrc TSRMLS_DC)
}
/* }}} */
+#ifndef HAVE_GD_BUNDLED
+/* {{{ php_gd_error_method
+ */
+void php_gd_error_method(int type, const char *format, va_list args)
+{
+ TSRMLS_FETCH();
+
+ php_verror(NULL, "", type, format, args TSRMLS_CC);
+}
+/* }}} */
+#endif
+
/* {{{ PHP_MSHUTDOWN_FUNCTION
*/
-#if HAVE_LIBT1 || HAVE_GD_FONTMUTEX
+#if HAVE_LIBT1
PHP_MSHUTDOWN_FUNCTION(gd)
{
-#if HAVE_LIBT1
T1_CloseLib();
-#endif
-#if HAVE_GD_FONTMUTEX && HAVE_LIBFREETYPE
+#if HAVE_GD_BUNDLED && HAVE_LIBFREETYPE
gdFontCacheMutexShutdown();
#endif
UNREGISTER_INI_ENTRIES();
@@ -1147,7 +1119,7 @@ PHP_MINIT_FUNCTION(gd)
le_gd = zend_register_list_destructors_ex(php_free_gd_image, NULL, "gd", module_number);
le_gd_font = zend_register_list_destructors_ex(php_free_gd_font, NULL, "gd font", module_number);
-#if HAVE_GD_FONTMUTEX && HAVE_LIBFREETYPE
+#if HAVE_GD_BUNDLED && HAVE_LIBFREETYPE
gdFontCacheMutexSetup();
#endif
#if HAVE_LIBT1
@@ -1157,7 +1129,9 @@ PHP_MINIT_FUNCTION(gd)
le_ps_font = zend_register_list_destructors_ex(php_free_ps_font, NULL, "gd PS font", module_number);
le_ps_enc = zend_register_list_destructors_ex(php_free_ps_enc, NULL, "gd PS encoding", module_number);
#endif
-
+#ifndef HAVE_GD_BUNDLED
+ gdSetErrorMethod(php_gd_error_method);
+#endif
REGISTER_INI_ENTRIES();
REGISTER_LONG_CONSTANT("IMG_GIF", 1, CONST_CS | CONST_PERSISTENT);
@@ -1166,14 +1140,14 @@ PHP_MINIT_FUNCTION(gd)
REGISTER_LONG_CONSTANT("IMG_PNG", 4, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("IMG_WBMP", 8, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("IMG_XPM", 16, CONST_CS | CONST_PERSISTENT);
-#ifdef gdTiled
+
/* special colours for gd */
REGISTER_LONG_CONSTANT("IMG_COLOR_TILED", gdTiled, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("IMG_COLOR_STYLED", gdStyled, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("IMG_COLOR_BRUSHED", gdBrushed, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("IMG_COLOR_STYLEDBRUSHED", gdStyledBrushed, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("IMG_COLOR_TRANSPARENT", gdTransparent, CONST_CS | CONST_PERSISTENT);
-#endif
+
/* for imagefilledarc */
REGISTER_LONG_CONSTANT("IMG_ARC_ROUNDED", gdArc, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("IMG_ARC_PIE", gdPie, CONST_CS | CONST_PERSISTENT);
@@ -1181,18 +1155,54 @@ PHP_MINIT_FUNCTION(gd)
REGISTER_LONG_CONSTANT("IMG_ARC_NOFILL", gdNoFill, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("IMG_ARC_EDGED", gdEdged, CONST_CS | CONST_PERSISTENT);
-/* GD2 image format types */
-#ifdef GD2_FMT_RAW
+ /* GD2 image format types */
REGISTER_LONG_CONSTANT("IMG_GD2_RAW", GD2_FMT_RAW, CONST_CS | CONST_PERSISTENT);
-#endif
-#ifdef GD2_FMT_COMPRESSED
REGISTER_LONG_CONSTANT("IMG_GD2_COMPRESSED", GD2_FMT_COMPRESSED, CONST_CS | CONST_PERSISTENT);
-#endif
-#if HAVE_GD_BUNDLED
+ REGISTER_LONG_CONSTANT("IMG_FLIP_HORIZONTAL", GD_FLIP_HORINZONTAL, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IMG_FLIP_VERTICAL", GD_FLIP_VERTICAL, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IMG_FLIP_BOTH", GD_FLIP_BOTH, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("IMG_EFFECT_REPLACE", gdEffectReplace, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("IMG_EFFECT_ALPHABLEND", gdEffectAlphaBlend, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("IMG_EFFECT_NORMAL", gdEffectNormal, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("IMG_EFFECT_OVERLAY", gdEffectOverlay, CONST_CS | CONST_PERSISTENT);
+
+ REGISTER_LONG_CONSTANT("IMG_CROP_DEFAULT", GD_CROP_DEFAULT, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IMG_CROP_TRANSPARENT", GD_CROP_TRANSPARENT, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IMG_CROP_BLACK", GD_CROP_BLACK, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IMG_CROP_WHITE", GD_CROP_WHITE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IMG_CROP_SIDES", GD_CROP_SIDES, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IMG_CROP_THRESHOLD", GD_CROP_THRESHOLD, CONST_CS | CONST_PERSISTENT);
+
+
+ REGISTER_LONG_CONSTANT("IMG_BELL", GD_BELL, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IMG_BESSEL", GD_BESSEL, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IMG_BILINEAR_FIXED", GD_BILINEAR_FIXED, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IMG_BICUBIC", GD_BICUBIC, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IMG_BICUBIC_FIXED", GD_BICUBIC_FIXED, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IMG_BLACKMAN", GD_BLACKMAN, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IMG_BOX", GD_BOX, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IMG_BSPLINE", GD_BSPLINE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IMG_CATMULLROM", GD_CATMULLROM, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IMG_GAUSSIAN", GD_GAUSSIAN, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IMG_GENERALIZED_CUBIC", GD_GENERALIZED_CUBIC, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IMG_HERMITE", GD_HERMITE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IMG_HAMMING", GD_HAMMING, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IMG_HANNING", GD_HANNING, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IMG_MITCHELL", GD_MITCHELL, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IMG_POWER", GD_POWER, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IMG_QUADRATIC", GD_QUADRATIC, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IMG_SINC", GD_SINC, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IMG_NEAREST_NEIGHBOUR", GD_NEAREST_NEIGHBOUR, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IMG_WEIGHTED4", GD_WEIGHTED4, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IMG_TRIANGLE", GD_TRIANGLE, CONST_CS | CONST_PERSISTENT);
+
+ REGISTER_LONG_CONSTANT("IMG_AFFINE_TRANSLATE", GD_AFFINE_TRANSLATE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IMG_AFFINE_SCALE", GD_AFFINE_SCALE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IMG_AFFINE_ROTATE", GD_AFFINE_ROTATE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IMG_AFFINE_SHEAR_HORIZONTAL", GD_AFFINE_SHEAR_HORIZONTAL, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IMG_AFFINE_SHEAR_VERTICAL", GD_AFFINE_SHEAR_VERTICAL, CONST_CS | CONST_PERSISTENT);
+
+#if defined(HAVE_GD_BUNDLED)
REGISTER_LONG_CONSTANT("GD_BUNDLED", 1, CONST_CS | CONST_PERSISTENT);
#else
REGISTER_LONG_CONSTANT("GD_BUNDLED", 0, CONST_CS | CONST_PERSISTENT);
@@ -1247,27 +1257,19 @@ PHP_MINIT_FUNCTION(gd)
/* {{{ PHP_RSHUTDOWN_FUNCTION
*/
-#if HAVE_GD_STRINGFT && (HAVE_LIBFREETYPE && (HAVE_GD_FONTCACHESHUTDOWN || HAVE_GD_FREEFONTCACHE))
+#if HAVE_GD_FREETYPE && HAVE_LIBFREETYPE
PHP_RSHUTDOWN_FUNCTION(gd)
{
-#if HAVE_GD_FONTCACHESHUTDOWN
gdFontCacheShutdown();
-#else
- gdFreeFontCache();
-#endif
return SUCCESS;
}
#endif
/* }}} */
-#if HAVE_GD_BUNDLED
+#if defined(HAVE_GD_BUNDLED)
#define PHP_GD_VERSION_STRING "bundled (2.1.0 compatible)"
#else
-# ifdef GD_VERSION_STRING
-# define PHP_GD_VERSION_STRING GD_VERSION_STRING
-# else
-# define PHP_GD_VERSION_STRING "2.0"
-# endif
+# define PHP_GD_VERSION_STRING GD_VERSION_STRING
#endif
/* {{{ PHP_MINFO_FUNCTION
@@ -1306,20 +1308,13 @@ PHP_MINFO_FUNCTION(gd)
php_info_print_table_row(2, "T1Lib Support", "enabled");
#endif
-/* this next part is stupid ... if I knew better, I'd put them all on one row (cmv) */
-
-#ifdef HAVE_GD_GIF_READ
php_info_print_table_row(2, "GIF Read Support", "enabled");
-#endif
-#ifdef HAVE_GD_GIF_CREATE
php_info_print_table_row(2, "GIF Create Support", "enabled");
-#endif
+
#ifdef HAVE_GD_JPG
{
- char tmp[12];
- snprintf(tmp, sizeof(tmp), "%s", gdJpegGetVersionString());
php_info_print_table_row(2, "JPEG Support", "enabled");
- php_info_print_table_row(2, "libJPEG Version", tmp);
+ php_info_print_table_row(2, "libJPEG Version", gdJpegGetVersionString());
}
#endif
@@ -1327,10 +1322,8 @@ PHP_MINFO_FUNCTION(gd)
php_info_print_table_row(2, "PNG Support", "enabled");
php_info_print_table_row(2, "libPNG Version", gdPngGetVersionString());
#endif
-#ifdef HAVE_GD_WBMP
php_info_print_table_row(2, "WBMP Support", "enabled");
-#endif
-#if defined(HAVE_GD_XPM) && defined(HAVE_GD_BUNDLED)
+#if defined(HAVE_GD_XPM)
php_info_print_table_row(2, "XPM Support", "enabled");
{
char tmp[12];
@@ -1338,12 +1331,13 @@ PHP_MINFO_FUNCTION(gd)
php_info_print_table_row(2, "libXpm Version", tmp);
}
#endif
-#ifdef HAVE_GD_XBM
php_info_print_table_row(2, "XBM Support", "enabled");
-#endif
-#if defined(USE_GD_JISX0208) && defined(HAVE_GD_BUNDLED)
+#if defined(USE_GD_JISX0208)
php_info_print_table_row(2, "JIS-mapped Japanese Font Support", "enabled");
#endif
+#ifdef HAVE_GD_WEBP
+ php_info_print_table_row(2, "WebP Support", "enabled");
+#endif
php_info_print_table_end();
DISPLAY_INI_ENTRIES();
}
@@ -1377,16 +1371,8 @@ PHP_FUNCTION(gd_info)
#else
add_assoc_bool(return_value, "T1Lib Support", 0);
#endif
-#ifdef HAVE_GD_GIF_READ
add_assoc_bool(return_value, "GIF Read Support", 1);
-#else
- add_assoc_bool(return_value, "GIF Read Support", 0);
-#endif
-#ifdef HAVE_GD_GIF_CREATE
add_assoc_bool(return_value, "GIF Create Support", 1);
-#else
- add_assoc_bool(return_value, "GIF Create Support", 0);
-#endif
#ifdef HAVE_GD_JPG
add_assoc_bool(return_value, "JPEG Support", 1);
#else
@@ -1397,22 +1383,14 @@ PHP_FUNCTION(gd_info)
#else
add_assoc_bool(return_value, "PNG Support", 0);
#endif
-#ifdef HAVE_GD_WBMP
add_assoc_bool(return_value, "WBMP Support", 1);
-#else
- add_assoc_bool(return_value, "WBMP Support", 0);
-#endif
-#if defined(HAVE_GD_XPM) && defined(HAVE_GD_BUNDLED)
+#if defined(HAVE_GD_XPM)
add_assoc_bool(return_value, "XPM Support", 1);
#else
add_assoc_bool(return_value, "XPM Support", 0);
#endif
-#ifdef HAVE_GD_XBM
add_assoc_bool(return_value, "XBM Support", 1);
-#else
- add_assoc_bool(return_value, "XBM Support", 0);
-#endif
-#if defined(USE_GD_JISX0208) && defined(HAVE_GD_BUNDLED)
+#if defined(USE_GD_JISX0208)
add_assoc_bool(return_value, "JIS-mapped Japanese Font Support", 1);
#else
add_assoc_bool(return_value, "JIS-mapped Japanese Font Support", 0);
@@ -1427,62 +1405,6 @@ PHP_GD_API int phpi_get_le_gd(void)
}
/* }}} */
-#ifndef HAVE_GDIMAGECOLORRESOLVE
-
-/* {{{ gdImageColorResolve
- */
-/********************************************************************/
-/* gdImageColorResolve is a replacement for the old fragment: */
-/* */
-/* if ((color=gdImageColorExact(im,R,G,B)) < 0) */
-/* if ((color=gdImageColorAllocate(im,R,G,B)) < 0) */
-/* color=gdImageColorClosest(im,R,G,B); */
-/* */
-/* in a single function */
-
-int gdImageColorResolve(gdImagePtr im, int r, int g, int b)
-{
- int c;
- int ct = -1;
- int op = -1;
- long rd, gd, bd, dist;
- long mindist = 3*255*255; /* init to max poss dist */
-
- for (c = 0; c < im->colorsTotal; c++) {
- if (im->open[c]) {
- op = c; /* Save open slot */
- continue; /* Color not in use */
- }
- rd = (long) (im->red [c] - r);
- gd = (long) (im->green[c] - g);
- bd = (long) (im->blue [c] - b);
- dist = rd * rd + gd * gd + bd * bd;
- if (dist < mindist) {
- if (dist == 0) {
- return c; /* Return exact match color */
- }
- mindist = dist;
- ct = c;
- }
- }
- /* no exact match. We now know closest, but first try to allocate exact */
- if (op == -1) {
- op = im->colorsTotal;
- if (op == gdMaxColors) { /* No room for more colors */
- return ct; /* Return closest available color */
- }
- im->colorsTotal++;
- }
- im->red [op] = r;
- im->green[op] = g;
- im->blue [op] = b;
- im->open [op] = 0;
- return op; /* Return newly allocated color */
-}
-/* }}} */
-
-#endif
-
#define FLIPWORD(a) (((a & 0xff000000) >> 24) | ((a & 0x00ff0000) >> 8) | ((a & 0x0000ff00) << 8) | ((a & 0x000000ff) << 24))
/* {{{ proto int imageloadfont(string filename)
@@ -1545,13 +1467,7 @@ PHP_FUNCTION(imageloadfont)
body_size = font->w * font->h * font->nchars;
}
- if (overflow2(font->nchars, font->h)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error reading font, invalid font header");
- efree(font);
- php_stream_close(stream);
- RETURN_FALSE;
- }
- if (overflow2(font->nchars * font->h, font->w )) {
+ if (overflow2(font->nchars, font->h) || overflow2(font->nchars * font->h, font->w )) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error reading font, invalid font header");
efree(font);
php_stream_close(stream);
@@ -1622,9 +1538,15 @@ PHP_FUNCTION(imagesetstyle)
break;
}
- convert_to_long_ex(item);
-
- stylearr[index++] = Z_LVAL_PP(item);
+ if (Z_TYPE_PP(item) != IS_LONG) {
+ zval lval;
+ lval = **item;
+ zval_copy_ctor(&lval);
+ convert_to_long(&lval);
+ stylearr[index++] = Z_LVAL(lval);
+ } else {
+ stylearr[index++] = Z_LVAL_PP(item);
+ }
}
gdImageSetStyle(im, stylearr, index);
@@ -1703,6 +1625,29 @@ PHP_FUNCTION(imagetruecolortopalette)
}
/* }}} */
+
+
+/* {{{ proto void imagetruecolortopalette(resource im, bool ditherFlag, int colorsWanted)
+ Convert a true colour image to a palette based image with a number of colours, optionally using dithering. */
+PHP_FUNCTION(imagepalettetotruecolor)
+{
+ zval *IM;
+ gdImagePtr im;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &IM) == FAILURE) {
+ return;
+ }
+
+ ZEND_FETCH_RESOURCE(im, gdImagePtr, &IM, -1, "Image", le_gd);
+
+ if (gdImagePaletteToTrueColor(im) == 0) {
+ RETURN_FALSE;
+ }
+
+ RETURN_TRUE;
+}
+/* }}} */
+
/* {{{ proto bool imagecolormatch(resource im1, resource im2)
Makes the colors of the palette version of an image more closely match the true color version */
PHP_FUNCTION(imagecolormatch)
@@ -1851,7 +1796,6 @@ PHP_FUNCTION(imagesavealpha)
}
/* }}} */
-#if HAVE_GD_BUNDLED
/* {{{ proto bool imagelayereffect(resource im, int effect)
Set the alpha blending flag to use the bundled libgd layering effects */
PHP_FUNCTION(imagelayereffect)
@@ -1870,7 +1814,6 @@ PHP_FUNCTION(imagelayereffect)
RETURN_TRUE;
}
/* }}} */
-#endif
/* {{{ proto int imagecolorallocatealpha(resource im, int red, int green, int blue, int alpha)
Allocate a color with an alpha level. Works for true color and palette based images */
@@ -2145,7 +2088,7 @@ PHP_FUNCTION(imagerotate)
ZEND_FETCH_RESOURCE(im_src, gdImagePtr, &SIM, -1, "Image", le_gd);
- im_dst = gdImageRotate(im_src, degrees, color, ignoretransparent);
+ im_dst = gdImageRotateInterpolated(im_src, (float)degrees, color);
if (im_dst != NULL) {
ZEND_REGISTER_RESOURCE(return_value, im_dst, le_gd);
@@ -2155,7 +2098,6 @@ PHP_FUNCTION(imagerotate)
}
/* }}} */
-#if HAVE_GD_IMAGESETTILE
/* {{{ proto bool imagesettile(resource image, resource tile)
Set the tile image to $tile when filling $image with the "IMG_COLOR_TILED" color */
PHP_FUNCTION(imagesettile)
@@ -2175,9 +2117,7 @@ PHP_FUNCTION(imagesettile)
RETURN_TRUE;
}
/* }}} */
-#endif
-#if HAVE_GD_IMAGESETBRUSH
/* {{{ proto bool imagesetbrush(resource image, resource brush)
Set the brush image to $brush when filling $image with the "IMG_COLOR_BRUSHED" color */
PHP_FUNCTION(imagesetbrush)
@@ -2197,7 +2137,6 @@ PHP_FUNCTION(imagesetbrush)
RETURN_TRUE;
}
/* }}} */
-#endif
/* {{{ proto resource imagecreate(int x_size, int y_size)
Create a new image */
@@ -2230,19 +2169,15 @@ PHP_FUNCTION(imagecreate)
PHP_FUNCTION(imagetypes)
{
int ret=0;
-#ifdef HAVE_GD_GIF_CREATE
ret = 1;
-#endif
#ifdef HAVE_GD_JPG
ret |= 2;
#endif
#ifdef HAVE_GD_PNG
ret |= 4;
#endif
-#ifdef HAVE_GD_WBMP
ret |= 8;
-#endif
-#if defined(HAVE_GD_XPM) && defined(HAVE_GD_BUNDLED)
+#if defined(HAVE_GD_XPM)
ret |= 16;
#endif
@@ -2254,13 +2189,31 @@ PHP_FUNCTION(imagetypes)
}
/* }}} */
+/* {{{ _php_ctx_getmbi
+ */
+
+static int _php_ctx_getmbi(gdIOCtx *ctx)
+{
+ int i, mbi = 0;
+
+ do {
+ i = (ctx->getC)(ctx);
+ if (i < 0) {
+ return -1;
+ }
+ mbi = (mbi << 7) | (i & 0x7f);
+ } while (i & 0x80);
+
+ return mbi;
+}
+/* }}} */
+
/* {{{ _php_image_type
*/
static const char php_sig_gd2[3] = {'g', 'd', '2'};
static int _php_image_type (char data[8])
{
-#ifdef HAVE_LIBGD15
/* Based on ext/standard/image.c */
if (data == NULL) {
@@ -2278,34 +2231,22 @@ static int _php_image_type (char data[8])
} else if (!memcmp(data, php_sig_gif, 3)) {
return PHP_GDIMG_TYPE_GIF;
}
-#ifdef HAVE_GD_WBMP
else {
gdIOCtx *io_ctx;
io_ctx = gdNewDynamicCtxEx(8, data, 0);
if (io_ctx) {
- if (getmbi((int(*)(void *)) gdGetC, io_ctx) == 0 && skipheader((int(*)(void *)) gdGetC, io_ctx) == 0 ) {
-#if HAVE_LIBGD204
+ if (_php_ctx_getmbi(io_ctx) == 0 && _php_ctx_getmbi(io_ctx) >= 0) {
io_ctx->gd_free(io_ctx);
-#else
- io_ctx->free(io_ctx);
-#endif
return PHP_GDIMG_TYPE_WBM;
} else {
-#if HAVE_LIBGD204
io_ctx->gd_free(io_ctx);
-#else
- io_ctx->free(io_ctx);
-#endif
}
}
}
-#endif
return -1;
-#endif
}
/* }}} */
-#ifdef HAVE_LIBGD15
/* {{{ _php_image_create_from_string
*/
gdImagePtr _php_image_create_from_string(zval **data, char *tn, gdImagePtr (*ioctx_func_p)() TSRMLS_DC)
@@ -2322,19 +2263,11 @@ gdImagePtr _php_image_create_from_string(zval **data, char *tn, gdImagePtr (*ioc
im = (*ioctx_func_p)(io_ctx);
if (!im) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Passed data is not in '%s' format", tn);
-#if HAVE_LIBGD204
io_ctx->gd_free(io_ctx);
-#else
- io_ctx->free(io_ctx);
-#endif
return NULL;
}
-#if HAVE_LIBGD204
io_ctx->gd_free(io_ctx);
-#else
- io_ctx->free(io_ctx);
-#endif
return im;
}
@@ -2383,30 +2316,15 @@ PHP_FUNCTION(imagecreatefromstring)
break;
case PHP_GDIMG_TYPE_GIF:
-#ifdef HAVE_GD_GIF_READ
im = _php_image_create_from_string(data, "GIF", gdImageCreateFromGifCtx TSRMLS_CC);
-#else
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "No GIF support in this PHP build");
- RETURN_FALSE;
-#endif
break;
case PHP_GDIMG_TYPE_WBM:
-#ifdef HAVE_GD_WBMP
im = _php_image_create_from_string(data, "WBMP", gdImageCreateFromWBMPCtx TSRMLS_CC);
-#else
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "No WBMP support in this PHP build");
- RETURN_FALSE;
-#endif
break;
case PHP_GDIMG_TYPE_GD2:
-#ifdef HAVE_GD_GD2
im = _php_image_create_from_string(data, "GD2", gdImageCreateFromGd2Ctx TSRMLS_CC);
-#else
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "No GD2 support in this PHP build");
- RETURN_FALSE;
-#endif
break;
default:
@@ -2422,7 +2340,6 @@ PHP_FUNCTION(imagecreatefromstring)
ZEND_REGISTER_RESOURCE(return_value, im, le_gd);
}
/* }}} */
-#endif
/* {{{ _php_image_create_from
*/
@@ -2434,9 +2351,8 @@ static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type,
gdImagePtr im = NULL;
php_stream *stream;
FILE * fp = NULL;
-#ifdef HAVE_GD_JPG
long ignore_warning;
-#endif
+
if (image_type == PHP_GDIMG_TYPE_GD2PART) {
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sllll", &file, &file_len, &srcx, &srcy, &width, &height) == FAILURE) {
return;
@@ -2451,39 +2367,18 @@ static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type,
}
}
+
stream = php_stream_open_wrapper(file, "rb", REPORT_ERRORS|IGNORE_PATH|IGNORE_URL_WIN, NULL);
if (stream == NULL) {
RETURN_FALSE;
}
-#ifndef USE_GD_IOCTX
- ioctx_func_p = NULL; /* don't allow sockets without IOCtx */
-#endif
-
- if (image_type == PHP_GDIMG_TYPE_WEBP) {
- size_t buff_size;
- char *buff;
-
- /* needs to be malloc (persistent) - GD will free() it later */
- buff_size = php_stream_copy_to_mem(stream, &buff, PHP_STREAM_COPY_ALL, 1);
- if (!buff_size) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,"Cannot read image data");
- goto out_err;
- }
- im = (*ioctx_func_p)(buff_size, buff);
- if (!im) {
- goto out_err;
- }
- goto register_im;
- }
-
/* try and avoid allocating a FILE* if the stream is not naturally a FILE* */
if (php_stream_is(stream, PHP_STREAM_IS_STDIO)) {
if (FAILURE == php_stream_cast(stream, PHP_STREAM_AS_STDIO, (void**)&fp, REPORT_ERRORS)) {
goto out_err;
}
} else if (ioctx_func_p) {
-#ifdef USE_GD_IOCTX
/* we can create an io context */
gdIOCtx* io_ctx;
size_t buff_size;
@@ -2509,15 +2404,10 @@ static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type,
} else {
im = (*ioctx_func_p)(io_ctx);
}
-#if HAVE_LIBGD204
io_ctx->gd_free(io_ctx);
-#else
- io_ctx->free(io_ctx);
-#endif
pefree(buff, 1);
-#endif
}
- else {
+ else if (php_stream_can_cast(stream, PHP_STREAM_AS_STDIO)) {
/* try and force the stream to be FILE* */
if (FAILURE == php_stream_cast(stream, PHP_STREAM_AS_STDIO | PHP_STREAM_CAST_TRY_HARD, (void **) &fp, REPORT_ERRORS)) {
goto out_err;
@@ -2529,7 +2419,7 @@ static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type,
case PHP_GDIMG_TYPE_GD2PART:
im = (*func_p)(fp, srcx, srcy, width, height);
break;
-#if defined(HAVE_GD_XPM) && defined(HAVE_GD_BUNDLED)
+#if defined(HAVE_GD_XPM)
case PHP_GDIMG_TYPE_XPM:
im = gdImageCreateFromXpm(file);
break;
@@ -2538,11 +2428,7 @@ static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type,
#ifdef HAVE_GD_JPG
case PHP_GDIMG_TYPE_JPG:
ignore_warning = INI_INT("gd.jpeg_ignore_warning");
-#ifdef HAVE_GD_BUNDLED
- im = gdImageCreateFromJpeg(fp, ignore_warning);
-#else
- im = gdImageCreateFromJpeg(fp);
-#endif
+ im = gdImageCreateFromJpegEx(fp, ignore_warning);
break;
#endif
@@ -2554,7 +2440,7 @@ static void _php_image_create_from(INTERNAL_FUNCTION_PARAMETERS, int image_type,
fflush(fp);
}
-register_im:
+/* register_im: */
if (im) {
ZEND_REGISTER_RESOURCE(return_value, im, le_gd);
php_stream_close(stream);
@@ -2569,7 +2455,6 @@ out_err:
}
/* }}} */
-#ifdef HAVE_GD_GIF_READ
/* {{{ proto resource imagecreatefromgif(string filename)
Create a new image from GIF file or URL */
PHP_FUNCTION(imagecreatefromgif)
@@ -2577,7 +2462,6 @@ PHP_FUNCTION(imagecreatefromgif)
_php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GIF, "GIF", gdImageCreateFromGif, gdImageCreateFromGifCtx);
}
/* }}} */
-#endif /* HAVE_GD_GIF_READ */
#ifdef HAVE_GD_JPG
/* {{{ proto resource imagecreatefromjpeg(string filename)
@@ -2600,16 +2484,15 @@ PHP_FUNCTION(imagecreatefrompng)
#endif /* HAVE_GD_PNG */
#ifdef HAVE_GD_WEBP
-/* {{{ proto resource imagecreatefrompng(string filename)
- Create a new image from PNG file or URL */
+/* {{{ proto resource imagecreatefromwebp(string filename)
+ Create a new image from WEBP file or URL */
PHP_FUNCTION(imagecreatefromwebp)
{
- _php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_WEBP, "WEBP", gdImageCreateFromWebpPtr, gdImageCreateFromWebpPtr);
+ _php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_WEBP, "WEBP", gdImageCreateFromWebp, gdImageCreateFromWebpCtx);
}
/* }}} */
#endif /* HAVE_GD_VPX */
-#ifdef HAVE_GD_XBM
/* {{{ proto resource imagecreatefromxbm(string filename)
Create a new image from XBM file or URL */
PHP_FUNCTION(imagecreatefromxbm)
@@ -2617,9 +2500,8 @@ PHP_FUNCTION(imagecreatefromxbm)
_php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_XBM, "XBM", gdImageCreateFromXbm, NULL);
}
/* }}} */
-#endif /* HAVE_GD_XBM */
-#if defined(HAVE_GD_XPM) && defined(HAVE_GD_BUNDLED)
+#if defined(HAVE_GD_XPM)
/* {{{ proto resource imagecreatefromxpm(string filename)
Create a new image from XPM file or URL */
PHP_FUNCTION(imagecreatefromxpm)
@@ -2629,7 +2511,6 @@ PHP_FUNCTION(imagecreatefromxpm)
/* }}} */
#endif
-#ifdef HAVE_GD_WBMP
/* {{{ proto resource imagecreatefromwbmp(string filename)
Create a new image from WBMP file or URL */
PHP_FUNCTION(imagecreatefromwbmp)
@@ -2637,7 +2518,6 @@ PHP_FUNCTION(imagecreatefromwbmp)
_php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_WBM, "WBMP", gdImageCreateFromWBMP, gdImageCreateFromWBMPCtx);
}
/* }}} */
-#endif /* HAVE_GD_WBMP */
/* {{{ proto resource imagecreatefromgd(string filename)
Create a new image from GD file or URL */
@@ -2647,7 +2527,6 @@ PHP_FUNCTION(imagecreatefromgd)
}
/* }}} */
-#ifdef HAVE_GD_GD2
/* {{{ proto resource imagecreatefromgd2(string filename)
Create a new image from GD2 file or URL */
PHP_FUNCTION(imagecreatefromgd2)
@@ -2663,7 +2542,6 @@ PHP_FUNCTION(imagecreatefromgd2part)
_php_image_create_from(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GD2PART, "GD2", gdImageCreateFromGd2Part, gdImageCreateFromGd2PartCtx);
}
/* }}} */
-#endif /* HAVE_GD_GD2 */
/* {{{ _php_image_output
*/
@@ -2708,7 +2586,6 @@ static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char
}
switch (image_type) {
-#ifdef HAVE_GD_WBMP
case PHP_GDIMG_CONVERT_WBM:
if (q == -1) {
q = 0;
@@ -2718,7 +2595,6 @@ static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char
}
gdImageWBMP(im, q, fp);
break;
-#endif
case PHP_GDIMG_TYPE_JPG:
(*func_p)(im, fp, q);
break;
@@ -2734,14 +2610,12 @@ static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char
}
(*func_p)(im, fp);
break;
-#ifdef HAVE_GD_GD2
case PHP_GDIMG_TYPE_GD2:
if (q == -1) {
q = 128;
}
(*func_p)(im, fp, q, t);
break;
-#endif
default:
if (q == -1) {
q = 128;
@@ -2764,7 +2638,6 @@ static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char
}
switch (image_type) {
-#ifdef HAVE_GD_WBMP
case PHP_GDIMG_CONVERT_WBM:
if (q == -1) {
q = 0;
@@ -2774,7 +2647,6 @@ static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char
}
gdImageWBMP(im, q, tmp);
break;
-#endif
case PHP_GDIMG_TYPE_JPG:
(*func_p)(im, tmp, q);
break;
@@ -2792,14 +2664,12 @@ static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char
}
(*func_p)(im, tmp);
break;
-#ifdef HAVE_GD_GD2
case PHP_GDIMG_TYPE_GD2:
if (q == -1) {
q = 128;
}
(*func_p)(im, tmp, q, t);
break;
-#endif
default:
(*func_p)(im, tmp);
break;
@@ -2827,15 +2697,12 @@ static void _php_image_output(INTERNAL_FUNCTION_PARAMETERS, int image_type, char
/* {{{ proto int imagexbm(int im, string filename [, int foreground])
Output XBM image to browser or file */
-#if HAVE_GD_BUNDLED
PHP_FUNCTION(imagexbm)
{
_php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_XBM, "XBM", gdImageXbmCtx);
}
-#endif
/* }}} */
-#ifdef HAVE_GD_GIF_CREATE
/* {{{ proto bool imagegif(resource im [, string filename])
Output GIF image to browser or file */
PHP_FUNCTION(imagegif)
@@ -2843,7 +2710,6 @@ PHP_FUNCTION(imagegif)
_php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GIF, "GIF", gdImageGifCtx);
}
/* }}} */
-#endif /* HAVE_GD_GIF_CREATE */
#ifdef HAVE_GD_PNG
/* {{{ proto bool imagepng(resource im [, string filename])
@@ -2858,7 +2724,7 @@ PHP_FUNCTION(imagepng)
#ifdef HAVE_GD_WEBP
/* {{{ proto bool imagewebp(resource im [, string filename[, quality]] )
- Output PNG image to browser or file */
+ Output WEBP image to browser or file */
PHP_FUNCTION(imagewebp)
{
_php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_WEBP, "WEBP", gdImageWebpCtx);
@@ -2877,7 +2743,6 @@ PHP_FUNCTION(imagejpeg)
/* }}} */
#endif /* HAVE_GD_JPG */
-#ifdef HAVE_GD_WBMP
/* {{{ proto bool imagewbmp(resource im [, string filename, [, int foreground]])
Output WBMP image to browser or file */
PHP_FUNCTION(imagewbmp)
@@ -2885,7 +2750,6 @@ PHP_FUNCTION(imagewbmp)
_php_image_output_ctx(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_WBM, "WBMP", gdImageWBMPCtx);
}
/* }}} */
-#endif /* HAVE_GD_WBMP */
/* {{{ proto bool imagegd(resource im [, string filename])
Output GD image to browser or file */
@@ -2895,7 +2759,6 @@ PHP_FUNCTION(imagegd)
}
/* }}} */
-#ifdef HAVE_GD_GD2
/* {{{ proto bool imagegd2(resource im [, string filename, [, int chunk_size, [, int type]]])
Output GD2 image to browser or file */
PHP_FUNCTION(imagegd2)
@@ -2903,7 +2766,6 @@ PHP_FUNCTION(imagegd2)
_php_image_output(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_TYPE_GD2, "GD2", gdImageGd2);
}
/* }}} */
-#endif /* HAVE_GD_GD2 */
/* {{{ proto bool imagedestroy(resource im)
Destroy an image */
@@ -2948,7 +2810,6 @@ PHP_FUNCTION(imagecolorallocate)
}
/* }}} */
-#if HAVE_LIBGD15
/* {{{ proto void imagepalettecopy(resource dst, resource src)
Copy the palette from the src image onto the dst image */
PHP_FUNCTION(imagepalettecopy)
@@ -2966,7 +2827,6 @@ PHP_FUNCTION(imagepalettecopy)
gdImagePaletteCopy(dst, src);
}
/* }}} */
-#endif
/* {{{ proto int imagecolorat(resource im, int x, int y)
Get the index of the color of a pixel */
@@ -3018,7 +2878,6 @@ PHP_FUNCTION(imagecolorclosest)
}
/* }}} */
-#if HAVE_COLORCLOSESTHWB
/* {{{ proto int imagecolorclosesthwb(resource im, int red, int green, int blue)
Get the index of the color which has the hue, white and blackness nearest to the given color */
PHP_FUNCTION(imagecolorclosesthwb)
@@ -3036,7 +2895,6 @@ PHP_FUNCTION(imagecolorclosesthwb)
RETURN_LONG(gdImageColorClosestHWB(im, red, green, blue));
}
/* }}} */
-#endif
/* {{{ proto bool imagecolordeallocate(resource im, int index)
De-allocate a color for an image */
@@ -3494,14 +3352,26 @@ static void php_imagepolygon(INTERNAL_FUNCTION_PARAMETERS, int filled)
for (i = 0; i < npoints; i++) {
if (zend_hash_index_find(Z_ARRVAL_P(POINTS), (i * 2), (void **) &var) == SUCCESS) {
- SEPARATE_ZVAL((var));
- convert_to_long(*var);
- points[i].x = Z_LVAL_PP(var);
+ if (Z_TYPE_PP(var) != IS_LONG) {
+ zval lval;
+ lval = **var;
+ zval_copy_ctor(&lval);
+ convert_to_long(&lval);
+ points[i].x = Z_LVAL(lval);
+ } else {
+ points[i].x = Z_LVAL_PP(var);
+ }
}
if (zend_hash_index_find(Z_ARRVAL_P(POINTS), (i * 2) + 1, (void **) &var) == SUCCESS) {
- SEPARATE_ZVAL(var);
- convert_to_long(*var);
- points[i].y = Z_LVAL_PP(var);
+ if (Z_TYPE_PP(var) != IS_LONG) {
+ zval lval;
+ lval = **var;
+ zval_copy_ctor(&lval);
+ convert_to_long(&lval);
+ points[i].y = Z_LVAL(lval);
+ } else {
+ points[i].y = Z_LVAL_PP(var);
+ }
}
}
@@ -3758,7 +3628,6 @@ PHP_FUNCTION(imagecopy)
}
/* }}} */
-#if HAVE_LIBGD15
/* {{{ proto bool imagecopymerge(resource src_im, resource dst_im, int dst_x, int dst_y, int src_x, int src_y, int src_w, int src_h, int pct)
Merge one part of an image with another */
PHP_FUNCTION(imagecopymerge)
@@ -3816,7 +3685,6 @@ PHP_FUNCTION(imagecopymergegray)
RETURN_TRUE;
}
/* }}} */
-#endif
/* {{{ proto bool imagecopyresized(resource dst_im, resource src_im, int dst_x, int dst_y, int src_x, int src_y, int dst_w, int dst_h, int src_w, int src_h)
Copy and resize part of an image */
@@ -3894,7 +3762,7 @@ PHP_FUNCTION(imagesy)
#ifdef ENABLE_GD_TTF
-#if HAVE_LIBFREETYPE && HAVE_GD_STRINGFTEX
+#if HAVE_GD_FREETYPE && HAVE_LIBFREETYPE
/* {{{ proto array imageftbbox(float size, float angle, string font_file, string text [, array extrainfo])
Give the bounding box of a text using fonts via freetype2 */
PHP_FUNCTION(imageftbbox)
@@ -3910,7 +3778,7 @@ PHP_FUNCTION(imagefttext)
php_imagettftext_common(INTERNAL_FUNCTION_PARAM_PASSTHRU, TTFTEXT_DRAW, 1);
}
/* }}} */
-#endif
+#endif /* HAVE_GD_FREETYPE && HAVE_LIBFREETYPE */
/* {{{ proto array imagettfbbox(float size, float angle, string font_file, string text)
Give the bounding box of a text using TrueType fonts */
@@ -3940,13 +3808,7 @@ static void php_imagettftext_common(INTERNAL_FUNCTION_PARAMETERS, int mode, int
char *str = NULL, *fontname = NULL;
char *error = NULL;
int argc = ZEND_NUM_ARGS();
-#if HAVE_GD_STRINGFTEX
gdFTStringExtra strex = {0};
-#endif
-
-#if !HAVE_GD_STRINGFTEX
- assert(!extended);
-#endif
if (mode == TTFTEXT_BBOX) {
if (argc < 4 || argc > ((extended) ? 5 : 4)) {
@@ -3966,7 +3828,6 @@ static void php_imagettftext_common(INTERNAL_FUNCTION_PARAMETERS, int mode, int
/* convert angle to radians */
angle = angle * (M_PI/180);
-#if HAVE_GD_STRINGFTEX
if (extended && EXT) { /* parse extended info */
HashPosition pos;
@@ -3993,7 +3854,6 @@ static void php_imagettftext_common(INTERNAL_FUNCTION_PARAMETERS, int mode, int
} while (zend_hash_move_forward_ex(HASH_OF(EXT), &pos) == SUCCESS);
}
-#endif
#ifdef VIRTUAL_DIR
{
@@ -4003,25 +3863,18 @@ static void php_imagettftext_common(INTERNAL_FUNCTION_PARAMETERS, int mode, int
fontname = NULL;
}
}
-#endif
+#endif /* VIRTUAL_DIR */
PHP_GD_CHECK_OPEN_BASEDIR(fontname, "Invalid font filename");
-#ifdef USE_GD_IMGSTRTTF
-# if HAVE_GD_STRINGFTEX
+#ifdef HAVE_GD_FREETYPE
if (extended) {
error = gdImageStringFTEx(im, brect, col, fontname, ptsize, angle, x, y, str, &strex);
}
else
-# endif
+ error = gdImageStringFT(im, brect, col, fontname, ptsize, angle, x, y, str);
-# if HAVE_GD_STRINGFT
- error = gdImageStringFT(im, brect, col, fontname, ptsize, angle, x, y, str);
-# elif HAVE_GD_STRINGTTF
- error = gdImageStringTTF(im, brect, col, fontname, ptsize, angle, x, y, str);
-# endif
-
-#endif
+#endif /* HAVE_GD_FREETYPE */
if (error) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", error);
@@ -4492,7 +4345,6 @@ PHP_FUNCTION(imagepsbbox)
/* }}} */
#endif
-#ifdef HAVE_GD_WBMP
/* {{{ proto bool image2wbmp(resource im [, string filename [, int threshold]])
Output WBMP image to browser or file */
PHP_FUNCTION(image2wbmp)
@@ -4500,9 +4352,8 @@ PHP_FUNCTION(image2wbmp)
_php_image_output(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GDIMG_CONVERT_WBM, "WBMP", _php_image_bw_convert);
}
/* }}} */
-#endif /* HAVE_GD_WBMP */
-#if defined(HAVE_GD_JPG) && defined(HAVE_GD_WBMP)
+#if defined(HAVE_GD_JPG)
/* {{{ proto bool jpeg2wbmp (string f_org, string f_dest, int d_height, int d_width, int threshold)
Convert JPEG image to WBMP image */
PHP_FUNCTION(jpeg2wbmp)
@@ -4512,7 +4363,7 @@ PHP_FUNCTION(jpeg2wbmp)
/* }}} */
#endif
-#if defined(HAVE_GD_PNG) && defined(HAVE_GD_WBMP)
+#if defined(HAVE_GD_PNG)
/* {{{ proto bool png2wbmp (string f_org, string f_dest, int d_height, int d_width, int threshold)
Convert PNG image to WBMP image */
PHP_FUNCTION(png2wbmp)
@@ -4522,7 +4373,6 @@ PHP_FUNCTION(png2wbmp)
/* }}} */
#endif
-#ifdef HAVE_GD_WBMP
/* {{{ _php_image_bw_convert
* It converts a gd Image to bw using a threshold value */
static void _php_image_bw_convert(gdImagePtr im_org, gdIOCtx *out, int threshold)
@@ -4569,11 +4419,7 @@ static void _php_image_bw_convert(gdImagePtr im_org, gdIOCtx *out, int threshold
gdImageSetPixel (im_dest, x, y, color);
}
}
-#ifdef USE_GD_IOCTX
gdImageWBMPCtx (im_dest, black, out);
-#else
- gdImageWBMP (im_dest, black, out);
-#endif
}
/* }}} */
@@ -4597,9 +4443,7 @@ static void _php_image_convert(INTERNAL_FUNCTION_PARAMETERS, int image_type )
int int_threshold;
int x, y;
float x_ratio, y_ratio;
-#ifdef HAVE_GD_JPG
long ignore_warning;
-#endif
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "pplll", &f_org, &f_org_len, &f_dest, &f_dest_len, &height, &width, &threshold) == FAILURE) {
return;
@@ -4638,7 +4482,6 @@ static void _php_image_convert(INTERNAL_FUNCTION_PARAMETERS, int image_type )
}
switch (image_type) {
-#ifdef HAVE_GD_GIF_READ
case PHP_GDIMG_TYPE_GIF:
im_org = gdImageCreateFromGif(org);
if (im_org == NULL) {
@@ -4646,16 +4489,11 @@ static void _php_image_convert(INTERNAL_FUNCTION_PARAMETERS, int image_type )
RETURN_FALSE;
}
break;
-#endif /* HAVE_GD_GIF_READ */
#ifdef HAVE_GD_JPG
case PHP_GDIMG_TYPE_JPG:
ignore_warning = INI_INT("gd.jpeg_ignore_warning");
-#ifdef HAVE_GD_BUNDLED
- im_org = gdImageCreateFromJpeg(org, ignore_warning);
-#else
- im_org = gdImageCreateFromJpeg(org);
-#endif
+ im_org = gdImageCreateFromJpegEx(org, ignore_warning);
if (im_org == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open '%s' Not a valid JPEG file", fn_dest);
RETURN_FALSE;
@@ -4663,7 +4501,6 @@ static void _php_image_convert(INTERNAL_FUNCTION_PARAMETERS, int image_type )
break;
#endif /* HAVE_GD_JPG */
-
#ifdef HAVE_GD_PNG
case PHP_GDIMG_TYPE_PNG:
im_org = gdImageCreateFromPng(org);
@@ -4764,9 +4601,6 @@ static void _php_image_convert(INTERNAL_FUNCTION_PARAMETERS, int image_type )
RETURN_TRUE;
}
/* }}} */
-#endif /* HAVE_GD_WBMP */
-
-#endif /* HAVE_LIBGD */
/* Section Filters */
#define PHP_GD_SINGLE_RES \
@@ -5043,9 +4877,15 @@ PHP_FUNCTION(imageconvolution)
for (j=0; j<3; j++) {
if (zend_hash_index_find(Z_ARRVAL_PP(var), (j), (void **) &var2) == SUCCESS) {
- SEPARATE_ZVAL(var2);
- convert_to_double(*var2);
- matrix[i][j] = Z_DVAL_PP(var2);
+ if (Z_TYPE_PP(var2) != IS_DOUBLE) {
+ zval dval;
+ dval = **var;
+ zval_copy_ctor(&dval);
+ convert_to_double(&dval);
+ matrix[i][j] = (float)Z_DVAL(dval);
+ } else {
+ matrix[i][j] = (float)Z_DVAL_PP(var2);
+ }
} else {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "You must have a 3x3 matrix");
RETURN_FALSE;
@@ -5053,7 +4893,7 @@ PHP_FUNCTION(imageconvolution)
}
}
}
- res = gdImageConvolution(im_src, matrix, div, offset);
+ res = gdImageConvolution(im_src, matrix, (float)div, (float)offset);
if (res) {
RETURN_TRUE;
@@ -5064,6 +4904,42 @@ PHP_FUNCTION(imageconvolution)
/* }}} */
/* End section: Filters */
+/* {{{ proto void imageflip(resource im, int mode)
+ Flip an image (in place) horizontally, vertically or both directions. */
+PHP_FUNCTION(imageflip)
+{
+ zval *IM;
+ long mode;
+ gdImagePtr im;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &IM, &mode) == FAILURE) {
+ return;
+ }
+
+ ZEND_FETCH_RESOURCE(im, gdImagePtr, &IM, -1, "Image", le_gd);
+
+ switch (mode) {
+ case GD_FLIP_VERTICAL:
+ gdImageFlipVertical(im);
+ break;
+
+ case GD_FLIP_HORINZONTAL:
+ gdImageFlipHorizontal(im);
+ break;
+
+ case GD_FLIP_BOTH:
+ gdImageFlipBoth(im);
+ break;
+
+ default:
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown flip mode");
+ RETURN_FALSE;
+ }
+
+ RETURN_TRUE;
+}
+/* }}} */
+
#ifdef HAVE_GD_BUNDLED
/* {{{ proto bool imageantialias(resource im, bool on)
Should antialiased functions used or not*/
@@ -5084,6 +4960,517 @@ PHP_FUNCTION(imageantialias)
/* }}} */
#endif
+/* {{{ proto void imagecrop(resource im, array rect)
+ Crop an image using the given coordinates and size, x, y, width and height. */
+PHP_FUNCTION(imagecrop)
+{
+ zval *IM;
+ gdImagePtr im;
+ gdImagePtr im_crop;
+ gdRect rect;
+ zval *z_rect;
+ zval **tmp;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra", &IM, &z_rect) == FAILURE) {
+ return;
+ }
+
+ ZEND_FETCH_RESOURCE(im, gdImagePtr, &IM, -1, "Image", le_gd);
+
+ if (zend_hash_find(HASH_OF(z_rect), "x", sizeof("x"), (void **)&tmp) != FAILURE) {
+ if (Z_TYPE_PP(tmp) != IS_LONG) {
+ zval lval;
+ lval = **tmp;
+ zval_copy_ctor(&lval);
+ convert_to_long(&lval);
+ rect.x = Z_LVAL(lval);
+ } else {
+ rect.x = Z_LVAL_PP(tmp);
+ }
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing x position");
+ RETURN_FALSE;
+ }
+
+ if (zend_hash_find(HASH_OF(z_rect), "y", sizeof("x"), (void **)&tmp) != FAILURE) {
+ if (Z_TYPE_PP(tmp) != IS_LONG) {
+ zval lval;
+ lval = **tmp;
+ zval_copy_ctor(&lval);
+ convert_to_long(&lval);
+ rect.y = Z_LVAL(lval);
+ } else {
+ rect.y = Z_LVAL_PP(tmp);
+ }
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing y position");
+ RETURN_FALSE;
+ }
+
+ if (zend_hash_find(HASH_OF(z_rect), "width", sizeof("width"), (void **)&tmp) != FAILURE) {
+ if (Z_TYPE_PP(tmp) != IS_LONG) {
+ zval lval;
+ lval = **tmp;
+ zval_copy_ctor(&lval);
+ convert_to_long(&lval);
+ rect.width = Z_LVAL(lval);
+ } else {
+ rect.width = Z_LVAL_PP(tmp);
+ }
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing width");
+ RETURN_FALSE;
+ }
+
+ if (zend_hash_find(HASH_OF(z_rect), "height", sizeof("height"), (void **)&tmp) != FAILURE) {
+ if (Z_TYPE_PP(tmp) != IS_LONG) {
+ zval lval;
+ lval = **tmp;
+ zval_copy_ctor(&lval);
+ convert_to_long(&lval);
+ rect.height = Z_LVAL(lval);
+ } else {
+ rect.height = Z_LVAL_PP(tmp);
+ }
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing height");
+ RETURN_FALSE;
+ }
+
+ im_crop = gdImageCrop(im, &rect);
+
+ if (im_crop == NULL) {
+ RETURN_FALSE;
+ } else {
+ ZEND_REGISTER_RESOURCE(return_value, im_crop, le_gd);
+ }
+}
+/* }}} */
+
+/* {{{ proto void imagecropauto(resource im [, int mode [, threshold [, color]]])
+ Crop an image automatically using one of the available modes. */
+PHP_FUNCTION(imagecropauto)
+{
+ zval *IM;
+ long mode = -1;
+ long color = -1;
+ double threshold = 0.5f;
+ gdImagePtr im;
+ gdImagePtr im_crop;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|ldl", &IM, &mode, &threshold, &color) == FAILURE) {
+ return;
+ }
+
+ ZEND_FETCH_RESOURCE(im, gdImagePtr, &IM, -1, "Image", le_gd);
+
+ switch (mode) {
+ case -1:
+ mode = GD_CROP_DEFAULT;
+ case GD_CROP_DEFAULT:
+ case GD_CROP_TRANSPARENT:
+ case GD_CROP_BLACK:
+ case GD_CROP_WHITE:
+ case GD_CROP_SIDES:
+ im_crop = gdImageCropAuto(im, mode);
+ break;
+
+ case GD_CROP_THRESHOLD:
+ if (color < 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Color argument missing with threshold mode");
+ RETURN_FALSE;
+ }
+ im_crop = gdImageCropThreshold(im, color, (float) threshold);
+ break;
+
+ default:
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown crop mode");
+ RETURN_FALSE;
+ }
+ if (im_crop == NULL) {
+ RETURN_FALSE;
+ } else {
+ ZEND_REGISTER_RESOURCE(return_value, im_crop, le_gd);
+ }
+}
+/* }}} */
+
+/* {{{ proto resource imagescale(resource im, new_width[, new_height[, method]])
+ Scale an image using the given new width and height. */
+PHP_FUNCTION(imagescale)
+{
+ zval *IM;
+ gdImagePtr im;
+ gdImagePtr im_scaled;
+ int new_width, new_height = -1;
+ gdInterpolationMethod method = GD_BILINEAR_FIXED;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|ll", &IM, &new_width, &new_height, &method) == FAILURE) {
+ return;
+ }
+
+ ZEND_FETCH_RESOURCE(im, gdImagePtr, &IM, -1, "Image", le_gd);
+ im_scaled = gdImageScale(im, new_width, new_height);
+ goto finish;
+ switch (method) {
+ case GD_NEAREST_NEIGHBOUR:
+ im_scaled = gdImageScaleNearestNeighbour(im, new_width, new_height);
+ break;
+
+ case GD_BILINEAR_FIXED:
+ im_scaled = gdImageScaleBilinear(im, new_width, new_height);
+ break;
+
+ case GD_BICUBIC:
+ im_scaled = gdImageScaleBicubicFixed(im, new_width, new_height);
+ break;
+
+ case GD_BICUBIC_FIXED:
+ im_scaled = gdImageScaleBicubicFixed(im, new_width, new_height);
+ break;
+
+ default:
+ im_scaled = gdImageScaleTwoPass(im, im->sx, im->sy, new_width, new_height);
+ break;
+
+ }
+finish:
+ if (im_scaled == NULL) {
+ RETURN_FALSE;
+ } else {
+ ZEND_REGISTER_RESOURCE(return_value, im_scaled, le_gd);
+ }
+}
+/* }}} */
+
+/* {{{ proto resource imageaffine(resource src, array affine[, array clip])
+ Return an image containing the affine tramsformed src image, using an optional clipping area */
+PHP_FUNCTION(imageaffine)
+{
+ zval *IM;
+ gdImagePtr src;
+ gdImagePtr dst;
+ gdRect rect;
+ gdRectPtr pRect = NULL;
+ zval *z_rect = NULL;
+ zval *z_affine;
+ zval **tmp;
+ double affine[6];
+ int i, nelems;
+ zval **zval_affine_elem = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra|a", &IM, &z_affine, &z_rect) == FAILURE) {
+ return;
+ }
+
+ ZEND_FETCH_RESOURCE(src, gdImagePtr, &IM, -1, "Image", le_gd);
+
+ if ((nelems = zend_hash_num_elements(Z_ARRVAL_P(z_affine))) != 6) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Affine array must have six elements");
+ RETURN_FALSE;
+ }
+
+ for (i = 0; i < nelems; i++) {
+ if (zend_hash_index_find(Z_ARRVAL_P(z_affine), i, (void **) &zval_affine_elem) == SUCCESS) {
+ switch (Z_TYPE_PP(zval_affine_elem)) {
+ case IS_LONG:
+ affine[i] = Z_LVAL_PP(zval_affine_elem);
+ break;
+ case IS_DOUBLE:
+ affine[i] = Z_DVAL_PP(zval_affine_elem);
+ break;
+ case IS_STRING:
+ {
+ zval dval;
+ dval = **zval_affine_elem;
+ zval_copy_ctor(&dval);
+ convert_to_double(&dval);
+ affine[i] = Z_DVAL(dval);
+ }
+ break;
+ default:
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid type for element %i", i);
+ RETURN_FALSE;
+ }
+ }
+ }
+
+ if (z_rect != NULL) {
+ if (zend_hash_find(HASH_OF(z_rect), "x", sizeof("x"), (void **)&tmp) != FAILURE) {
+ if (Z_TYPE_PP(tmp) != IS_LONG) {
+ zval lval;
+ lval = **tmp;
+ zval_copy_ctor(&lval);
+ convert_to_long(&lval);
+ rect.x = Z_LVAL(lval);
+ } else {
+ rect.x = Z_LVAL_PP(tmp);
+ }
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing x position");
+ RETURN_FALSE;
+ }
+
+ if (zend_hash_find(HASH_OF(z_rect), "y", sizeof("x"), (void **)&tmp) != FAILURE) {
+ if (Z_TYPE_PP(tmp) != IS_LONG) {
+ zval lval;
+ lval = **tmp;
+ zval_copy_ctor(&lval);
+ convert_to_long(&lval);
+ rect.y = Z_LVAL(lval);
+ } else {
+ rect.y = Z_LVAL_PP(tmp);
+ }
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing y position");
+ RETURN_FALSE;
+ }
+
+ if (zend_hash_find(HASH_OF(z_rect), "width", sizeof("width"), (void **)&tmp) != FAILURE) {
+ if (Z_TYPE_PP(tmp) != IS_LONG) {
+ zval lval;
+ lval = **tmp;
+ zval_copy_ctor(&lval);
+ convert_to_long(&lval);
+ rect.width = Z_LVAL(lval);
+ } else {
+ rect.width = Z_LVAL_PP(tmp);
+ }
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing width");
+ RETURN_FALSE;
+ }
+
+ if (zend_hash_find(HASH_OF(z_rect), "height", sizeof("height"), (void **)&tmp) != FAILURE) {
+ if (Z_TYPE_PP(tmp) != IS_LONG) {
+ zval lval;
+ lval = **tmp;
+ zval_copy_ctor(&lval);
+ convert_to_long(&lval);
+ rect.height = Z_LVAL(lval);
+ } else {
+ rect.height = Z_LVAL_PP(tmp);
+ }
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing height");
+ RETURN_FALSE;
+ }
+ pRect = &rect;
+ } else {
+ rect.x = -1;
+ rect.y = -1;
+ rect.width = gdImageSX(src);
+ rect.height = gdImageSY(src);
+ pRect = NULL;
+ }
+
+
+ //int gdTransformAffineGetImage(gdImagePtr *dst, const gdImagePtr src, gdRectPtr src_area, const double affine[6]);
+ if (gdTransformAffineGetImage(&dst, src, pRect, affine) != GD_TRUE) {
+ RETURN_FALSE;
+ }
+
+ if (dst == NULL) {
+ RETURN_FALSE;
+ } else {
+ ZEND_REGISTER_RESOURCE(return_value, dst, le_gd);
+ }
+}
+/* }}} */
+
+/* {{{ proto array imageaffinematrixget(type[, options])
+ Return an image containing the affine tramsformed src image, using an optional clipping area */
+PHP_FUNCTION(imageaffinematrixget)
+{
+ double affine[6];
+ long type;
+ zval *options;
+ zval **tmp;
+ int res = GD_FALSE, i;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|z", &type, &options) == FAILURE) {
+ return;
+ }
+
+ switch((gdAffineStandardMatrix)type) {
+ case GD_AFFINE_TRANSLATE:
+ case GD_AFFINE_SCALE: {
+ double x, y;
+ if (Z_TYPE_P(options) != IS_ARRAY) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Array expected as options");
+ }
+ if (zend_hash_find(HASH_OF(options), "x", sizeof("x"), (void **)&tmp) != FAILURE) {
+ if (Z_TYPE_PP(tmp) != IS_DOUBLE) {
+ zval dval;
+ dval = **tmp;
+ zval_copy_ctor(&dval);
+ convert_to_double(&dval);
+ x = Z_DVAL(dval);
+ } else {
+ x = Z_DVAL_PP(tmp);
+ }
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing x position");
+ RETURN_FALSE;
+ }
+
+ if (zend_hash_find(HASH_OF(options), "y", sizeof("y"), (void **)&tmp) != FAILURE) {
+ if (Z_TYPE_PP(tmp) != IS_DOUBLE) {
+ zval dval;
+ dval = **tmp;
+ zval_copy_ctor(&dval);
+ convert_to_double(&dval);
+ y = Z_DVAL(dval);
+ } else {
+ y = Z_DVAL_PP(tmp);
+ }
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Missing y position");
+ RETURN_FALSE;
+ }
+
+ if (type == GD_AFFINE_TRANSLATE) {
+ res = gdAffineTranslate(affine, x, y);
+ } else {
+ res = gdAffineScale(affine, x, y);
+ }
+ break;
+ }
+
+ case GD_AFFINE_ROTATE:
+ case GD_AFFINE_SHEAR_HORIZONTAL:
+ case GD_AFFINE_SHEAR_VERTICAL: {
+ double angle;
+
+ convert_to_double_ex(&options);
+ angle = Z_DVAL_P(options);
+
+ if (type == GD_AFFINE_SHEAR_HORIZONTAL) {
+ res = gdAffineShearHorizontal(affine, angle);
+ } else if (type == GD_AFFINE_SHEAR_VERTICAL) {
+ res = gdAffineShearVertical(affine, angle);
+ } else {
+ res = gdAffineRotate(affine, angle);
+ }
+ break;
+ }
+
+ default:
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid type for element %li", type);
+ RETURN_FALSE;
+ }
+
+ if (res == GD_FALSE) {
+ RETURN_FALSE;
+ } else {
+ array_init(return_value);
+ for (i = 0; i < 6; i++) {
+ add_index_double(return_value, i, affine[i]);
+ }
+ }
+}
+
+
+/* {{{ proto array imageaffineconcat(array m1, array m2)
+ Concat two matrices (as in doing many ops in one go) */
+PHP_FUNCTION(imageaffinematrixconcat)
+{
+ double m1[6];
+ double m2[6];
+ double mr[6];
+
+ zval **tmp;
+ zval *z_m1;
+ zval *z_m2;
+ int i, nelems;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "aa", &z_m1, &z_m2) == FAILURE) {
+ return;
+ }
+
+ if (((nelems = zend_hash_num_elements(Z_ARRVAL_P(z_m1))) != 6) || (nelems = zend_hash_num_elements(Z_ARRVAL_P(z_m2))) != 6) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Affine arrays must have six elements");
+ RETURN_FALSE;
+ }
+
+ for (i = 0; i < 6; i++) {
+ if (zend_hash_index_find(Z_ARRVAL_P(z_m1), i, (void **) &tmp) == SUCCESS) {
+ switch (Z_TYPE_PP(tmp)) {
+ case IS_LONG:
+ m1[i] = Z_LVAL_PP(tmp);
+ break;
+ case IS_DOUBLE:
+ m1[i] = Z_DVAL_PP(tmp);
+ break;
+ case IS_STRING:
+ {
+ zval dval;
+ dval = **tmp;
+ zval_copy_ctor(&dval);
+ convert_to_double(&dval);
+ m1[i] = Z_DVAL(dval);
+ }
+ break;
+ default:
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid type for element %i", i);
+ RETURN_FALSE;
+ }
+ }
+ if (zend_hash_index_find(Z_ARRVAL_P(z_m2), i, (void **) &tmp) == SUCCESS) {
+ switch (Z_TYPE_PP(tmp)) {
+ case IS_LONG:
+ m2[i] = Z_LVAL_PP(tmp);
+ break;
+ case IS_DOUBLE:
+ m2[i] = Z_DVAL_PP(tmp);
+ break;
+ case IS_STRING:
+ {
+ zval dval;
+ dval = **tmp;
+ zval_copy_ctor(&dval);
+ convert_to_double(&dval);
+ m2[i] = Z_DVAL(dval);
+ }
+ break;
+ default:
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid type for element %i", i);
+ RETURN_FALSE;
+ }
+ }
+ }
+
+ if (gdAffineConcat (mr, m1, m2) != GD_TRUE) {
+ RETURN_FALSE;
+ }
+
+ array_init(return_value);
+ for (i = 0; i < 6; i++) {
+ add_index_double(return_value, i, mr[i]);
+ }
+}
+
+/* {{{ proto resource imagesetinterpolation(resource im, [, method]])
+ Set the default interpolation method, passing -1 or 0 sets it to the libgd default (bilinear). */
+PHP_FUNCTION(imagesetinterpolation)
+{
+ zval *IM;
+ gdImagePtr im;
+ long method = GD_BILINEAR_FIXED;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &IM, &method) == FAILURE) {
+ return;
+ }
+
+ ZEND_FETCH_RESOURCE(im, gdImagePtr, &IM, -1, "Image", le_gd);
+
+ if (method == -1) {
+ method = GD_BILINEAR_FIXED;
+ }
+ RETURN_BOOL(gdImageSetInterpolationMethod(im, (gdInterpolationMethod) method));
+}
+/* }}} */
+
/*
* Local variables:
* tab-width: 4
diff --git a/ext/gd/gd_compat.c b/ext/gd/gd_compat.c
new file mode 100644
index 0000000000..dc6a95ae11
--- /dev/null
+++ b/ext/gd/gd_compat.c
@@ -0,0 +1,63 @@
+#include "php_config.h"
+
+#ifdef HAVE_GD_PNG
+/* needs to be first */
+# include <png.h>
+#endif
+
+#ifdef HAVE_GD_JPG
+# include <jpeglib.h>
+#endif
+
+#include "gd_compat.h"
+#include "php.h"
+
+#ifdef HAVE_GD_JPG
+int gdJpegGetVersionInt()
+{
+ return JPEG_LIB_VERSION;
+}
+
+const char * gdJpegGetVersionString()
+{
+ switch(JPEG_LIB_VERSION) {
+ case 62:
+ return "6b";
+ break;
+
+ case 70:
+ return "7";
+ break;
+
+ case 80:
+ return "8";
+ break;
+
+ default:
+ return "unknown";
+ }
+}
+#endif
+
+#ifdef HAVE_GD_PNG
+const char * gdPngGetVersionString()
+{
+ return PNG_LIBPNG_VER_STRING;
+}
+#endif
+
+int overflow2(int a, int b)
+{
+ TSRMLS_FETCH();
+
+ if(a <= 0 || b <= 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "gd warning: one parameter to a memory allocation multiplication is negative or zero, failing operation gracefully\n");
+ return 1;
+ }
+ if(a > INT_MAX / b) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "gd warning: product of memory allocation multiplication would exceed INT_MAX, failing operation gracefully\n");
+ return 1;
+ }
+ return 0;
+}
+
diff --git a/ext/gd/gd_compat.h b/ext/gd/gd_compat.h
new file mode 100644
index 0000000000..db757f5988
--- /dev/null
+++ b/ext/gd/gd_compat.h
@@ -0,0 +1,14 @@
+#ifndef GD_COMPAT_H
+#define GD_COMPAT_H 1
+
+#ifndef HAVE_GD_BUNDLED
+/* from gd_compat.c */
+const char * gdPngGetVersionString();
+const char * gdJpegGetVersionString();
+int gdJpegGetVersionInt();
+#endif
+
+/* from gd_compat.c of libgd/gd_security.c */
+int overflow2(int a, int b);
+
+#endif /* GD_COMPAT_H */
diff --git a/ext/gd/gd_ctx.c b/ext/gd/gd_ctx.c
index bff691fad2..59eff80443 100644
--- a/ext/gd/gd_ctx.c
+++ b/ext/gd/gd_ctx.c
@@ -189,11 +189,7 @@ static void _php_image_output_ctx(INTERNAL_FUNCTION_PARAMETERS, int image_type,
break;
}
-#if HAVE_LIBGD204
ctx->gd_free(ctx);
-#else
- ctx->free(ctx);
-#endif
RETURN_TRUE;
}
diff --git a/ext/gd/gdcache.c b/ext/gd/gdcache.c
index 2349e38b93..2af6737f74 100644
--- a/ext/gd/gdcache.c
+++ b/ext/gd/gdcache.c
@@ -44,7 +44,7 @@
#else
#include <php_config.h>
#endif
-#if HAVE_LIBFREETYPE && !defined(HAVE_GD_CACHE_CREATE)
+#if HAVE_LIBFREETYPE && !defined(HAVE_GD_BUNDLED)
#include "gdcache.h"
@@ -95,6 +95,11 @@ gdCacheGet( gdCache_head_t *head, void *keydata )
void *userdata;
elem = head->mru;
+ if (elem == NULL) {
+ return NULL;
+
+ }
+
while(elem) {
if ((*(head->gdCacheTest))(elem->userdata, keydata)) {
if (i) { /* if not already most-recently-used */
diff --git a/ext/gd/libgd/gd.c b/ext/gd/libgd/gd.c
index fa75898ddb..54890bc177 100644
--- a/ext/gd/libgd/gd.c
+++ b/ext/gd/libgd/gd.c
@@ -168,6 +168,8 @@ gdImagePtr gdImageCreate (int sx, int sy)
im->cy1 = 0;
im->cx2 = im->sx - 1;
im->cy2 = im->sy - 1;
+ im->interpolation = NULL;
+ im->interpolation_id = GD_BILINEAR_FIXED;
return im;
}
@@ -183,7 +185,7 @@ gdImagePtr gdImageCreateTrueColor (int sx, int sy)
if (overflow2(sizeof(unsigned char *), sy)) {
return NULL;
}
-
+
if (overflow2(sizeof(int), sx)) {
return NULL;
}
@@ -221,6 +223,8 @@ gdImagePtr gdImageCreateTrueColor (int sx, int sy)
im->cy1 = 0;
im->cx2 = im->sx - 1;
im->cy2 = im->sy - 1;
+ im->interpolation = NULL;
+ im->interpolation_id = GD_BILINEAR_FIXED;
return im;
}
@@ -1954,7 +1958,6 @@ static void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc)
{
int i, l, x1, x2, dy;
int oc; /* old pixel value */
- int tiled;
int wx2,wy2;
/* stack of filled segments */
struct seg *stack;
@@ -1966,7 +1969,6 @@ static void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc)
}
wx2=im->sx;wy2=im->sy;
- tiled = nc==gdTiled;
nc = gdImageTileGet(im,x,y);
@@ -2031,7 +2033,6 @@ void gdImageRectangle (gdImagePtr im, int x1, int y1, int x2, int y2, int color)
{
int x1h = x1, x1v = x1, y1h = y1, y1v = y1, x2h = x2, x2v = x2, y2h = y2, y2v = y2;
int thick = im->thick;
- int half1 = 1;
int t;
if (x1 == x2 && y1 == y2 && thick == 1) {
@@ -2053,7 +2054,7 @@ void gdImageRectangle (gdImagePtr im, int x1, int y1, int x2, int y2, int color)
if (thick > 1) {
int cx, cy, x1ul, y1ul, x2lr, y2lr;
int half = thick >> 1;
- half1 = thick - half;
+
x1ul = x1 - half;
y1ul = y1 - half;
@@ -2351,8 +2352,6 @@ void gdImageCopyResized (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int
int colorMap[gdMaxColors];
/* Stretch vectors */
int *stx, *sty;
- /* We only need to use floating point to determine the correct stretch vector for one line's worth. */
- double accum;
if (overflow2(sizeof(int), srcW)) {
return;
@@ -2363,7 +2362,6 @@ void gdImageCopyResized (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int
stx = (int *) gdMalloc (sizeof (int) * srcW);
sty = (int *) gdMalloc (sizeof (int) * srcH);
- accum = 0;
/* Fixed by Mao Morimoto 2.0.16 */
for (i = 0; (i < srcW); i++) {
@@ -3009,3 +3007,75 @@ void gdImageGetClip (gdImagePtr im, int *x1P, int *y1P, int *x2P, int *y2P)
*y2P = im->cy2;
}
+/* convert a palette image to true color */
+int gdImagePaletteToTrueColor(gdImagePtr src)
+{
+ unsigned int y;
+ unsigned int yy;
+
+ if (src == NULL) {
+ return 0;
+ }
+
+ if (src->trueColor == 1) {
+ return 1;
+ } else {
+ unsigned int x;
+ const unsigned int sy = gdImageSY(src);
+ const unsigned int sx = gdImageSX(src);
+
+ src->tpixels = (int **) gdMalloc(sizeof(int *) * sy);
+ if (src->tpixels == NULL) {
+ return 0;
+ }
+
+ for (y = 0; y < sy; y++) {
+ const unsigned char *src_row = src->pixels[y];
+ int * dst_row;
+
+ /* no need to calloc it, we overwrite all pxl anyway */
+ src->tpixels[y] = (int *) gdMalloc(sx * sizeof(int));
+ if (src->tpixels[y] == NULL) {
+ goto clean_on_error;
+ }
+
+ dst_row = src->tpixels[y];
+ for (x = 0; x < sx; x++) {
+ const unsigned char c = *(src_row + x);
+ if (c == src->transparent) {
+ *(dst_row + x) = gdTrueColorAlpha(0, 0, 0, 127);
+ } else {
+ *(dst_row + x) = gdTrueColorAlpha(src->red[c], src->green[c], src->blue[c], src->alpha[c]);
+ }
+ }
+ }
+ }
+
+ /* free old palette buffer */
+ for (yy = y - 1; yy >= yy - 1; yy--) {
+ gdFree(src->pixels[yy]);
+ }
+ gdFree(src->pixels);
+ src->trueColor = 1;
+ src->pixels = NULL;
+ src->alphaBlendingFlag = 0;
+ src->saveAlphaFlag = 1;
+
+ if (src->transparent >= 0) {
+ const unsigned char c = src->transparent;
+ src->transparent = gdTrueColorAlpha(src->red[c], src->green[c], src->blue[c], src->alpha[c]);
+ }
+
+ return 1;
+
+clean_on_error:
+ if (y > 0) {
+
+ for (yy = y; yy >= yy - 1; y--) {
+ gdFree(src->tpixels[y]);
+ }
+ gdFree(src->tpixels);
+ }
+ return 0;
+}
+
diff --git a/ext/gd/libgd/gd.h b/ext/gd/libgd/gd.h
index 8aedc2c38c..72515108d6 100644
--- a/ext/gd/libgd/gd.h
+++ b/ext/gd/libgd/gd.h
@@ -93,6 +93,10 @@ void php_gd_error(const char *format, ...);
#define gdEffectNormal 2
#define gdEffectOverlay 3
+#define GD_TRUE 1
+#define GD_FALSE 0
+
+#define GD_EPSILON 1e-6
/* This function accepts truecolor pixel values only. The
source color is composited with the destination color
@@ -101,6 +105,67 @@ void php_gd_error(const char *format, ...);
int gdAlphaBlend(int dest, int src);
+/**
+ * Group: Transform
+ *
+ * Constants: gdInterpolationMethod
+
+ * GD_BELL - Bell
+ * GD_BESSEL - Bessel
+ * GD_BILINEAR_FIXED - fixed point bilinear
+ * GD_BICUBIC - Bicubic
+ * GD_BICUBIC_FIXED - fixed point bicubic integer
+ * GD_BLACKMAN - Blackman
+ * GD_BOX - Box
+ * GD_BSPLINE - BSpline
+ * GD_CATMULLROM - Catmullrom
+ * GD_GAUSSIAN - Gaussian
+ * GD_GENERALIZED_CUBIC - Generalized cubic
+ * GD_HERMITE - Hermite
+ * GD_HAMMING - Hamming
+ * GD_HANNING - Hannig
+ * GD_MITCHELL - Mitchell
+ * GD_NEAREST_NEIGHBOUR - Nearest neighbour interpolation
+ * GD_POWER - Power
+ * GD_QUADRATIC - Quadratic
+ * GD_SINC - Sinc
+ * GD_TRIANGLE - Triangle
+ * GD_WEIGHTED4 - 4 pixels weighted bilinear interpolation
+ *
+ * See also:
+ * <gdSetInterpolationMethod>
+ **/
+typedef enum {
+ GD_DEFAULT = 0,
+ GD_BELL,
+ GD_BESSEL,
+ GD_BILINEAR_FIXED,
+ GD_BICUBIC,
+ GD_BICUBIC_FIXED,
+ GD_BLACKMAN,
+ GD_BOX,
+ GD_BSPLINE,
+ GD_CATMULLROM,
+ GD_GAUSSIAN,
+ GD_GENERALIZED_CUBIC,
+ GD_HERMITE,
+ GD_HAMMING,
+ GD_HANNING,
+ GD_MITCHELL,
+ GD_NEAREST_NEIGHBOUR,
+ GD_POWER,
+ GD_QUADRATIC,
+ GD_SINC,
+ GD_TRIANGLE,
+ GD_WEIGHTED4,
+ GD_METHOD_COUNT = 21
+} gdInterpolationMethod;
+
+/* define struct with name and func ptr and add it to gdImageStruct gdInterpolationMethod interpolation; */
+
+/* Interpolation function ptr */
+typedef double (* interpolation_method )(double);
+
typedef struct gdImageStruct {
/* Palette-based image pixels */
unsigned char ** pixels;
@@ -188,10 +253,35 @@ typedef struct gdImageStruct {
int cy1;
int cx2;
int cy2;
+ gdInterpolationMethod interpolation_id;
+ interpolation_method interpolation;
} gdImage;
typedef gdImage * gdImagePtr;
+/* Point type for use in polygon drawing. */
+
+/**
+ * Group: Types
+ *
+ * typedef: gdPointF
+ * Defines a point in a 2D coordinate system using floating point
+ * values.
+ * x - Floating point position (increase from left to right)
+ * y - Floating point Row position (increase from top to bottom)
+ *
+ * typedef: gdPointFPtr
+ * Pointer to a <gdPointF>
+ *
+ * See also:
+ * <gdImageCreate>, <gdImageCreateTrueColor>,
+ **/
+typedef struct
+{
+ double x, y;
+}
+gdPointF, *gdPointFPtr;
+
typedef struct {
/* # of characters in font */
int nchars;
@@ -209,6 +299,31 @@ typedef struct {
/* Text functions take these. */
typedef gdFont *gdFontPtr;
+
+/**
+ * Group: Types
+ *
+ * typedef: gdRect
+ * Defines a rectilinear region.
+ *
+ * x - left position
+ * y - right position
+ * width - Rectangle width
+ * height - Rectangle height
+ *
+ * typedef: gdRectPtr
+ * Pointer to a <gdRect>
+ *
+ * See also:
+ * <gdSetInterpolationMethod>
+ **/
+typedef struct
+{
+ int x, y;
+ int width, height;
+}
+gdRect, *gdRectPtr;
+
/* For backwards compatibility only. Use gdImageSetStyle()
for MUCH more flexible line drawing. Also see
gdImageSetBrush(). */
@@ -247,8 +362,12 @@ gdImagePtr gdImageCreateFromPng(FILE *fd);
gdImagePtr gdImageCreateFromPngCtx(gdIOCtxPtr in);
gdImagePtr gdImageCreateFromWBMP(FILE *inFile);
gdImagePtr gdImageCreateFromWBMPCtx(gdIOCtx *infile);
-gdImagePtr gdImageCreateFromJpeg(FILE *infile, int ignore_warning);
-gdImagePtr gdImageCreateFromJpegCtx(gdIOCtx *infile, int ignore_warning);
+gdImagePtr gdImageCreateFromJpeg(FILE *infile);
+gdImagePtr gdImageCreateFromJpegEx(FILE *infile, int ignore_warning);
+gdImagePtr gdImageCreateFromJpegCtx(gdIOCtx *infile);
+gdImagePtr gdImageCreateFromJpegCtxEx(gdIOCtx *infile, int ignore_warning);
+gdImagePtr gdImageCreateFromJpegPtr (int size, void *data);
+gdImagePtr gdImageCreateFromJpegPtrEx (int size, void *data, int ignore_warning);
gdImagePtr gdImageCreateFromWebp(FILE *fd);
gdImagePtr gdImageCreateFromWebpCtx(gdIOCtxPtr in);
gdImagePtr gdImageCreateFromWebpPtr (int size, void *data);
@@ -444,7 +563,7 @@ void gdImageColorDeallocate(gdImagePtr im, int color);
gdImagePtr gdImageCreatePaletteFromTrueColor (gdImagePtr im, int ditherFlag, int colorsWanted);
void gdImageTrueColorToPalette(gdImagePtr im, int ditherFlag, int colorsWanted);
-
+int gdImagePaletteToTrueColor(gdImagePtr src);
/* An attempt at getting the results of gdImageTrueColorToPalette
to look a bit more like the original (im1 is the original
@@ -575,6 +694,7 @@ gdImagePtr gdImageRotate180(gdImagePtr src, int ignoretransparent);
gdImagePtr gdImageRotate270(gdImagePtr src, int ignoretransparent);
gdImagePtr gdImageRotate45(gdImagePtr src, double dAngle, int clrBack, int ignoretransparent);
gdImagePtr gdImageRotate (gdImagePtr src, double dAngle, int clrBack, int ignoretransparent);
+gdImagePtr gdImageRotateInterpolated(const gdImagePtr src, const float angle, int bgcolor);
void gdImageSetBrush(gdImagePtr im, gdImagePtr brush);
void gdImageSetTile(gdImagePtr im, gdImagePtr tile);
@@ -682,6 +802,88 @@ int gdImageSmooth(gdImagePtr im, float weight);
/* Image comparison definitions */
int gdImageCompare(gdImagePtr im1, gdImagePtr im2);
+void gdImageFlipHorizontal(gdImagePtr im);
+void gdImageFlipVertical(gdImagePtr im);
+void gdImageFlipBoth(gdImagePtr im);
+
+#define GD_FLIP_HORINZONTAL 1
+#define GD_FLIP_VERTICAL 2
+#define GD_FLIP_BOTH 3
+
+/**
+ * Group: Crop
+ *
+ * Constants: gdCropMode
+ * GD_CROP_DEFAULT - Default crop mode (4 corners or background)
+ * GD_CROP_TRANSPARENT - Crop using the transparent color
+ * GD_CROP_BLACK - Crop black borders
+ * GD_CROP_WHITE - Crop white borders
+ * GD_CROP_SIDES - Crop using colors of the 4 corners
+ *
+ * See also:
+ * <gdImageAutoCrop>
+ **/
+enum gdCropMode {
+ GD_CROP_DEFAULT = 0,
+ GD_CROP_TRANSPARENT,
+ GD_CROP_BLACK,
+ GD_CROP_WHITE,
+ GD_CROP_SIDES,
+ GD_CROP_THRESHOLD
+};
+
+gdImagePtr gdImageCrop(gdImagePtr src, const gdRectPtr crop);
+gdImagePtr gdImageCropAuto(gdImagePtr im, const unsigned int mode);
+gdImagePtr gdImageCropThreshold(gdImagePtr im, const unsigned int color, const float threshold);
+
+int gdImageSetInterpolationMethod(gdImagePtr im, gdInterpolationMethod id);
+
+gdImagePtr gdImageScaleBilinear(gdImagePtr im, const unsigned int new_width, const unsigned int new_height);
+gdImagePtr gdImageScaleBicubic(gdImagePtr src_img, const unsigned int new_width, const unsigned int new_height);
+gdImagePtr gdImageScaleBicubicFixed(gdImagePtr src, const unsigned int width, const unsigned int height);
+gdImagePtr gdImageScaleNearestNeighbour(gdImagePtr im, const unsigned int width, const unsigned int height);
+gdImagePtr gdImageScaleTwoPass(const gdImagePtr pOrigImage, const unsigned int uOrigWidth, const unsigned int uOrigHeight, const unsigned int uNewWidth, const unsigned int uNewHeight);
+gdImagePtr gdImageScale(const gdImagePtr src, const unsigned int new_width, const unsigned int new_height);
+
+gdImagePtr gdImageRotateNearestNeighbour(gdImagePtr src, const float degrees, const int bgColor);
+gdImagePtr gdImageRotateBilinear(gdImagePtr src, const float degrees, const int bgColor);
+gdImagePtr gdImageRotateBicubicFixed(gdImagePtr src, const float degrees, const int bgColor);
+gdImagePtr gdImageRotateGeneric(gdImagePtr src, const float degrees, const int bgColor);
+
+
+
+typedef enum {
+ GD_AFFINE_TRANSLATE = 0,
+ GD_AFFINE_SCALE,
+ GD_AFFINE_ROTATE,
+ GD_AFFINE_SHEAR_HORIZONTAL,
+ GD_AFFINE_SHEAR_VERTICAL,
+} gdAffineStandardMatrix;
+
+int gdAffineApplyToPointF (gdPointFPtr dst, const gdPointFPtr src, const double affine[6]);
+int gdAffineInvert (double dst[6], const double src[6]);
+int gdAffineFlip (double dst_affine[6], const double src_affine[6], const int flip_h, const int flip_v);
+int gdAffineConcat (double dst[6], const double m1[6], const double m2[6]);
+
+int gdAffineIdentity (double dst[6]);
+int gdAffineScale (double dst[6], const double scale_x, const double scale_y);
+int gdAffineRotate (double dst[6], const double angle);
+int gdAffineShearHorizontal (double dst[6], const double angle);
+int gdAffineShearVertical(double dst[6], const double angle);
+int gdAffineTranslate (double dst[6], const double offset_x, const double offset_y);
+double gdAffineExpansion (const double src[6]);
+int gdAffineRectilinear (const double src[6]);
+int gdAffineEqual (const double matrix1[6], const double matrix2[6]);
+int gdTransformAffineGetImage(gdImagePtr *dst, const gdImagePtr src, gdRectPtr src_area, const double affine[6]);
+int gdTransformAffineCopy(gdImagePtr dst, int dst_x, int dst_y, const gdImagePtr src, gdRectPtr src_region, const double affine[6]);
+/*
+gdTransformAffineCopy(gdImagePtr dst, int x0, int y0, int x1, int y1,
+ const gdImagePtr src, int src_width, int src_height,
+ const double affine[6]);
+*/
+int gdTransformAffineBoundingBox(gdRectPtr src, const double affine[6], gdRectPtr bbox);
+
+
#define GD_CMP_IMAGE 1 /* Actual image IS different */
#define GD_CMP_NUM_COLORS 2 /* Number of Colours in pallette differ */
#define GD_CMP_COLOR 4 /* Image colours differ */
diff --git a/ext/gd/libgd/gd_compat.c b/ext/gd/libgd/gd_compat.c
deleted file mode 100644
index 473ea203e5..0000000000
--- a/ext/gd/libgd/gd_compat.c
+++ /dev/null
@@ -1,35 +0,0 @@
-#include "php_config.h"
-#ifdef HAVE_GD_PNG
-/* needs to be first */
-# include <png.h>
-#endif
-
-#ifdef HAVE_GD_JPG
-# include <jpeglib.h>
-#endif
-
-#ifdef HAVE_GD_JPG
-int gdJpegGetVersionInt()
-{
- return JPEG_LIB_VERSION;
-}
-
-const char * gdJpegGetVersionString()
-{
- switch(JPEG_LIB_VERSION) {
- case 62:
- return "6b";
- break;
- default:
- return "unknown";
- }
-}
-#endif
-
-#ifdef HAVE_GD_PNG
-const char * gdPngGetVersionString()
-{
- return PNG_LIBPNG_VER_STRING;
-}
-#endif
-
diff --git a/ext/gd/libgd/gd_compat.h b/ext/gd/libgd/gd_compat.h
deleted file mode 100644
index 779e709a63..0000000000
--- a/ext/gd/libgd/gd_compat.h
+++ /dev/null
@@ -1,66 +0,0 @@
-#ifndef GD_COMPAT_H
-#define GD_COMPAT_H 1
-
-#if HAVE_GD_BUNDLED
-# include "gd.h"
-#else
-# include <gd.h>
-#endif
-
-const char * gdPngGetVersionString();
-const char * gdJpegGetVersionString();
-int gdJpegGetVersionInt();
-int overflow2(int a, int b);
-
-/* filters section
- *
- * Negate the imag src, white becomes black,
- * The red, green, and blue intensities of an image are negated.
- * White becomes black, yellow becomes blue, etc.
- */
-int gdImageNegate(gdImagePtr src);
-
-/* Convert the image src to a grayscale image */
-int gdImageGrayScale(gdImagePtr src);
-
-/* Set the brightness level <brightness> for the image src */
-int gdImageBrightness(gdImagePtr src, int brightness);
-
-/* Set the contrast level <contrast> for the image <src> */
-int gdImageContrast(gdImagePtr src, double contrast);
-
-/* Simply adds or substracts respectively red, green or blue to a pixel */
-int gdImageColor(gdImagePtr src, const int red, const int green, const int blue, const int alpha);
-
-#if !defined(HAVE_GD_IMAGE_CONVOLUTION)
-/* Image convolution by a 3x3 custom matrix */
-int gdImageConvolution(gdImagePtr src, float ft[3][3], float filter_div, float offset);
-int gdImageEdgeDetectQuick(gdImagePtr src);
-int gdImageGaussianBlur(gdImagePtr im);
-int gdImageSelectiveBlur( gdImagePtr src);
-int gdImageEmboss(gdImagePtr im);
-int gdImageMeanRemoval(gdImagePtr im);
-int gdImageSmooth(gdImagePtr im, float weight);
-#endif
-
-#if !defined(HAVE_GD_IMAGE_PIXELATE)
-enum gdPixelateMode {
- GD_PIXELATE_UPPERLEFT,
- GD_PIXELATE_AVERAGE
-};
-
-int gdImagePixelate(gdImagePtr im, int block_size, const unsigned int mode);
-#endif
-
-int gdImagePixelate(gdImagePtr im, int block_size, const unsigned int mode);
-
-#if !HAVE_GD_IMAGEELLIPSE
-void gdImageEllipse(gdImagePtr im, int cx, int cy, int w, int h, int c);
-#endif
-
-gdImagePtr gdImageRotate (gdImagePtr src, double dAngle, int clrBack, int ignoretransparent);
-
-int gdImageColorMatch (gdImagePtr im1, gdImagePtr im2);
-
-#endif
-
diff --git a/ext/gd/libgd/gd_crop.c b/ext/gd/libgd/gd_crop.c
new file mode 100644
index 0000000000..bba425d0e3
--- /dev/null
+++ b/ext/gd/libgd/gd_crop.c
@@ -0,0 +1,369 @@
+/**
+ * Title: Crop
+ *
+ * A couple of functions to crop images, automatically (auto detection of
+ * the borders color), using a given color (with or without tolerance)
+ * or using a selection.
+ *
+ * The threshold method works relatively well but it can be improved.
+ * Maybe L*a*b* and Delta-E will give better results (and a better
+ * granularity).
+ *
+ * Example:
+ * (start code)
+ * im2 = gdImageAutoCrop(im, GD_CROP_SIDES);
+ * if (im2) {
+
+ * }
+ * gdImageDestroy(im2);
+ * (end code)
+ **/
+
+#include <gd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+static int gdGuessBackgroundColorFromCorners(gdImagePtr im, int *color);
+static int gdColorMatch(gdImagePtr im, int col1, int col2, float threshold);
+
+/**
+ * Function: gdImageCrop
+ * Crops the src image using the area defined by the <crop> rectangle.
+ * The result is returned as a new image.
+ *
+ *
+ * Parameters:
+ * src - Source image
+ * crop - Rectangular region to crop
+ *
+ * Returns:
+ * <gdImagePtr> on success or NULL
+ */
+gdImagePtr gdImageCrop(gdImagePtr src, const gdRectPtr crop)
+{
+ gdImagePtr dst;
+ int y;
+
+ /* check size */
+ if (crop->width<=0 || crop->height<=0) {
+ return NULL;
+ }
+
+ /* allocate the requested size (could be only partially filled) */
+ if (src->trueColor) {
+ dst = gdImageCreateTrueColor(crop->width, crop->height);
+ gdImageSaveAlpha(dst, 1);
+ } else {
+ dst = gdImageCreate(crop->width, crop->height);
+ gdImagePaletteCopy(dst, src);
+ }
+ if (dst == NULL) {
+ return NULL;
+ }
+ dst->transparent = src->transparent;
+
+ /* check position in the src image */
+ if (crop->x < 0 || crop->x>=src->sx || crop->y<0 || crop->y>=src->sy) {
+ return dst;
+ }
+
+ /* reduce size if needed */
+ if ((src->sx - crop->width) < crop->x) {
+ crop->width = src->sx - crop->x;
+ }
+ if ((src->sy - crop->height) < crop->y) {
+ crop->height = src->sy - crop->y;
+ }
+
+#if 0
+printf("rect->x: %i\nrect->y: %i\nrect->width: %i\nrect->height: %i\n", crop->x, crop->y, crop->width, crop->height);
+#endif
+ y = crop->y;
+ if (src->trueColor) {
+ unsigned int dst_y = 0;
+ while (y < (crop->y + (crop->height - 1))) {
+ /* TODO: replace 4 w/byte per channel||pitch once available */
+ memcpy(dst->tpixels[dst_y++], src->tpixels[y++] + crop->x, crop->width * 4);
+ }
+ } else {
+ int x;
+ for (y = crop->y; y < (crop->y + (crop->height - 1)); y++) {
+ for (x = crop->x; x < (crop->x + (crop->width - 1)); x++) {
+ dst->pixels[y - crop->y][x - crop->x] = src->pixels[y][x];
+ }
+ }
+ }
+ return dst;
+}
+
+/**
+ * Function: gdImageAutoCrop
+ * Automatic croping of the src image using the given mode
+ * (see <gdCropMode>)
+ *
+ *
+ * Parameters:
+ * im - Source image
+ * mode - crop mode
+ *
+ * Returns:
+ * <gdImagePtr> on success or NULL
+ *
+ * See also:
+ * <gdCropMode>
+ */
+gdImagePtr gdImageCropAuto(gdImagePtr im, const unsigned int mode)
+{
+ const int width = gdImageSX(im);
+ const int height = gdImageSY(im);
+
+ int x,y;
+ int color, corners, match;
+ gdRect crop;
+
+ crop.x = 0;
+ crop.y = 0;
+ crop.width = 0;
+ crop.height = 0;
+
+ switch (mode) {
+ case GD_CROP_TRANSPARENT:
+ color = gdImageGetTransparent(im);
+ break;
+
+ case GD_CROP_BLACK:
+ color = gdImageColorClosestAlpha(im, 0, 0, 0, 0);
+ break;
+
+ case GD_CROP_WHITE:
+ color = gdImageColorClosestAlpha(im, 255, 255, 255, 0);
+ break;
+
+ case GD_CROP_SIDES:
+ corners = gdGuessBackgroundColorFromCorners(im, &color);
+ break;
+
+ case GD_CROP_DEFAULT:
+ default:
+ color = gdImageGetTransparent(im);
+ if (color == -1) {
+ corners = gdGuessBackgroundColorFromCorners(im, &color);
+ }
+ break;
+ }
+
+ /* TODO: Add gdImageGetRowPtr and works with ptr at the row level
+ * for the true color and palette images
+ * new formats will simply work with ptr
+ */
+ match = 1;
+ for (y = 0; match && y < height; y++) {
+ for (x = 0; match && x < width; x++) {
+ int c2 = gdImageGetPixel(im, x, y);
+ match = (color == c2);
+ }
+ }
+
+ /* Nothing to do > bye
+ * Duplicate the image?
+ */
+ if (y == height - 1) {
+ return NULL;
+ }
+
+ crop.y = y -1;
+ match = 1;
+ for (y = height - 1; match && y >= 0; y--) {
+ for (x = 0; match && x < width; x++) {
+ match = (color == gdImageGetPixel(im, x,y));
+ }
+ }
+
+ if (y == 0) {
+ crop.height = height - crop.y + 1;
+ } else {
+ crop.height = y - crop.y + 2;
+ }
+
+ match = 1;
+ for (x = 0; match && x < width; x++) {
+ for (y = 0; match && y < crop.y + crop.height - 1; y++) {
+ match = (color == gdImageGetPixel(im, x,y));
+ }
+ }
+ crop.x = x - 1;
+
+ match = 1;
+ for (x = width - 1; match && x >= 0; x--) {
+ for (y = 0; match && y < crop.y + crop.height - 1; y++) {
+ match = (color == gdImageGetPixel(im, x,y));
+ }
+ }
+ crop.width = x - crop.x + 2;
+ if (crop.x <= 0 || crop.y <= 0 || crop.width <= 0 || crop.height <= 0) {
+ return NULL;
+ }
+ return gdImageCrop(im, &crop);
+}
+/*TODOs: Implement DeltaE instead, way better perceptual differences */
+/**
+ * Function: gdImageThresholdCrop
+ * Crop an image using a given color. The threshold argument defines
+ * the tolerance to be used while comparing the image color and the
+ * color to crop. The method used to calculate the color difference
+ * is based on the color distance in the RGB(a) cube.
+ *
+ *
+ * Parameters:
+ * im - Source image
+ * color - color to crop
+ * threshold - tolerance (0..100)
+ *
+ * Returns:
+ * <gdImagePtr> on success or NULL
+ *
+ * See also:
+ * <gdCropMode>, <gdImageAutoCrop> or <gdImageCrop>
+ */
+gdImagePtr gdImageCropThreshold(gdImagePtr im, const unsigned int color, const float threshold)
+{
+ const int width = gdImageSX(im);
+ const int height = gdImageSY(im);
+
+ int x,y;
+ int match;
+ gdRect crop;
+
+ crop.x = 0;
+ crop.y = 0;
+ crop.width = 0;
+ crop.height = 0;
+
+ /* Pierre: crop everything sounds bad */
+ if (threshold > 1.0) {
+ return NULL;
+ }
+
+ /* TODO: Add gdImageGetRowPtr and works with ptr at the row level
+ * for the true color and palette images
+ * new formats will simply work with ptr
+ */
+ match = 1;
+ for (y = 0; match && y < height; y++) {
+ for (x = 0; match && x < width; x++) {
+ match = (gdColorMatch(im, color, gdImageGetPixel(im, x,y), threshold)) > 0;
+ }
+ }
+
+ /* Pierre
+ * Nothing to do > bye
+ * Duplicate the image?
+ */
+ if (y == height - 1) {
+ return NULL;
+ }
+
+ crop.y = y -1;
+ match = 1;
+ for (y = height - 1; match && y >= 0; y--) {
+ for (x = 0; match && x < width; x++) {
+ match = (gdColorMatch(im, color, gdImageGetPixel(im, x, y), threshold)) > 0;
+ }
+ }
+
+ if (y == 0) {
+ crop.height = height - crop.y + 1;
+ } else {
+ crop.height = y - crop.y + 2;
+ }
+
+ match = 1;
+ for (x = 0; match && x < width; x++) {
+ for (y = 0; match && y < crop.y + crop.height - 1; y++) {
+ match = (gdColorMatch(im, color, gdImageGetPixel(im, x,y), threshold)) > 0;
+ }
+ }
+ crop.x = x - 1;
+
+ match = 1;
+ for (x = width - 1; match && x >= 0; x--) {
+ for (y = 0; match && y < crop.y + crop.height - 1; y++) {
+ match = (gdColorMatch(im, color, gdImageGetPixel(im, x,y), threshold)) > 0;
+ }
+ }
+ crop.width = x - crop.x + 2;
+
+ return gdImageCrop(im, &crop);
+}
+
+/* This algorithm comes from pnmcrop (http://netpbm.sourceforge.net/)
+ * Three steps:
+ * - if 3 corners are equal.
+ * - if two are equal.
+ * - Last solution: average the colors
+ */
+static int gdGuessBackgroundColorFromCorners(gdImagePtr im, int *color)
+{
+ const int tl = gdImageGetPixel(im, 0, 0);
+ const int tr = gdImageGetPixel(im, gdImageSX(im) - 1, 0);
+ const int bl = gdImageGetPixel(im, 0, gdImageSY(im) -1);
+ const int br = gdImageGetPixel(im, gdImageSX(im) - 1, gdImageSY(im) -1);
+
+ if (tr == bl && tr == br) {
+ *color = tr;
+ return 3;
+ } else if (tl == bl && tl == br) {
+ *color = tl;
+ return 3;
+ } else if (tl == tr && tl == br) {
+ *color = tl;
+ return 3;
+ } else if (tl == tr && tl == bl) {
+ *color = tl;
+ return 3;
+ } else if (tl == tr || tl == bl || tl == br) {
+ *color = tl;
+ return 2;
+ } else if (tr == bl) {
+ *color = tr;
+ return 2;
+ } else if (br == bl) {
+ *color = bl;
+ return 2;
+ } else {
+ register int r,b,g,a;
+
+ r = (int)(0.5f + (gdImageRed(im, tl) + gdImageRed(im, tr) + gdImageRed(im, bl) + gdImageRed(im, br)) / 4);
+ g = (int)(0.5f + (gdImageGreen(im, tl) + gdImageGreen(im, tr) + gdImageGreen(im, bl) + gdImageGreen(im, br)) / 4);
+ b = (int)(0.5f + (gdImageBlue(im, tl) + gdImageBlue(im, tr) + gdImageBlue(im, bl) + gdImageBlue(im, br)) / 4);
+ a = (int)(0.5f + (gdImageAlpha(im, tl) + gdImageAlpha(im, tr) + gdImageAlpha(im, bl) + gdImageAlpha(im, br)) / 4);
+ *color = gdImageColorClosestAlpha(im, r, g, b, a);
+ return 0;
+ }
+}
+
+static int gdColorMatch(gdImagePtr im, int col1, int col2, float threshold)
+{
+ const int dr = gdImageRed(im, col1) - gdImageRed(im, col2);
+ const int dg = gdImageGreen(im, col1) - gdImageGreen(im, col2);
+ const int db = gdImageBlue(im, col1) - gdImageBlue(im, col2);
+ const int da = gdImageAlpha(im, col1) - gdImageAlpha(im, col2);
+ const double dist = sqrt(dr * dr + dg * dg + db * db + da * da);
+ const double dist_perc = sqrt(dist / (255^2 + 255^2 + 255^2));
+ return (dist_perc <= threshold);
+ //return (100.0 * dist / 195075) < threshold;
+}
+
+/*
+ * To be implemented when we have more image formats.
+ * Buffer like gray8 gray16 or rgb8 will require some tweak
+ * and can be done in this function (called from the autocrop
+ * function. (Pierre)
+ */
+#if 0
+static int colors_equal (const int col1, const in col2)
+{
+
+}
+#endif
diff --git a/ext/gd/libgd/gd_interpolation.c b/ext/gd/libgd/gd_interpolation.c
new file mode 100644
index 0000000000..3643535f2e
--- /dev/null
+++ b/ext/gd/libgd/gd_interpolation.c
@@ -0,0 +1,2550 @@
+/*
+ * Filtered Image Rescaling
+ * Based on Gems III
+ * - Schumacher general filtered image rescaling
+ * (pp. 414-424)
+ * by Dale Schumacher
+ *
+ * Additional changes by Ray Gardener, Daylon Graphics Ltd.
+ * December 4, 1999
+ *
+ * Ported to libgd by Pierre Joye. Support for multiple channels
+ * added (argb for now).
+ *
+ * Initial sources code is avaibable in the Gems Source Code Packages:
+ * http://www.acm.org/pubs/tog/GraphicsGems/GGemsIII.tar.gz
+ */
+
+/*
+ Summary:
+
+ - Horizontal filter contributions are calculated on the fly,
+ as each column is mapped from src to dst image. This lets
+ us omit having to allocate a temporary full horizontal stretch
+ of the src image.
+
+ - If none of the src pixels within a sampling region differ,
+ then the output pixel is forced to equal (any of) the source pixel.
+ This ensures that filters do not corrupt areas of constant color.
+
+ - Filter weight contribution results, after summing, are
+ rounded to the nearest pixel color value instead of
+ being casted to ILubyte (usually an int or char). Otherwise,
+ artifacting occurs.
+
+*/
+
+/*
+ Additional functions are available for simple rotation or up/downscaling.
+ downscaling using the fixed point implementations are usually much faster
+ than the existing gdImageCopyResampled while having a similar or better
+ quality.
+
+ For image rotations, the optimized versions have a lazy antialiasing for
+ the edges of the images. For a much better antialiased result, the affine
+ function is recommended.
+*/
+
+/*
+TODO:
+ - Optimize pixel accesses and loops once we have continuous buffer
+ - Add scale support for a portion only of an image (equivalent of copyresized/resampled)
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include <gd.h>
+#include "gdhelpers.h"
+
+#ifdef _MSC_VER
+# pragma optimize("t", on)
+# include <emmintrin.h>
+#endif
+
+#ifndef MIN
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#endif
+#define MIN3(a,b,c) ((a)<(b)?(MIN(a,c)):(MIN(b,c)))
+#ifndef MAX
+#define MAX(a,b) ((a)<(b)?(b):(a))
+#endif
+#define MAX3(a,b,c) ((a)<(b)?(MAX(b,c)):(MAX(a,c)))
+
+#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
+
+/* only used here, let do a generic fixed point integers later if required by other
+ part of GD */
+typedef long gdFixed;
+/* Integer to fixed point */
+#define gd_itofx(x) ((x) << 8)
+
+/* Float to fixed point */
+#define gd_ftofx(x) (long)((x) * 256)
+
+/* Double to fixed point */
+#define gd_dtofx(x) (long)((x) * 256)
+
+/* Fixed point to integer */
+#define gd_fxtoi(x) ((x) >> 8)
+
+/* Fixed point to float */
+# define gd_fxtof(x) ((float)(x) / 256)
+
+/* Fixed point to double */
+#define gd_fxtod(x) ((double)(x) / 256)
+
+/* Multiply a fixed by a fixed */
+#define gd_mulfx(x,y) (((x) * (y)) >> 8)
+
+/* Divide a fixed by a fixed */
+#define gd_divfx(x,y) (((x) << 8) / (y))
+
+typedef struct
+{
+ double *Weights; /* Normalized weights of neighboring pixels */
+ int Left,Right; /* Bounds of source pixels window */
+} ContributionType; /* Contirbution information for a single pixel */
+
+typedef struct
+{
+ ContributionType *ContribRow; /* Row (or column) of contribution weights */
+ unsigned int WindowSize, /* Filter window size (of affecting source pixels) */
+ LineLength; /* Length of line (no. or rows / cols) */
+} LineContribType;
+
+/* Each core filter has its own radius */
+#define DEFAULT_FILTER_BICUBIC 3.0
+#define DEFAULT_FILTER_BOX 0.5
+#define DEFAULT_FILTER_GENERALIZED_CUBIC 0.5
+#define DEFAULT_FILTER_RADIUS 1.0
+#define DEFAULT_LANCZOS8_RADIUS 8.0
+#define DEFAULT_LANCZOS3_RADIUS 3.0
+#define DEFAULT_HERMITE_RADIUS 1.0
+#define DEFAULT_BOX_RADIUS 0.5
+#define DEFAULT_TRIANGLE_RADIUS 1.0
+#define DEFAULT_BELL_RADIUS 1.5
+#define DEFAULT_CUBICSPLINE_RADIUS 2.0
+#define DEFAULT_MITCHELL_RADIUS 2.0
+#define DEFAULT_COSINE_RADIUS 1.0
+#define DEFAULT_CATMULLROM_RADIUS 2.0
+#define DEFAULT_QUADRATIC_RADIUS 1.5
+#define DEFAULT_QUADRATICBSPLINE_RADIUS 1.5
+#define DEFAULT_CUBICCONVOLUTION_RADIUS 3.0
+#define DEFAULT_GAUSSIAN_RADIUS 1.0
+#define DEFAULT_HANNING_RADIUS 1.0
+#define DEFAULT_HAMMING_RADIUS 1.0
+#define DEFAULT_SINC_RADIUS 1.0
+#define DEFAULT_WELSH_RADIUS 1.0
+
+enum GD_RESIZE_FILTER_TYPE{
+ FILTER_DEFAULT = 0,
+ FILTER_BELL,
+ FILTER_BESSEL,
+ FILTER_BLACKMAN,
+ FILTER_BOX,
+ FILTER_BSPLINE,
+ FILTER_CATMULLROM,
+ FILTER_COSINE,
+ FILTER_CUBICCONVOLUTION,
+ FILTER_CUBICSPLINE,
+ FILTER_HERMITE,
+ FILTER_LANCZOS3,
+ FILTER_LANCZOS8,
+ FILTER_MITCHELL,
+ FILTER_QUADRATIC,
+ FILTER_QUADRATICBSPLINE,
+ FILTER_TRIANGLE,
+ FILTER_GAUSSIAN,
+ FILTER_HANNING,
+ FILTER_HAMMING,
+ FILTER_SINC,
+ FILTER_WELSH,
+
+ FILTER_CALLBACK = 999
+};
+
+typedef enum GD_RESIZE_FILTER_TYPE gdResizeFilterType;
+
+static double KernelBessel_J1(const double x)
+{
+ double p, q;
+
+ register long i;
+
+ static const double
+ Pone[] =
+ {
+ 0.581199354001606143928050809e+21,
+ -0.6672106568924916298020941484e+20,
+ 0.2316433580634002297931815435e+19,
+ -0.3588817569910106050743641413e+17,
+ 0.2908795263834775409737601689e+15,
+ -0.1322983480332126453125473247e+13,
+ 0.3413234182301700539091292655e+10,
+ -0.4695753530642995859767162166e+7,
+ 0.270112271089232341485679099e+4
+ },
+ Qone[] =
+ {
+ 0.11623987080032122878585294e+22,
+ 0.1185770712190320999837113348e+20,
+ 0.6092061398917521746105196863e+17,
+ 0.2081661221307607351240184229e+15,
+ 0.5243710262167649715406728642e+12,
+ 0.1013863514358673989967045588e+10,
+ 0.1501793594998585505921097578e+7,
+ 0.1606931573481487801970916749e+4,
+ 0.1e+1
+ };
+
+ p = Pone[8];
+ q = Qone[8];
+ for (i=7; i >= 0; i--)
+ {
+ p = p*x*x+Pone[i];
+ q = q*x*x+Qone[i];
+ }
+ return (double)(p/q);
+}
+
+static double KernelBessel_P1(const double x)
+{
+ double p, q;
+
+ register long i;
+
+ static const double
+ Pone[] =
+ {
+ 0.352246649133679798341724373e+5,
+ 0.62758845247161281269005675e+5,
+ 0.313539631109159574238669888e+5,
+ 0.49854832060594338434500455e+4,
+ 0.2111529182853962382105718e+3,
+ 0.12571716929145341558495e+1
+ },
+ Qone[] =
+ {
+ 0.352246649133679798068390431e+5,
+ 0.626943469593560511888833731e+5,
+ 0.312404063819041039923015703e+5,
+ 0.4930396490181088979386097e+4,
+ 0.2030775189134759322293574e+3,
+ 0.1e+1
+ };
+
+ p = Pone[5];
+ q = Qone[5];
+ for (i=4; i >= 0; i--)
+ {
+ p = p*(8.0/x)*(8.0/x)+Pone[i];
+ q = q*(8.0/x)*(8.0/x)+Qone[i];
+ }
+ return (double)(p/q);
+}
+
+static double KernelBessel_Q1(const double x)
+{
+ double p, q;
+
+ register long i;
+
+ static const double
+ Pone[] =
+ {
+ 0.3511751914303552822533318e+3,
+ 0.7210391804904475039280863e+3,
+ 0.4259873011654442389886993e+3,
+ 0.831898957673850827325226e+2,
+ 0.45681716295512267064405e+1,
+ 0.3532840052740123642735e-1
+ },
+ Qone[] =
+ {
+ 0.74917374171809127714519505e+4,
+ 0.154141773392650970499848051e+5,
+ 0.91522317015169922705904727e+4,
+ 0.18111867005523513506724158e+4,
+ 0.1038187585462133728776636e+3,
+ 0.1e+1
+ };
+
+ p = Pone[5];
+ q = Qone[5];
+ for (i=4; i >= 0; i--)
+ {
+ p = p*(8.0/x)*(8.0/x)+Pone[i];
+ q = q*(8.0/x)*(8.0/x)+Qone[i];
+ }
+ return (double)(p/q);
+}
+
+static double KernelBessel_Order1(double x)
+{
+ double p, q;
+
+ if (x == 0.0)
+ return (0.0f);
+ p = x;
+ if (x < 0.0)
+ x=(-x);
+ if (x < 8.0)
+ return (p*KernelBessel_J1(x));
+ q = (double)sqrt(2.0f/(M_PI*x))*(double)(KernelBessel_P1(x)*(1.0f/sqrt(2.0f)*(sin(x)-cos(x)))-8.0f/x*KernelBessel_Q1(x)*
+ (-1.0f/sqrt(2.0f)*(sin(x)+cos(x))));
+ if (p < 0.0f)
+ q = (-q);
+ return (q);
+}
+
+static double filter_bessel(const double x)
+{
+ if (x == 0.0f)
+ return (double)(M_PI/4.0f);
+ return (KernelBessel_Order1((double)M_PI*x)/(2.0f*x));
+}
+
+
+static double filter_blackman(const double x)
+{
+ return (0.42f+0.5f*(double)cos(M_PI*x)+0.08f*(double)cos(2.0f*M_PI*x));
+}
+
+/**
+ * Bicubic interpolation kernel (a=-1):
+ \verbatim
+ /
+ | 1-2|t|**2+|t|**3 , if |t| < 1
+ h(t) = | 4-8|t|+5|t|**2-|t|**3 , if 1<=|t|<2
+ | 0 , otherwise
+ \
+ \endverbatim
+ * ***bd*** 2.2004
+ */
+static double filter_bicubic(const double t)
+{
+ const double abs_t = (double)fabs(t);
+ const double abs_t_sq = abs_t * abs_t;
+ if (abs_t<1) return 1-2*abs_t_sq+abs_t_sq*abs_t;
+ if (abs_t<2) return 4 - 8*abs_t +5*abs_t_sq - abs_t_sq*abs_t;
+ return 0;
+}
+
+/**
+ * Generalized cubic kernel (for a=-1 it is the same as BicubicKernel):
+ \verbatim
+ /
+ | (a+2)|t|**3 - (a+3)|t|**2 + 1 , |t| <= 1
+ h(t) = | a|t|**3 - 5a|t|**2 + 8a|t| - 4a , 1 < |t| <= 2
+ | 0 , otherwise
+ \
+ \endverbatim
+ * Often used values for a are -1 and -1/2.
+ */
+static double filter_generalized_cubic(const double t)
+{
+ const double a = -DEFAULT_FILTER_GENERALIZED_CUBIC;
+ double abs_t = (double)fabs(t);
+ double abs_t_sq = abs_t * abs_t;
+ if (abs_t < 1) return (a + 2) * abs_t_sq * abs_t - (a + 3) * abs_t_sq + 1;
+ if (abs_t < 2) return a * abs_t_sq * abs_t - 5 * a * abs_t_sq + 8 * a * abs_t - 4 * a;
+ return 0;
+}
+
+/* CubicSpline filter, default radius 2 */
+static double filter_cubic_spline(const double x1)
+{
+ const double x = x1 < 0.0 ? -x1 : x1;
+
+ if (x < 1.0 ) {
+ const double x2 = x*x;
+
+ return (0.5 * x2 * x - x2 + 2.0 / 3.0);
+ }
+ if (x < 2.0) {
+ return (pow(2.0 - x, 3.0)/6.0);
+ }
+ return 0;
+}
+
+/* CubicConvolution filter, default radius 3 */
+static double filter_cubic_convolution(const double x1)
+{
+ const double x = x1 < 0.0 ? -x1 : x1;
+ const double x2 = x1 * x1;
+ const double x2_x = x2 * x;
+
+ if (x <= 1.0) return ((4.0 / 3.0)* x2_x - (7.0 / 3.0) * x2 + 1.0);
+ if (x <= 2.0) return (- (7.0 / 12.0) * x2_x + 3 * x2 - (59.0 / 12.0) * x + 2.5);
+ if (x <= 3.0) return ( (1.0/12.0) * x2_x - (2.0 / 3.0) * x2 + 1.75 * x - 1.5);
+ return 0;
+}
+
+static double filter_box(double x) {
+ if (x < - DEFAULT_FILTER_BOX)
+ return 0.0f;
+ if (x < DEFAULT_FILTER_BOX)
+ return 1.0f;
+ return 0.0f;
+}
+
+static double filter_catmullrom(const double x)
+{
+ if (x < -2.0)
+ return(0.0f);
+ if (x < -1.0)
+ return(0.5f*(4.0f+x*(8.0f+x*(5.0f+x))));
+ if (x < 0.0)
+ return(0.5f*(2.0f+x*x*(-5.0f-3.0f*x)));
+ if (x < 1.0)
+ return(0.5f*(2.0f+x*x*(-5.0f+3.0f*x)));
+ if (x < 2.0)
+ return(0.5f*(4.0f+x*(-8.0f+x*(5.0f-x))));
+ return(0.0f);
+}
+
+static double filter_filter(double t)
+{
+ /* f(t) = 2|t|^3 - 3|t|^2 + 1, -1 <= t <= 1 */
+ if(t < 0.0) t = -t;
+ if(t < 1.0) return((2.0 * t - 3.0) * t * t + 1.0);
+ return(0.0);
+}
+
+
+/* Lanczos8 filter, default radius 8 */
+static double filter_lanczos8(const double x1)
+{
+ const double x = x1 < 0.0 ? -x1 : x1;
+#define R DEFAULT_LANCZOS8_RADIUS
+
+ if ( x == 0.0) return 1;
+
+ if ( x < R) {
+ return R * sin(x*M_PI) * sin(x * M_PI/ R) / (x * M_PI * x * M_PI);
+ }
+ return 0.0;
+#undef R
+}
+
+
+/* Lanczos3 filter, default radius 3 */
+static double filter_lanczos3(const double x1)
+{
+ const double x = x1 < 0.0 ? -x1 : x1;
+#define R DEFAULT_LANCZOS3_RADIUS
+
+ if ( x == 0.0) return 1;
+
+ if ( x < R)
+ {
+ return R * sin(x*M_PI) * sin(x * M_PI / R) / (x * M_PI * x * M_PI);
+ }
+ return 0.0;
+#undef R
+}
+
+/* Hermite filter, default radius 1 */
+static double filter_hermite(const double x1)
+{
+ const double x = x1 < 0.0 ? -x1 : x1;
+
+ if (x < 1.0) return ((2.0 * x - 3) * x * x + 1.0 );
+
+ return 0.0;
+}
+
+/* Trangle filter, default radius 1 */
+static double filter_triangle(const double x1)
+{
+ const double x = x1 < 0.0 ? -x1 : x1;
+ if (x < 1.0) return (1.0 - x);
+ return 0.0;
+}
+
+/* Bell filter, default radius 1.5 */
+static double filter_bell(const double x1)
+{
+ const double x = x1 < 0.0 ? -x1 : x1;
+
+ if (x < 0.5) return (0.75 - x*x);
+ if (x < 1.5) return (0.5 * pow(x - 1.5, 2.0));
+ return 0.0;
+}
+
+/* Mitchell filter, default radius 2.0 */
+static double filter_mitchell(const double x)
+{
+#define KM_B (1.0f/3.0f)
+#define KM_C (1.0f/3.0f)
+#define KM_P0 (( 6.0f - 2.0f * KM_B ) / 6.0f)
+#define KM_P2 ((-18.0f + 12.0f * KM_B + 6.0f * KM_C) / 6.0f)
+#define KM_P3 (( 12.0f - 9.0f * KM_B - 6.0f * KM_C) / 6.0f)
+#define KM_Q0 (( 8.0f * KM_B + 24.0f * KM_C) / 6.0f)
+#define KM_Q1 ((-12.0f * KM_B - 48.0f * KM_C) / 6.0f)
+#define KM_Q2 (( 6.0f * KM_B + 30.0f * KM_C) / 6.0f)
+#define KM_Q3 (( -1.0f * KM_B - 6.0f * KM_C) / 6.0f)
+
+ if (x < -2.0)
+ return(0.0f);
+ if (x < -1.0)
+ return(KM_Q0-x*(KM_Q1-x*(KM_Q2-x*KM_Q3)));
+ if (x < 0.0f)
+ return(KM_P0+x*x*(KM_P2-x*KM_P3));
+ if (x < 1.0f)
+ return(KM_P0+x*x*(KM_P2+x*KM_P3));
+ if (x < 2.0f)
+ return(KM_Q0+x*(KM_Q1+x*(KM_Q2+x*KM_Q3)));
+ return(0.0f);
+}
+
+
+
+/* Cosine filter, default radius 1 */
+static double filter_cosine(const double x)
+{
+ if ((x >= -1.0) && (x <= 1.0)) return ((cos(x * M_PI) + 1.0)/2.0);
+
+ return 0;
+}
+
+/* Quadratic filter, default radius 1.5 */
+static double filter_quadratic(const double x1)
+{
+ const double x = x1 < 0.0 ? -x1 : x1;
+
+ if (x <= 0.5) return (- 2.0 * x * x + 1);
+ if (x <= 1.5) return (x * x - 2.5* x + 1.5);
+ return 0.0;
+}
+
+static double filter_bspline(const double x)
+{
+ if (x>2.0f) {
+ return 0.0f;
+ } else {
+ double a, b, c, d;
+ /* Was calculated anyway cause the "if((x-1.0f) < 0)" */
+ const double xm1 = x - 1.0f;
+ const double xp1 = x + 1.0f;
+ const double xp2 = x + 2.0f;
+
+ if ((xp2) <= 0.0f) a = 0.0f; else a = xp2*xp2*xp2;
+ if ((xp1) <= 0.0f) b = 0.0f; else b = xp1*xp1*xp1;
+ if (x <= 0) c = 0.0f; else c = x*x*x;
+ if ((xm1) <= 0.0f) d = 0.0f; else d = xm1*xm1*xm1;
+
+ return (0.16666666666666666667f * (a - (4.0f * b) + (6.0f * c) - (4.0f * d)));
+ }
+}
+
+/* QuadraticBSpline filter, default radius 1.5 */
+static double filter_quadratic_bspline(const double x1)
+{
+ const double x = x1 < 0.0 ? -x1 : x1;
+
+ if (x <= 0.5) return (- x * x + 0.75);
+ if (x <= 1.5) return (0.5 * x * x - 1.5 * x + 1.125);
+ return 0.0;
+}
+
+static double filter_gaussian(const double x)
+{
+ /* return(exp((double) (-2.0 * x * x)) * sqrt(2.0 / M_PI)); */
+ return (double)(exp(-2.0f * x * x) * 0.79788456080287f);
+}
+
+static double filter_hanning(const double x)
+{
+ /* A Cosine windowing function */
+ return(0.5 + 0.5 * cos(M_PI * x));
+}
+
+static double filter_hamming(const double x)
+{
+ /* should be
+ (0.54+0.46*cos(M_PI*(double) x));
+ but this approximation is sufficient */
+ if (x < -1.0f)
+ return 0.0f;
+ if (x < 0.0f)
+ return 0.92f*(-2.0f*x-3.0f)*x*x+1.0f;
+ if (x < 1.0f)
+ return 0.92f*(2.0f*x-3.0f)*x*x+1.0f;
+ return 0.0f;
+}
+
+static double filter_power(const double x)
+{
+ const double a = 2.0f;
+ if (fabs(x)>1) return 0.0f;
+ return (1.0f - (double)fabs(pow(x,a)));
+}
+
+static double filter_sinc(const double x)
+{
+ /* X-scaled Sinc(x) function. */
+ if (x == 0.0) return(1.0);
+ return (sin(M_PI * (double) x) / (M_PI * (double) x));
+}
+
+static double filter_welsh(const double x)
+{
+ /* Welsh parabolic windowing filter */
+ if (x < 1.0)
+ return(1 - x*x);
+ return(0.0);
+}
+
+
+/* Copied from upstream's libgd */
+static inline int _color_blend (const int dst, const int src)
+{
+ const int src_alpha = gdTrueColorGetAlpha(src);
+
+ if( src_alpha == gdAlphaOpaque ) {
+ return src;
+ } else {
+ const int dst_alpha = gdTrueColorGetAlpha(dst);
+
+ if( src_alpha == gdAlphaTransparent ) return dst;
+ if( dst_alpha == gdAlphaTransparent ) {
+ return src;
+ } else {
+ register int alpha, red, green, blue;
+ const int src_weight = gdAlphaTransparent - src_alpha;
+ const int dst_weight = (gdAlphaTransparent - dst_alpha) * src_alpha / gdAlphaMax;
+ const int tot_weight = src_weight + dst_weight;
+
+ alpha = src_alpha * dst_alpha / gdAlphaMax;
+
+ red = (gdTrueColorGetRed(src) * src_weight
+ + gdTrueColorGetRed(dst) * dst_weight) / tot_weight;
+ green = (gdTrueColorGetGreen(src) * src_weight
+ + gdTrueColorGetGreen(dst) * dst_weight) / tot_weight;
+ blue = (gdTrueColorGetBlue(src) * src_weight
+ + gdTrueColorGetBlue(dst) * dst_weight) / tot_weight;
+
+ return ((alpha << 24) + (red << 16) + (green << 8) + blue);
+ }
+ }
+}
+
+static inline int _setEdgePixel(const gdImagePtr src, unsigned int x, unsigned int y, gdFixed coverage, const int bgColor)
+{
+ const gdFixed f_127 = gd_itofx(127);
+ register int c = src->tpixels[y][x];
+ c = c | (( (int) (gd_fxtof(gd_mulfx(coverage, f_127)) + 50.5f)) << 24);
+ return _color_blend(bgColor, c);
+}
+
+static inline int getPixelOverflowTC(gdImagePtr im, const int x, const int y, const int bgColor)
+{
+ if (gdImageBoundsSafe(im, x, y)) {
+ const int c = im->tpixels[y][x];
+ if (c == im->transparent) {
+ return bgColor == -1 ? gdTrueColorAlpha(0, 0, 0, 127) : bgColor;
+ }
+ return c;
+ } else {
+ register int border = 0;
+
+ if (y < im->cy1) {
+ border = im->tpixels[0][im->cx1];
+ goto processborder;
+ }
+
+ if (y < im->cy1) {
+ border = im->tpixels[0][im->cx1];
+ goto processborder;
+ }
+
+ if (y > im->cy2) {
+ if (x >= im->cx1 && x <= im->cx1) {
+ border = im->tpixels[im->cy2][x];
+ goto processborder;
+ } else {
+ return gdTrueColorAlpha(0, 0, 0, 127);
+ }
+ }
+
+ /* y is bound safe at this point */
+ if (x < im->cx1) {
+ border = im->tpixels[y][im->cx1];
+ goto processborder;
+ }
+
+ if (x > im->cx2) {
+ border = im->tpixels[y][im->cx2];
+ }
+
+processborder:
+ if (border == im->transparent) {
+ return gdTrueColorAlpha(0, 0, 0, 127);
+ } else{
+ return gdTrueColorAlpha(gdTrueColorGetRed(border), gdTrueColorGetGreen(border), gdTrueColorGetBlue(border), 127);
+ }
+ }
+}
+
+#define colorIndex2RGBA(c) gdTrueColorAlpha(im->red[(c)], im->green[(c)], im->blue[(c)], im->alpha[(c)])
+#define colorIndex2RGBcustomA(c, a) gdTrueColorAlpha(im->red[(c)], im->green[(c)], im->blue[(c)], im->alpha[(a)])
+static inline int getPixelOverflowPalette(gdImagePtr im, const int x, const int y, const int bgColor)
+{
+ if (gdImageBoundsSafe(im, x, y)) {
+ const int c = im->pixels[y][x];
+ if (c == im->transparent) {
+ return bgColor == -1 ? gdTrueColorAlpha(0, 0, 0, 127) : bgColor;
+ }
+ return colorIndex2RGBA(c);
+ } else {
+ register int border = 0;
+ if (y < im->cy1) {
+ border = gdImageGetPixel(im, im->cx1, 0);
+ goto processborder;
+ }
+
+ if (y < im->cy1) {
+ border = gdImageGetPixel(im, im->cx1, 0);
+ goto processborder;
+ }
+
+ if (y > im->cy2) {
+ if (x >= im->cx1 && x <= im->cx1) {
+ border = gdImageGetPixel(im, x, im->cy2);
+ goto processborder;
+ } else {
+ return gdTrueColorAlpha(0, 0, 0, 127);
+ }
+ }
+
+ /* y is bound safe at this point */
+ if (x < im->cx1) {
+ border = gdImageGetPixel(im, im->cx1, y);
+ goto processborder;
+ }
+
+ if (x > im->cx2) {
+ border = gdImageGetPixel(im, im->cx2, y);
+ }
+
+processborder:
+ if (border == im->transparent) {
+ return gdTrueColorAlpha(0, 0, 0, 127);
+ } else{
+ return colorIndex2RGBcustomA(border, 127);
+ }
+ }
+}
+
+static int getPixelInterpolateWeight(gdImagePtr im, const double x, const double y, const int bgColor)
+{
+ /* Closest pixel <= (xf,yf) */
+ int sx = (int)(x);
+ int sy = (int)(y);
+ const double xf = x - (double)sx;
+ const double yf = y - (double)sy;
+ const double nxf = (double) 1.0 - xf;
+ const double nyf = (double) 1.0 - yf;
+ const double m1 = xf * yf;
+ const double m2 = nxf * yf;
+ const double m3 = xf * nyf;
+ const double m4 = nxf * nyf;
+
+ /* get color values of neighbouring pixels */
+ const int c1 = im->trueColor == 1 ? getPixelOverflowTC(im, sx, sy, bgColor) : getPixelOverflowPalette(im, sx, sy, bgColor);
+ const int c2 = im->trueColor == 1 ? getPixelOverflowTC(im, sx - 1, sy, bgColor) : getPixelOverflowPalette(im, sx - 1, sy, bgColor);
+ const int c3 = im->trueColor == 1 ? getPixelOverflowTC(im, sx, sy - 1, bgColor) : getPixelOverflowPalette(im, sx, sy - 1, bgColor);
+ const int c4 = im->trueColor == 1 ? getPixelOverflowTC(im, sx - 1, sy - 1, bgColor) : getPixelOverflowPalette(im, sx, sy - 1, bgColor);
+ int r, g, b, a;
+
+ if (x < 0) sx--;
+ if (y < 0) sy--;
+
+ /* component-wise summing-up of color values */
+ if (im->trueColor) {
+ r = (int)(m1*gdTrueColorGetRed(c1) + m2*gdTrueColorGetRed(c2) + m3*gdTrueColorGetRed(c3) + m4*gdTrueColorGetRed(c4));
+ g = (int)(m1*gdTrueColorGetGreen(c1) + m2*gdTrueColorGetGreen(c2) + m3*gdTrueColorGetGreen(c3) + m4*gdTrueColorGetGreen(c4));
+ b = (int)(m1*gdTrueColorGetBlue(c1) + m2*gdTrueColorGetBlue(c2) + m3*gdTrueColorGetBlue(c3) + m4*gdTrueColorGetBlue(c4));
+ a = (int)(m1*gdTrueColorGetAlpha(c1) + m2*gdTrueColorGetAlpha(c2) + m3*gdTrueColorGetAlpha(c3) + m4*gdTrueColorGetAlpha(c4));
+ } else {
+ r = (int)(m1*im->red[(c1)] + m2*im->red[(c2)] + m3*im->red[(c3)] + m4*im->red[(c4)]);
+ g = (int)(m1*im->green[(c1)] + m2*im->green[(c2)] + m3*im->green[(c3)] + m4*im->green[(c4)]);
+ b = (int)(m1*im->blue[(c1)] + m2*im->blue[(c2)] + m3*im->blue[(c3)] + m4*im->blue[(c4)]);
+ a = (int)(m1*im->alpha[(c1)] + m2*im->alpha[(c2)] + m3*im->alpha[(c3)] + m4*im->alpha[(c4)]);
+ }
+
+ r = CLAMP(r, 0, 255);
+ g = CLAMP(g, 0, 255);
+ b = CLAMP(b, 0, 255);
+ a = CLAMP(a, 0, gdAlphaMax);
+ return gdTrueColorAlpha(r, g, b, a);
+}
+
+/**
+ * Function: getPixelInterpolated
+ * Returns the interpolated color value using the default interpolation
+ * method. The returned color is always in the ARGB format (truecolor).
+ *
+ * Parameters:
+ * im - Image to set the default interpolation method
+ * y - X value of the ideal position
+ * y - Y value of the ideal position
+ * method - Interpolation method <gdInterpolationMethod>
+ *
+ * Returns:
+ * GD_TRUE if the affine is rectilinear or GD_FALSE
+ *
+ * See also:
+ * <gdSetInterpolationMethod>
+ */
+int getPixelInterpolated(gdImagePtr im, const double x, const double y, const int bgColor)
+{
+ const int xi=(int)((x) < 0 ? x - 1: x);
+ const int yi=(int)((y) < 0 ? y - 1: y);
+ int yii;
+ int i;
+ double kernel, kernel_cache_y;
+ double kernel_x[12], kernel_y[4];
+ double new_r = 0.0f, new_g = 0.0f, new_b = 0.0f, new_a = 0.0f;
+
+ /* These methods use special implementations */
+ if (im->interpolation_id == GD_BILINEAR_FIXED || im->interpolation_id == GD_BICUBIC_FIXED || im->interpolation_id == GD_NEAREST_NEIGHBOUR) {
+ return -1;
+ }
+
+ /* Default to full alpha */
+ if (bgColor == -1) {
+ }
+
+ if (im->interpolation_id == GD_WEIGHTED4) {
+ return getPixelInterpolateWeight(im, x, y, bgColor);
+ }
+
+ if (im->interpolation_id == GD_NEAREST_NEIGHBOUR) {
+ if (im->trueColor == 1) {
+ return getPixelOverflowTC(im, xi, yi, bgColor);
+ } else {
+ return getPixelOverflowPalette(im, xi, yi, bgColor);
+ }
+ }
+ if (im->interpolation) {
+ for (i=0; i<4; i++) {
+ kernel_x[i] = (double) im->interpolation((double)(xi+i-1-x));
+ kernel_y[i] = (double) im->interpolation((double)(yi+i-1-y));
+ }
+ } else {
+ return -1;
+ }
+
+ /*
+ * TODO: use the known fast rgba multiplication implementation once
+ * the new formats are in place
+ */
+ for (yii = yi-1; yii < yi+3; yii++) {
+ int xii;
+ kernel_cache_y = kernel_y[yii-(yi-1)];
+ if (im->trueColor) {
+ for (xii=xi-1; xii<xi+3; xii++) {
+ const int rgbs = getPixelOverflowTC(im, xii, yii, bgColor);
+
+ kernel = kernel_cache_y * kernel_x[xii-(xi-1)];
+ new_r += kernel * gdTrueColorGetRed(rgbs);
+ new_g += kernel * gdTrueColorGetGreen(rgbs);
+ new_b += kernel * gdTrueColorGetBlue(rgbs);
+ new_a += kernel * gdTrueColorGetAlpha(rgbs);
+ }
+ } else {
+ for (xii=xi-1; xii<xi+3; xii++) {
+ const int rgbs = getPixelOverflowPalette(im, xii, yii, bgColor);
+
+ kernel = kernel_cache_y * kernel_x[xii-(xi-1)];
+ new_r += kernel * gdTrueColorGetRed(rgbs);
+ new_g += kernel * gdTrueColorGetGreen(rgbs);
+ new_b += kernel * gdTrueColorGetBlue(rgbs);
+ new_a += kernel * gdTrueColorGetAlpha(rgbs);
+ }
+ }
+ }
+
+ new_r = CLAMP(new_r, 0, 255);
+ new_g = CLAMP(new_g, 0, 255);
+ new_b = CLAMP(new_b, 0, 255);
+ new_a = CLAMP(new_a, 0, gdAlphaMax);
+
+ return gdTrueColorAlpha(((int)new_r), ((int)new_g), ((int)new_b), ((int)new_a));
+}
+
+static inline LineContribType * _gdContributionsAlloc(unsigned int line_length, unsigned int windows_size)
+{
+ unsigned int u = 0;
+ LineContribType *res;
+
+ res = (LineContribType *) gdMalloc(sizeof(LineContribType));
+ if (!res) {
+ return NULL;
+ }
+ res->WindowSize = windows_size;
+ res->LineLength = line_length;
+ res->ContribRow = (ContributionType *) gdMalloc(line_length * sizeof(ContributionType));
+
+ for (u = 0 ; u < line_length ; u++) {
+ res->ContribRow[u].Weights = (double *) gdMalloc(windows_size * sizeof(double));
+ }
+ return res;
+}
+
+static inline void _gdContributionsFree(LineContribType * p)
+{
+ unsigned int u;
+ for (u = 0; u < p->LineLength; u++) {
+ gdFree(p->ContribRow[u].Weights);
+ }
+ gdFree(p->ContribRow);
+ gdFree(p);
+}
+
+static inline LineContribType *_gdContributionsCalc(unsigned int line_size, unsigned int src_size, double scale_d, const interpolation_method pFilter)
+{
+ double width_d;
+ double scale_f_d = 1.0;
+ const double filter_width_d = DEFAULT_BOX_RADIUS;
+ int windows_size;
+ unsigned int u;
+ LineContribType *res;
+
+ if (scale_d < 1.0) {
+ width_d = filter_width_d / scale_d;
+ scale_f_d = scale_d;
+ } else {
+ width_d= filter_width_d;
+ }
+
+ windows_size = 2 * (int)ceil(width_d) + 1;
+ res = _gdContributionsAlloc(line_size, windows_size);
+
+ for (u = 0; u < line_size; u++) {
+ const double dCenter = (double)u / scale_d;
+ /* get the significant edge points affecting the pixel */
+ register int iLeft = MAX(0, (int)floor (dCenter - width_d));
+ int iRight = MIN((int)ceil(dCenter + width_d), (int)src_size - 1);
+ double dTotalWeight = 0.0;
+ int iSrc;
+
+ res->ContribRow[u].Left = iLeft;
+ res->ContribRow[u].Right = iRight;
+
+ /* Cut edge points to fit in filter window in case of spill-off */
+ if (iRight - iLeft + 1 > windows_size) {
+ if (iLeft < ((int)src_size - 1 / 2)) {
+ iLeft++;
+ } else {
+ iRight--;
+ }
+ }
+
+ for (iSrc = iLeft; iSrc <= iRight; iSrc++) {
+ dTotalWeight += (res->ContribRow[u].Weights[iSrc-iLeft] = scale_f_d * (*pFilter)(scale_f_d * (dCenter - (double)iSrc)));
+ }
+
+ if (dTotalWeight < 0.0) {
+ _gdContributionsFree(res);
+ return NULL;
+ }
+
+ if (dTotalWeight > 0.0) {
+ for (iSrc = iLeft; iSrc <= iRight; iSrc++) {
+ res->ContribRow[u].Weights[iSrc-iLeft] /= dTotalWeight;
+ }
+ }
+ }
+ return res;
+}
+
+static inline void _gdScaleRow(gdImagePtr pSrc, unsigned int src_width, gdImagePtr dst, unsigned int dst_width, unsigned int row, LineContribType *contrib)
+{
+ int *p_src_row = pSrc->tpixels[row];
+ int *p_dst_row = dst->tpixels[row];
+ unsigned int x;
+
+ for (x = 0; x < dst_width - 1; x++) {
+ register unsigned char r = 0, g = 0, b = 0, a = 0;
+ const int left = contrib->ContribRow[x].Left;
+ const int right = contrib->ContribRow[x].Right;
+ int i;
+
+ /* Accumulate each channel */
+ for (i = left; i <= right; i++) {
+ const int left_channel = i - left;
+ r += (unsigned char)(contrib->ContribRow[x].Weights[left_channel] * (double)(gdTrueColorGetRed(p_src_row[i])));
+ g += (unsigned char)(contrib->ContribRow[x].Weights[left_channel] * (double)(gdTrueColorGetGreen(p_src_row[i])));
+ b += (unsigned char)(contrib->ContribRow[x].Weights[left_channel] * (double)(gdTrueColorGetBlue(p_src_row[i])));
+ a += (unsigned char)(contrib->ContribRow[x].Weights[left_channel] * (double)(gdTrueColorGetAlpha(p_src_row[i])));
+ }
+ p_dst_row[x] = gdTrueColorAlpha(r, g, b, a);
+ }
+}
+
+static inline void _gdScaleHoriz(gdImagePtr pSrc, unsigned int src_width, unsigned int src_height, gdImagePtr pDst, unsigned int dst_width, unsigned int dst_height)
+{
+ unsigned int u;
+ LineContribType * contrib;
+
+ /* same width, just copy it */
+ if (dst_width == src_width) {
+ unsigned int y;
+ for (y = 0; y < src_height - 1; ++y) {
+ memcpy(pDst->tpixels[y], pSrc->tpixels[y], src_width);
+ }
+ }
+
+ contrib = _gdContributionsCalc(dst_width, src_width, (double)dst_width / (double)src_width, pSrc->interpolation);
+ if (contrib == NULL) {
+ return;
+ }
+ /* Scale each row */
+ for (u = 0; u < dst_height - 1; u++) {
+ _gdScaleRow(pSrc, src_width, pDst, dst_width, u, contrib);
+ }
+ _gdContributionsFree (contrib);
+}
+
+static inline void _gdScaleCol (gdImagePtr pSrc, unsigned int src_width, gdImagePtr pRes, unsigned int dst_width, unsigned int dst_height, unsigned int uCol, LineContribType *contrib)
+{
+ unsigned int y;
+ for (y = 0; y < dst_height - 1; y++) {
+ register unsigned char r = 0, g = 0, b = 0, a = 0;
+ const int iLeft = contrib->ContribRow[y].Left;
+ const int iRight = contrib->ContribRow[y].Right;
+ int i;
+ int *row = pRes->tpixels[y];
+
+ /* Accumulate each channel */
+ for (i = iLeft; i <= iRight; i++) {
+ const int pCurSrc = pSrc->tpixels[i][uCol];
+ const int i_iLeft = i - iLeft;
+ r += (unsigned char)(contrib->ContribRow[y].Weights[i_iLeft] * (double)(gdTrueColorGetRed(pCurSrc)));
+ g += (unsigned char)(contrib->ContribRow[y].Weights[i_iLeft] * (double)(gdTrueColorGetGreen(pCurSrc)));
+ b += (unsigned char)(contrib->ContribRow[y].Weights[i_iLeft] * (double)(gdTrueColorGetBlue(pCurSrc)));
+ a += (unsigned char)(contrib->ContribRow[y].Weights[i_iLeft] * (double)(gdTrueColorGetAlpha(pCurSrc)));
+ }
+ pRes->tpixels[y][uCol] = gdTrueColorAlpha(r, g, b, a);
+ }
+}
+
+static inline void _gdScaleVert (const gdImagePtr pSrc, const unsigned int src_width, const unsigned int src_height, const gdImagePtr pDst, const unsigned int dst_width, const unsigned int dst_height)
+{
+ unsigned int u;
+ LineContribType * contrib;
+
+ /* same height, copy it */
+ if (src_height == dst_height) {
+ unsigned int y;
+ for (y = 0; y < src_height - 1; ++y) {
+ memcpy(pDst->tpixels[y], pSrc->tpixels[y], src_width);
+ }
+ }
+
+ contrib = _gdContributionsCalc(dst_height, src_height, (double)(dst_height) / (double)(src_height), pSrc->interpolation);
+ /* scale each column */
+ for (u = 0; u < dst_width - 1; u++) {
+ _gdScaleCol(pSrc, src_width, pDst, dst_width, dst_height, u, contrib);
+ }
+ _gdContributionsFree(contrib);
+}
+
+gdImagePtr gdImageScaleTwoPass(const gdImagePtr src, const unsigned int src_width, const unsigned int src_height, const unsigned int new_width, const unsigned int new_height)
+{
+ gdImagePtr tmp_im;
+ gdImagePtr dst;
+
+ tmp_im = gdImageCreateTrueColor(new_width, src_height);
+ if (tmp_im == NULL) {
+ return NULL;
+ }
+ gdImageSetInterpolationMethod(tmp_im, src->interpolation_id);
+ _gdScaleHoriz(src, src_width, src_height, tmp_im, new_width, src_height);
+
+ dst = gdImageCreateTrueColor(new_width, new_height);
+ if (dst == NULL) {
+ gdFree(tmp_im);
+ return NULL;
+ }
+ gdImageSetInterpolationMethod(dst, src->interpolation_id);
+ _gdScaleVert(tmp_im, new_width, src_height, dst, new_width, new_height);
+ gdFree(tmp_im);
+
+ return dst;
+}
+
+gdImagePtr Scale(const gdImagePtr src, const unsigned int src_width, const unsigned int src_height, const gdImagePtr dst, const unsigned int new_width, const unsigned int new_height)
+{
+ gdImagePtr tmp_im;
+
+ tmp_im = gdImageCreateTrueColor(new_width, src_height);
+ if (tmp_im == NULL) {
+ return NULL;
+ }
+ gdImageSetInterpolationMethod(tmp_im, src->interpolation_id);
+
+ _gdScaleHoriz(src, src_width, src_height, tmp_im, new_width, src_height);
+ _gdScaleVert(tmp_im, new_width, src_height, dst, new_width, new_height);
+
+ gdFree(tmp_im);
+ return dst;
+}
+
+/*
+ BilinearFixed, BicubicFixed and nearest implementations are rewamped versions of the implementation in CBitmapEx
+ http://www.codeproject.com/Articles/29121/CBitmapEx-Free-C-Bitmap-Manipulation-Class
+ Integer only implementation, good to have for common usages like pre scale very large
+ images before using another interpolation methods for the last step.
+*/
+gdImagePtr gdImageScaleNearestNeighbour(gdImagePtr im, const unsigned int width, const unsigned int height)
+{
+ const unsigned long new_width = MAX(1, width);
+ const unsigned long new_height = MAX(1, height);
+ const float dx = (float)im->sx / (float)new_width;
+ const float dy = (float)im->sy / (float)new_height;
+ const gdFixed f_dx = gd_ftofx(dx);
+ const gdFixed f_dy = gd_ftofx(dy);
+
+ gdImagePtr dst_img;
+ unsigned long dst_offset_x;
+ unsigned long dst_offset_y = 0;
+ unsigned int i;
+
+ dst_img = gdImageCreateTrueColor(new_width, new_height);
+
+ if (dst_img == NULL) {
+ return NULL;
+ }
+
+ for (i=0; i<new_height; i++) {
+ unsigned int j;
+ dst_offset_x = 0;
+ if (im->trueColor) {
+ for (j=0; j<new_width; j++) {
+ const gdFixed f_i = gd_itofx(i);
+ const gdFixed f_j = gd_itofx(j);
+ const gdFixed f_a = gd_mulfx(f_i, f_dy);
+ const gdFixed f_b = gd_mulfx(f_j, f_dx);
+ const long m = gd_fxtoi(f_a);
+ const long n = gd_fxtoi(f_b);
+
+ dst_img->tpixels[dst_offset_y][dst_offset_x++] = im->tpixels[m][n];
+ }
+ } else {
+ for (j=0; j<new_width; j++) {
+ const gdFixed f_i = gd_itofx(i);
+ const gdFixed f_j = gd_itofx(j);
+ const gdFixed f_a = gd_mulfx(f_i, f_dy);
+ const gdFixed f_b = gd_mulfx(f_j, f_dx);
+ const long m = gd_fxtoi(f_a);
+ const long n = gd_fxtoi(f_b);
+
+ dst_img->tpixels[dst_offset_y][dst_offset_x++] = colorIndex2RGBA(im->pixels[m][n]);
+ }
+ }
+ dst_offset_y++;
+ }
+ return dst_img;
+}
+
+static inline int getPixelOverflowColorTC(gdImagePtr im, const int x, const int y, const int color)
+{
+ if (gdImageBoundsSafe(im, x, y)) {
+ const int c = im->tpixels[y][x];
+ if (c == im->transparent) {
+ return gdTrueColorAlpha(0, 0, 0, 127);
+ }
+ return c;
+ } else {
+ register int border = 0;
+ if (y < im->cy1) {
+ border = im->tpixels[0][im->cx1];
+ goto processborder;
+ }
+
+ if (y < im->cy1) {
+ border = im->tpixels[0][im->cx1];
+ goto processborder;
+ }
+
+ if (y > im->cy2) {
+ if (x >= im->cx1 && x <= im->cx1) {
+ border = im->tpixels[im->cy2][x];
+ goto processborder;
+ } else {
+ return gdTrueColorAlpha(0, 0, 0, 127);
+ }
+ }
+
+ /* y is bound safe at this point */
+ if (x < im->cx1) {
+ border = im->tpixels[y][im->cx1];
+ goto processborder;
+ }
+
+ if (x > im->cx2) {
+ border = im->tpixels[y][im->cx2];
+ }
+
+processborder:
+ if (border == im->transparent) {
+ return gdTrueColorAlpha(0, 0, 0, 127);
+ } else{
+ return gdTrueColorAlpha(gdTrueColorGetRed(border), gdTrueColorGetGreen(border), gdTrueColorGetBlue(border), 127);
+ }
+ }
+}
+
+static gdImagePtr gdImageScaleBilinearPalette(gdImagePtr im, const unsigned int new_width, const unsigned int new_height)
+{
+ long _width = MAX(1, new_width);
+ long _height = MAX(1, new_height);
+ float dx = (float)gdImageSX(im) / (float)_width;
+ float dy = (float)gdImageSY(im) / (float)_height;
+ gdFixed f_dx = gd_ftofx(dx);
+ gdFixed f_dy = gd_ftofx(dy);
+ gdFixed f_1 = gd_itofx(1);
+
+ int dst_offset_h;
+ int dst_offset_v = 0;
+ long i;
+ gdImagePtr new_img;
+ const int transparent = im->transparent;
+
+ new_img = gdImageCreateTrueColor(new_width, new_height);
+ if (new_img == NULL) {
+ return NULL;
+ }
+ new_img->transparent = gdTrueColorAlpha(im->red[transparent], im->green[transparent], im->blue[transparent], im->alpha[transparent]);
+
+ for (i=0; i < _height; i++) {
+ long j;
+ const gdFixed f_i = gd_itofx(i);
+ const gdFixed f_a = gd_mulfx(f_i, f_dy);
+ register long m = gd_fxtoi(f_a);
+
+ dst_offset_h = 0;
+
+ for (j=0; j < _width; j++) {
+ /* Update bitmap */
+ gdFixed f_j = gd_itofx(j);
+ gdFixed f_b = gd_mulfx(f_j, f_dx);
+
+ const long n = gd_fxtoi(f_b);
+ gdFixed f_f = f_a - gd_itofx(m);
+ gdFixed f_g = f_b - gd_itofx(n);
+
+ const gdFixed f_w1 = gd_mulfx(f_1-f_f, f_1-f_g);
+ const gdFixed f_w2 = gd_mulfx(f_1-f_f, f_g);
+ const gdFixed f_w3 = gd_mulfx(f_f, f_1-f_g);
+ const gdFixed f_w4 = gd_mulfx(f_f, f_g);
+ unsigned int pixel1;
+ unsigned int pixel2;
+ unsigned int pixel3;
+ unsigned int pixel4;
+ register gdFixed f_r1, f_r2, f_r3, f_r4,
+ f_g1, f_g2, f_g3, f_g4,
+ f_b1, f_b2, f_b3, f_b4,
+ f_a1, f_a2, f_a3, f_a4;
+
+ /* zero for the background color, nothig gets outside anyway */
+ pixel1 = getPixelOverflowPalette(im, n, m, 0);
+ pixel2 = getPixelOverflowPalette(im, n + 1, m, 0);
+ pixel3 = getPixelOverflowPalette(im, n, m + 1, 0);
+ pixel4 = getPixelOverflowPalette(im, n + 1, m + 1, 0);
+
+ f_r1 = gd_itofx(gdTrueColorGetRed(pixel1));
+ f_r2 = gd_itofx(gdTrueColorGetRed(pixel2));
+ f_r3 = gd_itofx(gdTrueColorGetRed(pixel3));
+ f_r4 = gd_itofx(gdTrueColorGetRed(pixel4));
+ f_g1 = gd_itofx(gdTrueColorGetGreen(pixel1));
+ f_g2 = gd_itofx(gdTrueColorGetGreen(pixel2));
+ f_g3 = gd_itofx(gdTrueColorGetGreen(pixel3));
+ f_g4 = gd_itofx(gdTrueColorGetGreen(pixel4));
+ f_b1 = gd_itofx(gdTrueColorGetBlue(pixel1));
+ f_b2 = gd_itofx(gdTrueColorGetBlue(pixel2));
+ f_b3 = gd_itofx(gdTrueColorGetBlue(pixel3));
+ f_b4 = gd_itofx(gdTrueColorGetBlue(pixel4));
+ f_a1 = gd_itofx(gdTrueColorGetAlpha(pixel1));
+ f_a2 = gd_itofx(gdTrueColorGetAlpha(pixel2));
+ f_a3 = gd_itofx(gdTrueColorGetAlpha(pixel3));
+ f_a4 = gd_itofx(gdTrueColorGetAlpha(pixel4));
+
+ {
+ const char red = (char) gd_fxtoi(gd_mulfx(f_w1, f_r1) + gd_mulfx(f_w2, f_r2) + gd_mulfx(f_w3, f_r3) + gd_mulfx(f_w4, f_r4));
+ const char green = (char) gd_fxtoi(gd_mulfx(f_w1, f_g1) + gd_mulfx(f_w2, f_g2) + gd_mulfx(f_w3, f_g3) + gd_mulfx(f_w4, f_g4));
+ const char blue = (char) gd_fxtoi(gd_mulfx(f_w1, f_b1) + gd_mulfx(f_w2, f_b2) + gd_mulfx(f_w3, f_b3) + gd_mulfx(f_w4, f_b4));
+ const char alpha = (char) gd_fxtoi(gd_mulfx(f_w1, f_a1) + gd_mulfx(f_w2, f_a2) + gd_mulfx(f_w3, f_a3) + gd_mulfx(f_w4, f_a4));
+
+ new_img->tpixels[dst_offset_v][dst_offset_h] = gdTrueColorAlpha(red, green, blue, alpha);
+ }
+
+ dst_offset_h++;
+ }
+
+ dst_offset_v++;
+ }
+ return new_img;
+}
+
+static gdImagePtr gdImageScaleBilinearTC(gdImagePtr im, const unsigned int new_width, const unsigned int new_height)
+{
+ long dst_w = MAX(1, new_width);
+ long dst_h = MAX(1, new_height);
+ float dx = (float)gdImageSX(im) / (float)dst_w;
+ float dy = (float)gdImageSY(im) / (float)dst_h;
+ gdFixed f_dx = gd_ftofx(dx);
+ gdFixed f_dy = gd_ftofx(dy);
+ gdFixed f_1 = gd_itofx(1);
+
+ int dst_offset_h;
+ int dst_offset_v = 0;
+ int dwSrcTotalOffset;
+ long i;
+ gdImagePtr new_img;
+
+ new_img = gdImageCreateTrueColor(new_width, new_height);
+ if (!new_img){
+ return NULL;
+ }
+
+ for (i=0; i < dst_h; i++) {
+ long j;
+ dst_offset_h = 0;
+ for (j=0; j < dst_w; j++) {
+ /* Update bitmap */
+ gdFixed f_i = gd_itofx(i);
+ gdFixed f_j = gd_itofx(j);
+ gdFixed f_a = gd_mulfx(f_i, f_dy);
+ gdFixed f_b = gd_mulfx(f_j, f_dx);
+ const long m = gd_fxtoi(f_a);
+ const long n = gd_fxtoi(f_b);
+ gdFixed f_f = f_a - gd_itofx(m);
+ gdFixed f_g = f_b - gd_itofx(n);
+
+ const gdFixed f_w1 = gd_mulfx(f_1-f_f, f_1-f_g);
+ const gdFixed f_w2 = gd_mulfx(f_1-f_f, f_g);
+ const gdFixed f_w3 = gd_mulfx(f_f, f_1-f_g);
+ const gdFixed f_w4 = gd_mulfx(f_f, f_g);
+ unsigned int pixel1;
+ unsigned int pixel2;
+ unsigned int pixel3;
+ unsigned int pixel4;
+ register gdFixed f_r1, f_r2, f_r3, f_r4,
+ f_g1, f_g2, f_g3, f_g4,
+ f_b1, f_b2, f_b3, f_b4,
+ f_a1, f_a2, f_a3, f_a4;
+ dwSrcTotalOffset = m + n;
+ /* 0 for bgColor, nothing gets outside anyway */
+ pixel1 = getPixelOverflowTC(im, n, m, 0);
+ pixel2 = getPixelOverflowTC(im, n + 1, m, 0);
+ pixel3 = getPixelOverflowTC(im, n, m + 1, 0);
+ pixel4 = getPixelOverflowTC(im, n + 1, m + 1, 0);
+
+ f_r1 = gd_itofx(gdTrueColorGetRed(pixel1));
+ f_r2 = gd_itofx(gdTrueColorGetRed(pixel2));
+ f_r3 = gd_itofx(gdTrueColorGetRed(pixel3));
+ f_r4 = gd_itofx(gdTrueColorGetRed(pixel4));
+ f_g1 = gd_itofx(gdTrueColorGetGreen(pixel1));
+ f_g2 = gd_itofx(gdTrueColorGetGreen(pixel2));
+ f_g3 = gd_itofx(gdTrueColorGetGreen(pixel3));
+ f_g4 = gd_itofx(gdTrueColorGetGreen(pixel4));
+ f_b1 = gd_itofx(gdTrueColorGetBlue(pixel1));
+ f_b2 = gd_itofx(gdTrueColorGetBlue(pixel2));
+ f_b3 = gd_itofx(gdTrueColorGetBlue(pixel3));
+ f_b4 = gd_itofx(gdTrueColorGetBlue(pixel4));
+ f_a1 = gd_itofx(gdTrueColorGetAlpha(pixel1));
+ f_a2 = gd_itofx(gdTrueColorGetAlpha(pixel2));
+ f_a3 = gd_itofx(gdTrueColorGetAlpha(pixel3));
+ f_a4 = gd_itofx(gdTrueColorGetAlpha(pixel4));
+ {
+ const char red = (char) gd_fxtoi(gd_mulfx(f_w1, f_r1) + gd_mulfx(f_w2, f_r2) + gd_mulfx(f_w3, f_r3) + gd_mulfx(f_w4, f_r4));
+ const char green = (char) gd_fxtoi(gd_mulfx(f_w1, f_g1) + gd_mulfx(f_w2, f_g2) + gd_mulfx(f_w3, f_g3) + gd_mulfx(f_w4, f_g4));
+ const char blue = (char) gd_fxtoi(gd_mulfx(f_w1, f_b1) + gd_mulfx(f_w2, f_b2) + gd_mulfx(f_w3, f_b3) + gd_mulfx(f_w4, f_b4));
+ const char alpha = (char) gd_fxtoi(gd_mulfx(f_w1, f_a1) + gd_mulfx(f_w2, f_a2) + gd_mulfx(f_w3, f_a3) + gd_mulfx(f_w4, f_a4));
+
+ new_img->tpixels[dst_offset_v][dst_offset_h] = gdTrueColorAlpha(red, green, blue, alpha);
+ }
+
+ dst_offset_h++;
+ }
+
+ dst_offset_v++;
+ }
+ return new_img;
+}
+
+gdImagePtr gdImageScaleBilinear(gdImagePtr im, const unsigned int new_width, const unsigned int new_height)
+{
+ if (im->trueColor) {
+ return gdImageScaleBilinearTC(im, new_width, new_height);
+ } else {
+ return gdImageScaleBilinearPalette(im, new_width, new_height);
+ }
+}
+
+gdImagePtr gdImageScaleBicubicFixed(gdImagePtr src, const unsigned int width, const unsigned int height)
+{
+ const long new_width = MAX(1, width);
+ const long new_height = MAX(1, height);
+ const int src_w = gdImageSX(src);
+ const int src_h = gdImageSY(src);
+ const gdFixed f_dx = gd_ftofx((float)src_w / (float)new_width);
+ const gdFixed f_dy = gd_ftofx((float)src_h / (float)new_height);
+ const gdFixed f_1 = gd_itofx(1);
+ const gdFixed f_2 = gd_itofx(2);
+ const gdFixed f_4 = gd_itofx(4);
+ const gdFixed f_6 = gd_itofx(6);
+ const gdFixed f_gamma = gd_ftofx(1.04f);
+ gdImagePtr dst;
+
+ unsigned int dst_offset_x;
+ unsigned int dst_offset_y = 0;
+ long i;
+
+ /* impact perf a bit, but not that much. Implementation for palette
+ images can be done at a later point.
+ */
+ if (src->trueColor == 0) {
+ gdImagePaletteToTrueColor(src);
+ }
+
+ dst = gdImageCreateTrueColor(new_width, new_height);
+ if (!dst) {
+ return NULL;
+ }
+
+ dst->saveAlphaFlag = 1;
+
+ for (i=0; i < new_height; i++) {
+ long j;
+ dst_offset_x = 0;
+
+ for (j=0; j < new_width; j++) {
+ const gdFixed f_a = gd_mulfx(gd_itofx(i), f_dy);
+ const gdFixed f_b = gd_mulfx(gd_itofx(j), f_dx);
+ const long m = gd_fxtoi(f_a);
+ const long n = gd_fxtoi(f_b);
+ const gdFixed f_f = f_a - gd_itofx(m);
+ const gdFixed f_g = f_b - gd_itofx(n);
+ unsigned int src_offset_x[16], src_offset_y[16];
+ long k;
+ register gdFixed f_red = 0, f_green = 0, f_blue = 0, f_alpha = 0;
+ unsigned char red, green, blue, alpha = 0;
+ int *dst_row = dst->tpixels[dst_offset_y];
+
+ if ((m < 1) || (n < 1)) {
+ src_offset_x[0] = n;
+ src_offset_y[0] = m;
+ } else {
+ src_offset_x[0] = n - 1;
+ src_offset_y[0] = m;
+ }
+
+ if (m < 1) {
+ src_offset_x[1] = n;
+ src_offset_y[1] = m;
+ } else {
+ src_offset_x[1] = n;
+ src_offset_y[1] = m;
+ }
+
+ if ((m < 1) || (n >= src_w - 1)) {
+ src_offset_x[2] = n;
+ src_offset_y[2] = m;
+ } else {
+ src_offset_x[2] = n + 1;
+ src_offset_y[2] = m;
+ }
+
+ if ((m < 1) || (n >= src_w - 2)) {
+ src_offset_x[3] = n;
+ src_offset_y[3] = m;
+ } else {
+ src_offset_x[3] = n + 1 + 1;
+ src_offset_y[3] = m;
+ }
+
+ if (n < 1) {
+ src_offset_x[4] = n;
+ src_offset_y[4] = m;
+ } else {
+ src_offset_x[4] = n - 1;
+ src_offset_y[4] = m;
+ }
+
+ src_offset_x[5] = n;
+ src_offset_y[5] = m;
+ if (n >= src_w-1) {
+ src_offset_x[6] = n;
+ src_offset_y[6] = m;
+ } else {
+ src_offset_x[6] = n + 1;
+ src_offset_y[6] = m;
+ }
+
+ if (n >= src_w - 2) {
+ src_offset_x[7] = n;
+ src_offset_y[7] = m;
+ } else {
+ src_offset_x[7] = n + 1 + 1;
+ src_offset_y[7] = m;
+ }
+
+ if ((m >= src_h - 1) || (n < 1)) {
+ src_offset_x[8] = n;
+ src_offset_y[8] = m;
+ } else {
+ src_offset_x[8] = n - 1;
+ src_offset_y[8] = m;
+ }
+
+ if (m >= src_h - 1) {
+ src_offset_x[8] = n;
+ src_offset_y[8] = m;
+ } else {
+ src_offset_x[9] = n;
+ src_offset_y[9] = m;
+ }
+
+ if ((m >= src_h-1) || (n >= src_w-1)) {
+ src_offset_x[10] = n;
+ src_offset_y[10] = m;
+ } else {
+ src_offset_x[10] = n + 1;
+ src_offset_y[10] = m;
+ }
+
+ if ((m >= src_h - 1) || (n >= src_w - 2)) {
+ src_offset_x[11] = n;
+ src_offset_y[11] = m;
+ } else {
+ src_offset_x[11] = n + 1 + 1;
+ src_offset_y[11] = m;
+ }
+
+ if ((m >= src_h - 2) || (n < 1)) {
+ src_offset_x[12] = n;
+ src_offset_y[12] = m;
+ } else {
+ src_offset_x[12] = n - 1;
+ src_offset_y[12] = m;
+ }
+
+ if (m >= src_h - 2) {
+ src_offset_x[13] = n;
+ src_offset_y[13] = m;
+ } else {
+ src_offset_x[13] = n;
+ src_offset_y[13] = m;
+ }
+
+ if ((m >= src_h - 2) || (n >= src_w - 1)) {
+ src_offset_x[14] = n;
+ src_offset_y[14] = m;
+ } else {
+ src_offset_x[14] = n + 1;
+ src_offset_y[14] = m;
+ }
+
+ if ((m >= src_h - 2) || (n >= src_w - 2)) {
+ src_offset_x[15] = n;
+ src_offset_y[15] = m;
+ } else {
+ src_offset_x[15] = n + 1 + 1;
+ src_offset_y[15] = m;
+ }
+
+ for (k = -1; k < 3; k++) {
+ const gdFixed f = gd_itofx(k)-f_f;
+ const gdFixed f_fm1 = f - f_1;
+ const gdFixed f_fp1 = f + f_1;
+ const gdFixed f_fp2 = f + f_2;
+ register gdFixed f_a = 0, f_b = 0, f_d = 0, f_c = 0;
+ register gdFixed f_RY;
+ int l;
+
+ if (f_fp2 > 0) f_a = gd_mulfx(f_fp2, gd_mulfx(f_fp2,f_fp2));
+ if (f_fp1 > 0) f_b = gd_mulfx(f_fp1, gd_mulfx(f_fp1,f_fp1));
+ if (f > 0) f_c = gd_mulfx(f, gd_mulfx(f,f));
+ if (f_fm1 > 0) f_d = gd_mulfx(f_fm1, gd_mulfx(f_fm1,f_fm1));
+
+ f_RY = gd_divfx((f_a - gd_mulfx(f_4,f_b) + gd_mulfx(f_6,f_c) - gd_mulfx(f_4,f_d)),f_6);
+
+ for (l = -1; l < 3; l++) {
+ const gdFixed f = gd_itofx(l) - f_g;
+ const gdFixed f_fm1 = f - f_1;
+ const gdFixed f_fp1 = f + f_1;
+ const gdFixed f_fp2 = f + f_2;
+ register gdFixed f_a = 0, f_b = 0, f_c = 0, f_d = 0;
+ register gdFixed f_RX, f_R, f_rs, f_gs, f_bs, f_ba;
+ register int c;
+ const int _k = ((k+1)*4) + (l+1);
+
+ if (f_fp2 > 0) f_a = gd_mulfx(f_fp2,gd_mulfx(f_fp2,f_fp2));
+
+ if (f_fp1 > 0) f_b = gd_mulfx(f_fp1,gd_mulfx(f_fp1,f_fp1));
+
+ if (f > 0) f_c = gd_mulfx(f,gd_mulfx(f,f));
+
+ if (f_fm1 > 0) f_d = gd_mulfx(f_fm1,gd_mulfx(f_fm1,f_fm1));
+
+ f_RX = gd_divfx((f_a-gd_mulfx(f_4,f_b)+gd_mulfx(f_6,f_c)-gd_mulfx(f_4,f_d)),f_6);
+ f_R = gd_mulfx(f_RY,f_RX);
+
+ c = src->tpixels[*(src_offset_y + _k)][*(src_offset_x + _k)];
+ f_rs = gd_itofx(gdTrueColorGetRed(c));
+ f_gs = gd_itofx(gdTrueColorGetGreen(c));
+ f_bs = gd_itofx(gdTrueColorGetBlue(c));
+ f_ba = gd_itofx(gdTrueColorGetAlpha(c));
+
+ f_red += gd_mulfx(f_rs,f_R);
+ f_green += gd_mulfx(f_gs,f_R);
+ f_blue += gd_mulfx(f_bs,f_R);
+ f_alpha += gd_mulfx(f_ba,f_R);
+ }
+ }
+
+ red = (unsigned char) CLAMP(gd_fxtoi(gd_mulfx(f_red, f_gamma)), 0, 255);
+ green = (unsigned char) CLAMP(gd_fxtoi(gd_mulfx(f_green, f_gamma)), 0, 255);
+ blue = (unsigned char) CLAMP(gd_fxtoi(gd_mulfx(f_blue, f_gamma)), 0, 255);
+ alpha = (unsigned char) CLAMP(gd_fxtoi(gd_mulfx(f_alpha, f_gamma)), 0, 127);
+
+ *(dst_row + dst_offset_x) = gdTrueColorAlpha(red, green, blue, alpha);
+
+ dst_offset_x++;
+ }
+ dst_offset_y++;
+ }
+ return dst;
+}
+
+gdImagePtr gdImageScale(const gdImagePtr src, const unsigned int new_width, const unsigned int new_height)
+{
+ gdImagePtr im_scaled = NULL;
+
+ if (src == NULL || src->interpolation_id < 0 || src->interpolation_id > GD_METHOD_COUNT) {
+ return 0;
+ }
+
+ switch (src->interpolation_id) {
+ /*Special cases, optimized implementations */
+ case GD_NEAREST_NEIGHBOUR:
+ im_scaled = gdImageScaleNearestNeighbour(src, new_width, new_height);
+ break;
+
+ case GD_BILINEAR_FIXED:
+ im_scaled = gdImageScaleBilinear(src, new_width, new_height);
+ break;
+
+ case GD_BICUBIC_FIXED:
+ im_scaled = gdImageScaleBicubicFixed(src, new_width, new_height);
+ break;
+
+ /* generic */
+ default:
+ if (src->interpolation == NULL) {
+ return NULL;
+ }
+ im_scaled = gdImageScaleTwoPass(src, src->sx, src->sy, new_width, new_height);
+ break;
+ }
+ return im_scaled;
+}
+
+gdImagePtr gdImageRotateNearestNeighbour(gdImagePtr src, const float degrees, const int bgColor)
+{
+ float _angle = ((float) (-degrees / 180.0f) * (float)M_PI);
+ const int src_w = gdImageSX(src);
+ const int src_h = gdImageSY(src);
+ const unsigned int new_width = (unsigned int)(abs((int)(src_w * cos(_angle))) + abs((int)(src_h * sin(_angle))) + 0.5f);
+ const unsigned int new_height = (unsigned int)(abs((int)(src_w * sin(_angle))) + abs((int)(src_h * cos(_angle))) + 0.5f);
+ const gdFixed f_0_5 = gd_ftofx(0.5f);
+ const gdFixed f_H = gd_itofx(src_h/2);
+ const gdFixed f_W = gd_itofx(src_w/2);
+ const gdFixed f_cos = gd_ftofx(cos(-_angle));
+ const gdFixed f_sin = gd_ftofx(sin(-_angle));
+
+ unsigned int dst_offset_x;
+ unsigned int dst_offset_y = 0;
+ unsigned int i;
+ gdImagePtr dst;
+
+ dst = gdImageCreateTrueColor(new_width, new_height);
+ if (!dst) {
+ return NULL;
+ }
+ dst->saveAlphaFlag = 1;
+ for (i = 0; i < new_height; i++) {
+ unsigned int j;
+ dst_offset_x = 0;
+ for (j = 0; j < new_width; j++) {
+ gdFixed f_i = gd_itofx((int)i - (int)new_height/2);
+ gdFixed f_j = gd_itofx((int)j - (int)new_width/2);
+ gdFixed f_m = gd_mulfx(f_j,f_sin) + gd_mulfx(f_i,f_cos) + f_0_5 + f_H;
+ gdFixed f_n = gd_mulfx(f_j,f_cos) - gd_mulfx(f_i,f_sin) + f_0_5 + f_W;
+ long m = gd_fxtoi(f_m);
+ long n = gd_fxtoi(f_n);
+
+ if ((m > 0) && (m < src_h-1) && (n > 0) && (n < src_w-1)) {
+ if (dst_offset_y < new_height) {
+ dst->tpixels[dst_offset_y][dst_offset_x++] = src->tpixels[m][n];
+ }
+ } else {
+ if (dst_offset_y < new_height) {
+ dst->tpixels[dst_offset_y][dst_offset_x++] = bgColor;
+ }
+ }
+ }
+ dst_offset_y++;
+ }
+ return dst;
+}
+
+gdImagePtr gdImageRotateGeneric(gdImagePtr src, const float degrees, const int bgColor)
+{
+ float _angle = ((float) (-degrees / 180.0f) * (float)M_PI);
+ const int src_w = gdImageSX(src);
+ const int src_h = gdImageSY(src);
+ const unsigned int new_width = (unsigned int)(abs((int)(src_w * cos(_angle))) + abs((int)(src_h * sin(_angle))) + 0.5f);
+ const unsigned int new_height = (unsigned int)(abs((int)(src_w * sin(_angle))) + abs((int)(src_h * cos(_angle))) + 0.5f);
+ const gdFixed f_0_5 = gd_ftofx(0.5f);
+ const gdFixed f_H = gd_itofx(src_h/2);
+ const gdFixed f_W = gd_itofx(src_w/2);
+ const gdFixed f_cos = gd_ftofx(cos(-_angle));
+ const gdFixed f_sin = gd_ftofx(sin(-_angle));
+
+ unsigned int dst_offset_x;
+ unsigned int dst_offset_y = 0;
+ unsigned int i;
+ gdImagePtr dst;
+
+ const gdFixed f_slop_y = f_sin;
+ const gdFixed f_slop_x = f_cos;
+ const gdFixed f_slop = f_slop_x > 0 && f_slop_x > 0 ?
+ f_slop_x > f_slop_y ? gd_divfx(f_slop_y, f_slop_x) : gd_divfx(f_slop_x, f_slop_y)
+ : 0;
+
+
+ dst = gdImageCreateTrueColor(new_width, new_height);
+ if (!dst) {
+ return NULL;
+ }
+ dst->saveAlphaFlag = 1;
+
+ for (i = 0; i < new_height; i++) {
+ unsigned int j;
+ dst_offset_x = 0;
+ for (j = 0; j < new_width; j++) {
+ gdFixed f_i = gd_itofx((int)i - (int)new_height/ 2);
+ gdFixed f_j = gd_itofx((int)j - (int)new_width / 2);
+ gdFixed f_m = gd_mulfx(f_j,f_sin) + gd_mulfx(f_i,f_cos) + f_0_5 + f_H;
+ gdFixed f_n = gd_mulfx(f_j,f_cos) - gd_mulfx(f_i,f_sin) + f_0_5 + f_W;
+ long m = gd_fxtoi(f_m);
+ long n = gd_fxtoi(f_n);
+
+ if ((n <= 0) || (m <= 0) || (m >= src_h) || (n >= src_w)) {
+ dst->tpixels[dst_offset_y][dst_offset_x++] = bgColor;
+ } else if ((n <= 1) || (m <= 1) || (m >= src_h - 1) || (n >= src_w - 1)) {
+ gdFixed f_127 = gd_itofx(127);
+ register int c = getPixelInterpolated(src, n, m, bgColor);
+ c = c | (( gdTrueColorGetAlpha(c) + ((int)(127* gd_fxtof(f_slop)))) << 24);
+
+ dst->tpixels[dst_offset_y][dst_offset_x++] = _color_blend(bgColor, c);
+ } else {
+ dst->tpixels[dst_offset_y][dst_offset_x++] = getPixelInterpolated(src, n, m, bgColor);
+ }
+ }
+ dst_offset_y++;
+ }
+ return dst;
+}
+
+gdImagePtr gdImageRotateBilinear(gdImagePtr src, const float degrees, const int bgColor)
+{
+ float _angle = (float)((- degrees / 180.0f) * M_PI);
+ const unsigned int src_w = gdImageSX(src);
+ const unsigned int src_h = gdImageSY(src);
+ unsigned int new_width = abs((int)(src_w*cos(_angle))) + abs((int)(src_h*sin(_angle) + 0.5f));
+ unsigned int new_height = abs((int)(src_w*sin(_angle))) + abs((int)(src_h*cos(_angle) + 0.5f));
+ const gdFixed f_0_5 = gd_ftofx(0.5f);
+ const gdFixed f_H = gd_itofx(src_h/2);
+ const gdFixed f_W = gd_itofx(src_w/2);
+ const gdFixed f_cos = gd_ftofx(cos(-_angle));
+ const gdFixed f_sin = gd_ftofx(sin(-_angle));
+ const gdFixed f_1 = gd_itofx(1);
+ unsigned int i;
+ unsigned int dst_offset_x;
+ unsigned int dst_offset_y = 0;
+ unsigned int src_offset_x, src_offset_y;
+ gdImagePtr dst;
+
+ dst = gdImageCreateTrueColor(new_width, new_height);
+ if (dst == NULL) {
+ return NULL;
+ }
+ dst->saveAlphaFlag = 1;
+
+ for (i = 0; i < new_height; i++) {
+ unsigned int j;
+ dst_offset_x = 0;
+
+ for (j=0; j < new_width; j++) {
+ const gdFixed f_i = gd_itofx((int)i - (int)new_height/2);
+ const gdFixed f_j = gd_itofx((int)j - (int)new_width/2);
+ const gdFixed f_m = gd_mulfx(f_j,f_sin) + gd_mulfx(f_i,f_cos) + f_0_5 + f_H;
+ const gdFixed f_n = gd_mulfx(f_j,f_cos) - gd_mulfx(f_i,f_sin) + f_0_5 + f_W;
+ const unsigned int m = gd_fxtoi(f_m);
+ const unsigned int n = gd_fxtoi(f_n);
+
+ if ((m > 0) && (m < src_h - 1) && (n > 0) && (n < src_w - 1)) {
+ const gdFixed f_f = f_m - gd_itofx(m);
+ const gdFixed f_g = f_n - gd_itofx(n);
+ const gdFixed f_w1 = gd_mulfx(f_1-f_f, f_1-f_g);
+ const gdFixed f_w2 = gd_mulfx(f_1-f_f, f_g);
+ const gdFixed f_w3 = gd_mulfx(f_f, f_1-f_g);
+ const gdFixed f_w4 = gd_mulfx(f_f, f_g);
+
+ if (n < src_w - 1) {
+ src_offset_x = n + 1;
+ src_offset_y = m;
+ }
+
+ if (m < src_h-1) {
+ src_offset_x = n;
+ src_offset_y = m + 1;
+ }
+
+ if (!((n >= src_w-1) || (m >= src_h-1))) {
+ src_offset_x = n + 1;
+ src_offset_y = m + 1;
+ }
+ {
+ const int pixel1 = src->tpixels[src_offset_y][src_offset_x];
+ register int pixel2, pixel3, pixel4;
+
+ if (src_offset_y + 1 >= src_h) {
+ pixel2 = bgColor;
+ pixel3 = bgColor;
+ pixel4 = bgColor;
+ } else if (src_offset_x + 1 >= src_w) {
+ pixel2 = bgColor;
+ pixel3 = bgColor;
+ pixel4 = bgColor;
+ } else {
+ pixel2 = src->tpixels[src_offset_y][src_offset_x + 1];
+ pixel3 = src->tpixels[src_offset_y + 1][src_offset_x];
+ pixel4 = src->tpixels[src_offset_y + 1][src_offset_x + 1];
+ }
+ {
+ const gdFixed f_r1 = gd_itofx(gdTrueColorGetRed(pixel1));
+ const gdFixed f_r2 = gd_itofx(gdTrueColorGetRed(pixel2));
+ const gdFixed f_r3 = gd_itofx(gdTrueColorGetRed(pixel3));
+ const gdFixed f_r4 = gd_itofx(gdTrueColorGetRed(pixel4));
+ const gdFixed f_g1 = gd_itofx(gdTrueColorGetGreen(pixel1));
+ const gdFixed f_g2 = gd_itofx(gdTrueColorGetGreen(pixel2));
+ const gdFixed f_g3 = gd_itofx(gdTrueColorGetGreen(pixel3));
+ const gdFixed f_g4 = gd_itofx(gdTrueColorGetGreen(pixel4));
+ const gdFixed f_b1 = gd_itofx(gdTrueColorGetBlue(pixel1));
+ const gdFixed f_b2 = gd_itofx(gdTrueColorGetBlue(pixel2));
+ const gdFixed f_b3 = gd_itofx(gdTrueColorGetBlue(pixel3));
+ const gdFixed f_b4 = gd_itofx(gdTrueColorGetBlue(pixel4));
+ const gdFixed f_a1 = gd_itofx(gdTrueColorGetAlpha(pixel1));
+ const gdFixed f_a2 = gd_itofx(gdTrueColorGetAlpha(pixel2));
+ const gdFixed f_a3 = gd_itofx(gdTrueColorGetAlpha(pixel3));
+ const gdFixed f_a4 = gd_itofx(gdTrueColorGetAlpha(pixel4));
+ const gdFixed f_red = gd_mulfx(f_w1, f_r1) + gd_mulfx(f_w2, f_r2) + gd_mulfx(f_w3, f_r3) + gd_mulfx(f_w4, f_r4);
+ const gdFixed f_green = gd_mulfx(f_w1, f_g1) + gd_mulfx(f_w2, f_g2) + gd_mulfx(f_w3, f_g3) + gd_mulfx(f_w4, f_g4);
+ const gdFixed f_blue = gd_mulfx(f_w1, f_b1) + gd_mulfx(f_w2, f_b2) + gd_mulfx(f_w3, f_b3) + gd_mulfx(f_w4, f_b4);
+ const gdFixed f_alpha = gd_mulfx(f_w1, f_a1) + gd_mulfx(f_w2, f_a2) + gd_mulfx(f_w3, f_a3) + gd_mulfx(f_w4, f_a4);
+
+ const unsigned char red = (unsigned char) CLAMP(gd_fxtoi(f_red), 0, 255);
+ const unsigned char green = (unsigned char) CLAMP(gd_fxtoi(f_green), 0, 255);
+ const unsigned char blue = (unsigned char) CLAMP(gd_fxtoi(f_blue), 0, 255);
+ const unsigned char alpha = (unsigned char) CLAMP(gd_fxtoi(f_alpha), 0, 127);
+
+ dst->tpixels[dst_offset_y][dst_offset_x++] = gdTrueColorAlpha(red, green, blue, alpha);
+ }
+ }
+ } else {
+ dst->tpixels[dst_offset_y][dst_offset_x++] = bgColor;
+ }
+ }
+ dst_offset_y++;
+ }
+ return dst;
+}
+
+gdImagePtr gdImageRotateBicubicFixed(gdImagePtr src, const float degrees, const int bgColor)
+{
+ const float _angle = (float)((- degrees / 180.0f) * M_PI);
+ const int src_w = gdImageSX(src);
+ const int src_h = gdImageSY(src);
+ const unsigned int new_width = abs((int)(src_w*cos(_angle))) + abs((int)(src_h*sin(_angle) + 0.5f));
+ const unsigned int new_height = abs((int)(src_w*sin(_angle))) + abs((int)(src_h*cos(_angle) + 0.5f));
+ const gdFixed f_0_5 = gd_ftofx(0.5f);
+ const gdFixed f_H = gd_itofx(src_h/2);
+ const gdFixed f_W = gd_itofx(src_w/2);
+ const gdFixed f_cos = gd_ftofx(cos(-_angle));
+ const gdFixed f_sin = gd_ftofx(sin(-_angle));
+ const gdFixed f_1 = gd_itofx(1);
+ const gdFixed f_2 = gd_itofx(2);
+ const gdFixed f_4 = gd_itofx(4);
+ const gdFixed f_6 = gd_itofx(6);
+ const gdFixed f_gama = gd_ftofx(1.04f);
+
+ unsigned int dst_offset_x;
+ unsigned int dst_offset_y = 0;
+ unsigned int i;
+ gdImagePtr dst;
+
+ dst = gdImageCreateTrueColor(new_width, new_height);
+
+ if (dst == NULL) {
+ return NULL;
+ }
+ dst->saveAlphaFlag = 1;
+
+ for (i=0; i < new_height; i++) {
+ unsigned int j;
+ dst_offset_x = 0;
+
+ for (j=0; j < new_width; j++) {
+ const gdFixed f_i = gd_itofx((int)i - (int)new_height/2);
+ const gdFixed f_j = gd_itofx((int)j - (int)new_width/2);
+ const gdFixed f_m = gd_mulfx(f_j,f_sin) + gd_mulfx(f_i,f_cos) + f_0_5 + f_H;
+ const gdFixed f_n = gd_mulfx(f_j,f_cos) - gd_mulfx(f_i,f_sin) + f_0_5 + f_W;
+ const int m = gd_fxtoi(f_m);
+ const int n = gd_fxtoi(f_n);
+
+ if ((m > 0) && (m < src_h - 1) && (n > 0) && (n < src_w-1)) {
+ const gdFixed f_f = f_m - gd_itofx(m);
+ const gdFixed f_g = f_n - gd_itofx(n);
+ unsigned int src_offset_x[16], src_offset_y[16];
+ unsigned char red, green, blue, alpha;
+ gdFixed f_red=0, f_green=0, f_blue=0, f_alpha=0;
+ int k;
+
+ if ((m < 1) || (n < 1)) {
+ src_offset_x[0] = n;
+ src_offset_y[0] = m;
+ } else {
+ src_offset_x[0] = n - 1;
+ src_offset_y[0] = m;
+ }
+
+ if (m < 1) {
+ src_offset_x[1] = n;
+ src_offset_y[1] = m;
+ } else {
+ src_offset_x[1] = n;
+ src_offset_y[1] = m ;
+ }
+
+ if ((m < 1) || (n >= src_w-1)) {
+ src_offset_x[2] = - 1;
+ src_offset_y[2] = - 1;
+ } else {
+ src_offset_x[2] = n + 1;
+ src_offset_y[2] = m ;
+ }
+
+ if ((m < 1) || (n >= src_w-2)) {
+ src_offset_x[3] = - 1;
+ src_offset_y[3] = - 1;
+ } else {
+ src_offset_x[3] = n + 1 + 1;
+ src_offset_y[3] = m ;
+ }
+
+ if (n < 1) {
+ src_offset_x[4] = - 1;
+ src_offset_y[4] = - 1;
+ } else {
+ src_offset_x[4] = n - 1;
+ src_offset_y[4] = m;
+ }
+
+ src_offset_x[5] = n;
+ src_offset_y[5] = m;
+ if (n >= src_w-1) {
+ src_offset_x[6] = - 1;
+ src_offset_y[6] = - 1;
+ } else {
+ src_offset_x[6] = n + 1;
+ src_offset_y[6] = m;
+ }
+
+ if (n >= src_w-2) {
+ src_offset_x[7] = - 1;
+ src_offset_y[7] = - 1;
+ } else {
+ src_offset_x[7] = n + 1 + 1;
+ src_offset_y[7] = m;
+ }
+
+ if ((m >= src_h-1) || (n < 1)) {
+ src_offset_x[8] = - 1;
+ src_offset_y[8] = - 1;
+ } else {
+ src_offset_x[8] = n - 1;
+ src_offset_y[8] = m;
+ }
+
+ if (m >= src_h-1) {
+ src_offset_x[8] = - 1;
+ src_offset_y[8] = - 1;
+ } else {
+ src_offset_x[9] = n;
+ src_offset_y[9] = m;
+ }
+
+ if ((m >= src_h-1) || (n >= src_w-1)) {
+ src_offset_x[10] = - 1;
+ src_offset_y[10] = - 1;
+ } else {
+ src_offset_x[10] = n + 1;
+ src_offset_y[10] = m;
+ }
+
+ if ((m >= src_h-1) || (n >= src_w-2)) {
+ src_offset_x[11] = - 1;
+ src_offset_y[11] = - 1;
+ } else {
+ src_offset_x[11] = n + 1 + 1;
+ src_offset_y[11] = m;
+ }
+
+ if ((m >= src_h-2) || (n < 1)) {
+ src_offset_x[12] = - 1;
+ src_offset_y[12] = - 1;
+ } else {
+ src_offset_x[12] = n - 1;
+ src_offset_y[12] = m;
+ }
+
+ if (m >= src_h-2) {
+ src_offset_x[13] = - 1;
+ src_offset_y[13] = - 1;
+ } else {
+ src_offset_x[13] = n;
+ src_offset_y[13] = m;
+ }
+
+ if ((m >= src_h-2) || (n >= src_w - 1)) {
+ src_offset_x[14] = - 1;
+ src_offset_y[14] = - 1;
+ } else {
+ src_offset_x[14] = n + 1;
+ src_offset_y[14] = m;
+ }
+
+ if ((m >= src_h-2) || (n >= src_w-2)) {
+ src_offset_x[15] = - 1;
+ src_offset_y[15] = - 1;
+ } else {
+ src_offset_x[15] = n + 1 + 1;
+ src_offset_y[15] = m;
+ }
+
+ for (k=-1; k<3; k++) {
+ const gdFixed f = gd_itofx(k)-f_f;
+ const gdFixed f_fm1 = f - f_1;
+ const gdFixed f_fp1 = f + f_1;
+ const gdFixed f_fp2 = f + f_2;
+ gdFixed f_a = 0, f_b = 0,f_c = 0, f_d = 0;
+ gdFixed f_RY;
+ int l;
+
+ if (f_fp2 > 0) {
+ f_a = gd_mulfx(f_fp2,gd_mulfx(f_fp2,f_fp2));
+ }
+
+ if (f_fp1 > 0) {
+ f_b = gd_mulfx(f_fp1,gd_mulfx(f_fp1,f_fp1));
+ }
+
+ if (f > 0) {
+ f_c = gd_mulfx(f,gd_mulfx(f,f));
+ }
+
+ if (f_fm1 > 0) {
+ f_d = gd_mulfx(f_fm1,gd_mulfx(f_fm1,f_fm1));
+ }
+ f_RY = gd_divfx((f_a-gd_mulfx(f_4,f_b)+gd_mulfx(f_6,f_c)-gd_mulfx(f_4,f_d)),f_6);
+
+ for (l=-1; l< 3; l++) {
+ const gdFixed f = gd_itofx(l) - f_g;
+ const gdFixed f_fm1 = f - f_1;
+ const gdFixed f_fp1 = f + f_1;
+ const gdFixed f_fp2 = f + f_2;
+ gdFixed f_a = 0, f_b = 0, f_c = 0, f_d = 0;
+ gdFixed f_RX, f_R;
+ const int _k = ((k + 1) * 4) + (l + 1);
+ register gdFixed f_rs, f_gs, f_bs, f_as;
+ register int c;
+
+ if (f_fp2 > 0) {
+ f_a = gd_mulfx(f_fp2,gd_mulfx(f_fp2,f_fp2));
+ }
+
+ if (f_fp1 > 0) {
+ f_b = gd_mulfx(f_fp1,gd_mulfx(f_fp1,f_fp1));
+ }
+
+ if (f > 0) {
+ f_c = gd_mulfx(f,gd_mulfx(f,f));
+ }
+
+ if (f_fm1 > 0) {
+ f_d = gd_mulfx(f_fm1,gd_mulfx(f_fm1,f_fm1));
+ }
+
+ f_RX = gd_divfx((f_a - gd_mulfx(f_4, f_b) + gd_mulfx(f_6, f_c) - gd_mulfx(f_4, f_d)), f_6);
+ f_R = gd_mulfx(f_RY, f_RX);
+
+ if ((src_offset_x[_k] <= 0) || (src_offset_y[_k] <= 0) || (src_offset_y[_k] >= src_h) || (src_offset_x[_k] >= src_w)) {
+ c = bgColor;
+ } else if ((src_offset_x[_k] <= 1) || (src_offset_y[_k] <= 1) || (src_offset_y[_k] >= (int)src_h - 1) || (src_offset_x[_k] >= (int)src_w - 1)) {
+ gdFixed f_127 = gd_itofx(127);
+ c = src->tpixels[src_offset_y[_k]][src_offset_x[_k]];
+ c = c | (( (int) (gd_fxtof(gd_mulfx(f_R, f_127)) + 50.5f)) << 24);
+ c = _color_blend(bgColor, c);
+ } else {
+ c = src->tpixels[src_offset_y[_k]][src_offset_x[_k]];
+ }
+
+ f_rs = gd_itofx(gdTrueColorGetRed(c));
+ f_gs = gd_itofx(gdTrueColorGetGreen(c));
+ f_bs = gd_itofx(gdTrueColorGetBlue(c));
+ f_as = gd_itofx(gdTrueColorGetAlpha(c));
+
+ f_red += gd_mulfx(f_rs, f_R);
+ f_green += gd_mulfx(f_gs, f_R);
+ f_blue += gd_mulfx(f_bs, f_R);
+ f_alpha += gd_mulfx(f_as, f_R);
+ }
+ }
+
+ red = (unsigned char) CLAMP(gd_fxtoi(gd_mulfx(f_red, f_gama)), 0, 255);
+ green = (unsigned char) CLAMP(gd_fxtoi(gd_mulfx(f_green, f_gama)), 0, 255);
+ blue = (unsigned char) CLAMP(gd_fxtoi(gd_mulfx(f_blue, f_gama)), 0, 255);
+ alpha = (unsigned char) CLAMP(gd_fxtoi(gd_mulfx(f_alpha, f_gama)), 0, 127);
+
+ dst->tpixels[dst_offset_y][dst_offset_x] = gdTrueColorAlpha(red, green, blue, alpha);
+ } else {
+ dst->tpixels[dst_offset_y][dst_offset_x] = bgColor;
+ }
+ dst_offset_x++;
+ }
+
+ dst_offset_y++;
+ }
+ return dst;
+}
+
+gdImagePtr gdImageRotateInterpolated(const gdImagePtr src, const float angle, int bgcolor)
+{
+ const int angle_rounded = (int)floor(angle * 100);
+
+ if (bgcolor < 0) {
+ return NULL;
+ }
+
+ /* impact perf a bit, but not that much. Implementation for palette
+ images can be done at a later point.
+ */
+ if (src->trueColor == 0) {
+ if (bgcolor >= 0) {
+ bgcolor = gdTrueColorAlpha(src->red[bgcolor], src->green[bgcolor], src->blue[bgcolor], src->alpha[bgcolor]);
+ }
+ gdImagePaletteToTrueColor(src);
+ }
+
+ /* no interpolation needed here */
+ switch (angle_rounded) {
+ case 9000:
+ return gdImageRotate90(src, 0);
+ case 18000:
+ return gdImageRotate180(src, 0);
+ case 27000:
+ return gdImageRotate270(src, 0);
+ }
+
+ if (src == NULL || src->interpolation_id < 1 || src->interpolation_id > GD_METHOD_COUNT) {
+ return NULL;
+ }
+
+ switch (src->interpolation_id) {
+ case GD_NEAREST_NEIGHBOUR:
+ return gdImageRotateNearestNeighbour(src, angle, bgcolor);
+ break;
+
+ case GD_BILINEAR_FIXED:
+ return gdImageRotateBilinear(src, angle, bgcolor);
+ break;
+
+ case GD_BICUBIC_FIXED:
+ return gdImageRotateBicubicFixed(src, angle, bgcolor);
+ break;
+
+ default:
+ return gdImageRotateGeneric(src, angle, bgcolor);
+ }
+ return NULL;
+}
+
+/**
+ * Title: Affine transformation
+ **/
+
+/**
+ * Group: Transform
+ **/
+
+ static void gdImageClipRectangle(gdImagePtr im, gdRectPtr r)
+{
+ int c1x, c1y, c2x, c2y;
+ int x1,y1;
+
+ gdImageGetClip(im, &c1x, &c1y, &c2x, &c2y);
+ x1 = r->x + r->width - 1;
+ y1 = r->y + r->height - 1;
+ r->x = CLAMP(r->x, c1x, c2x);
+ r->y = CLAMP(r->y, c1y, c2y);
+ r->width = CLAMP(x1, c1x, c2x) - r->x + 1;
+ r->height = CLAMP(y1, c1y, c2y) - r->y + 1;
+}
+
+void gdDumpRect(const char *msg, gdRectPtr r)
+{
+ printf("%s (%i, %i) (%i, %i)\n", msg, r->x, r->y, r->width, r->height);
+}
+
+/**
+ * Function: gdTransformAffineGetImage
+ * Applies an affine transformation to a region and return an image
+ * containing the complete transformation.
+ *
+ * Parameters:
+ * dst - Pointer to a gdImagePtr to store the created image, NULL when
+ * the creation or the transformation failed
+ * src - Source image
+ * src_area - rectangle defining the source region to transform
+ * dstY - Y position in the destination image
+ * affine - The desired affine transformation
+ *
+ * Returns:
+ * GD_TRUE if the affine is rectilinear or GD_FALSE
+ */
+int gdTransformAffineGetImage(gdImagePtr *dst,
+ const gdImagePtr src,
+ gdRectPtr src_area,
+ const double affine[6])
+{
+ int res;
+ double m[6];
+ gdRect bbox;
+ gdRect area_full;
+
+ if (src_area == NULL) {
+ area_full.x = 0;
+ area_full.y = 0;
+ area_full.width = gdImageSX(src);
+ area_full.height = gdImageSY(src);
+ src_area = &area_full;
+ }
+
+ gdTransformAffineBoundingBox(src_area, affine, &bbox);
+
+ *dst = gdImageCreateTrueColor(bbox.width, bbox.height);
+ if (*dst == NULL) {
+ return GD_FALSE;
+ }
+ (*dst)->saveAlphaFlag = 1;
+
+ if (!src->trueColor) {
+ gdImagePaletteToTrueColor(src);
+ }
+
+ /* Translate to dst origin (0,0) */
+ gdAffineTranslate(m, -bbox.x, -bbox.y);
+ gdAffineConcat(m, affine, m);
+
+ gdImageAlphaBlending(*dst, 0);
+
+ res = gdTransformAffineCopy(*dst,
+ 0,0,
+ src,
+ src_area,
+ m);
+
+ if (res != GD_TRUE) {
+ gdImageDestroy(*dst);
+ dst = NULL;
+ return GD_FALSE;
+ } else {
+ return GD_TRUE;
+ }
+}
+
+/**
+ * Function: gdTransformAffineCopy
+ * Applies an affine transformation to a region and copy the result
+ * in a destination to the given position.
+ *
+ * Parameters:
+ * dst - Image to draw the transformed image
+ * src - Source image
+ * dstX - X position in the destination image
+ * dstY - Y position in the destination image
+ * src_area - Rectangular region to rotate in the src image
+ *
+ * Returns:
+ * GD_TRUE if the affine is rectilinear or GD_FALSE
+ */
+int gdTransformAffineCopy(gdImagePtr dst,
+ int dst_x, int dst_y,
+ const gdImagePtr src,
+ gdRectPtr src_region,
+ const double affine[6])
+{
+ int c1x,c1y,c2x,c2y;
+ int backclip = 0;
+ int backup_clipx1, backup_clipy1, backup_clipx2, backup_clipy2;
+ register int x, y, src_offset_x, src_offset_y;
+ double inv[6];
+ int *dst_p;
+ gdPointF pt, src_pt;
+ gdRect bbox;
+ int end_x, end_y;
+ gdInterpolationMethod interpolation_id_bak = GD_DEFAULT;
+ interpolation_method interpolation_bak;
+
+ /* These methods use special implementations */
+ if (src->interpolation_id == GD_BILINEAR_FIXED || src->interpolation_id == GD_BICUBIC_FIXED || src->interpolation_id == GD_NEAREST_NEIGHBOUR) {
+ interpolation_id_bak = src->interpolation_id;
+ interpolation_bak = src->interpolation;
+
+ gdImageSetInterpolationMethod(src, GD_BICUBIC);
+ }
+
+
+ gdImageClipRectangle(src, src_region);
+
+ if (src_region->x > 0 || src_region->y > 0
+ || src_region->width < gdImageSX(src)
+ || src_region->height < gdImageSY(src)) {
+ backclip = 1;
+
+ gdImageGetClip(src, &backup_clipx1, &backup_clipy1,
+ &backup_clipx2, &backup_clipy2);
+
+ gdImageSetClip(src, src_region->x, src_region->y,
+ src_region->x + src_region->width - 1,
+ src_region->y + src_region->height - 1);
+ }
+
+ if (!gdTransformAffineBoundingBox(src_region, affine, &bbox)) {
+ if (backclip) {
+ gdImageSetClip(src, backup_clipx1, backup_clipy1,
+ backup_clipx2, backup_clipy2);
+ }
+ gdImageSetInterpolationMethod(src, interpolation_id_bak);
+ return GD_FALSE;
+ }
+
+ gdImageGetClip(dst, &c1x, &c1y, &c2x, &c2y);
+
+ end_x = bbox.width + (int) fabs(bbox.x);
+ end_y = bbox.height + (int) fabs(bbox.y);
+
+ /* Get inverse affine to let us work with destination -> source */
+ gdAffineInvert(inv, affine);
+
+ src_offset_x = src_region->x;
+ src_offset_y = src_region->y;
+
+ if (dst->alphaBlendingFlag) {
+ for (y = bbox.y; y <= end_y; y++) {
+ pt.y = y + 0.5;
+ for (x = 0; x <= end_x; x++) {
+ pt.x = x + 0.5;
+ gdAffineApplyToPointF(&src_pt, &pt, inv);
+ gdImageSetPixel(dst, dst_x + x, dst_y + y, getPixelInterpolated(src, src_offset_x + src_pt.x, src_offset_y + src_pt.y, 0));
+ }
+ }
+ } else {
+ for (y = 0; y <= end_y; y++) {
+ pt.y = y + 0.5 + bbox.y;
+ if ((dst_y + y) < 0 || ((dst_y + y) > gdImageSY(dst) -1)) {
+ continue;
+ }
+ dst_p = dst->tpixels[dst_y + y] + dst_x;
+
+ for (x = 0; x <= end_x; x++) {
+ pt.x = x + 0.5 + bbox.x;
+ gdAffineApplyToPointF(&src_pt, &pt, inv);
+
+ if ((dst_x + x) < 0 || (dst_x + x) > (gdImageSX(dst) - 1)) {
+ break;
+ }
+ *(dst_p++) = getPixelInterpolated(src, src_offset_x + src_pt.x, src_offset_y + src_pt.y, -1);
+ }
+ }
+ }
+
+ /* Restore clip if required */
+ if (backclip) {
+ gdImageSetClip(src, backup_clipx1, backup_clipy1,
+ backup_clipx2, backup_clipy2);
+ }
+
+ gdImageSetInterpolationMethod(src, interpolation_id_bak);
+ return GD_TRUE;
+}
+
+/**
+ * Function: gdTransformAffineBoundingBox
+ * Returns the bounding box of an affine transformation applied to a
+ * rectangular area <gdRect>
+ *
+ * Parameters:
+ * src - Rectangular source area for the affine transformation
+ * affine - the affine transformation
+ * bbox - the resulting bounding box
+ *
+ * Returns:
+ * GD_TRUE if the affine is rectilinear or GD_FALSE
+ */
+int gdTransformAffineBoundingBox(gdRectPtr src, const double affine[6], gdRectPtr bbox)
+{
+ gdPointF extent[4], min, max, point;
+ int i;
+
+ extent[0].x=0.0;
+ extent[0].y=0.0;
+ extent[1].x=(double) src->width;
+ extent[1].y=0.0;
+ extent[2].x=(double) src->width;
+ extent[2].y=(double) src->height;
+ extent[3].x=0.0;
+ extent[3].y=(double) src->height;
+
+ for (i=0; i < 4; i++) {
+ point=extent[i];
+ if (gdAffineApplyToPointF(&extent[i], &point, affine) != GD_TRUE) {
+ return GD_FALSE;
+ }
+ }
+ min=extent[0];
+ max=extent[0];
+
+ for (i=1; i < 4; i++) {
+ if (min.x > extent[i].x)
+ min.x=extent[i].x;
+ if (min.y > extent[i].y)
+ min.y=extent[i].y;
+ if (max.x < extent[i].x)
+ max.x=extent[i].x;
+ if (max.y < extent[i].y)
+ max.y=extent[i].y;
+ }
+ bbox->x = (int) min.x;
+ bbox->y = (int) min.y;
+ bbox->width = (int) floor(max.x - min.x) - 1;
+ bbox->height = (int) floor(max.y - min.y);
+ return GD_TRUE;
+}
+
+int gdImageSetInterpolationMethod(gdImagePtr im, gdInterpolationMethod id)
+{
+ if (im == NULL || id < 0 || id > GD_METHOD_COUNT) {
+ return 0;
+ }
+
+ switch (id) {
+ case GD_DEFAULT:
+ im->interpolation_id = GD_BILINEAR_FIXED;
+ im->interpolation = NULL;
+ break;
+
+ /* Optimized versions */
+ case GD_BILINEAR_FIXED:
+ case GD_BICUBIC_FIXED:
+ case GD_NEAREST_NEIGHBOUR:
+ case GD_WEIGHTED4:
+ im->interpolation = NULL;
+ break;
+
+ /* generic versions*/
+ case GD_BELL:
+ im->interpolation = filter_bell;
+ break;
+ case GD_BESSEL:
+ im->interpolation = filter_bessel;
+ break;
+ case GD_BICUBIC:
+ im->interpolation = filter_bicubic;
+ break;
+ case GD_BLACKMAN:
+ im->interpolation = filter_blackman;
+ break;
+ case GD_BOX:
+ im->interpolation = filter_box;
+ break;
+ case GD_BSPLINE:
+ im->interpolation = filter_bspline;
+ break;
+ case GD_CATMULLROM:
+ im->interpolation = filter_catmullrom;
+ break;
+ case GD_GAUSSIAN:
+ im->interpolation = filter_gaussian;
+ break;
+ case GD_GENERALIZED_CUBIC:
+ im->interpolation = filter_generalized_cubic;
+ break;
+ case GD_HERMITE:
+ im->interpolation = filter_hermite;
+ break;
+ case GD_HAMMING:
+ im->interpolation = filter_hamming;
+ break;
+ case GD_HANNING:
+ im->interpolation = filter_hanning;
+ break;
+ case GD_MITCHELL:
+ im->interpolation = filter_mitchell;
+ break;
+ case GD_POWER:
+ im->interpolation = filter_power;
+ break;
+ case GD_QUADRATIC:
+ im->interpolation = filter_quadratic;
+ break;
+ case GD_SINC:
+ im->interpolation = filter_sinc;
+ break;
+ case GD_TRIANGLE:
+ im->interpolation = filter_triangle;
+ break;
+
+ default:
+ return 0;
+ break;
+ }
+ im->interpolation_id = id;
+ return 1;
+}
+
+#ifdef _MSC_VER
+# pragma optimize("", on)
+#endif
diff --git a/ext/gd/libgd/gd_jpeg.c b/ext/gd/libgd/gd_jpeg.c
index 175c5b85fd..a882b28c88 100644
--- a/ext/gd/libgd/gd_jpeg.c
+++ b/ext/gd/libgd/gd_jpeg.c
@@ -269,21 +269,31 @@ void gdImageJpegCtx (gdImagePtr im, gdIOCtx * outfile, int quality)
gdFree (row);
}
-gdImagePtr gdImageCreateFromJpeg (FILE * inFile, int ignore_warning)
+gdImagePtr gdImageCreateFromJpeg (FILE * inFile)
+{
+ return gdImageCreateFromJpegEx(inFile, 1);
+}
+
+gdImagePtr gdImageCreateFromJpegEx (FILE * inFile, int ignore_warning)
{
gdImagePtr im;
gdIOCtx *in = gdNewFileCtx(inFile);
- im = gdImageCreateFromJpegCtx(in, ignore_warning);
+ im = gdImageCreateFromJpegCtxEx(in, ignore_warning);
in->gd_free (in);
return im;
}
-gdImagePtr gdImageCreateFromJpegPtr (int size, void *data, int ignore_warning)
+gdImagePtr gdImageCreateFromJpegPtr (int size, void *data)
+{
+ return gdImageCreateFromJpegPtrEx(size, data, 1);
+}
+
+gdImagePtr gdImageCreateFromJpegPtrEx (int size, void *data, int ignore_warning)
{
gdImagePtr im;
gdIOCtx *in = gdNewDynamicCtxEx(size, data, 0);
- im = gdImageCreateFromJpegCtx(in, ignore_warning);
+ im = gdImageCreateFromJpegCtxEx(in, ignore_warning);
in->gd_free(in);
return im;
@@ -298,7 +308,12 @@ static int CMYKToRGB(int c, int m, int y, int k, int inverted);
* Create a gd-format image from the JPEG-format INFILE. Returns the
* image, or NULL upon error.
*/
-gdImagePtr gdImageCreateFromJpegCtx (gdIOCtx * infile, int ignore_warning)
+gdImagePtr gdImageCreateFromJpegCtx (gdIOCtx * infile)
+{
+ return gdImageCreateFromJpegCtxEx(infile, 1);
+}
+
+gdImagePtr gdImageCreateFromJpegCtxEx (gdIOCtx * infile, int ignore_warning)
{
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
diff --git a/ext/gd/libgd/gd_matrix.c b/ext/gd/libgd/gd_matrix.c
new file mode 100644
index 0000000000..83438bdbe3
--- /dev/null
+++ b/ext/gd/libgd/gd_matrix.c
@@ -0,0 +1,334 @@
+#include "gd.h"
+#include <math.h>
+
+#ifndef M_PI
+# define M_PI 3.14159265358979323846
+#endif
+
+/**
+ * Title: Matrix
+ * Group: Affine Matrix
+ */
+
+/**
+ * Function: gdAffineApplyToPointF
+ * Applies an affine transformation to a point (floating point
+ * gdPointF)
+ *
+ *
+ * Parameters:
+ * dst - Where to store the resulting point
+ * affine - Source Point
+ * flip_horz - affine matrix
+ *
+ * Returns:
+ * GD_TRUE if the affine is rectilinear or GD_FALSE
+ */
+int gdAffineApplyToPointF (gdPointFPtr dst, const gdPointFPtr src,
+ const double affine[6])
+{
+ double x = src->x;
+ double y = src->y;
+ x = src->x;
+ y = src->y;
+ dst->x = x * affine[0] + y * affine[2] + affine[4];
+ dst->y = x * affine[1] + y * affine[3] + affine[5];
+ return GD_TRUE;
+}
+
+/**
+ * Function: gdAffineInvert
+ * Find the inverse of an affine transformation.
+ *
+ * All non-degenerate affine transforms are invertible. Applying the
+ * inverted matrix will restore the original values. Multiplying <src>
+ * by <dst> (commutative) will return the identity affine (rounding
+ * error possible).
+ *
+ * Parameters:
+ * dst - Where to store the resulting affine transform
+ * src_affine - Original affine matrix
+ * flip_horz - Whether or not to flip horizontally
+ * flip_vert - Whether or not to flip vertically
+ *
+ * See also:
+ * <gdAffineIdentity>
+ *
+ * Returns:
+ * GD_TRUE if the affine is rectilinear or GD_FALSE
+ */
+int gdAffineInvert (double dst[6], const double src[6])
+{
+ double r_det = (src[0] * src[3] - src[1] * src[2]);
+
+ if (r_det <= 0.0) {
+ return GD_FALSE;
+ }
+
+ r_det = 1.0 / r_det;
+ dst[0] = src[3] * r_det;
+ dst[1] = -src[1] * r_det;
+ dst[2] = -src[2] * r_det;
+ dst[3] = src[0] * r_det;
+ dst[4] = -src[4] * dst[0] - src[5] * dst[2];
+ dst[5] = -src[4] * dst[1] - src[5] * dst[3];
+ return GD_TRUE;
+}
+
+/**
+ * Function: gdAffineFlip
+ * Flip an affine transformation horizontally or vertically.
+ *
+ * Flips the affine transform, giving GD_FALSE for <flip_horz> and
+ * <flip_vert> will clone the affine matrix. GD_TRUE for both will
+ * copy a 180° rotation.
+ *
+ * Parameters:
+ * dst - Where to store the resulting affine transform
+ * src_affine - Original affine matrix
+ * flip_h - Whether or not to flip horizontally
+ * flip_v - Whether or not to flip vertically
+ *
+ * Returns:
+ * GD_SUCCESS on success or GD_FAILURE
+ */
+int gdAffineFlip (double dst[6], const double src[6], const int flip_h, const int flip_v)
+{
+ dst[0] = flip_h ? - src[0] : src[0];
+ dst[1] = flip_h ? - src[1] : src[1];
+ dst[2] = flip_v ? - src[2] : src[2];
+ dst[3] = flip_v ? - src[3] : src[3];
+ dst[4] = flip_h ? - src[4] : src[4];
+ dst[5] = flip_v ? - src[5] : src[5];
+ return GD_TRUE;
+}
+
+/**
+ * Function: gdAffineConcat
+ * Concat (Multiply) two affine transformation matrices.
+ *
+ * Concats two affine transforms together, i.e. the result
+ * will be the equivalent of doing first the transformation m1 and then
+ * m2. All parameters can be the same matrix (safe to call using
+ * the same array for all three arguments).
+ *
+ * Parameters:
+ * dst - Where to store the resulting affine transform
+ * m1 - First affine matrix
+ * m2 - Second affine matrix
+ *
+ * Returns:
+ * GD_SUCCESS on success or GD_FAILURE
+ */
+int gdAffineConcat (double dst[6], const double m1[6], const double m2[6])
+{
+ double dst0, dst1, dst2, dst3, dst4, dst5;
+
+ dst0 = m1[0] * m2[0] + m1[1] * m2[2];
+ dst1 = m1[0] * m2[1] + m1[1] * m2[3];
+ dst2 = m1[2] * m2[0] + m1[3] * m2[2];
+ dst3 = m1[2] * m2[1] + m1[3] * m2[3];
+ dst4 = m1[4] * m2[0] + m1[5] * m2[2] + m2[4];
+ dst5 = m1[4] * m2[1] + m1[5] * m2[3] + m2[5];
+ dst[0] = dst0;
+ dst[1] = dst1;
+ dst[2] = dst2;
+ dst[3] = dst3;
+ dst[4] = dst4;
+ dst[5] = dst5;
+ return GD_TRUE;
+}
+
+/**
+ * Function: gdAffineIdentity
+ * Set up the identity matrix.
+ *
+ * Parameters:
+ * dst - Where to store the resulting affine transform
+ *
+ * Returns:
+ * GD_SUCCESS on success or GD_FAILURE
+ */
+int gdAffineIdentity (double dst[6])
+{
+ dst[0] = 1;
+ dst[1] = 0;
+ dst[2] = 0;
+ dst[3] = 1;
+ dst[4] = 0;
+ dst[5] = 0;
+ return GD_TRUE;
+}
+
+/**
+ * Function: gdAffineScale
+ * Set up a scaling matrix.
+ *
+ * Parameters:
+ * scale_x - X scale factor
+ * scale_y - Y scale factor
+ *
+ * Returns:
+ * GD_SUCCESS on success or GD_FAILURE
+ */
+int gdAffineScale (double dst[6], const double scale_x, const double scale_y)
+{
+ dst[0] = scale_x;
+ dst[1] = 0;
+ dst[2] = 0;
+ dst[3] = scale_y;
+ dst[4] = 0;
+ dst[5] = 0;
+ return GD_TRUE;
+}
+
+/**
+ * Function: gdAffineRotate
+ * Set up a rotation affine transform.
+ *
+ * Like the other angle in libGD, in which increasing y moves
+ * downward, this is a counterclockwise rotation.
+ *
+ * Parameters:
+ * dst - Where to store the resulting affine transform
+ * angle - Rotation angle in degrees
+ *
+ * Returns:
+ * GD_SUCCESS on success or GD_FAILURE
+ */
+int gdAffineRotate (double dst[6], const double angle)
+{
+ const double sin_t = sin (angle * M_PI / 180.0);
+ const double cos_t = cos (angle * M_PI / 180.0);
+
+ dst[0] = cos_t;
+ dst[1] = sin_t;
+ dst[2] = -sin_t;
+ dst[3] = cos_t;
+ dst[4] = 0;
+ dst[5] = 0;
+ return GD_TRUE;
+}
+
+/**
+ * Function: gdAffineShearHorizontal
+ * Set up a horizontal shearing matrix || becomes \\.
+ *
+ * Parameters:
+ * dst - Where to store the resulting affine transform
+ * angle - Shear angle in degrees
+ *
+ * Returns:
+ * GD_SUCCESS on success or GD_FAILURE
+ */
+int gdAffineShearHorizontal(double dst[6], const double angle)
+{
+ dst[0] = 1;
+ dst[1] = 0;
+ dst[2] = tan(angle * M_PI / 180.0);
+ dst[3] = 1;
+ dst[4] = 0;
+ dst[5] = 0;
+ return GD_TRUE;
+}
+
+/**
+ * Function: gdAffineShearVertical
+ * Set up a vertical shearing matrix, columns are untouched.
+ *
+ * Parameters:
+ * dst - Where to store the resulting affine transform
+ * angle - Shear angle in degrees
+ *
+ * Returns:
+ * GD_SUCCESS on success or GD_FAILURE
+ */
+int gdAffineShearVertical(double dst[6], const double angle)
+{
+ dst[0] = 1;
+ dst[1] = tan(angle * M_PI / 180.0);;
+ dst[2] = 0;
+ dst[3] = 1;
+ dst[4] = 0;
+ dst[5] = 0;
+ return GD_TRUE;
+}
+
+/**
+ * Function: gdAffineTranslate
+ * Set up a translation matrix.
+ *
+ * Parameters:
+ * dst - Where to store the resulting affine transform
+ * offset_x - Horizontal translation amount
+ * offset_y - Vertical translation amount
+ *
+ * Returns:
+ * GD_SUCCESS on success or GD_FAILURE
+ */
+int gdAffineTranslate (double dst[6], const double offset_x, const double offset_y)
+{
+ dst[0] = 1;
+ dst[1] = 0;
+ dst[2] = 0;
+ dst[3] = 1;
+ dst[4] = offset_x;
+ dst[5] = offset_y;
+ return GD_TRUE;
+}
+
+/**
+ * gdAffineexpansion: Find the affine's expansion factor.
+ * @src: The affine transformation.
+ *
+ * Finds the expansion factor, i.e. the square root of the factor
+ * by which the affine transform affects area. In an affine transform
+ * composed of scaling, rotation, shearing, and translation, returns
+ * the amount of scaling.
+ *
+ * GD_SUCCESS on success or GD_FAILURE
+ **/
+double gdAffineExpansion (const double src[6])
+{
+ return sqrt (fabs (src[0] * src[3] - src[1] * src[2]));
+}
+
+/**
+ * Function: gdAffineRectilinear
+ * Determines whether the affine transformation is axis aligned. A
+ * tolerance has been implemented using GD_EPSILON.
+ *
+ * Parameters:
+ * m - The affine transformation
+ *
+ * Returns:
+ * GD_TRUE if the affine is rectilinear or GD_FALSE
+ */
+int gdAffineRectilinear (const double m[6])
+{
+ return ((fabs (m[1]) < GD_EPSILON && fabs (m[2]) < GD_EPSILON) ||
+ (fabs (m[0]) < GD_EPSILON && fabs (m[3]) < GD_EPSILON));
+}
+
+/**
+ * Function: gdAffineEqual
+ * Determines whether two affine transformations are equal. A tolerance
+ * has been implemented using GD_EPSILON.
+ *
+ * Parameters:
+ * m1 - The first affine transformation
+ * m2 - The first affine transformation
+ *
+ * Returns:
+ * GD_SUCCESS on success or GD_FAILURE
+ */
+int gdAffineEqual (const double m1[6], const double m2[6])
+{
+ return (fabs (m1[0] - m2[0]) < GD_EPSILON &&
+ fabs (m1[1] - m2[1]) < GD_EPSILON &&
+ fabs (m1[2] - m2[2]) < GD_EPSILON &&
+ fabs (m1[3] - m2[3]) < GD_EPSILON &&
+ fabs (m1[4] - m2[4]) < GD_EPSILON &&
+ fabs (m1[5] - m2[5]) < GD_EPSILON);
+}
+
diff --git a/ext/gd/libgd/gd_png.c b/ext/gd/libgd/gd_png.c
index bdbb7ee7d3..a012cc63b8 100644
--- a/ext/gd/libgd/gd_png.c
+++ b/ext/gd/libgd/gd_png.c
@@ -134,6 +134,7 @@ gdImagePtr gdImageCreateFromPngCtx (gdIOCtx * infile)
volatile int transparent = -1;
volatile int palette_allocated = FALSE;
+
/* Make sure the signature can't match by dumb luck -- TBB */
/* GRR: isn't sizeof(infile) equal to the size of the pointer? */
memset (sig, 0, sizeof(sig));
@@ -345,6 +346,7 @@ gdImagePtr gdImageCreateFromPngCtx (gdIOCtx * infile)
open[i] = 1;
}
}
+
/* 2.0.12: Slaven Rezic: palette images are not the only images
* with a simple transparent color setting.
*/
diff --git a/ext/gd/libgd/gd_transform.c b/ext/gd/libgd/gd_transform.c
new file mode 100644
index 0000000000..9051525eec
--- /dev/null
+++ b/ext/gd/libgd/gd_transform.c
@@ -0,0 +1,73 @@
+#include "gd.h"
+
+void gdImageFlipVertical(gdImagePtr im)
+{
+ register int x, y;
+
+ if (im->trueColor) {
+ for (y = 0; y < im->sy / 2; y++) {
+ int *row_dst = im->tpixels[y];
+ int *row_src = im->tpixels[im->sy - 1 - y];
+ for (x = 0; x < im->sx; x++) {
+ register int p;
+ p = row_dst[x];
+ row_dst[x] = im->tpixels[im->sy - 1 - y][x];
+ row_src[x] = p;
+ }
+ }
+ } else {
+ unsigned char p;
+ for (y = 0; y < im->sy / 2; y++) {
+ for (x = 0; x < im->sx; x++) {
+ p = im->pixels[y][x];
+ im->pixels[y][x] = im->pixels[im->sy - 1 - y][x];
+ im->pixels[im->sy - 1 - y][x] = p;
+ }
+ }
+ }
+ return;
+}
+
+void gdImageFlipHorizontal(gdImagePtr im)
+{
+
+ int x, y;
+
+ if (im->trueColor) {
+ int *px1, *px2, tmp;
+
+ for (y = 0; y < im->sy; y++) {
+ px1 = im->tpixels[y];
+ px2 = im->tpixels[y] + im->sx - 1;
+ for (x = 0; x < (im->sx >> 1); x++) {
+ tmp = *px1;
+ *px1 = *px2;
+ *px2 = tmp;
+ px1++;
+ px2--;
+ }
+ }
+ } else {
+ unsigned char *px1, *px2, tmp;
+
+ for (y = 0; y < im->sy; y++) {
+ px1 = im->pixels[y];
+ px2 = im->pixels[y] + im->sx - 1;
+ for (x = 0; x < (im->sx >> 1); x++) {
+ tmp = *px1;
+ *px1 = *px2;
+ *px2 = tmp;
+ px1++;
+ px2--;
+ }
+ }
+ }
+}
+
+void gdImageFlipBoth(gdImagePtr im)
+{
+ gdImageFlipVertical(im);
+ gdImageFlipHorizontal(im);
+}
+
+
diff --git a/ext/gd/libgd/gd_webp.c b/ext/gd/libgd/gd_webp.c
index 889f5f10a6..bf9ac9dd0e 100644
--- a/ext/gd/libgd/gd_webp.c
+++ b/ext/gd/libgd/gd_webp.c
@@ -58,11 +58,13 @@ gdImagePtr gdImageCreateFromWebpPtr (int size, void *data)
return im;
}
+#define GD_WEBP_ALLOC_STEP (4*1024)
+
gdImagePtr gdImageCreateFromWebpCtx (gdIOCtx * infile)
{
int width, height, ret;
- unsigned char *filedata;
- unsigned char dummy[1024];
+ unsigned char *filedata = NULL;
+ unsigned char *read, *temp;
unsigned char *Y = NULL;
unsigned char *U = NULL;
unsigned char *V = NULL;
@@ -70,16 +72,25 @@ gdImagePtr gdImageCreateFromWebpCtx (gdIOCtx * infile)
gdImagePtr im;
do {
- n = gdGetBuf(dummy, 1024, infile);
- size += n;
- } while (n != EOF);
+ temp = gdRealloc(filedata, size+GD_WEBP_ALLOC_STEP);
+ if (temp) {
+ filedata = temp;
+ read = temp + size;
+ } else {
+ if (filedata) {
+ gdFree(filedata);
+ }
+ php_gd_error("WebP decode: realloc failed");
+ return NULL;
+ }
+
+ n = gdGetBuf(read, GD_WEBP_ALLOC_STEP, infile);
+ /* differs from upstream where gdGetBuf return 0 instead of EOF */
+ if (n>0 && n!=EOF) {
+ size += n;
+ }
+ } while (n>0 && n!=EOF);
- filedata = gdMalloc(size);
- if (!filedata) {
- php_gd_error("WebP decode: alloc failed");
- return NULL;
- }
- gdGetBuf(filedata, size, infile);
ret = WebPDecode(filedata, size, &Y, &U, &V, &width, &height);
gdFree(filedata);
if (ret != webp_success) {
diff --git a/ext/gd/php_gd.h b/ext/gd/php_gd.h
index 92fc438bc9..1f32a8f9b1 100644
--- a/ext/gd/php_gd.h
+++ b/ext/gd/php_gd.h
@@ -22,15 +22,13 @@
#ifndef PHP_GD_H
#define PHP_GD_H
-#define HAVE_GDIMAGECREATEFROMPNG 1
-
#if HAVE_LIBFREETYPE
# ifndef ENABLE_GD_TTF
# define ENABLE_GD_TTF
# endif
#endif
-#if HAVE_LIBGD
+#if defined(HAVE_LIBGD) || defined(HAVE_GD_BUNDLED)
/* open_basedir and safe_mode checks */
#define PHP_GD_CHECK_OPEN_BASEDIR(filename, errormsg) \
@@ -69,10 +67,10 @@ extern zend_module_entry gd_module_entry;
/* gd.c functions */
PHP_MINFO_FUNCTION(gd);
PHP_MINIT_FUNCTION(gd);
-#if HAVE_LIBT1 || HAVE_GD_FONTMUTEX
+#if HAVE_LIBT1
PHP_MSHUTDOWN_FUNCTION(gd);
#endif
-#if HAVE_GD_STRINGFT
+#if HAVE_GD_FREETYPE && HAVE_LIBFREETYPE
PHP_RSHUTDOWN_FUNCTION(gd);
#endif
@@ -104,6 +102,7 @@ PHP_FUNCTION(imagefttext);
PHP_FUNCTION(imagecreatetruecolor);
PHP_FUNCTION(imagetruecolortopalette);
+PHP_FUNCTION(imagepalettetotruecolor);
PHP_FUNCTION(imagesetthickness);
PHP_FUNCTION(imagefilledellipse);
PHP_FUNCTION(imagefilledarc);
@@ -122,10 +121,20 @@ PHP_FUNCTION(imagegrabscreen);
PHP_FUNCTION(imagerotate);
+PHP_FUNCTION(imageflip);
+
#ifdef HAVE_GD_BUNDLED
PHP_FUNCTION(imageantialias);
#endif
+PHP_FUNCTION(imagecrop);
+PHP_FUNCTION(imagecropauto);
+PHP_FUNCTION(imagescale);
+PHP_FUNCTION(imageaffine);
+PHP_FUNCTION(imageaffinematrixget);
+PHP_FUNCTION(imageaffinematrixconcat);
+PHP_FUNCTION(imagesetinterpolation);
+
PHP_FUNCTION(imagesetthickness);
PHP_FUNCTION(imagecopymergegray);
PHP_FUNCTION(imagesetbrush);
@@ -142,7 +151,7 @@ PHP_FUNCTION(imagecreatefromwbmp);
PHP_FUNCTION(imagecreatefromgd);
PHP_FUNCTION(imagecreatefromgd2);
PHP_FUNCTION(imagecreatefromgd2part);
-#if defined(HAVE_GD_XPM) && defined(HAVE_GD_BUNDLED)
+#if defined(HAVE_GD_XPM)
PHP_FUNCTION(imagecreatefromxpm);
#endif
@@ -193,10 +202,8 @@ PHP_FUNCTION(image2wbmp);
PHP_FUNCTION(imagecolormatch);
-#if HAVE_GD_BUNDLED
PHP_FUNCTION(imagelayereffect);
PHP_FUNCTION(imagexbm);
-#endif
PHP_FUNCTION(imagefilter);
PHP_FUNCTION(imageconvolution);
diff --git a/ext/gd/tests/bug43073.phpt b/ext/gd/tests/bug43073.phpt
index 4f448f2b4a..8ddd324421 100644
--- a/ext/gd/tests/bug43073.phpt
+++ b/ext/gd/tests/bug43073.phpt
@@ -33,19 +33,19 @@ imagepng($g, "$cwd/bug43073.png");
--CLEAN--
<?php @unlink(dirname(__FILE__) . '/bug43073.png'); ?>
--EXPECTF--
-(500, 402), (610, 402), (610, 376), (500, 376)
+(500, 40%d), (610, 40%d), (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)
+(40%d, 300), (40%d, 183), (38%d, 183), (38%d, 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)
+(300, %d), (18%d, %d), (18%d, 425), (%d, 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)
+(%d, 500), (%d, 618), (41%d, 618), (41%d, 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/bug48801.phpt b/ext/gd/tests/bug48801.phpt
index fd25541a52..773564f782 100644
--- a/ext/gd/tests/bug48801.phpt
+++ b/ext/gd/tests/bug48801.phpt
@@ -20,6 +20,6 @@ echo '(' . $bbox[6] . ', ' . $bbox[7] . ")\n";
?>
--EXPECTF--
(-1, 15)
-(155, 15)
-(155, -48)
+(15%d, 15)
+(15%d, -48)
(-1, -48)
diff --git a/ext/gd/tests/bug66356.phpt b/ext/gd/tests/bug66356.phpt
new file mode 100644
index 0000000000..2da91d61a9
--- /dev/null
+++ b/ext/gd/tests/bug66356.phpt
@@ -0,0 +1,40 @@
+--TEST--
+Bug #66356 (Heap Overflow Vulnerability in imagecrop())
+--SKIPIF--
+<?php
+ if(!extension_loaded('gd')){ die('skip gd extension not available'); }
+?>
+--FILE--
+<?php
+$img = imagecreatetruecolor(10, 10);
+
+// POC #1
+var_dump(imagecrop($img, array("x" => "a", "y" => 0, "width" => 10, "height" => 10)));
+
+$arr = array("x" => "a", "y" => "12b", "width" => 10, "height" => 10);
+var_dump(imagecrop($img, $arr));
+print_r($arr);
+
+// POC #2
+var_dump(imagecrop($img, array("x" => 0, "y" => 0, "width" => -1, "height" => 10)));
+
+// POC #3
+var_dump(imagecrop($img, array("x" => -20, "y" => -20, "width" => 10, "height" => 10)));
+
+// POC #4
+var_dump(imagecrop($img, array("x" => 0x7fffff00, "y" => 0, "width" => 10, "height" => 10)));
+
+?>
+--EXPECTF--
+resource(%d) of type (gd)
+resource(%d) of type (gd)
+Array
+(
+ [x] => a
+ [y] => 12b
+ [width] => 10
+ [height] => 10
+)
+bool(false)
+resource(%d) of type (gd)
+resource(%d) of type (gd) \ No newline at end of file
diff --git a/ext/gd/tests/imagecrop_auto.phpt b/ext/gd/tests/imagecrop_auto.phpt
new file mode 100644
index 0000000000..1c1929d8e8
--- /dev/null
+++ b/ext/gd/tests/imagecrop_auto.phpt
@@ -0,0 +1,84 @@
+--TEST--
+Testing imagecropauto()
+--SKIPIF--
+<?php
+if ( ! extension_loaded('gd') || !function_exists('imagecrop')) die( 'skip GD imagecropauto not present; skipping test' );
+?>
+--FILE--
+<?php
+
+echo "TC IMG_CROP_DEFAULT\n";
+$im = imagecreatetruecolor(99, 99);
+imagefilledrectangle($im, 20, 20, 30, 30, 0xff);
+$im_crop = imagecropauto($im, IMG_CROP_DEFAULT);
+var_dump(imagesx($im_crop));
+var_dump(imagesy($im_crop));
+
+echo "Palette IMG_CROP_DEFAULT\n";
+$im = imagecreate(99, 99);
+imagefilledrectangle($im, 20, 20, 30, 30, 0xff);
+$im_crop = imagecropauto($im, IMG_CROP_DEFAULT);
+var_dump(imagesx($im_crop));
+var_dump(imagesy($im_crop));
+
+echo "TC IMG_CROP_SIDES\n";
+$im = imagecreatetruecolor(99, 99);
+imagefilledrectangle($im, 20, 20, 30, 30, 0xff);
+$im_crop = imagecropauto($im, IMG_CROP_SIDES);
+var_dump(imagesx($im_crop));
+var_dump(imagesy($im_crop));
+
+echo "Palette IMG_CROP_SIDES\n";
+$im = imagecreate(99, 99);
+imagefilledrectangle($im, 20, 20, 30, 30, 0xff);
+$im_crop = imagecropauto($im, IMG_CROP_SIDES);
+var_dump(imagesx($im_crop));
+var_dump(imagesy($im_crop));
+
+echo "TC IMG_CROP_BLACK\n";
+$im = imagecreatetruecolor(50, 50);
+imagefilledrectangle($im, 20, 20, 30, 30, 0xff);
+$im_crop = imagecropauto($im, IMG_CROP_BLACK);
+var_dump(imagesx($im_crop));
+var_dump(imagesy($im_crop));
+
+echo "Palette IMG_CROP_BLACK\n";
+$im = imagecreate(50, 50);
+$bgd = imagecolorallocate($im, 0, 0, 0);
+$b = imagecolorallocate($im, 0, 0, 255);
+imagefilledrectangle($im, 20, 20, 30, 30, 0xff);
+$im_crop = imagecropauto($im, IMG_CROP_BLACK);
+var_dump(imagesx($im_crop));
+var_dump(imagesy($im_crop));
+
+echo "IMG_CROP_THRESHOLD\n";
+$im = imagecreatefrompng(__DIR__ . "/logo_noise.png");
+$im_crop = imagecropauto($im, IMG_CROP_THRESHOLD, 0.1, 0x0);
+imagepng($im_crop, __DIR__ . "/crop_threshold.png");
+var_dump(imagesx($im_crop));
+var_dump(imagesy($im_crop));
+
+@unlink(__DIR__ . "/crop_threshold.png");
+?>
+--EXPECT--
+TC IMG_CROP_DEFAULT
+int(11)
+int(11)
+Palette IMG_CROP_DEFAULT
+int(11)
+int(11)
+TC IMG_CROP_SIDES
+int(11)
+int(11)
+Palette IMG_CROP_SIDES
+int(11)
+int(11)
+TC IMG_CROP_BLACK
+int(11)
+int(11)
+Palette IMG_CROP_BLACK
+int(11)
+int(11)
+IMG_CROP_THRESHOLD
+int(240)
+int(134)
diff --git a/ext/gd/tests/imageflip.phpt b/ext/gd/tests/imageflip.phpt
new file mode 100644
index 0000000000..a326e0a2ba
--- /dev/null
+++ b/ext/gd/tests/imageflip.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Testing imageflip() of GD library
+--SKIPIF--
+<?php
+if ( ! extension_loaded('gd') || !function_exists('imageflip')) die( 'skip GD not present; skipping test' );
+?>
+--FILE--
+<?php
+
+$im = imagecreatetruecolor( 99, 99 );
+
+imagesetpixel($im, 0, 0, 0xFF);
+imagesetpixel($im, 0, 98, 0x00FF00);
+imagesetpixel($im, 98, 0, 0xFF0000);
+imagesetpixel($im, 98, 98, 0x0000FF);
+
+imageflip($im, IMG_FLIP_HORIZONTAL);
+imageflip($im, IMG_FLIP_VERTICAL);
+imageflip($im, IMG_FLIP_BOTH);
+
+var_dump(dechex(imagecolorat($im, 0, 0)));
+var_dump(dechex(imagecolorat($im, 0, 98)));
+var_dump(dechex(imagecolorat($im, 98, 0)));
+var_dump(dechex(imagecolorat($im, 98, 98)));
+?>
+--EXPECT--
+string(2) "ff"
+string(4) "ff00"
+string(6) "ff0000"
+string(2) "ff" \ No newline at end of file
diff --git a/ext/gd/tests/imageloadfont_invalid.phpt b/ext/gd/tests/imageloadfont_invalid.phpt
index 07bf150ac8..6cf0e336b6 100644
--- a/ext/gd/tests/imageloadfont_invalid.phpt
+++ b/ext/gd/tests/imageloadfont_invalid.phpt
@@ -3,7 +3,6 @@ imageloadfont() function crashes
--SKIPIF--
<?php
if (!extension_loaded('gd')) die("skip gd extension not available\n");
- if (!GD_BUNDLED) die('skip external GD libraries always fail');
?>
--FILE--
<?php
diff --git a/ext/gd/tests/logo_noise.png b/ext/gd/tests/logo_noise.png
new file mode 100644
index 0000000000..c9bde52c30
--- /dev/null
+++ b/ext/gd/tests/logo_noise.png
Binary files differ
diff --git a/ext/gettext/config.m4 b/ext/gettext/config.m4
index 02d436c6e7..24dddd3a43 100644
--- a/ext/gettext/config.m4
+++ b/ext/gettext/config.m4
@@ -3,7 +3,7 @@ dnl $Id$
dnl
PHP_ARG_WITH(gettext,for GNU gettext support,
-[ --with-gettext[=DIR] Include GNU gettext support])
+[ --with-gettext[=DIR] Include GNU gettext support])
if test "$PHP_GETTEXT" != "no"; then
for i in $PHP_GETTEXT /usr/local /usr; do
diff --git a/ext/gmp/config.m4 b/ext/gmp/config.m4
index 9606b2f56d..2140aaf701 100644
--- a/ext/gmp/config.m4
+++ b/ext/gmp/config.m4
@@ -3,7 +3,7 @@ dnl $Id$
dnl
PHP_ARG_WITH(gmp, for GNU MP support,
-[ --with-gmp[=DIR] Include GNU MP support])
+[ --with-gmp[=DIR] Include GNU MP support])
if test "$PHP_GMP" != "no"; then
diff --git a/ext/hash/config.m4 b/ext/hash/config.m4
index 79ac25e19f..44c6d267bc 100644
--- a/ext/hash/config.m4
+++ b/ext/hash/config.m4
@@ -2,7 +2,7 @@ dnl $Id$
dnl config.m4 for extension hash
PHP_ARG_WITH(mhash, for mhash support,
-[ --with-mhash[=DIR] Include mhash support])
+[ --with-mhash[=DIR] Include mhash support])
PHP_ARG_ENABLE(hash, whether to enable hash support,
[ --disable-hash Disable hash support], yes)
diff --git a/ext/hash/hash.c b/ext/hash/hash.c
index bd9dcca59f..5222a395e6 100644
--- a/ext/hash/hash.c
+++ b/ext/hash/hash.c
@@ -23,6 +23,7 @@
#include "config.h"
#endif
+#include <math.h>
#include "php_hash.h"
#include "ext/standard/info.h"
#include "ext/standard/file.h"
@@ -202,10 +203,45 @@ PHP_FUNCTION(hash_file)
}
/* }}} */
+static inline void php_hash_string_xor_char(unsigned char *out, const unsigned char *in, const unsigned char xor_with, const int length) {
+ int i;
+ for (i=0; i < length; i++) {
+ out[i] = in[i] ^ xor_with;
+ }
+}
+
+static inline void php_hash_string_xor(unsigned char *out, const unsigned char *in, const unsigned char *xor_with, const int length) {
+ int i;
+ for (i=0; i < length; i++) {
+ out[i] = in[i] ^ xor_with[i];
+ }
+}
+
+static inline void php_hash_hmac_prep_key(unsigned char *K, const php_hash_ops *ops, void *context, const unsigned char *key, const int key_len) {
+ memset(K, 0, ops->block_size);
+ if (key_len > ops->block_size) {
+ /* Reduce the key first */
+ ops->hash_init(context);
+ ops->hash_update(context, key, key_len);
+ ops->hash_final(K, context);
+ } else {
+ memcpy(K, key, key_len);
+ }
+ /* XOR the key with 0x36 to get the ipad) */
+ php_hash_string_xor_char(K, K, 0x36, ops->block_size);
+}
+
+static inline void php_hash_hmac_round(unsigned char *final, const php_hash_ops *ops, void *context, const unsigned char *key, const unsigned char *data, const long data_size) {
+ ops->hash_init(context);
+ ops->hash_update(context, key, ops->block_size);
+ ops->hash_update(context, data, data_size);
+ ops->hash_final(final, context);
+}
+
static void php_hash_do_hash_hmac(INTERNAL_FUNCTION_PARAMETERS, int isfilename, zend_bool raw_output_default) /* {{{ */
{
char *algo, *data, *digest, *key, *K;
- int algo_len, data_len, key_len, i;
+ int algo_len, data_len, key_len;
zend_bool raw_output = raw_output_default;
const php_hash_ops *ops;
void *context;
@@ -230,52 +266,29 @@ static void php_hash_do_hash_hmac(INTERNAL_FUNCTION_PARAMETERS, int isfilename,
}
context = emalloc(ops->context_size);
- ops->hash_init(context);
K = emalloc(ops->block_size);
- memset(K, 0, ops->block_size);
+ digest = emalloc(ops->digest_size + 1);
- if (key_len > ops->block_size) {
- /* Reduce the key first */
- ops->hash_update(context, (unsigned char *) key, key_len);
- ops->hash_final((unsigned char *) K, context);
- /* Make the context ready to start over */
- ops->hash_init(context);
- } else {
- memcpy(K, key, key_len);
- }
-
- /* XOR ipad */
- for(i=0; i < ops->block_size; i++) {
- K[i] ^= 0x36;
- }
- ops->hash_update(context, (unsigned char *) K, ops->block_size);
+ php_hash_hmac_prep_key((unsigned char *) K, ops, context, (unsigned char *) key, key_len);
if (isfilename) {
char buf[1024];
int n;
-
+ ops->hash_init(context);
+ ops->hash_update(context, (unsigned char *) K, ops->block_size);
while ((n = php_stream_read(stream, buf, sizeof(buf))) > 0) {
ops->hash_update(context, (unsigned char *) buf, n);
}
php_stream_close(stream);
+ ops->hash_final((unsigned char *) digest, context);
} else {
- ops->hash_update(context, (unsigned char *) data, data_len);
+ php_hash_hmac_round((unsigned char *) digest, ops, context, (unsigned char *) K, (unsigned char *) data, data_len);
}
- digest = emalloc(ops->digest_size + 1);
- ops->hash_final((unsigned char *) digest, context);
+ php_hash_string_xor_char((unsigned char *) K, (unsigned char *) K, 0x6A, ops->block_size);
- /* Convert K to opad -- 0x6A = 0x36 ^ 0x5C */
- for(i=0; i < ops->block_size; i++) {
- K[i] ^= 0x6A;
- }
-
- /* Feed this result into the outter hash */
- ops->hash_init(context);
- ops->hash_update(context, (unsigned char *) K, ops->block_size);
- ops->hash_update(context, (unsigned char *) digest, ops->digest_size);
- ops->hash_final((unsigned char *) digest, context);
+ php_hash_hmac_round((unsigned char *) digest, ops, context, (unsigned char *) K, (unsigned char *) digest, ops->digest_size);
/* Zero the key */
memset(K, 0, ops->block_size);
@@ -584,13 +597,138 @@ PHP_FUNCTION(hash_algos)
array_init(return_value);
for(zend_hash_internal_pointer_reset_ex(&php_hash_hashtable, &pos);
- (type = zend_hash_get_current_key_ex(&php_hash_hashtable, &str, &str_len, &idx, 0, &pos)) != HASH_KEY_NON_EXISTANT;
+ (type = zend_hash_get_current_key_ex(&php_hash_hashtable, &str, &str_len, &idx, 0, &pos)) != HASH_KEY_NON_EXISTENT;
zend_hash_move_forward_ex(&php_hash_hashtable, &pos)) {
add_next_index_stringl(return_value, str, str_len-1, 1);
}
}
/* }}} */
+/* {{{ proto string hash_pbkdf2(string algo, string password, string salt, int iterations [, int length = 0, bool raw_output = false])
+Generate a PBKDF2 hash of the given password and salt
+Returns lowercase hexits by default */
+PHP_FUNCTION(hash_pbkdf2)
+{
+ char *returnval, *algo, *salt, *pass = NULL;
+ unsigned char *computed_salt, *digest, *temp, *result, *K1, *K2 = NULL;
+ long loops, i, j, algo_len, pass_len, iterations, length, digest_length = 0;
+ int argc, salt_len = 0;
+ zend_bool raw_output = 0;
+ const php_hash_ops *ops;
+ void *context;
+
+ argc = ZEND_NUM_ARGS();
+ if (zend_parse_parameters(argc TSRMLS_CC, "sssl|lb", &algo, &algo_len, &pass, &pass_len, &salt, &salt_len, &iterations, &length, &raw_output) == FAILURE) {
+ return;
+ }
+
+ ops = php_hash_fetch_ops(algo, algo_len);
+ if (!ops) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown hashing algorithm: %s", algo);
+ RETURN_FALSE;
+ }
+
+ if (iterations <= 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Iterations must be a positive integer: %ld", iterations);
+ RETURN_FALSE;
+ }
+
+ if (length < 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length must be greater than or equal to 0: %ld", length);
+ RETURN_FALSE;
+ }
+
+ if (salt_len > INT_MAX - 4) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Supplied salt is too long, max of INT_MAX - 4 bytes: %d supplied", salt_len);
+ RETURN_FALSE;
+ }
+
+ context = emalloc(ops->context_size);
+ ops->hash_init(context);
+
+ K1 = emalloc(ops->block_size);
+ K2 = emalloc(ops->block_size);
+ digest = emalloc(ops->digest_size);
+ temp = emalloc(ops->digest_size);
+
+ /* Setup Keys that will be used for all hmac rounds */
+ php_hash_hmac_prep_key(K1, ops, context, (unsigned char *) pass, pass_len);
+ /* Convert K1 to opad -- 0x6A = 0x36 ^ 0x5C */
+ php_hash_string_xor_char(K2, K1, 0x6A, ops->block_size);
+
+ /* Setup Main Loop to build a long enough result */
+ if (length == 0) {
+ length = ops->digest_size;
+ if (!raw_output) {
+ length = length * 2;
+ }
+ }
+ digest_length = length;
+ if (!raw_output) {
+ digest_length = (long) ceil((float) length / 2.0);
+ }
+
+ loops = (long) ceil((float) digest_length / (float) ops->digest_size);
+
+ result = safe_emalloc(loops, ops->digest_size, 0);
+
+ computed_salt = safe_emalloc(salt_len, 1, 4);
+ memcpy(computed_salt, (unsigned char *) salt, salt_len);
+
+ for (i = 1; i <= loops; i++) {
+ /* digest = hash_hmac(salt + pack('N', i), password) { */
+
+ /* pack("N", i) */
+ computed_salt[salt_len] = (unsigned char) (i >> 24);
+ computed_salt[salt_len + 1] = (unsigned char) ((i & 0xFF0000) >> 16);
+ computed_salt[salt_len + 2] = (unsigned char) ((i & 0xFF00) >> 8);
+ computed_salt[salt_len + 3] = (unsigned char) (i & 0xFF);
+
+ php_hash_hmac_round(digest, ops, context, K1, computed_salt, (long) salt_len + 4);
+ php_hash_hmac_round(digest, ops, context, K2, digest, ops->digest_size);
+ /* } */
+
+ /* temp = digest */
+ memcpy(temp, digest, ops->digest_size);
+
+ /*
+ * Note that the loop starting at 1 is intentional, since we've already done
+ * the first round of the algorithm.
+ */
+ for (j = 1; j < iterations; j++) {
+ /* digest = hash_hmac(digest, password) { */
+ php_hash_hmac_round(digest, ops, context, K1, digest, ops->digest_size);
+ php_hash_hmac_round(digest, ops, context, K2, digest, ops->digest_size);
+ /* } */
+ /* temp ^= digest */
+ php_hash_string_xor(temp, temp, digest, ops->digest_size);
+ }
+ /* result += temp */
+ memcpy(result + ((i - 1) * ops->digest_size), temp, ops->digest_size);
+ }
+ /* Zero potentially sensitive variables */
+ memset(K1, 0, ops->block_size);
+ memset(K2, 0, ops->block_size);
+ memset(computed_salt, 0, salt_len + 4);
+ efree(K1);
+ efree(K2);
+ efree(computed_salt);
+ efree(context);
+ efree(digest);
+ efree(temp);
+
+ returnval = safe_emalloc(length, 1, 1);
+ if (raw_output) {
+ memcpy(returnval, result, length);
+ } else {
+ php_hash_bin2hex(returnval, result, digest_length);
+ }
+ returnval[length] = 0;
+ efree(result);
+ RETURN_STRINGL(returnval, length, 0);
+}
+/* }}} */
+
/* Module Housekeeping */
static void php_hash_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
@@ -904,7 +1042,7 @@ PHP_MINFO_FUNCTION(hash)
long type;
for(zend_hash_internal_pointer_reset_ex(&php_hash_hashtable, &pos);
- (type = zend_hash_get_current_key_ex(&php_hash_hashtable, &str, NULL, &idx, 0, &pos)) != HASH_KEY_NON_EXISTANT;
+ (type = zend_hash_get_current_key_ex(&php_hash_hashtable, &str, NULL, &idx, 0, &pos)) != HASH_KEY_NON_EXISTENT;
zend_hash_move_forward_ex(&php_hash_hashtable, &pos)) {
s += slprintf(s, e - s, "%s ", str);
}
@@ -1003,6 +1141,15 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_hash_algos, 0)
ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO_EX(arginfo_hash_pbkdf2, 0, 0, 4)
+ ZEND_ARG_INFO(0, algo)
+ ZEND_ARG_INFO(0, password)
+ ZEND_ARG_INFO(0, salt)
+ ZEND_ARG_INFO(0, iterations)
+ ZEND_ARG_INFO(0, length)
+ ZEND_ARG_INFO(0, raw_output)
+ZEND_END_ARG_INFO()
+
/* BC Land */
#ifdef PHP_MHASH_BC
ZEND_BEGIN_ARG_INFO(arginfo_mhash_get_block_size, 0)
@@ -1049,6 +1196,7 @@ const zend_function_entry hash_functions[] = {
PHP_FE(hash_copy, arginfo_hash_copy)
PHP_FE(hash_algos, arginfo_hash_algos)
+ PHP_FE(hash_pbkdf2, arginfo_hash_pbkdf2)
/* BC Land */
#ifdef PHP_HASH_MD5_NOT_IN_CORE
@@ -1105,3 +1253,4 @@ ZEND_GET_MODULE(hash)
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
+
diff --git a/ext/hash/php_hash.h b/ext/hash/php_hash.h
index d4f5b16e24..1d35ae8a46 100644
--- a/ext/hash/php_hash.h
+++ b/ext/hash/php_hash.h
@@ -127,6 +127,7 @@ PHP_FUNCTION(hash_update_stream);
PHP_FUNCTION(hash_update_file);
PHP_FUNCTION(hash_final);
PHP_FUNCTION(hash_algos);
+PHP_FUNCTION(hash_pbkdf2);
PHP_HASH_API const php_hash_ops *php_hash_fetch_ops(const char *algo, int algo_len);
PHP_HASH_API void php_hash_register_algo(const char *algo, const php_hash_ops *ops);
diff --git a/ext/hash/tests/bug64745.phpt b/ext/hash/tests/bug64745.phpt
new file mode 100644
index 0000000000..427f89b728
--- /dev/null
+++ b/ext/hash/tests/bug64745.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Bug #64745 hash_pbkdf2() truncates data when using default length and hex output
+--SKIPIF--
+<?php extension_loaded('hash') or die('skip'); ?>
+--FILE--
+<?php
+$hash = hash_pbkdf2('sha1', 'password', 'salt', 1, 0);
+$rawHash = hash_pbkdf2('sha1', 'password', 'salt', 1, 0, true);
+
+var_dump($hash);
+var_dump(bin2hex($rawHash));
+
+?>
+--EXPECT--
+string(40) "0c60c80f961f0e71f3a9b524af6012062fe037a6"
+string(40) "0c60c80f961f0e71f3a9b524af6012062fe037a6"
+
diff --git a/ext/hash/tests/hash_pbkdf2_basic.phpt b/ext/hash/tests/hash_pbkdf2_basic.phpt
new file mode 100644
index 0000000000..fdccc4b6ea
--- /dev/null
+++ b/ext/hash/tests/hash_pbkdf2_basic.phpt
@@ -0,0 +1,37 @@
+--TEST--
+Test hash_pbkdf2() function : basic functionality
+--SKIPIF--
+<?php extension_loaded('hash') or die('skip: hash extension not loaded.'); ?>
+--FILE--
+<?php
+
+/* Prototype : string hash_hmac ( string $algo , string $data , string $key [, bool $raw_output ] )
+ * Description: Generate a keyed hash value using the HMAC method
+ * Source code: ext/hash/hash.c
+ * Alias to functions:
+*/
+
+echo "*** Testing hash_pbkdf2() : basic functionality ***\n";
+
+echo "sha1: " . hash_pbkdf2('sha1', 'password', 'salt', 1, 20)."\n";
+echo "sha1(raw): " . bin2hex(hash_pbkdf2('sha1', 'password', 'salt', 1, 20, TRUE))."\n";
+echo "sha1(rounds): " . hash_pbkdf2('sha1', 'passwordPASSWORDpassword', 'saltSALTsaltSALTsaltSALTsaltSALTsalt', 4096, 25)."\n";
+echo "sha1(rounds)(raw): " . bin2hex(hash_pbkdf2('sha1', 'passwordPASSWORDpassword', 'saltSALTsaltSALTsaltSALTsaltSALTsalt', 4096, 25, TRUE))."\n";
+echo "sha256: " . hash_pbkdf2('sha256', 'password', 'salt', 1, 20)."\n";
+echo "sha256(raw): " . bin2hex(hash_pbkdf2('sha256', 'password', 'salt', 1, 20, TRUE))."\n";
+echo "sha256(rounds): " . hash_pbkdf2('sha256', 'passwordPASSWORDpassword', 'saltSALTsaltSALTsaltSALTsaltSALTsalt', 4096, 40)."\n";
+echo "sha256(rounds)(raw): " . bin2hex(hash_pbkdf2('sha256', 'passwordPASSWORDpassword', 'saltSALTsaltSALTsaltSALTsaltSALTsalt', 4096, 40, TRUE))."\n";
+
+?>
+===Done===
+--EXPECT--
+*** Testing hash_pbkdf2() : basic functionality ***
+sha1: 0c60c80f961f0e71f3a9
+sha1(raw): 0c60c80f961f0e71f3a9b524af6012062fe037a6
+sha1(rounds): 3d2eec4fe41c849b80c8d8366
+sha1(rounds)(raw): 3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038
+sha256: 120fb6cffcf8b32c43e7
+sha256(raw): 120fb6cffcf8b32c43e7225256c4f837a86548c9
+sha256(rounds): 348c89dbcbd32b2f32d814b8116e84cf2b17347e
+sha256(rounds)(raw): 348c89dbcbd32b2f32d814b8116e84cf2b17347ebc1800181c4e2a1fb8dd53e1c635518c7dac47e9
+===Done===
diff --git a/ext/hash/tests/hash_pbkdf2_error.phpt b/ext/hash/tests/hash_pbkdf2_error.phpt
new file mode 100644
index 0000000000..fd70cca581
--- /dev/null
+++ b/ext/hash/tests/hash_pbkdf2_error.phpt
@@ -0,0 +1,78 @@
+--TEST--
+Test hash_pbkdf2() function : error functionality
+--SKIPIF--
+<?php extension_loaded('hash') or die('skip: hash extension not loaded.'); ?>
+--FILE--
+<?php
+
+/* {{{ proto string hash_pbkdf2(string algo, string password, string salt, int iterations [, int length = 0, bool raw_output = false])
+Generate a PBKDF2 hash of the given password and salt
+Returns lowercase hexbits by default */
+
+echo "*** Testing hash_pbkdf2() : error conditions ***\n";
+
+$password = 'password';
+$salt = 'salt';
+
+echo "\n-- Testing hash_pbkdf2() function with less than expected no. of arguments --\n";
+var_dump(@hash_pbkdf2());
+echo $php_errormsg . "\n";
+var_dump(@hash_pbkdf2('crc32'));
+echo $php_errormsg . "\n";
+var_dump(@hash_pbkdf2('crc32', $password));
+echo $php_errormsg . "\n";
+var_dump(@hash_pbkdf2('crc32', $password, $salt));
+echo $php_errormsg . "\n";
+
+echo "\n-- Testing hash_pbkdf2() function with more than expected no. of arguments --\n";
+var_dump(@hash_pbkdf2('crc32', $password, $salt, 10, 10, true, 'extra arg'));
+echo $php_errormsg . "\n";
+
+echo "\n-- Testing hash_pbkdf2() function with invalid hash algorithm --\n";
+var_dump(@hash_pbkdf2('foo', $password, $salt, 1));
+echo $php_errormsg . "\n";
+
+echo "\n-- Testing hash_pbkdf2() function with invalid iterations --\n";
+var_dump(@hash_pbkdf2('md5', $password, $salt, 0));
+echo $php_errormsg . "\n";
+var_dump(@hash_pbkdf2('md5', $password, $salt, -1));
+echo $php_errormsg . "\n";
+
+echo "\n-- Testing hash_pbkdf2() function with invalid length --\n";
+var_dump(@hash_pbkdf2('md5', $password, $salt, 1, -1));
+echo $php_errormsg . "\n\n";
+
+?>
+===Done===
+--EXPECT--
+*** Testing hash_pbkdf2() : error conditions ***
+
+-- Testing hash_pbkdf2() function with less than expected no. of arguments --
+NULL
+hash_pbkdf2() expects at least 4 parameters, 0 given
+NULL
+hash_pbkdf2() expects at least 4 parameters, 1 given
+NULL
+hash_pbkdf2() expects at least 4 parameters, 2 given
+NULL
+hash_pbkdf2() expects at least 4 parameters, 3 given
+
+-- Testing hash_pbkdf2() function with more than expected no. of arguments --
+NULL
+hash_pbkdf2() expects at most 6 parameters, 7 given
+
+-- Testing hash_pbkdf2() function with invalid hash algorithm --
+bool(false)
+hash_pbkdf2(): Unknown hashing algorithm: foo
+
+-- Testing hash_pbkdf2() function with invalid iterations --
+bool(false)
+hash_pbkdf2(): Iterations must be a positive integer: 0
+bool(false)
+hash_pbkdf2(): Iterations must be a positive integer: -1
+
+-- Testing hash_pbkdf2() function with invalid length --
+bool(false)
+hash_pbkdf2(): Length must be greater than or equal to 0: -1
+
+===Done===
diff --git a/ext/iconv/config.m4 b/ext/iconv/config.m4
index d673b0adba..10d21ccc6d 100644
--- a/ext/iconv/config.m4
+++ b/ext/iconv/config.m4
@@ -3,7 +3,7 @@ dnl $Id$
dnl
PHP_ARG_WITH(iconv, for iconv support,
-[ --without-iconv[=DIR] Exclude iconv support], yes)
+[ --without-iconv[=DIR] Exclude iconv support], yes)
if test "$PHP_ICONV" != "no"; then
diff --git a/ext/imap/config.m4 b/ext/imap/config.m4
index 3fcf6742da..d664215e66 100644
--- a/ext/imap/config.m4
+++ b/ext/imap/config.m4
@@ -95,7 +95,7 @@ AC_DEFUN([PHP_IMAP_SSL_CHK], [
PHP_ARG_WITH(imap,for IMAP support,
-[ --with-imap[=DIR] Include IMAP support. DIR is the c-client install prefix])
+[ --with-imap[=DIR] Include IMAP support. DIR is the c-client install prefix])
PHP_ARG_WITH(kerberos,for IMAP Kerberos support,
[ --with-kerberos[=DIR] IMAP: Include Kerberos support. DIR is the Kerberos install prefix], no, no)
diff --git a/ext/interbase/config.m4 b/ext/interbase/config.m4
index 603145ad6c..dfd850b00a 100644
--- a/ext/interbase/config.m4
+++ b/ext/interbase/config.m4
@@ -3,7 +3,7 @@ dnl $Id$
dnl
PHP_ARG_WITH(interbase,for InterBase support,
-[ --with-interbase[=DIR] Include InterBase support. DIR is the InterBase base
+[ --with-interbase[=DIR] Include InterBase support. DIR is the InterBase base
install directory [/usr/interbase]])
if test "$PHP_INTERBASE" != "no"; then
diff --git a/ext/interbase/tests/skipif.inc b/ext/interbase/tests/skipif.inc
index 79813f69e6..8f903a5ea5 100644
--- a/ext/interbase/tests/skipif.inc
+++ b/ext/interbase/tests/skipif.inc
@@ -1,9 +1,8 @@
<?php /* $Id$ */
-if (!extension_loaded("interbase")) print "skip interbase extension not available";
+if (!extension_loaded("interbase")) print "skip interbase extension not available";
require("interbase.inc");
if(!@ibase_connect($test_base)){
die("skip cannot connnect");
}
-
?>
diff --git a/ext/intl/ERROR.CONVENTIONS b/ext/intl/ERROR.CONVENTIONS
new file mode 100644
index 0000000000..41cd14ec06
--- /dev/null
+++ b/ext/intl/ERROR.CONVENTIONS
@@ -0,0 +1,115 @@
+The intl extension has particular conventions regarding error reporting.
+These conventions are enumerated in this document.
+
+:: The last error is always stored globally.
+
+The global error code can be obtained in userland with intl_get_error_code().
+This is a U_* error code defined by ICU, but it does not have necessarily to be
+returned obtained after a call to an ICU function. That is to say, the internal
+PHP wrapper functions can set these error codes when appropriate. For instance,
+in response to bad arguments (e.g. zend_parse_parameters() failure), the PHP
+wrapper function should set the global error code to U_ILLEGAL_ARGUMENT_ERROR).
+
+The error code (an integer) can be converter to the corresponding enum name
+string in userland with intl_error_name().
+
+The associated message can be obtained with intl_get_error_message(). This is a
+message set by the PHP wrapping code, not by ICU. The message should include the
+name of the function that failed in order to make debugging easier (though if
+you activate warnings with intl.error_level or exceptions with
+intl.use_exceptions you get more fine-grained information about where the
+error occurred).
+
+The internal PHP code can set the global last error with:
+void intl_error_set_code(intl_error* err, UErrorCode err_code TSRMLS_DC);
+void intl_error_set_custom_msg(intl_error* err, char* msg, int copyMsg TSRMLS_DC);
+void intl_error_set(intl_error* err, UErrorCode code, char* msg, int copyMsg TSRMLS_DC);
+
+and by passing NULL as the first parameter. The last function is a combination
+of the first two. If the message is not a static buffer, copyMsg should be 1.
+This makes the message string be copied and freed when no longer needed. There's
+no way to pass ownership of the string without it being copied.
+
+
+:: The last is ALSO stored in the object whose method call triggered the error,
+ unless the error is due to bad arguments, in which case only the global error
+ should be set
+
+Objects store an intl_error structed in their private data. For instance:
+typedef struct {
+ zend_object zo;
+ intl_error err;
+ Calendar* ucal;
+} Calendar_object;
+
+The global error and the object error can be SIMULTANEOUSLY set with these
+functions:
+void intl_errors_set_custom_msg(intl_error* err, char* msg, int copyMsg TSRMLS_DC);
+void intl_errors_set_code(intl_error* err, UErrorCode err_code TSRMLS_DC);
+void intl_errors_set(intl_error* err, UErrorCode code, char* msg, int copyMsg TSRMLS_DC);
+
+by passing a pointer to the object's intl_error structed as the first parameter.
+Node the extra 's' in the functions' names ('errors', not 'error').
+
+Static methods should only set the global error.
+
+
+:: Intl classes that can be instantiated should provide ::getErrorCode() and
+ getErrorMessage() methods
+
+These methods are used to retrieve the error codes stored in the object's
+private intl_error structured and mirror the global intl_get_error_code() and
+intl_get_error_message().
+
+
+:: Intl methods and functions should return FALSE on error (even argument
+ parsing errors), not NULL. Constructors and factory methods are the
+ exception; these should return NULL, not FALSE.
+
+Not that constructors in Intl generally (always?) don't throws exceptions.
+They instead destroy the object to that the result of new IntlClass() can
+be NULL. This may be surprising.
+
+
+:: Intl functions and methods should reset the global error before doing
+ anything else (even parse the arguments); instance methods should also reset
+ the object's private error
+
+Errors should be lost after a function call. This is different from the way
+ICU operates, where functions return immediately if an error is set.
+
+Error resetting can be done with:
+void intl_error_reset(NULL TSRMLS_DC); /* reset global error */
+void intl_errors_reset(intl_error* err TSRMLS_DC ); /* reset global and object error */
+
+In practice, intl_errors_reset() is not used because most classes have also
+plain functions mapped to the same internal functions as their instance methods.
+Fetching of the object is done with zend_parse_method_parameters() instead of
+directly using getThis(). Therefore, no reference to object is obtained until
+the arguments are fully parsed. Without a reference to the object, there's no
+way to reset the object's internal error code. Instead, resetting of the
+object's internal error code is done upon fetching the object from its zval.
+
+Example:
+U_CFUNC PHP_FUNCTION(breakiter_set_text)
+{
+ /* ... variable declations ... */
+ BREAKITER_METHOD_INIT_VARS; /* macro also resets global error */
+ object = getThis();
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",
+ &text, &text_len) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "breakiter_set_text: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ /* ... */
+
+ BREAKITER_METHOD_FETCH_OBJECT; /* macro also resets object's error */
+
+ /* ... */
+}
+
+Implementations of ::getErrorCode() and ::getErrorMessage() should not reset the
+object's error code.
diff --git a/ext/intl/breakiterator/breakiterator_class.cpp b/ext/intl/breakiterator/breakiterator_class.cpp
new file mode 100644
index 0000000000..7ca7e94c95
--- /dev/null
+++ b/ext/intl/breakiterator/breakiterator_class.cpp
@@ -0,0 +1,397 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <unicode/brkiter.h>
+#include <unicode/rbbi.h>
+#include "codepointiterator_internal.h"
+
+#include "breakiterator_iterators.h"
+
+#include <typeinfo>
+
+extern "C" {
+#define USE_BREAKITERATOR_POINTER 1
+#include "breakiterator_class.h"
+#include "breakiterator_methods.h"
+#include "rulebasedbreakiterator_methods.h"
+#include "codepointiterator_methods.h"
+#include <zend_exceptions.h>
+#include <zend_interfaces.h>
+#include <assert.h>
+}
+
+using PHP::CodePointBreakIterator;
+
+/* {{{ Global variables */
+zend_class_entry *BreakIterator_ce_ptr;
+zend_class_entry *RuleBasedBreakIterator_ce_ptr;
+zend_class_entry *CodePointBreakIterator_ce_ptr;
+zend_object_handlers BreakIterator_handlers;
+/* }}} */
+
+U_CFUNC void breakiterator_object_create(zval *object,
+ BreakIterator *biter TSRMLS_DC)
+{
+ UClassID classId = biter->getDynamicClassID();
+ zend_class_entry *ce;
+
+ if (classId == RuleBasedBreakIterator::getStaticClassID()) {
+ ce = RuleBasedBreakIterator_ce_ptr;
+ } else if (classId == CodePointBreakIterator::getStaticClassID()) {
+ ce = CodePointBreakIterator_ce_ptr;
+ } else {
+ ce = BreakIterator_ce_ptr;
+ }
+
+ object_init_ex(object, ce);
+ breakiterator_object_construct(object, biter TSRMLS_CC);
+}
+
+U_CFUNC void breakiterator_object_construct(zval *object,
+ BreakIterator *biter TSRMLS_DC)
+{
+ BreakIterator_object *bio;
+
+ BREAKITER_METHOD_FETCH_OBJECT_NO_CHECK; //populate to from object
+ assert(bio->biter == NULL);
+ bio->biter = biter;
+}
+
+/* {{{ compare handler for BreakIterator */
+static int BreakIterator_compare_objects(zval *object1,
+ zval *object2 TSRMLS_DC)
+{
+ BreakIterator_object *bio1,
+ *bio2;
+
+ bio1 = (BreakIterator_object*)zend_object_store_get_object(object1 TSRMLS_CC);
+ bio2 = (BreakIterator_object*)zend_object_store_get_object(object2 TSRMLS_CC);
+
+ if (bio1->biter == NULL || bio2->biter == NULL) {
+ return bio1->biter == bio2->biter ? 0 : 1;
+ }
+
+ return *bio1->biter == *bio2->biter ? 0 : 1;
+}
+/* }}} */
+
+/* {{{ clone handler for BreakIterator */
+static zend_object_value BreakIterator_clone_obj(zval *object TSRMLS_DC)
+{
+ BreakIterator_object *bio_orig,
+ *bio_new;
+ zend_object_value ret_val;
+
+ bio_orig = (BreakIterator_object*)zend_object_store_get_object(object TSRMLS_CC);
+ intl_errors_reset(INTL_DATA_ERROR_P(bio_orig) TSRMLS_CC);
+
+ ret_val = BreakIterator_ce_ptr->create_object(Z_OBJCE_P(object) TSRMLS_CC);
+ bio_new = (BreakIterator_object*)zend_object_store_get_object_by_handle(
+ ret_val.handle TSRMLS_CC);
+
+ zend_objects_clone_members(&bio_new->zo, ret_val,
+ &bio_orig->zo, Z_OBJ_HANDLE_P(object) TSRMLS_CC);
+
+ if (bio_orig->biter != NULL) {
+ BreakIterator *new_biter;
+
+ new_biter = bio_orig->biter->clone();
+ if (!new_biter) {
+ char *err_msg;
+ intl_errors_set_code(BREAKITER_ERROR_P(bio_orig),
+ U_MEMORY_ALLOCATION_ERROR TSRMLS_CC);
+ intl_errors_set_custom_msg(BREAKITER_ERROR_P(bio_orig),
+ "Could not clone BreakIterator", 0 TSRMLS_CC);
+ err_msg = intl_error_get_message(BREAKITER_ERROR_P(bio_orig) TSRMLS_CC);
+ zend_throw_exception(NULL, err_msg, 0 TSRMLS_CC);
+ efree(err_msg);
+ } else {
+ bio_new->biter = new_biter;
+ bio_new->text = bio_orig->text;
+ if (bio_new->text) {
+ zval_add_ref(&bio_new->text);
+ }
+ }
+ } else {
+ zend_throw_exception(NULL, "Cannot clone unconstructed BreakIterator", 0 TSRMLS_CC);
+ }
+
+ return ret_val;
+}
+/* }}} */
+
+/* {{{ get_debug_info handler for BreakIterator */
+static HashTable *BreakIterator_get_debug_info(zval *object, int *is_temp TSRMLS_DC)
+{
+ zval zv = zval_used_for_init;
+ BreakIterator_object *bio;
+ const BreakIterator *biter;
+
+ *is_temp = 1;
+
+ array_init_size(&zv, 8);
+
+ bio = (BreakIterator_object*)zend_object_store_get_object(object TSRMLS_CC);
+ biter = bio->biter;
+
+ if (biter == NULL) {
+ add_assoc_bool_ex(&zv, "valid", sizeof("valid"), 0);
+ return Z_ARRVAL(zv);
+ }
+ add_assoc_bool_ex(&zv, "valid", sizeof("valid"), 1);
+
+ if (bio->text == NULL) {
+ add_assoc_null_ex(&zv, "text", sizeof("text"));
+ } else {
+ zval_add_ref(&bio->text);
+ add_assoc_zval_ex(&zv, "text", sizeof("text"), bio->text);
+ }
+
+ add_assoc_string_ex(&zv, "type", sizeof("type"),
+ const_cast<char*>(typeid(*biter).name()), 1);
+
+ return Z_ARRVAL(zv);
+}
+/* }}} */
+
+/* {{{ void breakiterator_object_init(BreakIterator_object* to)
+ * Initialize internals of BreakIterator_object not specific to zend standard objects.
+ */
+static void breakiterator_object_init(BreakIterator_object *bio TSRMLS_DC)
+{
+ intl_error_init(BREAKITER_ERROR_P(bio) TSRMLS_CC);
+ bio->biter = NULL;
+ bio->text = NULL;
+}
+/* }}} */
+
+/* {{{ BreakIterator_objects_dtor */
+static void BreakIterator_objects_dtor(void *object,
+ zend_object_handle handle TSRMLS_DC)
+{
+ zend_objects_destroy_object((zend_object*)object, handle TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ BreakIterator_objects_free */
+static void BreakIterator_objects_free(zend_object *object TSRMLS_DC)
+{
+ BreakIterator_object* bio = (BreakIterator_object*) object;
+
+ if (bio->text) {
+ zval_ptr_dtor(&bio->text);
+ }
+ if (bio->biter) {
+ delete bio->biter;
+ bio->biter = NULL;
+ }
+ intl_error_reset(BREAKITER_ERROR_P(bio) TSRMLS_CC);
+
+ zend_object_std_dtor(&bio->zo TSRMLS_CC);
+
+ efree(bio);
+}
+/* }}} */
+
+/* {{{ BreakIterator_object_create */
+static zend_object_value BreakIterator_object_create(zend_class_entry *ce TSRMLS_DC)
+{
+ zend_object_value retval;
+ BreakIterator_object* intern;
+
+ intern = (BreakIterator_object*)ecalloc(1, sizeof(BreakIterator_object));
+
+ zend_object_std_init(&intern->zo, ce TSRMLS_CC);
+#if PHP_VERSION_ID < 50399
+ zend_hash_copy(intern->zo.properties, &(ce->default_properties),
+ (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval*));
+#else
+ object_properties_init((zend_object*) intern, ce);
+#endif
+ breakiterator_object_init(intern TSRMLS_CC);
+
+ retval.handle = zend_objects_store_put(
+ intern,
+ BreakIterator_objects_dtor,
+ (zend_objects_free_object_storage_t) BreakIterator_objects_free,
+ NULL TSRMLS_CC);
+
+ retval.handlers = &BreakIterator_handlers;
+
+ return retval;
+}
+/* }}} */
+
+/* {{{ BreakIterator/RuleBasedBreakIterator methods arguments info */
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_biter_void, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_biter_locale, 0, 0, 0)
+ ZEND_ARG_INFO(0, locale)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_biter_setText, 0, 0, 1)
+ ZEND_ARG_INFO(0, text)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_biter_next, 0, 0, 0)
+ ZEND_ARG_INFO(0, offset)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_biter_offset, 0, 0, 1)
+ ZEND_ARG_INFO(0, offset)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_biter_get_locale, 0, 0, 1)
+ ZEND_ARG_INFO(0, locale_type)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_biter_getPartsIterator, 0, 0, 0)
+ ZEND_ARG_INFO(0, key_type)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_rbbi___construct, 0, 0, 1)
+ ZEND_ARG_INFO(0, rules)
+ ZEND_ARG_INFO(0, areCompiled)
+ZEND_END_ARG_INFO()
+
+/* }}} */
+
+/* {{{ BreakIterator_class_functions
+ * Every 'BreakIterator' class method has an entry in this table
+ */
+static const zend_function_entry BreakIterator_class_functions[] = {
+ PHP_ME(BreakIterator, __construct, ainfo_biter_void, ZEND_ACC_PRIVATE)
+ PHP_ME_MAPPING(createWordInstance, breakiter_create_word_instance, ainfo_biter_locale, ZEND_ACC_STATIC | ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(createLineInstance, breakiter_create_line_instance, ainfo_biter_locale, ZEND_ACC_STATIC | ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(createCharacterInstance, breakiter_create_character_instance, ainfo_biter_locale, ZEND_ACC_STATIC | ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(createSentenceInstance, breakiter_create_sentence_instance, ainfo_biter_locale, ZEND_ACC_STATIC | ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(createTitleInstance, breakiter_create_title_instance, ainfo_biter_locale, ZEND_ACC_STATIC | ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(createCodePointInstance, breakiter_create_code_point_instance, ainfo_biter_void, ZEND_ACC_STATIC | ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(getText, breakiter_get_text, ainfo_biter_void, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(setText, breakiter_set_text, ainfo_biter_setText, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(first, breakiter_first, ainfo_biter_void, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(last, breakiter_last, ainfo_biter_void, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(previous, breakiter_previous, ainfo_biter_void, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(next, breakiter_next, ainfo_biter_next, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(current, breakiter_current, ainfo_biter_void, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(following, breakiter_following, ainfo_biter_offset, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(preceding, breakiter_preceding, ainfo_biter_offset, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(isBoundary, breakiter_is_boundary, ainfo_biter_offset, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(getLocale, breakiter_get_locale, ainfo_biter_get_locale, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(getPartsIterator, breakiter_get_parts_iterator, ainfo_biter_getPartsIterator, ZEND_ACC_PUBLIC)
+
+ PHP_ME_MAPPING(getErrorCode, breakiter_get_error_code, ainfo_biter_void, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(getErrorMessage, breakiter_get_error_message, ainfo_biter_void, ZEND_ACC_PUBLIC)
+ PHP_FE_END
+};
+/* }}} */
+
+/* {{{ RuleBasedBreakIterator_class_functions
+ */
+static const zend_function_entry RuleBasedBreakIterator_class_functions[] = {
+ PHP_ME(IntlRuleBasedBreakIterator, __construct, ainfo_rbbi___construct, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(getRules, rbbi_get_rules, ainfo_biter_void, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(getRuleStatus, rbbi_get_rule_status, ainfo_biter_void, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(getRuleStatusVec, rbbi_get_rule_status_vec, ainfo_biter_void, ZEND_ACC_PUBLIC)
+#if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 48
+ PHP_ME_MAPPING(getBinaryRules, rbbi_get_binary_rules, ainfo_biter_void, ZEND_ACC_PUBLIC)
+#endif
+ PHP_FE_END
+};
+/* }}} */
+
+/* {{{ CodePointBreakIterator_class_functions
+ */
+static const zend_function_entry CodePointBreakIterator_class_functions[] = {
+ PHP_ME_MAPPING(getLastCodePoint, cpbi_get_last_code_point, ainfo_biter_void, ZEND_ACC_PUBLIC)
+ PHP_FE_END
+};
+/* }}} */
+
+
+/* {{{ breakiterator_register_BreakIterator_class
+ * Initialize 'BreakIterator' class
+ */
+U_CFUNC void breakiterator_register_BreakIterator_class(TSRMLS_D)
+{
+ zend_class_entry ce;
+
+ /* Create and register 'BreakIterator' class. */
+ INIT_CLASS_ENTRY(ce, "IntlBreakIterator", BreakIterator_class_functions);
+ ce.create_object = BreakIterator_object_create;
+ ce.get_iterator = _breakiterator_get_iterator;
+ BreakIterator_ce_ptr = zend_register_internal_class(&ce TSRMLS_CC);
+
+ memcpy(&BreakIterator_handlers, zend_get_std_object_handlers(),
+ sizeof BreakIterator_handlers);
+ BreakIterator_handlers.compare_objects = BreakIterator_compare_objects;
+ BreakIterator_handlers.clone_obj = BreakIterator_clone_obj;
+ BreakIterator_handlers.get_debug_info = BreakIterator_get_debug_info;
+
+ zend_class_implements(BreakIterator_ce_ptr TSRMLS_CC, 1,
+ zend_ce_traversable);
+
+ zend_declare_class_constant_long(BreakIterator_ce_ptr,
+ "DONE", sizeof("DONE") - 1, BreakIterator::DONE TSRMLS_CC );
+
+ /* Declare constants that are defined in the C header */
+#define BREAKITER_DECL_LONG_CONST(name) \
+ zend_declare_class_constant_long(BreakIterator_ce_ptr, #name, \
+ sizeof(#name) - 1, UBRK_ ## name TSRMLS_CC)
+
+ BREAKITER_DECL_LONG_CONST(WORD_NONE);
+ BREAKITER_DECL_LONG_CONST(WORD_NONE_LIMIT);
+ BREAKITER_DECL_LONG_CONST(WORD_NUMBER);
+ BREAKITER_DECL_LONG_CONST(WORD_NUMBER_LIMIT);
+ BREAKITER_DECL_LONG_CONST(WORD_LETTER);
+ BREAKITER_DECL_LONG_CONST(WORD_LETTER_LIMIT);
+ BREAKITER_DECL_LONG_CONST(WORD_KANA);
+ BREAKITER_DECL_LONG_CONST(WORD_KANA_LIMIT);
+ BREAKITER_DECL_LONG_CONST(WORD_IDEO);
+ BREAKITER_DECL_LONG_CONST(WORD_IDEO_LIMIT);
+
+ BREAKITER_DECL_LONG_CONST(LINE_SOFT);
+ BREAKITER_DECL_LONG_CONST(LINE_SOFT_LIMIT);
+ BREAKITER_DECL_LONG_CONST(LINE_HARD);
+ BREAKITER_DECL_LONG_CONST(LINE_HARD_LIMIT);
+
+ BREAKITER_DECL_LONG_CONST(SENTENCE_TERM);
+ BREAKITER_DECL_LONG_CONST(SENTENCE_TERM_LIMIT);
+ BREAKITER_DECL_LONG_CONST(SENTENCE_SEP);
+ BREAKITER_DECL_LONG_CONST(SENTENCE_SEP_LIMIT);
+
+#undef BREAKITER_DECL_LONG_CONST
+
+
+ /* Create and register 'RuleBasedBreakIterator' class. */
+ INIT_CLASS_ENTRY(ce, "IntlRuleBasedBreakIterator",
+ RuleBasedBreakIterator_class_functions);
+ RuleBasedBreakIterator_ce_ptr = zend_register_internal_class_ex(&ce,
+ BreakIterator_ce_ptr, NULL TSRMLS_CC);
+
+ /* Create and register 'CodePointBreakIterator' class. */
+ INIT_CLASS_ENTRY(ce, "IntlCodePointBreakIterator",
+ CodePointBreakIterator_class_functions);
+ CodePointBreakIterator_ce_ptr = zend_register_internal_class_ex(&ce,
+ BreakIterator_ce_ptr, NULL TSRMLS_CC);
+}
+/* }}} */
diff --git a/ext/intl/breakiterator/breakiterator_class.h b/ext/intl/breakiterator/breakiterator_class.h
new file mode 100644
index 0000000000..cc5d51256f
--- /dev/null
+++ b/ext/intl/breakiterator/breakiterator_class.h
@@ -0,0 +1,71 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+ */
+
+#ifndef BREAKITERATOR_CLASS_H
+#define BREAKITERATOR_CLASS_H
+
+//redefinition of inline in PHP headers causes problems, so include this before
+#include <math.h>
+
+#include <php.h>
+#include "../intl_error.h"
+#include "../intl_data.h"
+
+#ifndef USE_BREAKITERATOR_POINTER
+typedef void BreakIterator;
+#endif
+
+typedef struct {
+ zend_object zo;
+
+ // error handling
+ intl_error err;
+
+ // ICU break iterator
+ BreakIterator* biter;
+
+ // current text
+ zval *text;
+} BreakIterator_object;
+
+#define BREAKITER_ERROR(bio) (bio)->err
+#define BREAKITER_ERROR_P(bio) &(BREAKITER_ERROR(bio))
+
+#define BREAKITER_ERROR_CODE(bio) INTL_ERROR_CODE(BREAKITER_ERROR(bio))
+#define BREAKITER_ERROR_CODE_P(bio) &(INTL_ERROR_CODE(BREAKITER_ERROR(bio)))
+
+#define BREAKITER_METHOD_INIT_VARS INTL_METHOD_INIT_VARS(BreakIterator, bio)
+#define BREAKITER_METHOD_FETCH_OBJECT_NO_CHECK INTL_METHOD_FETCH_OBJECT(BreakIterator, bio)
+#define BREAKITER_METHOD_FETCH_OBJECT \
+ BREAKITER_METHOD_FETCH_OBJECT_NO_CHECK; \
+ if (bio->biter == NULL) \
+ { \
+ intl_errors_set(&bio->err, U_ILLEGAL_ARGUMENT_ERROR, "Found unconstructed BreakIterator", 0 TSRMLS_CC); \
+ RETURN_FALSE; \
+ }
+
+void breakiterator_object_create(zval *object, BreakIterator *break_iter TSRMLS_DC);
+
+void breakiterator_object_construct(zval *object, BreakIterator *break_iter TSRMLS_DC);
+
+void breakiterator_register_BreakIterator_class(TSRMLS_D);
+
+extern zend_class_entry *BreakIterator_ce_ptr,
+ *RuleBasedBreakIterator_ce_ptr;
+
+extern zend_object_handlers BreakIterator_handlers;
+
+#endif /* #ifndef BREAKITERATOR_CLASS_H */
diff --git a/ext/intl/breakiterator/breakiterator_iterators.cpp b/ext/intl/breakiterator/breakiterator_iterators.cpp
new file mode 100644
index 0000000000..3748991aed
--- /dev/null
+++ b/ext/intl/breakiterator/breakiterator_iterators.cpp
@@ -0,0 +1,342 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <unicode/brkiter.h>
+
+#include "breakiterator_iterators.h"
+#include "../common/common_enum.h"
+
+extern "C" {
+#define USE_BREAKITERATOR_POINTER
+#include "breakiterator_class.h"
+#include "../intl_convert.h"
+#include "../locale/locale.h"
+#include <zend_exceptions.h>
+}
+
+static zend_class_entry *IntlPartsIterator_ce_ptr;
+static zend_object_handlers IntlPartsIterator_handlers;
+
+/* BreakIterator's iterator */
+
+inline BreakIterator *_breakiter_prolog(zend_object_iterator *iter TSRMLS_DC)
+{
+ BreakIterator_object *bio;
+ bio = (BreakIterator_object*)zend_object_store_get_object(
+ (const zval*)iter->data TSRMLS_CC);
+ intl_errors_reset(BREAKITER_ERROR_P(bio) TSRMLS_CC);
+ if (bio->biter == NULL) {
+ intl_errors_set(BREAKITER_ERROR_P(bio), U_INVALID_STATE_ERROR,
+ "The BreakIterator object backing the PHP iterator is not "
+ "properly constructed", 0 TSRMLS_CC);
+ }
+ return bio->biter;
+}
+
+static void _breakiterator_destroy_it(zend_object_iterator *iter TSRMLS_DC)
+{
+ zval_ptr_dtor((zval**)&iter->data);
+}
+
+static void _breakiterator_move_forward(zend_object_iterator *iter TSRMLS_DC)
+{
+ BreakIterator *biter = _breakiter_prolog(iter TSRMLS_CC);
+ zoi_with_current *zoi_iter = (zoi_with_current*)iter;
+
+ iter->funcs->invalidate_current(iter TSRMLS_CC);
+
+ if (biter == NULL) {
+ return;
+ }
+
+ int32_t pos = biter->next();
+ if (pos != BreakIterator::DONE) {
+ MAKE_STD_ZVAL(zoi_iter->current);
+ ZVAL_LONG(zoi_iter->current, (long)pos);
+ } //else we've reached the end of the enum, nothing more is required
+}
+
+static void _breakiterator_rewind(zend_object_iterator *iter TSRMLS_DC)
+{
+ BreakIterator *biter = _breakiter_prolog(iter TSRMLS_CC);
+ zoi_with_current *zoi_iter = (zoi_with_current*)iter;
+
+ int32_t pos = biter->first();
+ MAKE_STD_ZVAL(zoi_iter->current);
+ ZVAL_LONG(zoi_iter->current, (long)pos);
+}
+
+static zend_object_iterator_funcs breakiterator_iterator_funcs = {
+ zoi_with_current_dtor,
+ zoi_with_current_valid,
+ zoi_with_current_get_current_data,
+ NULL,
+ _breakiterator_move_forward,
+ _breakiterator_rewind,
+ zoi_with_current_invalidate_current
+};
+
+U_CFUNC zend_object_iterator *_breakiterator_get_iterator(
+ zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
+{
+ BreakIterator_object *bio;
+ if (by_ref) {
+ zend_throw_exception(NULL,
+ "Iteration by reference is not supported", 0 TSRMLS_CC);
+ return NULL;
+ }
+
+ bio = (BreakIterator_object*)zend_object_store_get_object(object TSRMLS_CC);
+ BreakIterator *biter = bio->biter;
+
+ if (biter == NULL) {
+ zend_throw_exception(NULL,
+ "The BreakIterator is not properly constructed", 0 TSRMLS_CC);
+ return NULL;
+ }
+
+ zoi_with_current *zoi_iter =
+ static_cast<zoi_with_current*>(emalloc(sizeof *zoi_iter));
+ zoi_iter->zoi.data = static_cast<void*>(object);
+ zoi_iter->zoi.funcs = &breakiterator_iterator_funcs;
+ zoi_iter->zoi.index = 0;
+ zoi_iter->destroy_it = _breakiterator_destroy_it;
+ zoi_iter->wrapping_obj = NULL; /* not used; object is in zoi.data */
+ zoi_iter->current = NULL;
+
+ zval_add_ref(&object);
+
+ return reinterpret_cast<zend_object_iterator *>(zoi_iter);
+}
+
+/* BreakIterator parts iterator */
+
+typedef struct zoi_break_iter_parts {
+ zoi_with_current zoi_cur;
+ parts_iter_key_type key_type;
+ BreakIterator_object *bio; /* so we don't have to fetch it all the time */
+} zoi_break_iter_parts;
+
+static void _breakiterator_parts_destroy_it(zend_object_iterator *iter TSRMLS_DC)
+{
+ zval_ptr_dtor(reinterpret_cast<zval**>(&iter->data));
+}
+
+static void _breakiterator_parts_get_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC)
+{
+ /* the actual work is done in move_forward and rewind */
+ ZVAL_LONG(key, iter->index);
+}
+
+static void _breakiterator_parts_move_forward(zend_object_iterator *iter TSRMLS_DC)
+{
+ zoi_break_iter_parts *zoi_bit = (zoi_break_iter_parts*)iter;
+ BreakIterator_object *bio = zoi_bit->bio;
+
+ iter->funcs->invalidate_current(iter TSRMLS_CC);
+
+ int32_t cur,
+ next;
+
+ cur = bio->biter->current();
+ if (cur == BreakIterator::DONE) {
+ return;
+ }
+ next = bio->biter->next();
+ if (next == BreakIterator::DONE) {
+ return;
+ }
+
+ if (zoi_bit->key_type == PARTS_ITERATOR_KEY_LEFT) {
+ iter->index = cur;
+ } else if (zoi_bit->key_type == PARTS_ITERATOR_KEY_RIGHT) {
+ iter->index = next;
+ }
+ /* else zoi_bit->key_type == PARTS_ITERATOR_KEY_SEQUENTIAL
+ * No need to do anything, the engine increments ->index */
+
+ const char *s = Z_STRVAL_P(bio->text);
+ int32_t slen = Z_STRLEN_P(bio->text),
+ len;
+ char *res;
+
+ if (next == BreakIterator::DONE) {
+ next = slen;
+ }
+ assert(next <= slen && next >= cur);
+ len = next - cur;
+ res = static_cast<char*>(emalloc(len + 1));
+
+ memcpy(res, &s[cur], len);
+ res[len] = '\0';
+
+ MAKE_STD_ZVAL(zoi_bit->zoi_cur.current);
+ ZVAL_STRINGL(zoi_bit->zoi_cur.current, res, len, 0);
+}
+
+static void _breakiterator_parts_rewind(zend_object_iterator *iter TSRMLS_DC)
+{
+ zoi_break_iter_parts *zoi_bit = (zoi_break_iter_parts*)iter;
+ BreakIterator_object *bio = zoi_bit->bio;
+
+ if (zoi_bit->zoi_cur.current) {
+ iter->funcs->invalidate_current(iter TSRMLS_CC);
+ }
+
+ bio->biter->first();
+
+ iter->funcs->move_forward(iter TSRMLS_CC);
+}
+
+static zend_object_iterator_funcs breakiterator_parts_it_funcs = {
+ zoi_with_current_dtor,
+ zoi_with_current_valid,
+ zoi_with_current_get_current_data,
+ _breakiterator_parts_get_current_key,
+ _breakiterator_parts_move_forward,
+ _breakiterator_parts_rewind,
+ zoi_with_current_invalidate_current
+};
+
+void IntlIterator_from_BreakIterator_parts(zval *break_iter_zv,
+ zval *object,
+ parts_iter_key_type key_type TSRMLS_DC)
+{
+ IntlIterator_object *ii;
+
+ zval_add_ref(&break_iter_zv);
+
+ object_init_ex(object, IntlPartsIterator_ce_ptr);
+ ii = (IntlIterator_object*)zend_object_store_get_object(object TSRMLS_CC);
+
+ ii->iterator = (zend_object_iterator*)emalloc(sizeof(zoi_break_iter_parts));
+ ii->iterator->data = break_iter_zv;
+ ii->iterator->funcs = &breakiterator_parts_it_funcs;
+ ii->iterator->index = 0;
+ ((zoi_with_current*)ii->iterator)->destroy_it = _breakiterator_parts_destroy_it;
+ ((zoi_with_current*)ii->iterator)->wrapping_obj = object;
+ ((zoi_with_current*)ii->iterator)->current = NULL;
+
+ ((zoi_break_iter_parts*)ii->iterator)->bio = (BreakIterator_object*)
+ zend_object_store_get_object(break_iter_zv TSRMLS_CC);
+ assert(((zoi_break_iter_parts*)ii->iterator)->bio->biter != NULL);
+ ((zoi_break_iter_parts*)ii->iterator)->key_type = key_type;
+}
+
+U_CFUNC zend_object_value IntlPartsIterator_object_create(zend_class_entry *ce TSRMLS_DC)
+{
+ zend_object_value retval;
+
+ retval = IntlIterator_ce_ptr->create_object(ce TSRMLS_CC);
+ retval.handlers = &IntlPartsIterator_handlers;
+
+ return retval;
+}
+
+U_CFUNC zend_function *IntlPartsIterator_get_method(zval **object_ptr,
+ char *method, int method_len, const zend_literal *key TSRMLS_DC)
+{
+ zend_literal local_literal = {0};
+ zend_function *ret;
+ ALLOCA_FLAG(use_heap)
+
+ if (key == NULL) {
+ Z_STRVAL(local_literal.constant) = static_cast<char*>(
+ do_alloca(method_len + 1, use_heap));
+ zend_str_tolower_copy(Z_STRVAL(local_literal.constant),
+ method, method_len);
+ local_literal.hash_value = zend_hash_func(
+ Z_STRVAL(local_literal.constant), method_len + 1);
+ key = &local_literal;
+ }
+
+ if ((key->hash_value & 0xFFFFFFFF) == 0xA2B486A1 /* hash of getrulestatus\0 */
+ && method_len == sizeof("getrulestatus") - 1
+ && memcmp("getrulestatus", Z_STRVAL(key->constant), method_len) == 0) {
+ IntlIterator_object *obj = (IntlIterator_object*)
+ zend_object_store_get_object(*object_ptr TSRMLS_CC);
+ if (obj->iterator && obj->iterator->data) {
+ zval *break_iter_zv = static_cast<zval*>(obj->iterator->data);
+ *object_ptr = break_iter_zv;
+ ret = Z_OBJ_HANDLER_P(break_iter_zv, get_method)(object_ptr,
+ method, method_len, key TSRMLS_CC);
+ goto end;
+ }
+ }
+
+ ret = std_object_handlers.get_method(object_ptr,
+ method, method_len, key TSRMLS_CC);
+
+end:
+ if (key == &local_literal) {
+ free_alloca(Z_STRVAL(local_literal.constant), use_heap);
+ }
+
+ return ret;
+}
+
+U_CFUNC PHP_METHOD(IntlPartsIterator, getBreakIterator)
+{
+ INTLITERATOR_METHOD_INIT_VARS;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "IntlPartsIterator::getBreakIterator: bad arguments", 0 TSRMLS_CC);
+ return;
+ }
+
+ INTLITERATOR_METHOD_FETCH_OBJECT;
+
+ zval *biter_zval = static_cast<zval*>(ii->iterator->data);
+ RETURN_ZVAL(biter_zval, 1, 0);
+}
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_parts_it_void, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+static const zend_function_entry IntlPartsIterator_class_functions[] = {
+ PHP_ME(IntlPartsIterator, getBreakIterator, ainfo_parts_it_void, ZEND_ACC_PUBLIC)
+ PHP_FE_END
+};
+
+U_CFUNC void breakiterator_register_IntlPartsIterator_class(TSRMLS_D)
+{
+ zend_class_entry ce;
+
+ /* Create and register 'BreakIterator' class. */
+ INIT_CLASS_ENTRY(ce, "IntlPartsIterator", IntlPartsIterator_class_functions);
+ IntlPartsIterator_ce_ptr = zend_register_internal_class_ex(&ce,
+ IntlIterator_ce_ptr, NULL TSRMLS_CC);
+ IntlPartsIterator_ce_ptr->create_object = IntlPartsIterator_object_create;
+
+ memcpy(&IntlPartsIterator_handlers, &IntlIterator_handlers,
+ sizeof IntlPartsIterator_handlers);
+ IntlPartsIterator_handlers.get_method = IntlPartsIterator_get_method;
+
+#define PARTSITER_DECL_LONG_CONST(name) \
+ zend_declare_class_constant_long(IntlPartsIterator_ce_ptr, #name, \
+ sizeof(#name) - 1, PARTS_ITERATOR_ ## name TSRMLS_CC)
+
+ PARTSITER_DECL_LONG_CONST(KEY_SEQUENTIAL);
+ PARTSITER_DECL_LONG_CONST(KEY_LEFT);
+ PARTSITER_DECL_LONG_CONST(KEY_RIGHT);
+
+#undef PARTSITER_DECL_LONG_CONST
+}
diff --git a/ext/intl/breakiterator/breakiterator_iterators.h b/ext/intl/breakiterator/breakiterator_iterators.h
new file mode 100644
index 0000000000..a955f3a8e7
--- /dev/null
+++ b/ext/intl/breakiterator/breakiterator_iterators.h
@@ -0,0 +1,42 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+*/
+#ifndef INTL_BREAKITERATOR_ITERATORS_H
+#define INTL_BREAKITERATOR_ITERATORS_H
+
+#include <unicode/umachine.h>
+
+U_CDECL_BEGIN
+#include <math.h>
+#include <php.h>
+U_CDECL_END
+
+typedef enum {
+ PARTS_ITERATOR_KEY_SEQUENTIAL,
+ PARTS_ITERATOR_KEY_LEFT,
+ PARTS_ITERATOR_KEY_RIGHT,
+} parts_iter_key_type;
+
+#ifdef __cplusplus
+void IntlIterator_from_BreakIterator_parts(zval *break_iter_zv,
+ zval *object,
+ parts_iter_key_type key_type TSRMLS_DC);
+#endif
+
+U_CFUNC zend_object_iterator *_breakiterator_get_iterator(
+ zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC);
+U_CFUNC void breakiterator_register_IntlPartsIterator_class(TSRMLS_D);
+
+#endif
diff --git a/ext/intl/breakiterator/breakiterator_methods.cpp b/ext/intl/breakiterator/breakiterator_methods.cpp
new file mode 100644
index 0000000000..1a1b4fd127
--- /dev/null
+++ b/ext/intl/breakiterator/breakiterator_methods.cpp
@@ -0,0 +1,452 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <unicode/brkiter.h>
+#include "codepointiterator_internal.h"
+
+#include "breakiterator_iterators.h"
+
+extern "C" {
+#include "../php_intl.h"
+#define USE_BREAKITERATOR_POINTER 1
+#include "breakiterator_class.h"
+#include "../locale/locale.h"
+#include <zend_exceptions.h>
+}
+
+using PHP::CodePointBreakIterator;
+
+U_CFUNC PHP_METHOD(BreakIterator, __construct)
+{
+ zend_throw_exception( NULL,
+ "An object of this type cannot be created with the new operator",
+ 0 TSRMLS_CC );
+}
+
+static void _breakiter_factory(const char *func_name,
+ BreakIterator *(*func)(const Locale&, UErrorCode&),
+ INTERNAL_FUNCTION_PARAMETERS)
+{
+ BreakIterator *biter;
+ const char *locale_str = NULL;
+ int dummy;
+ char *msg;
+ UErrorCode status = UErrorCode();
+ intl_error_reset(NULL TSRMLS_CC);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!",
+ &locale_str, &dummy) == FAILURE) {
+ spprintf(&msg, 0, "%s: bad arguments", func_name);
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, msg, 1 TSRMLS_CC);
+ efree(msg);
+ RETURN_NULL();
+ }
+
+ if (locale_str == NULL) {
+ locale_str = intl_locale_get_default(TSRMLS_C);
+ }
+
+ biter = func(Locale::createFromName(locale_str), status);
+ intl_error_set_code(NULL, status TSRMLS_CC);
+ if (U_FAILURE(status)) {
+ spprintf(&msg, 0, "%s: error creating BreakIterator",
+ func_name);
+ intl_error_set_custom_msg(NULL, msg, 1 TSRMLS_CC);
+ efree(msg);
+ RETURN_NULL();
+ }
+
+ breakiterator_object_create(return_value, biter TSRMLS_CC);
+}
+
+U_CFUNC PHP_FUNCTION(breakiter_create_word_instance)
+{
+ _breakiter_factory("breakiter_create_word_instance",
+ &BreakIterator::createWordInstance,
+ INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+
+U_CFUNC PHP_FUNCTION(breakiter_create_line_instance)
+{
+ _breakiter_factory("breakiter_create_line_instance",
+ &BreakIterator::createLineInstance,
+ INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+
+U_CFUNC PHP_FUNCTION(breakiter_create_character_instance)
+{
+ _breakiter_factory("breakiter_create_character_instance",
+ &BreakIterator::createCharacterInstance,
+ INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+
+U_CFUNC PHP_FUNCTION(breakiter_create_sentence_instance)
+{
+ _breakiter_factory("breakiter_create_sentence_instance",
+ &BreakIterator::createSentenceInstance,
+ INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+
+U_CFUNC PHP_FUNCTION(breakiter_create_title_instance)
+{
+ _breakiter_factory("breakiter_create_title_instance",
+ &BreakIterator::createTitleInstance,
+ INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+
+U_CFUNC PHP_FUNCTION(breakiter_create_code_point_instance)
+{
+ UErrorCode status = UErrorCode();
+ intl_error_reset(NULL TSRMLS_CC);
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "breakiter_create_code_point_instance: bad arguments", 0 TSRMLS_CC);
+ RETURN_NULL();
+ }
+
+ CodePointBreakIterator *cpbi = new CodePointBreakIterator();
+ breakiterator_object_create(return_value, cpbi TSRMLS_CC);
+}
+
+U_CFUNC PHP_FUNCTION(breakiter_get_text)
+{
+ BREAKITER_METHOD_INIT_VARS;
+ object = getThis();
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "breakiter_get_text: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ BREAKITER_METHOD_FETCH_OBJECT;
+
+ if (bio->text == NULL) {
+ RETURN_NULL();
+ } else {
+ RETURN_ZVAL(bio->text, 1, 0);
+ }
+}
+
+U_CFUNC PHP_FUNCTION(breakiter_set_text)
+{
+ char *text;
+ int text_len;
+ UText *ut = NULL;
+ zval **textzv;
+ BREAKITER_METHOD_INIT_VARS;
+ object = getThis();
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",
+ &text, &text_len) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "breakiter_set_text: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ int res = zend_get_parameters_ex(1, &textzv);
+ assert(res == SUCCESS);
+
+ BREAKITER_METHOD_FETCH_OBJECT;
+
+ /* assert it's safe to use text and text_len because zpp changes the
+ * arguments in the stack */
+ assert(text == Z_STRVAL_PP(textzv));
+
+ ut = utext_openUTF8(ut, text, text_len, BREAKITER_ERROR_CODE_P(bio));
+ INTL_CTOR_CHECK_STATUS(bio, "breakiter_set_text: error opening UText");
+
+ bio->biter->setText(ut, BREAKITER_ERROR_CODE(bio));
+ utext_close(ut); /* ICU shallow clones the UText */
+ INTL_CTOR_CHECK_STATUS(bio, "breakiter_set_text: error calling "
+ "BreakIterator::setText()");
+
+ /* When ICU clones the UText, it does not copy the buffer, so we have to
+ * keep the string buffer around by holding a reference to its zval. This
+ * also allows a faste implementation of getText() */
+ if (bio->text != NULL) {
+ zval_ptr_dtor(&bio->text);
+ }
+ bio->text = *textzv;
+ zval_add_ref(&bio->text);
+
+ RETURN_TRUE;
+}
+
+static void _breakiter_no_args_ret_int32(
+ const char *func_name,
+ int32_t (BreakIterator::*func)(),
+ INTERNAL_FUNCTION_PARAMETERS)
+{
+ char *msg;
+ BREAKITER_METHOD_INIT_VARS;
+ object = getThis();
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ spprintf(&msg, 0, "%s: bad arguments", func_name);
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, msg, 1 TSRMLS_CC);
+ efree(msg);
+ RETURN_FALSE;
+ }
+
+ BREAKITER_METHOD_FETCH_OBJECT;
+
+ int32_t res = (bio->biter->*func)();
+
+ RETURN_LONG((long)res);
+}
+
+static void _breakiter_int32_ret_int32(
+ const char *func_name,
+ int32_t (BreakIterator::*func)(int32_t),
+ INTERNAL_FUNCTION_PARAMETERS)
+{
+ char *msg;
+ long arg;
+ BREAKITER_METHOD_INIT_VARS;
+ object = getThis();
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &arg) == FAILURE) {
+ spprintf(&msg, 0, "%s: bad arguments", func_name);
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, msg, 1 TSRMLS_CC);
+ efree(msg);
+ RETURN_FALSE;
+ }
+
+ BREAKITER_METHOD_FETCH_OBJECT;
+
+ if (arg < INT32_MIN || arg > INT32_MAX) {
+ spprintf(&msg, 0, "%s: offset argument is outside bounds of "
+ "a 32-bit wide integer", func_name);
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, msg, 1 TSRMLS_CC);
+ efree(msg);
+ RETURN_FALSE;
+ }
+
+ int32_t res = (bio->biter->*func)((int32_t)arg);
+
+ RETURN_LONG((long)res);
+}
+
+U_CFUNC PHP_FUNCTION(breakiter_first)
+{
+ _breakiter_no_args_ret_int32("breakiter_first",
+ &BreakIterator::first,
+ INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+
+U_CFUNC PHP_FUNCTION(breakiter_last)
+{
+ _breakiter_no_args_ret_int32("breakiter_last",
+ &BreakIterator::last,
+ INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+
+U_CFUNC PHP_FUNCTION(breakiter_previous)
+{
+ _breakiter_no_args_ret_int32("breakiter_previous",
+ &BreakIterator::previous,
+ INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+
+U_CFUNC PHP_FUNCTION(breakiter_next)
+{
+ bool no_arg_version = false;
+
+ if (ZEND_NUM_ARGS() == 0) {
+ no_arg_version = true;
+ } else if (ZEND_NUM_ARGS() == 1) {
+ zval **arg;
+ int res = zend_get_parameters_ex(1, &arg);
+ assert(res == SUCCESS);
+ if (Z_TYPE_PP(arg) == IS_NULL) {
+ no_arg_version = true;
+ ht = 0; /* pretend we don't have any argument */
+ } else {
+ no_arg_version = false;
+ }
+ }
+
+ if (no_arg_version) {
+ _breakiter_no_args_ret_int32("breakiter_next",
+ &BreakIterator::next,
+ INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ } else {
+ _breakiter_int32_ret_int32("breakiter_next",
+ &BreakIterator::next,
+ INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ }
+}
+
+U_CFUNC PHP_FUNCTION(breakiter_current)
+{
+ BREAKITER_METHOD_INIT_VARS;
+ object = getThis();
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "breakiter_current: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ BREAKITER_METHOD_FETCH_OBJECT;
+
+ int32_t res = bio->biter->current();
+
+ RETURN_LONG((long)res);
+}
+
+U_CFUNC PHP_FUNCTION(breakiter_following)
+{
+ _breakiter_int32_ret_int32("breakiter_following",
+ &BreakIterator::following,
+ INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+
+U_CFUNC PHP_FUNCTION(breakiter_preceding)
+{
+ _breakiter_int32_ret_int32("breakiter_preceding",
+ &BreakIterator::preceding,
+ INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+
+U_CFUNC PHP_FUNCTION(breakiter_is_boundary)
+{
+ long offset;
+ BREAKITER_METHOD_INIT_VARS;
+ object = getThis();
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",
+ &offset) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "breakiter_is_boundary: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (offset < INT32_MIN || offset > INT32_MAX) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "breakiter_is_boundary: offset argument is outside bounds of "
+ "a 32-bit wide integer", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ BREAKITER_METHOD_FETCH_OBJECT;
+
+ UBool res = bio->biter->isBoundary((int32_t)offset);
+
+ RETURN_BOOL((long)res);
+}
+
+U_CFUNC PHP_FUNCTION(breakiter_get_locale)
+{
+ long locale_type;
+ BREAKITER_METHOD_INIT_VARS;
+ object = getThis();
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &locale_type) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "breakiter_get_locale: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (locale_type != ULOC_ACTUAL_LOCALE && locale_type != ULOC_VALID_LOCALE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "breakiter_get_locale: invalid locale type", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ BREAKITER_METHOD_FETCH_OBJECT;
+
+ Locale locale = bio->biter->getLocale((ULocDataLocaleType)locale_type,
+ BREAKITER_ERROR_CODE(bio));
+ INTL_METHOD_CHECK_STATUS(bio,
+ "breakiter_get_locale: Call to ICU method has failed");
+
+ RETURN_STRING(locale.getName(), 1);
+}
+
+U_CFUNC PHP_FUNCTION(breakiter_get_parts_iterator)
+{
+ long key_type = 0;
+ BREAKITER_METHOD_INIT_VARS;
+ object = getThis();
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &key_type) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "breakiter_get_parts_iterator: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (key_type != PARTS_ITERATOR_KEY_SEQUENTIAL
+ && key_type != PARTS_ITERATOR_KEY_LEFT
+ && key_type != PARTS_ITERATOR_KEY_RIGHT) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "breakiter_get_parts_iterator: bad key type", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ BREAKITER_METHOD_FETCH_OBJECT;
+
+ IntlIterator_from_BreakIterator_parts(
+ object, return_value, (parts_iter_key_type)key_type TSRMLS_CC);
+}
+
+U_CFUNC PHP_FUNCTION(breakiter_get_error_code)
+{
+ BREAKITER_METHOD_INIT_VARS;
+ object = getThis();
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "breakiter_get_error_code: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ /* Fetch the object (without resetting its last error code ). */
+ bio = (BreakIterator_object*)zend_object_store_get_object(object TSRMLS_CC);
+ if (bio == NULL)
+ RETURN_FALSE;
+
+ RETURN_LONG((long)BREAKITER_ERROR_CODE(bio));
+}
+
+U_CFUNC PHP_FUNCTION(breakiter_get_error_message)
+{
+ const char* message = NULL;
+ BREAKITER_METHOD_INIT_VARS;
+ object = getThis();
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "breakiter_get_error_message: bad arguments", 0 TSRMLS_CC );
+ RETURN_FALSE;
+ }
+
+
+ /* Fetch the object (without resetting its last error code ). */
+ bio = (BreakIterator_object*)zend_object_store_get_object(object TSRMLS_CC);
+ if (bio == NULL)
+ RETURN_FALSE;
+
+ /* Return last error message. */
+ message = intl_error_get_message(BREAKITER_ERROR_P(bio) TSRMLS_CC);
+ RETURN_STRING(message, 0);
+}
diff --git a/ext/intl/breakiterator/breakiterator_methods.h b/ext/intl/breakiterator/breakiterator_methods.h
new file mode 100644
index 0000000000..bc9ce80105
--- /dev/null
+++ b/ext/intl/breakiterator/breakiterator_methods.h
@@ -0,0 +1,64 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+ */
+
+#ifndef BREAKITERATOR_METHODS_H
+#define BREAKITERATOR_METHODS_H
+
+#include <php.h>
+
+PHP_METHOD(BreakIterator, __construct);
+
+PHP_FUNCTION(breakiter_create_word_instance);
+
+PHP_FUNCTION(breakiter_create_line_instance);
+
+PHP_FUNCTION(breakiter_create_character_instance);
+
+PHP_FUNCTION(breakiter_create_sentence_instance);
+
+PHP_FUNCTION(breakiter_create_title_instance);
+
+PHP_FUNCTION(breakiter_create_code_point_instance);
+
+PHP_FUNCTION(breakiter_get_text);
+
+PHP_FUNCTION(breakiter_set_text);
+
+PHP_FUNCTION(breakiter_first);
+
+PHP_FUNCTION(breakiter_last);
+
+PHP_FUNCTION(breakiter_previous);
+
+PHP_FUNCTION(breakiter_next);
+
+PHP_FUNCTION(breakiter_current);
+
+PHP_FUNCTION(breakiter_following);
+
+PHP_FUNCTION(breakiter_preceding);
+
+PHP_FUNCTION(breakiter_is_boundary);
+
+PHP_FUNCTION(breakiter_get_locale);
+
+PHP_FUNCTION(breakiter_get_parts_iterator);
+
+PHP_FUNCTION(breakiter_get_error_code);
+
+PHP_FUNCTION(breakiter_get_error_message);
+
+#endif
diff --git a/ext/intl/breakiterator/codepointiterator_internal.cpp b/ext/intl/breakiterator/codepointiterator_internal.cpp
new file mode 100644
index 0000000000..bf9239d531
--- /dev/null
+++ b/ext/intl/breakiterator/codepointiterator_internal.cpp
@@ -0,0 +1,291 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+ */
+
+#include "codepointiterator_internal.h"
+#include <unicode/uchriter.h>
+#include <typeinfo>
+
+//copied from cmemory.h, which is not public
+typedef union {
+ long t1;
+ double t2;
+ void *t3;
+} UAlignedMemory;
+
+#define U_POINTER_MASK_LSB(ptr, mask) (((ptrdiff_t)(char *)(ptr)) & (mask))
+#define U_ALIGNMENT_OFFSET(ptr) U_POINTER_MASK_LSB(ptr, sizeof(UAlignedMemory) - 1)
+#define U_ALIGNMENT_OFFSET_UP(ptr) (sizeof(UAlignedMemory) - U_ALIGNMENT_OFFSET(ptr))
+
+using namespace PHP;
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(CodePointBreakIterator);
+
+CodePointBreakIterator::CodePointBreakIterator()
+: BreakIterator(), fCharIter(NULL), lastCodePoint(U_SENTINEL)
+{
+ UErrorCode uec = UErrorCode();
+ this->fText = utext_openUChars(NULL, NULL, 0, &uec);
+}
+
+CodePointBreakIterator::CodePointBreakIterator(const PHP::CodePointBreakIterator &other)
+: BreakIterator(other), fText(NULL), fCharIter(NULL), lastCodePoint(U_SENTINEL)
+{
+ *this = other;
+}
+
+CodePointBreakIterator& CodePointBreakIterator::operator=(const CodePointBreakIterator& that)
+{
+ UErrorCode uec = UErrorCode();
+ UText *ut_clone = NULL;
+
+ if (this == &that) {
+ return *this;
+ }
+
+ this->fText = utext_clone(this->fText, that.fText, FALSE, TRUE, &uec);
+
+ //don't bother copying the character iterator, getText() is deprecated
+ clearCurrentCharIter();
+
+ this->lastCodePoint = that.lastCodePoint;
+ return *this;
+}
+
+CodePointBreakIterator::~CodePointBreakIterator()
+{
+ if (this->fText) {
+ utext_close(this->fText);
+ }
+ clearCurrentCharIter();
+}
+
+UBool CodePointBreakIterator::operator==(const BreakIterator& that) const
+{
+ if (typeid(*this) != typeid(that)) {
+ return FALSE;
+ }
+
+ const CodePointBreakIterator& that2 =
+ static_cast<const CodePointBreakIterator&>(that);
+
+ if (!utext_equals(this->fText, that2.fText)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+CodePointBreakIterator* CodePointBreakIterator::clone(void) const
+{
+ return new CodePointBreakIterator(*this);
+}
+
+CharacterIterator& CodePointBreakIterator::getText(void) const
+{
+ if (this->fCharIter == NULL) {
+ //this method is deprecated anyway; setup bogus iterator
+ static const UChar c = 0;
+ this->fCharIter = new UCharCharacterIterator(&c, 0);
+ }
+
+ return *this->fCharIter;
+}
+
+UText *CodePointBreakIterator::getUText(UText *fillIn, UErrorCode &status) const
+{
+ return utext_clone(fillIn, this->fText, FALSE, TRUE, &status);
+}
+
+void CodePointBreakIterator::setText(const UnicodeString &text)
+{
+ UErrorCode uec = UErrorCode();
+
+ //this closes the previous utext, if any
+ this->fText = utext_openConstUnicodeString(this->fText, &text, &uec);
+
+ clearCurrentCharIter();
+}
+
+void CodePointBreakIterator::setText(UText *text, UErrorCode &status)
+{
+ if (U_FAILURE(status)) {
+ return;
+ }
+
+ this->fText = utext_clone(this->fText, text, FALSE, TRUE, &status);
+
+ clearCurrentCharIter();
+}
+
+void CodePointBreakIterator::adoptText(CharacterIterator* it)
+{
+ UErrorCode uec = UErrorCode();
+ clearCurrentCharIter();
+
+ this->fCharIter = it;
+ this->fText = utext_openCharacterIterator(this->fText, it, &uec);
+}
+
+int32_t CodePointBreakIterator::first(void)
+{
+ UTEXT_SETNATIVEINDEX(this->fText, 0);
+ this->lastCodePoint = U_SENTINEL;
+
+ return 0;
+}
+
+int32_t CodePointBreakIterator::last(void)
+{
+ int32_t pos = (int32_t)utext_nativeLength(this->fText);
+ UTEXT_SETNATIVEINDEX(this->fText, pos);
+ this->lastCodePoint = U_SENTINEL;
+
+ return pos;
+}
+
+int32_t CodePointBreakIterator::previous(void)
+{
+ this->lastCodePoint = UTEXT_PREVIOUS32(this->fText);
+ if (this->lastCodePoint == U_SENTINEL) {
+ return BreakIterator::DONE;
+ }
+
+ return (int32_t)UTEXT_GETNATIVEINDEX(this->fText);
+}
+
+int32_t CodePointBreakIterator::next(void)
+{
+ this->lastCodePoint = UTEXT_NEXT32(this->fText);
+ if (this->lastCodePoint == U_SENTINEL) {
+ return BreakIterator::DONE;
+ }
+
+ return (int32_t)UTEXT_GETNATIVEINDEX(this->fText);
+}
+
+int32_t CodePointBreakIterator::current(void) const
+{
+ return (int32_t)UTEXT_GETNATIVEINDEX(this->fText);
+}
+
+int32_t CodePointBreakIterator::following(int32_t offset)
+{
+ this->lastCodePoint = utext_next32From(this->fText, offset);
+ if (this->lastCodePoint == U_SENTINEL) {
+ return BreakIterator::DONE;
+ }
+
+ return (int32_t)UTEXT_GETNATIVEINDEX(this->fText);
+}
+
+int32_t CodePointBreakIterator::preceding(int32_t offset)
+{
+ this->lastCodePoint = utext_previous32From(this->fText, offset);
+ if (this->lastCodePoint == U_SENTINEL) {
+ return BreakIterator::DONE;
+ }
+
+ return (int32_t)UTEXT_GETNATIVEINDEX(this->fText);
+}
+
+UBool CodePointBreakIterator::isBoundary(int32_t offset)
+{
+ //this function has side effects, and it's supposed to
+ utext_setNativeIndex(this->fText, offset);
+ return (offset == utext_getNativeIndex(this->fText));
+}
+
+int32_t CodePointBreakIterator::next(int32_t n)
+{
+ UBool res = utext_moveIndex32(this->fText, n);
+
+#ifndef UTEXT_CURRENT32
+#define UTEXT_CURRENT32 utext_current32
+#endif
+
+ if (res) {
+ this->lastCodePoint = UTEXT_CURRENT32(this->fText);
+ return (int32_t)UTEXT_GETNATIVEINDEX(this->fText);
+ } else {
+ this->lastCodePoint = U_SENTINEL;
+ return BreakIterator::DONE;
+ }
+}
+
+CodePointBreakIterator *CodePointBreakIterator::createBufferClone(
+ void *stackBuffer, int32_t &bufferSize, UErrorCode &status)
+{
+ //see implementation of RuleBasedBreakIterator::createBufferClone()
+ if (U_FAILURE(status)) {
+ return NULL;
+ }
+
+ if (bufferSize <= 0) {
+ bufferSize = sizeof(CodePointBreakIterator) + U_ALIGNMENT_OFFSET_UP(0);
+ return NULL;
+ }
+
+ char *buf = (char*)stackBuffer;
+ uint32_t s = bufferSize;
+
+ if (stackBuffer == NULL) {
+ s = 0;
+ }
+
+ if (U_ALIGNMENT_OFFSET(stackBuffer) != 0) {
+ uint32_t offsetUp = (uint32_t)U_ALIGNMENT_OFFSET_UP(buf);
+ s -= offsetUp;
+ buf += offsetUp;
+ }
+
+ if (s < sizeof(CodePointBreakIterator)) {
+ CodePointBreakIterator *clonedBI = new CodePointBreakIterator(*this);
+ if (clonedBI == NULL) {
+ status = U_MEMORY_ALLOCATION_ERROR;
+ } else {
+ status = U_SAFECLONE_ALLOCATED_WARNING;
+ }
+
+ return clonedBI;
+ }
+
+ return new(buf) CodePointBreakIterator(*this);
+}
+
+CodePointBreakIterator &CodePointBreakIterator::refreshInputText(UText *input, UErrorCode &status)
+{
+ //see implementation of RuleBasedBreakIterator::createBufferClone()
+ if (U_FAILURE(status)) {
+ return *this;
+ }
+ if (input == NULL) {
+ status = U_ILLEGAL_ARGUMENT_ERROR;
+ return *this;
+ }
+
+ int64_t pos = utext_getNativeIndex(this->fText);
+ this->fText = utext_clone(this->fText, input, FALSE, TRUE, &status);
+ if (U_FAILURE(status)) {
+ return *this;
+ }
+
+ utext_setNativeIndex(this->fText, pos);
+ if (utext_getNativeIndex(fText) != pos) {
+ status = U_ILLEGAL_ARGUMENT_ERROR;
+ }
+
+ return *this;
+}
diff --git a/ext/intl/breakiterator/codepointiterator_internal.h b/ext/intl/breakiterator/codepointiterator_internal.h
new file mode 100644
index 0000000000..933347b859
--- /dev/null
+++ b/ext/intl/breakiterator/codepointiterator_internal.h
@@ -0,0 +1,98 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+ */
+
+#ifndef CODEPOINTITERATOR_INTERNAL_H
+#define CODEPOINTITERATOR_INTERNAL_H
+
+#include <unicode/brkiter.h>
+
+using U_ICU_NAMESPACE::BreakIterator;
+
+namespace PHP {
+
+ class CodePointBreakIterator : public BreakIterator {
+
+ public:
+ static UClassID getStaticClassID();
+
+ CodePointBreakIterator();
+
+ CodePointBreakIterator(const CodePointBreakIterator &other);
+
+ CodePointBreakIterator& operator=(const CodePointBreakIterator& that);
+
+ virtual ~CodePointBreakIterator();
+
+ virtual UBool operator==(const BreakIterator& that) const;
+
+ virtual CodePointBreakIterator* clone(void) const;
+
+ virtual UClassID getDynamicClassID(void) const;
+
+ virtual CharacterIterator& getText(void) const;
+
+ virtual UText *getUText(UText *fillIn, UErrorCode &status) const;
+
+ virtual void setText(const UnicodeString &text);
+
+ virtual void setText(UText *text, UErrorCode &status);
+
+ virtual void adoptText(CharacterIterator* it);
+
+ virtual int32_t first(void);
+
+ virtual int32_t last(void);
+
+ virtual int32_t previous(void);
+
+ virtual int32_t next(void);
+
+ virtual int32_t current(void) const;
+
+ virtual int32_t following(int32_t offset);
+
+ virtual int32_t preceding(int32_t offset);
+
+ virtual UBool isBoundary(int32_t offset);
+
+ virtual int32_t next(int32_t n);
+
+ virtual CodePointBreakIterator *createBufferClone(void *stackBuffer,
+ int32_t &BufferSize,
+ UErrorCode &status);
+
+ virtual CodePointBreakIterator &refreshInputText(UText *input, UErrorCode &status);
+
+ inline UChar32 getLastCodePoint()
+ {
+ return this->lastCodePoint;
+ }
+
+ private:
+ UText *fText;
+ UChar32 lastCodePoint;
+ mutable CharacterIterator *fCharIter;
+
+ inline void clearCurrentCharIter()
+ {
+ delete this->fCharIter;
+ this->fCharIter = NULL;
+ this->lastCodePoint = U_SENTINEL;
+ }
+ };
+}
+
+#endif
diff --git a/ext/intl/breakiterator/codepointiterator_methods.cpp b/ext/intl/breakiterator/codepointiterator_methods.cpp
new file mode 100644
index 0000000000..a833cf1853
--- /dev/null
+++ b/ext/intl/breakiterator/codepointiterator_methods.cpp
@@ -0,0 +1,44 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+ */
+
+#include "codepointiterator_internal.h"
+
+extern "C" {
+#define USE_BREAKITERATOR_POINTER 1
+#include "breakiterator_class.h"
+}
+
+using PHP::CodePointBreakIterator;
+
+static inline CodePointBreakIterator *fetch_cpbi(BreakIterator_object *bio) {
+ return (CodePointBreakIterator*)bio->biter;
+}
+
+U_CFUNC PHP_FUNCTION(cpbi_get_last_code_point)
+{
+ BREAKITER_METHOD_INIT_VARS;
+ object = getThis();
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "cpbi_get_last_code_point: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ BREAKITER_METHOD_FETCH_OBJECT;
+
+ RETURN_LONG(fetch_cpbi(bio)->getLastCodePoint());
+}
diff --git a/ext/intl/breakiterator/codepointiterator_methods.h b/ext/intl/breakiterator/codepointiterator_methods.h
new file mode 100644
index 0000000000..ad3b710fc8
--- /dev/null
+++ b/ext/intl/breakiterator/codepointiterator_methods.h
@@ -0,0 +1,24 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+ */
+
+#ifndef CODEPOINTITERATOR_METHODS_H
+#define CODEPOINTITERATOR_METHODS_H
+
+#include <php.h>
+
+PHP_FUNCTION(cpbi_get_last_code_point);
+
+#endif
diff --git a/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp b/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp
new file mode 100644
index 0000000000..454e5249fd
--- /dev/null
+++ b/ext/intl/breakiterator/rulebasedbreakiterator_methods.cpp
@@ -0,0 +1,221 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+ */
+
+#include <unicode/rbbi.h>
+
+extern "C" {
+#define USE_BREAKITERATOR_POINTER 1
+#include "breakiterator_class.h"
+#include <zend_exceptions.h>
+#include <limits.h>
+}
+
+#include "../intl_convertcpp.h"
+
+static inline RuleBasedBreakIterator *fetch_rbbi(BreakIterator_object *bio) {
+ return (RuleBasedBreakIterator*)bio->biter;
+}
+
+static void _php_intlrbbi_constructor_body(INTERNAL_FUNCTION_PARAMETERS)
+{
+ zval *object = getThis();
+ char *rules;
+ int rules_len;
+ zend_bool compiled = 0;
+ UErrorCode status = U_ZERO_ERROR;
+ intl_error_reset(NULL TSRMLS_CC);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b",
+ &rules, &rules_len, &compiled) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "rbbi_create_instance: bad arguments", 0 TSRMLS_CC);
+ RETURN_NULL();
+ }
+
+ // instantiation of ICU object
+ RuleBasedBreakIterator *rbbi;
+
+ if (!compiled) {
+ UnicodeString rulesStr;
+ UParseError parseError = UParseError();
+ if (intl_stringFromChar(rulesStr, rules, rules_len, &status)
+ == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "rbbi_create_instance: rules were not a valid UTF-8 string",
+ 0 TSRMLS_CC);
+ RETURN_NULL();
+ }
+
+ rbbi = new RuleBasedBreakIterator(rulesStr, parseError, status);
+ intl_error_set_code(NULL, status TSRMLS_CC);
+ if (U_FAILURE(status)) {
+ char *msg;
+ smart_str parse_error_str;
+ parse_error_str = intl_parse_error_to_string(&parseError);
+ spprintf(&msg, 0, "rbbi_create_instance: unable to create "
+ "RuleBasedBreakIterator from rules (%s)", parse_error_str.c);
+ smart_str_free(&parse_error_str);
+ intl_error_set_custom_msg(NULL, msg, 1 TSRMLS_CC);
+ efree(msg);
+ delete rbbi;
+ RETURN_NULL();
+ }
+ } else { // compiled
+#if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 48
+ rbbi = new RuleBasedBreakIterator((uint8_t*)rules, rules_len, status);
+ if (U_FAILURE(status)) {
+ intl_error_set(NULL, status, "rbbi_create_instance: unable to "
+ "create instance from compiled rules", 0 TSRMLS_CC);
+ delete rbbi;
+ RETURN_NULL();
+ }
+#else
+ intl_error_set(NULL, U_UNSUPPORTED_ERROR, "rbbi_create_instance: "
+ "compiled rules require ICU >= 4.8", 0 TSRMLS_CC);
+ RETURN_NULL();
+#endif
+ }
+
+ breakiterator_object_create(return_value, rbbi TSRMLS_CC);
+}
+
+U_CFUNC PHP_METHOD(IntlRuleBasedBreakIterator, __construct)
+{
+ zval orig_this = *getThis();
+
+ return_value = getThis();
+ //changes this to IS_NULL (without first destroying) if there's an error
+ _php_intlrbbi_constructor_body(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+
+ if (Z_TYPE_P(return_value) == IS_NULL) {
+ zend_object_store_ctor_failed(&orig_this TSRMLS_CC);
+ zval_dtor(&orig_this);
+ }
+}
+
+U_CFUNC PHP_FUNCTION(rbbi_get_rules)
+{
+ BREAKITER_METHOD_INIT_VARS;
+ object = getThis();
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "rbbi_get_rules: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ BREAKITER_METHOD_FETCH_OBJECT;
+
+ const UnicodeString rules = fetch_rbbi(bio)->getRules();
+
+ Z_TYPE_P(return_value) = IS_STRING;
+ if (intl_charFromString(rules, &Z_STRVAL_P(return_value),
+ &Z_STRLEN_P(return_value), BREAKITER_ERROR_CODE_P(bio)) == FAILURE)
+ {
+ intl_errors_set(BREAKITER_ERROR_P(bio), BREAKITER_ERROR_CODE(bio),
+ "rbbi_hash_code: Error converting result to UTF-8 string",
+ 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+}
+
+U_CFUNC PHP_FUNCTION(rbbi_get_rule_status)
+{
+ BREAKITER_METHOD_INIT_VARS;
+ object = getThis();
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "rbbi_get_rule_status: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ BREAKITER_METHOD_FETCH_OBJECT;
+
+ RETURN_LONG(fetch_rbbi(bio)->getRuleStatus());
+}
+
+U_CFUNC PHP_FUNCTION(rbbi_get_rule_status_vec)
+{
+ BREAKITER_METHOD_INIT_VARS;
+ object = getThis();
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "rbbi_get_rule_status_vec: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ BREAKITER_METHOD_FETCH_OBJECT;
+
+ int32_t num_rules = fetch_rbbi(bio)->getRuleStatusVec(NULL, 0,
+ BREAKITER_ERROR_CODE(bio));
+ if (BREAKITER_ERROR_CODE(bio) == U_BUFFER_OVERFLOW_ERROR) {
+ BREAKITER_ERROR_CODE(bio) = U_ZERO_ERROR;
+ } else {
+ // should not happen
+ INTL_METHOD_CHECK_STATUS(bio, "rbbi_get_rule_status_vec: failed "
+ " determining the number of status values");
+ }
+ int32_t *rules = new int32_t[num_rules];
+ num_rules = fetch_rbbi(bio)->getRuleStatusVec(rules, num_rules,
+ BREAKITER_ERROR_CODE(bio));
+ if (U_FAILURE(BREAKITER_ERROR_CODE(bio))) {
+ delete[] rules;
+ intl_errors_set(BREAKITER_ERROR_P(bio), BREAKITER_ERROR_CODE(bio),
+ "rbbi_get_rule_status_vec: failed obtaining the status values",
+ 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ array_init_size(return_value, num_rules);
+ for (int32_t i = 0; i < num_rules; i++) {
+ add_next_index_long(return_value, rules[i]);
+ }
+ delete[] rules;
+}
+
+#if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 48
+U_CFUNC PHP_FUNCTION(rbbi_get_binary_rules)
+{
+ BREAKITER_METHOD_INIT_VARS;
+ object = getThis();
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "rbbi_get_binary_rules: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ BREAKITER_METHOD_FETCH_OBJECT;
+
+ uint32_t rules_len;
+ const uint8_t *rules = fetch_rbbi(bio)->getBinaryRules(rules_len);
+
+ if (rules_len > INT_MAX - 1) {
+ intl_errors_set(BREAKITER_ERROR_P(bio), BREAKITER_ERROR_CODE(bio),
+ "rbbi_get_binary_rules: the rules are too large",
+ 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ char *ret_rules = static_cast<char*>(emalloc(rules_len + 1));
+ memcpy(ret_rules, rules, rules_len);
+ ret_rules[rules_len] = '\0';
+
+ RETURN_STRINGL(ret_rules, rules_len, 0);
+}
+#endif
diff --git a/ext/intl/breakiterator/rulebasedbreakiterator_methods.h b/ext/intl/breakiterator/rulebasedbreakiterator_methods.h
new file mode 100644
index 0000000000..861ca4253f
--- /dev/null
+++ b/ext/intl/breakiterator/rulebasedbreakiterator_methods.h
@@ -0,0 +1,32 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+ */
+
+#ifndef RULEBASEDBREAKITERATOR_METHODS_H
+#define RULEBASEDBREAKITERATOR_METHODS_H
+
+#include <php.h>
+
+PHP_METHOD(IntlRuleBasedBreakIterator, __construct);
+
+PHP_FUNCTION(rbbi_get_rules);
+
+PHP_FUNCTION(rbbi_get_rule_status);
+
+PHP_FUNCTION(rbbi_get_rule_status_vec);
+
+PHP_FUNCTION(rbbi_get_binary_rules);
+
+#endif
diff --git a/ext/intl/calendar/calendar_class.cpp b/ext/intl/calendar/calendar_class.cpp
new file mode 100644
index 0000000000..e13425097d
--- /dev/null
+++ b/ext/intl/calendar/calendar_class.cpp
@@ -0,0 +1,555 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "../intl_cppshims.h"
+
+#include <unicode/calendar.h>
+#include <unicode/gregocal.h>
+
+extern "C" {
+#define USE_TIMEZONE_POINTER 1
+#include "../timezone/timezone_class.h"
+#define USE_CALENDAR_POINTER 1
+#include "calendar_class.h"
+#include "calendar_methods.h"
+#include "gregoriancalendar_methods.h"
+#include <zend_exceptions.h>
+#include <assert.h>
+}
+
+/* {{{ Global variables */
+zend_class_entry *Calendar_ce_ptr;
+zend_class_entry *GregorianCalendar_ce_ptr;
+zend_object_handlers Calendar_handlers;
+/* }}} */
+
+U_CFUNC void calendar_object_create(zval *object,
+ Calendar *calendar TSRMLS_DC)
+{
+ UClassID classId = calendar->getDynamicClassID();
+ zend_class_entry *ce;
+
+ //if (dynamic_cast<GregorianCalendar*>(calendar) != NULL) {
+ if (classId == GregorianCalendar::getStaticClassID()) {
+ ce = GregorianCalendar_ce_ptr;
+ } else {
+ ce = Calendar_ce_ptr;
+ }
+
+ object_init_ex(object, ce);
+ calendar_object_construct(object, calendar TSRMLS_CC);
+}
+
+U_CFUNC Calendar *calendar_fetch_native_calendar(zval *object TSRMLS_DC)
+{
+ Calendar_object *co = (Calendar_object*)
+ zend_object_store_get_object(object TSRMLS_CC);
+
+ return co->ucal;
+}
+
+U_CFUNC void calendar_object_construct(zval *object,
+ Calendar *calendar TSRMLS_DC)
+{
+ Calendar_object *co;
+
+ CALENDAR_METHOD_FETCH_OBJECT_NO_CHECK; //populate to from object
+ assert(co->ucal == NULL);
+ co->ucal = (Calendar*)calendar;
+}
+
+/* {{{ clone handler for Calendar */
+static zend_object_value Calendar_clone_obj(zval *object TSRMLS_DC)
+{
+ Calendar_object *co_orig,
+ *co_new;
+ zend_object_value ret_val;
+ intl_error_reset(NULL TSRMLS_CC);
+
+ co_orig = (Calendar_object*)zend_object_store_get_object(object TSRMLS_CC);
+ intl_error_reset(INTL_DATA_ERROR_P(co_orig) TSRMLS_CC);
+
+ ret_val = Calendar_ce_ptr->create_object(Z_OBJCE_P(object) TSRMLS_CC);
+ co_new = (Calendar_object*)zend_object_store_get_object_by_handle(ret_val.handle TSRMLS_CC);
+
+ zend_objects_clone_members(&co_new->zo, ret_val,
+ &co_orig->zo, Z_OBJ_HANDLE_P(object) TSRMLS_CC);
+
+ if (co_orig->ucal != NULL) {
+ Calendar *newCalendar;
+
+ newCalendar = co_orig->ucal->clone();
+ if (!newCalendar) {
+ char *err_msg;
+ intl_errors_set_code(CALENDAR_ERROR_P(co_orig),
+ U_MEMORY_ALLOCATION_ERROR TSRMLS_CC);
+ intl_errors_set_custom_msg(CALENDAR_ERROR_P(co_orig),
+ "Could not clone IntlCalendar", 0 TSRMLS_CC);
+ err_msg = intl_error_get_message(CALENDAR_ERROR_P(co_orig) TSRMLS_CC);
+ zend_throw_exception(NULL, err_msg, 0 TSRMLS_CC);
+ efree(err_msg);
+ } else {
+ co_new->ucal = newCalendar;
+ }
+ } else {
+ zend_throw_exception(NULL, "Cannot clone unconstructed IntlCalendar", 0 TSRMLS_CC);
+ }
+
+ return ret_val;
+}
+/* }}} */
+
+static const struct {
+ UCalendarDateFields field;
+ const char *name;
+} debug_info_fields[] = {
+ {UCAL_ERA, "era"},
+ {UCAL_YEAR, "year"},
+ {UCAL_MONTH, "month"},
+ {UCAL_WEEK_OF_YEAR, "week of year"},
+ {UCAL_WEEK_OF_MONTH, "week of month"},
+ {UCAL_DAY_OF_YEAR, "day of year"},
+ {UCAL_DAY_OF_MONTH, "day of month"},
+ {UCAL_DAY_OF_WEEK, "day of week"},
+ {UCAL_DAY_OF_WEEK_IN_MONTH, "day of week in month"},
+ {UCAL_AM_PM, "AM/PM"},
+ {UCAL_HOUR, "hour"},
+ {UCAL_HOUR_OF_DAY, "hour of day"},
+ {UCAL_MINUTE, "minute"},
+ {UCAL_SECOND, "second"},
+ {UCAL_MILLISECOND, "millisecond"},
+ {UCAL_ZONE_OFFSET, "zone offset"},
+ {UCAL_DST_OFFSET, "DST offset"},
+ {UCAL_YEAR_WOY, "year for week of year"},
+ {UCAL_DOW_LOCAL, "localized day of week"},
+ {UCAL_EXTENDED_YEAR, "extended year"},
+ {UCAL_JULIAN_DAY, "julian day"},
+ {UCAL_MILLISECONDS_IN_DAY, "milliseconds in day"},
+ {UCAL_IS_LEAP_MONTH, "is leap month"},
+};
+
+/* {{{ get_debug_info handler for Calendar */
+static HashTable *Calendar_get_debug_info(zval *object, int *is_temp TSRMLS_DC)
+{
+ zval zv = zval_used_for_init,
+ *zfields;
+ Calendar_object *co;
+ const Calendar *cal;
+
+ *is_temp = 1;
+
+ array_init_size(&zv, 8);
+
+ co = (Calendar_object*)zend_object_store_get_object(object TSRMLS_CC);
+ cal = co->ucal;
+
+ if (cal == NULL) {
+ add_assoc_bool_ex(&zv, "valid", sizeof("valid"), 0);
+ return Z_ARRVAL(zv);
+ }
+
+ add_assoc_bool_ex(&zv, "valid", sizeof("valid"), 1);
+
+ add_assoc_string_ex(&zv, "type", sizeof("type"),
+ const_cast<char*>(cal->getType()), 1);
+
+ {
+ zval ztz = zval_used_for_init,
+ *ztz_debug;
+ int is_tmp;
+ HashTable *debug_info;
+
+ timezone_object_construct(&cal->getTimeZone(), &ztz , 0 TSRMLS_CC);
+ debug_info = Z_OBJ_HANDLER(ztz, get_debug_info)(&ztz, &is_tmp TSRMLS_CC);
+ assert(is_tmp == 1);
+
+ ALLOC_INIT_ZVAL(ztz_debug);
+ Z_TYPE_P(ztz_debug) = IS_ARRAY;
+ Z_ARRVAL_P(ztz_debug) = debug_info;
+ add_assoc_zval_ex(&zv, "timeZone", sizeof("timeZone"), ztz_debug);
+ }
+
+ {
+ UErrorCode uec = U_ZERO_ERROR;
+ Locale locale = cal->getLocale(ULOC_VALID_LOCALE, uec);
+ if (U_SUCCESS(uec)) {
+ add_assoc_string_ex(&zv, "locale", sizeof("locale"),
+ const_cast<char*>(locale.getName()), 1);
+ } else {
+ add_assoc_string_ex(&zv, "locale", sizeof("locale"),
+ const_cast<char*>(u_errorName(uec)), 1);
+ }
+ }
+
+ ALLOC_INIT_ZVAL(zfields);
+ array_init_size(zfields, UCAL_FIELD_COUNT);
+
+ for (int i = 0;
+ i < sizeof(debug_info_fields) / sizeof(*debug_info_fields);
+ i++) {
+ UErrorCode uec = U_ZERO_ERROR;
+ const char *name = debug_info_fields[i].name;
+ int32_t res = cal->get(debug_info_fields[i].field, uec);
+ if (U_SUCCESS(uec)) {
+ add_assoc_long(zfields, name, (long)res);
+ } else {
+ add_assoc_string(zfields, name, const_cast<char*>(u_errorName(uec)), 1);
+ }
+ }
+
+ add_assoc_zval_ex(&zv, "fields", sizeof("fields"), zfields);
+
+ return Z_ARRVAL(zv);
+}
+/* }}} */
+
+/* {{{ void calendar_object_init(Calendar_object* to)
+ * Initialize internals of Calendar_object not specific to zend standard objects.
+ */
+static void calendar_object_init(Calendar_object *co TSRMLS_DC)
+{
+ intl_error_init(CALENDAR_ERROR_P(co) TSRMLS_CC);
+ co->ucal = NULL;
+}
+/* }}} */
+
+/* {{{ Calendar_objects_dtor */
+static void Calendar_objects_dtor(void *object,
+ zend_object_handle handle TSRMLS_DC)
+{
+ zend_objects_destroy_object((zend_object*)object, handle TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ Calendar_objects_free */
+static void Calendar_objects_free(zend_object *object TSRMLS_DC)
+{
+ Calendar_object* co = (Calendar_object*) object;
+
+ if (co->ucal) {
+ delete co->ucal;
+ co->ucal = NULL;
+ }
+ intl_error_reset(CALENDAR_ERROR_P(co) TSRMLS_CC);
+
+ zend_object_std_dtor(&co->zo TSRMLS_CC);
+
+ efree(co);
+}
+/* }}} */
+
+/* {{{ Calendar_object_create */
+static zend_object_value Calendar_object_create(zend_class_entry *ce TSRMLS_DC)
+{
+ zend_object_value retval;
+ Calendar_object* intern;
+
+ intern = (Calendar_object*)ecalloc(1, sizeof(Calendar_object));
+
+ zend_object_std_init(&intern->zo, ce TSRMLS_CC);
+#if PHP_VERSION_ID < 50399
+ zend_hash_copy(intern->zo.properties, &(ce->default_properties),
+ (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval*));
+#else
+ object_properties_init((zend_object*) intern, ce);
+#endif
+ calendar_object_init(intern TSRMLS_CC);
+
+ retval.handle = zend_objects_store_put(
+ intern,
+ Calendar_objects_dtor,
+ (zend_objects_free_object_storage_t) Calendar_objects_free,
+ NULL TSRMLS_CC);
+
+ retval.handlers = &Calendar_handlers;
+
+ return retval;
+}
+/* }}} */
+
+/* {{{ Calendar methods arguments info */
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_cal_void, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_cal_field, 0, 0, 1)
+ ZEND_ARG_INFO(0, field)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_cal_dow, 0, 0, 1)
+ ZEND_ARG_INFO(0, dayOfWeek)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_cal_other_cal, 0, 0, 1)
+ ZEND_ARG_OBJ_INFO(0, calendar, IntlCalendar, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_cal_date, 0, 0, 1)
+ ZEND_ARG_INFO(0, date)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_cal_date_optional, 0, 0, 0)
+ ZEND_ARG_INFO(0, date)
+ZEND_END_ARG_INFO()
+
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_cal_createInstance, 0, 0, 0)
+ ZEND_ARG_INFO(0, timeZone)
+ ZEND_ARG_INFO(0, locale)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_cal_get_keyword_values_for_locale, 0, 0, 3)
+ ZEND_ARG_INFO(0, key)
+ ZEND_ARG_INFO(0, locale)
+ ZEND_ARG_INFO(0, commonlyUsed)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_cal_add, 0, 0, 2)
+ ZEND_ARG_INFO(0, field)
+ ZEND_ARG_INFO(0, amount)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_cal_setTimeZone, 0, 0, 1)
+ ZEND_ARG_INFO(0, timeZone)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_cal_set, 0, 0, 2)
+ ZEND_ARG_INFO(0, fieldOrYear)
+ ZEND_ARG_INFO(0, valueOrMonth)
+ ZEND_ARG_INFO(0, dayOfMonth)
+ ZEND_ARG_INFO(0, hour)
+ ZEND_ARG_INFO(0, minute)
+ ZEND_ARG_INFO(0, second)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_cal_roll, 0, 0, 2)
+ ZEND_ARG_INFO(0, field)
+ ZEND_ARG_INFO(0, amountOrUpOrDown)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_cal_clear, 0, 0, 0)
+ ZEND_ARG_INFO(0, field)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_cal_field_difference, 0, 0, 2)
+ ZEND_ARG_INFO(0, when)
+ ZEND_ARG_INFO(0, field)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_cal_get_locale, 0, 0, 1)
+ ZEND_ARG_INFO(0, localeType)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_cal_setLenient, 0, 0, 1)
+ ZEND_ARG_INFO(0, isLenient)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_cal_set_minimal_days_in_first_week, 0, 0, 1)
+ ZEND_ARG_INFO(0, numberOfDays)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_cal_from_date_time, 0, 0, 1)
+ ZEND_ARG_INFO(0, dateTime)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_cal_wall_time_option, 0, 0, 1)
+ ZEND_ARG_INFO(0, wallTimeOption)
+ZEND_END_ARG_INFO()
+
+/* Gregorian Calendar */
+ZEND_BEGIN_ARG_INFO_EX(ainfo_gregcal___construct, 0, 0, 0)
+ ZEND_ARG_INFO(0, timeZoneOrYear)
+ ZEND_ARG_INFO(0, localeOrMonth)
+ ZEND_ARG_INFO(0, dayOfMonth)
+ ZEND_ARG_INFO(0, hour)
+ ZEND_ARG_INFO(0, minute)
+ ZEND_ARG_INFO(0, second)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_gregcal_isLeapYear, 0, 0, 1)
+ ZEND_ARG_INFO(0, year)
+ZEND_END_ARG_INFO()
+
+/* }}} */
+
+/* {{{ Calendar_class_functions
+ * Every 'IntlCalendar' class method has an entry in this table
+ */
+static const zend_function_entry Calendar_class_functions[] = {
+ PHP_ME(IntlCalendar, __construct, ainfo_cal_void, ZEND_ACC_PRIVATE)
+ PHP_ME_MAPPING(createInstance, intlcal_create_instance, ainfo_cal_createInstance, ZEND_ACC_STATIC | ZEND_ACC_PUBLIC)
+#if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 42
+ PHP_ME_MAPPING(getKeywordValuesForLocale, intlcal_get_keyword_values_for_locale, ainfo_cal_get_keyword_values_for_locale, ZEND_ACC_STATIC | ZEND_ACC_PUBLIC)
+#endif
+ PHP_ME_MAPPING(getNow, intlcal_get_now, ainfo_cal_void, ZEND_ACC_STATIC | ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(getAvailableLocales, intlcal_get_available_locales, ainfo_cal_void, ZEND_ACC_STATIC | ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(get, intlcal_get, ainfo_cal_field, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(getTime, intlcal_get_time, ainfo_cal_void, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(setTime, intlcal_set_time, ainfo_cal_date, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(add, intlcal_add, ainfo_cal_add, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(setTimeZone, intlcal_set_time_zone, ainfo_cal_setTimeZone, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(after, intlcal_after, ainfo_cal_other_cal, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(before, intlcal_before, ainfo_cal_other_cal, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(set, intlcal_set, ainfo_cal_set, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(roll, intlcal_roll, ainfo_cal_roll, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(clear, intlcal_clear, ainfo_cal_clear, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(fieldDifference, intlcal_field_difference, ainfo_cal_field_difference, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(getActualMaximum, intlcal_get_actual_maximum, ainfo_cal_field, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(getActualMinimum, intlcal_get_actual_minimum, ainfo_cal_field, ZEND_ACC_PUBLIC)
+#if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 44
+ PHP_ME_MAPPING(getDayOfWeekType, intlcal_get_day_of_week_type, ainfo_cal_dow, ZEND_ACC_PUBLIC)
+#endif
+ PHP_ME_MAPPING(getFirstDayOfWeek, intlcal_get_first_day_of_week, ainfo_cal_void, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(getGreatestMinimum, intlcal_get_greatest_minimum, ainfo_cal_field, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(getLeastMaximum, intlcal_get_least_maximum, ainfo_cal_field, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(getLocale, intlcal_get_locale, ainfo_cal_get_locale, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(getMaximum, intlcal_get_maximum, ainfo_cal_field, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(getMinimalDaysInFirstWeek, intlcal_get_minimal_days_in_first_week, ainfo_cal_void, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(getMinimum, intlcal_get_minimum, ainfo_cal_field, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(getTimeZone, intlcal_get_time_zone, ainfo_cal_void, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(getType, intlcal_get_type, ainfo_cal_void, ZEND_ACC_PUBLIC)
+#if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 44
+ PHP_ME_MAPPING(getWeekendTransition,intlcal_get_weekend_transition, ainfo_cal_dow, ZEND_ACC_PUBLIC)
+#endif
+ PHP_ME_MAPPING(inDaylightTime, intlcal_in_daylight_time, ainfo_cal_void, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(isEquivalentTo, intlcal_is_equivalent_to, ainfo_cal_other_cal, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(isLenient, intlcal_is_lenient, ainfo_cal_void, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(isSet, intlcal_is_set, ainfo_cal_field, ZEND_ACC_PUBLIC)
+#if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 44
+ PHP_ME_MAPPING(isWeekend, intlcal_is_weekend, ainfo_cal_date_optional, ZEND_ACC_PUBLIC)
+#endif
+ PHP_ME_MAPPING(setFirstDayOfWeek, intlcal_set_first_day_of_week, ainfo_cal_dow, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(setLenient, intlcal_set_lenient, ainfo_cal_setLenient, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(setMinimalDaysInFirstWeek,intlcal_set_minimal_days_in_first_week,ainfo_cal_set_minimal_days_in_first_week,ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(equals, intlcal_equals, ainfo_cal_other_cal, ZEND_ACC_PUBLIC)
+#if U_ICU_VERSION_MAJOR_NUM >= 49
+ PHP_ME_MAPPING(getRepeatedWallTimeOption,intlcal_get_repeated_wall_time_option,ainfo_cal_void, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(getSkippedWallTimeOption,intlcal_get_skipped_wall_time_option,ainfo_cal_void, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(setRepeatedWallTimeOption,intlcal_set_repeated_wall_time_option,ainfo_cal_wall_time_option,ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(setSkippedWallTimeOption,intlcal_set_skipped_wall_time_option,ainfo_cal_wall_time_option,ZEND_ACC_PUBLIC)
+#endif
+ PHP_ME_MAPPING(fromDateTime, intlcal_from_date_time, ainfo_cal_from_date_time, ZEND_ACC_STATIC | ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(toDateTime, intlcal_to_date_time, ainfo_cal_void, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(getErrorCode, intlcal_get_error_code, ainfo_cal_void, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(getErrorMessage, intlcal_get_error_message, ainfo_cal_void, ZEND_ACC_PUBLIC)
+ PHP_FE_END
+};
+/* }}} */
+
+/* {{{ GregorianCalendar_class_functions
+ */
+static const zend_function_entry GregorianCalendar_class_functions[] = {
+ PHP_ME(IntlGregorianCalendar, __construct, ainfo_gregcal___construct, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(setGregorianChange, intlgregcal_set_gregorian_change, ainfo_cal_date, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(getGregorianChange, intlgregcal_get_gregorian_change, ainfo_cal_void, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(isLeapYear, intlgregcal_is_leap_year, ainfo_gregcal_isLeapYear, ZEND_ACC_PUBLIC)
+ PHP_FE_END
+};
+/* }}} */
+
+
+/* {{{ calendar_register_IntlCalendar_class
+ * Initialize 'IntlCalendar' class
+ */
+void calendar_register_IntlCalendar_class(TSRMLS_D)
+{
+ zend_class_entry ce;
+
+ /* Create and register 'IntlCalendar' class. */
+ INIT_CLASS_ENTRY(ce, "IntlCalendar", Calendar_class_functions);
+ ce.create_object = Calendar_object_create;
+ Calendar_ce_ptr = zend_register_internal_class(&ce TSRMLS_CC);
+ if (!Calendar_ce_ptr) {
+ //can't happen now without bigger problems before
+ php_error_docref0(NULL TSRMLS_CC, E_ERROR,
+ "IntlCalendar: class registration has failed.");
+ return;
+ }
+ memcpy( &Calendar_handlers, zend_get_std_object_handlers(),
+ sizeof Calendar_handlers);
+ Calendar_handlers.clone_obj = Calendar_clone_obj;
+ Calendar_handlers.get_debug_info = Calendar_get_debug_info;
+
+ /* Create and register 'IntlGregorianCalendar' class. */
+ INIT_CLASS_ENTRY(ce, "IntlGregorianCalendar", GregorianCalendar_class_functions);
+ GregorianCalendar_ce_ptr = zend_register_internal_class_ex(&ce,
+ Calendar_ce_ptr, NULL TSRMLS_CC);
+ if (!GregorianCalendar_ce_ptr) {
+ //can't happen know without bigger problems before
+ php_error_docref0(NULL TSRMLS_CC, E_ERROR,
+ "IntlGregorianCalendar: class registration has failed.");
+ return;
+ }
+
+ /* Declare 'IntlCalendar' class constants */
+#define CALENDAR_DECL_LONG_CONST(name, val) \
+ zend_declare_class_constant_long(Calendar_ce_ptr, name, sizeof(name) - 1, \
+ val TSRMLS_CC)
+
+ CALENDAR_DECL_LONG_CONST("FIELD_ERA", UCAL_ERA);
+ CALENDAR_DECL_LONG_CONST("FIELD_YEAR", UCAL_YEAR);
+ CALENDAR_DECL_LONG_CONST("FIELD_MONTH", UCAL_MONTH);
+ CALENDAR_DECL_LONG_CONST("FIELD_WEEK_OF_YEAR", UCAL_WEEK_OF_YEAR);
+ CALENDAR_DECL_LONG_CONST("FIELD_WEEK_OF_MONTH", UCAL_WEEK_OF_MONTH);
+ CALENDAR_DECL_LONG_CONST("FIELD_DATE", UCAL_DATE);
+ CALENDAR_DECL_LONG_CONST("FIELD_DAY_OF_YEAR", UCAL_DAY_OF_YEAR);
+ CALENDAR_DECL_LONG_CONST("FIELD_DAY_OF_WEEK", UCAL_DAY_OF_WEEK);
+ CALENDAR_DECL_LONG_CONST("FIELD_DAY_OF_WEEK_IN_MONTH", UCAL_DAY_OF_WEEK_IN_MONTH);
+ CALENDAR_DECL_LONG_CONST("FIELD_AM_PM", UCAL_AM_PM);
+ CALENDAR_DECL_LONG_CONST("FIELD_HOUR", UCAL_HOUR);
+ CALENDAR_DECL_LONG_CONST("FIELD_HOUR_OF_DAY", UCAL_HOUR_OF_DAY);
+ CALENDAR_DECL_LONG_CONST("FIELD_HOUR", UCAL_HOUR);
+ CALENDAR_DECL_LONG_CONST("FIELD_HOUR_OF_DAY", UCAL_HOUR_OF_DAY);
+ CALENDAR_DECL_LONG_CONST("FIELD_MINUTE", UCAL_MINUTE);
+ CALENDAR_DECL_LONG_CONST("FIELD_SECOND", UCAL_SECOND);
+ CALENDAR_DECL_LONG_CONST("FIELD_MILLISECOND", UCAL_MILLISECOND);
+ CALENDAR_DECL_LONG_CONST("FIELD_ZONE_OFFSET", UCAL_ZONE_OFFSET);
+ CALENDAR_DECL_LONG_CONST("FIELD_DST_OFFSET", UCAL_DST_OFFSET);
+ CALENDAR_DECL_LONG_CONST("FIELD_YEAR_WOY", UCAL_YEAR_WOY);
+ CALENDAR_DECL_LONG_CONST("FIELD_DOW_LOCAL", UCAL_DOW_LOCAL);
+ CALENDAR_DECL_LONG_CONST("FIELD_EXTENDED_YEAR", UCAL_EXTENDED_YEAR);
+ CALENDAR_DECL_LONG_CONST("FIELD_JULIAN_DAY", UCAL_JULIAN_DAY);
+ CALENDAR_DECL_LONG_CONST("FIELD_MILLISECONDS_IN_DAY", UCAL_MILLISECONDS_IN_DAY);
+ CALENDAR_DECL_LONG_CONST("FIELD_IS_LEAP_MONTH", UCAL_IS_LEAP_MONTH);
+ CALENDAR_DECL_LONG_CONST("FIELD_FIELD_COUNT", UCAL_FIELD_COUNT);
+ CALENDAR_DECL_LONG_CONST("FIELD_DAY_OF_MONTH", UCAL_DAY_OF_MONTH);
+
+ CALENDAR_DECL_LONG_CONST("DOW_SUNDAY", UCAL_SUNDAY);
+ CALENDAR_DECL_LONG_CONST("DOW_MONDAY", UCAL_MONDAY);
+ CALENDAR_DECL_LONG_CONST("DOW_TUESDAY", UCAL_TUESDAY);
+ CALENDAR_DECL_LONG_CONST("DOW_WEDNESDAY", UCAL_WEDNESDAY);
+ CALENDAR_DECL_LONG_CONST("DOW_THURSDAY", UCAL_THURSDAY);
+ CALENDAR_DECL_LONG_CONST("DOW_FRIDAY", UCAL_FRIDAY);
+ CALENDAR_DECL_LONG_CONST("DOW_SATURDAY", UCAL_SATURDAY);
+
+#if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 44
+ CALENDAR_DECL_LONG_CONST("DOW_TYPE_WEEKDAY", UCAL_WEEKDAY);
+ CALENDAR_DECL_LONG_CONST("DOW_TYPE_WEEKEND", UCAL_WEEKEND);
+ CALENDAR_DECL_LONG_CONST("DOW_TYPE_WEEKEND_OFFSET", UCAL_WEEKEND_ONSET);
+ CALENDAR_DECL_LONG_CONST("DOW_TYPE_WEEKEND_CEASE", UCAL_WEEKEND_CEASE);
+#endif
+
+#if U_ICU_VERSION_MAJOR_NUM >= 49
+ CALENDAR_DECL_LONG_CONST("WALLTIME_FIRST", UCAL_WALLTIME_FIRST);
+ CALENDAR_DECL_LONG_CONST("WALLTIME_LAST", UCAL_WALLTIME_LAST);
+ CALENDAR_DECL_LONG_CONST("WALLTIME_NEXT_VALID", UCAL_WALLTIME_NEXT_VALID);
+#endif
+}
+/* }}} */
diff --git a/ext/intl/calendar/calendar_class.h b/ext/intl/calendar/calendar_class.h
new file mode 100644
index 0000000000..140389b639
--- /dev/null
+++ b/ext/intl/calendar/calendar_class.h
@@ -0,0 +1,70 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+ */
+
+#ifndef CALENDAR_CLASS_H
+#define CALENDAR_CLASS_H
+
+//redefinition of inline in PHP headers causes problems, so include this before
+#include <math.h>
+
+#include <php.h>
+#include "intl_error.h"
+#include "intl_data.h"
+
+#ifndef USE_CALENDAR_POINTER
+typedef void Calendar;
+#endif
+
+typedef struct {
+ zend_object zo;
+
+ // error handling
+ intl_error err;
+
+ // ICU calendar
+ Calendar* ucal;
+} Calendar_object;
+
+#define CALENDAR_ERROR(co) (co)->err
+#define CALENDAR_ERROR_P(co) &(CALENDAR_ERROR(co))
+
+#define CALENDAR_ERROR_CODE(co) INTL_ERROR_CODE(CALENDAR_ERROR(co))
+#define CALENDAR_ERROR_CODE_P(co) &(INTL_ERROR_CODE(CALENDAR_ERROR(co)))
+
+#define CALENDAR_METHOD_INIT_VARS INTL_METHOD_INIT_VARS(Calendar, co)
+#define CALENDAR_METHOD_FETCH_OBJECT_NO_CHECK INTL_METHOD_FETCH_OBJECT(Calendar, co)
+#define CALENDAR_METHOD_FETCH_OBJECT \
+ CALENDAR_METHOD_FETCH_OBJECT_NO_CHECK; \
+ if (co->ucal == NULL) \
+ { \
+ intl_errors_set(&co->err, U_ILLEGAL_ARGUMENT_ERROR, "Found unconstructed IntlCalendar", 0 TSRMLS_CC); \
+ RETURN_FALSE; \
+ }
+
+void calendar_object_create(zval *object, Calendar *calendar TSRMLS_DC);
+
+Calendar *calendar_fetch_native_calendar(zval *object TSRMLS_DC);
+
+void calendar_object_construct(zval *object, Calendar *calendar TSRMLS_DC);
+
+void calendar_register_IntlCalendar_class(TSRMLS_D);
+
+extern zend_class_entry *Calendar_ce_ptr,
+ *GregorianCalendar_ce_ptr;
+
+extern zend_object_handlers Calendar_handlers;
+
+#endif /* #ifndef CALENDAR_CLASS_H */
diff --git a/ext/intl/calendar/calendar_methods.cpp b/ext/intl/calendar/calendar_methods.cpp
new file mode 100644
index 0000000000..ae7d0093f7
--- /dev/null
+++ b/ext/intl/calendar/calendar_methods.cpp
@@ -0,0 +1,1353 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "../intl_cppshims.h"
+
+#include <unicode/locid.h>
+#include <unicode/calendar.h>
+#include <unicode/ustring.h>
+
+#include "../intl_convertcpp.h"
+#include "../common/common_date.h"
+
+extern "C" {
+#include "../php_intl.h"
+#define USE_TIMEZONE_POINTER 1
+#include "../timezone/timezone_class.h"
+#define USE_CALENDAR_POINTER 1
+#include "calendar_class.h"
+#include "../intl_convert.h"
+#include <zend_exceptions.h>
+#include <zend_interfaces.h>
+#include <ext/date/php_date.h>
+}
+#include "../common/common_enum.h"
+
+U_CFUNC PHP_METHOD(IntlCalendar, __construct)
+{
+ zend_throw_exception( NULL,
+ "An object of this type cannot be created with the new operator",
+ 0 TSRMLS_CC );
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_create_instance)
+{
+ zval **zv_timezone = NULL;
+ const char *locale_str = NULL;
+ int dummy;
+ TimeZone *timeZone;
+ UErrorCode status = U_ZERO_ERROR;
+ intl_error_reset(NULL TSRMLS_CC);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|Zs!",
+ &zv_timezone, &locale_str, &dummy) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_create_calendar: bad arguments", 0 TSRMLS_CC);
+ RETURN_NULL();
+ }
+
+ timeZone = timezone_process_timezone_argument(zv_timezone, NULL,
+ "intlcal_create_instance" TSRMLS_CC);
+ if (timeZone == NULL) {
+ RETURN_NULL();
+ }
+
+ if (!locale_str) {
+ locale_str = intl_locale_get_default(TSRMLS_C);
+ }
+
+ Calendar *cal = Calendar::createInstance(timeZone,
+ Locale::createFromName(locale_str), status);
+ if (cal == NULL) {
+ delete timeZone;
+ intl_error_set(NULL, status, "Error creating ICU Calendar object", 0 TSRMLS_CC);
+ RETURN_NULL();
+ }
+
+ calendar_object_create(return_value, cal TSRMLS_CC);
+}
+
+#if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 42
+class BugStringCharEnumeration : public StringEnumeration
+{
+public:
+ BugStringCharEnumeration(UEnumeration* _uenum) : uenum(_uenum) {}
+
+ ~BugStringCharEnumeration()
+ {
+ uenum_close(uenum);
+ }
+
+ int32_t count(UErrorCode& status) const {
+ return uenum_count(uenum, &status);
+ }
+
+ virtual const UnicodeString* snext(UErrorCode& status)
+ {
+ int32_t length;
+ const UChar* str = uenum_unext(uenum, &length, &status);
+ if (str == 0 || U_FAILURE(status)) {
+ return 0;
+ }
+ return &unistr.setTo(str, length);
+ }
+
+ virtual const char* next(int32_t *resultLength, UErrorCode &status)
+ {
+ int32_t length = -1;
+ const char* str = uenum_next(uenum, &length, &status);
+ if (str == 0 || U_FAILURE(status)) {
+ return 0;
+ }
+ if (resultLength) {
+ //the bug is that uenum_next doesn't set the length
+ *resultLength = (length == -1) ? strlen(str) : length;
+ }
+
+ return str;
+ }
+
+ void reset(UErrorCode& status)
+ {
+ uenum_reset(uenum, &status);
+ }
+
+ virtual UClassID getDynamicClassID() const;
+
+ static UClassID U_EXPORT2 getStaticClassID();
+
+private:
+ UEnumeration *uenum;
+};
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(BugStringCharEnumeration)
+
+U_CFUNC PHP_FUNCTION(intlcal_get_keyword_values_for_locale)
+{
+ UErrorCode status = U_ZERO_ERROR;
+ char *key,
+ *locale;
+ int key_len,
+ locale_len;
+ zend_bool commonly_used;
+ intl_error_reset(NULL TSRMLS_CC);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssb",
+ &key, &key_len, &locale, &locale_len, &commonly_used) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_get_keyword_values_for_locale: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ //does not work; see ICU bug 9194
+#if 0
+ StringEnumeration *se = Calendar::getKeywordValuesForLocale(key,
+ Locale::createFromName(locale), (UBool)commonly_used,
+ status);
+ if (se == NULL) {
+ intl_error_set(NULL, status, "intlcal_get_keyword_values_for_locale: "
+ "error calling underlying method", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+#else
+ UEnumeration *uenum = ucal_getKeywordValuesForLocale(
+ key, locale, !!commonly_used, &status);
+ if (U_FAILURE(status)) {
+ uenum_close(uenum);
+ intl_error_set(NULL, status, "intlcal_get_keyword_values_for_locale: "
+ "error calling underlying method", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ StringEnumeration *se = new BugStringCharEnumeration(uenum);
+#endif
+
+ IntlIterator_from_StringEnumeration(se, return_value TSRMLS_CC);
+}
+#endif //ICU 4.2 only
+
+U_CFUNC PHP_FUNCTION(intlcal_get_now)
+{
+ intl_error_reset(NULL TSRMLS_CC);
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_get_now: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ RETURN_DOUBLE((double)Calendar::getNow());
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_get_available_locales)
+{
+ intl_error_reset(NULL TSRMLS_CC);
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_get_available_locales: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ int32_t count;
+ const Locale *availLocales = Calendar::getAvailableLocales(count);
+ array_init(return_value);
+ for (int i = 0; i < count; i++) {
+ Locale locale = availLocales[i];
+ add_next_index_string(return_value, locale.getName(), 1);
+ }
+}
+
+static void _php_intlcal_field_uec_ret_in32t_method(
+ int32_t (Calendar::*func)(UCalendarDateFields, UErrorCode&) const,
+ const char *method_name,
+ INTERNAL_FUNCTION_PARAMETERS)
+{
+ long field;
+ char *message;
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "Ol", &object, Calendar_ce_ptr, &field) == FAILURE) {
+ spprintf(&message, 0, "%s: bad arguments", method_name);
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, message, 1 TSRMLS_CC);
+ efree(message);
+ RETURN_FALSE;
+ }
+
+ if (field < 0 || field >= UCAL_FIELD_COUNT) {
+ spprintf(&message, 0, "%s: invalid field", method_name);
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, message, 1 TSRMLS_CC);
+ efree(message);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ int32_t result = (co->ucal->*func)(
+ (UCalendarDateFields)field, CALENDAR_ERROR_CODE(co));
+ INTL_METHOD_CHECK_STATUS(co, "Call to ICU method has failed");
+
+ RETURN_LONG((long)result);
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_get)
+{
+ _php_intlcal_field_uec_ret_in32t_method(&Calendar::get,
+ "intlcal_get", INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_get_time)
+{
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",
+ &object, Calendar_ce_ptr) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_get_time: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ UDate result = co->ucal->getTime(CALENDAR_ERROR_CODE(co));
+ INTL_METHOD_CHECK_STATUS(co,
+ "intlcal_get_time: error calling ICU Calendar::getTime");
+
+ RETURN_DOUBLE((double)result);
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_set_time)
+{
+ double time_arg;
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Od",
+ &object, Calendar_ce_ptr, &time_arg) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_set_time: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ co->ucal->setTime((UDate)time_arg, CALENDAR_ERROR_CODE(co));
+ INTL_METHOD_CHECK_STATUS(co, "Call to underlying method failed");
+
+ RETURN_TRUE;
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_add)
+{
+ long field,
+ amount;
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "Oll", &object, Calendar_ce_ptr, &field, &amount) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_add: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (field < 0 || field >= UCAL_FIELD_COUNT) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_add: invalid field", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+ if (amount < INT32_MIN || amount > INT32_MAX) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_add: amount out of bounds", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ co->ucal->add((UCalendarDateFields)field, (int32_t)amount, CALENDAR_ERROR_CODE(co));
+ INTL_METHOD_CHECK_STATUS(co, "intlcal_add: Call to underlying method failed");
+
+ RETURN_TRUE;
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_set_time_zone)
+{
+ zval *zv_timezone;
+ TimeZone *timeZone;
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "Oz!", &object, Calendar_ce_ptr, &zv_timezone) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_set_time_zone: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ if (zv_timezone == NULL) {
+ RETURN_TRUE; /* the method does nothing if passed null */
+ }
+
+ timeZone = timezone_process_timezone_argument(&zv_timezone,
+ CALENDAR_ERROR_P(co), "intlcal_set_time_zone" TSRMLS_CC);
+ if (timeZone == NULL) {
+ RETURN_FALSE;
+ }
+
+ co->ucal->adoptTimeZone(timeZone);
+
+ RETURN_TRUE;
+}
+
+
+static void _php_intlcal_before_after(
+ UBool (Calendar::*func)(const Calendar&, UErrorCode&) const,
+ INTERNAL_FUNCTION_PARAMETERS)
+{
+ zval *when_object;
+ Calendar_object *when_co;
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "OO", &object, Calendar_ce_ptr, &when_object, Calendar_ce_ptr)
+ == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_before/after: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ when_co = static_cast<Calendar_object*>(
+ zend_object_store_get_object(when_object TSRMLS_CC));
+ if (when_co->ucal == NULL) {
+ intl_errors_set(&co->err, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_before/after: Other IntlCalendar was unconstructed", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ UBool res = (co->ucal->*func)(*when_co->ucal, CALENDAR_ERROR_CODE(co));
+ INTL_METHOD_CHECK_STATUS(co, "intlcal_before/after: Error calling ICU method");
+
+ RETURN_BOOL((int)res);
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_after)
+{
+ _php_intlcal_before_after(&Calendar::after, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_before)
+{
+ _php_intlcal_before_after(&Calendar::before, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_set)
+{
+ long arg1, arg2, arg3, arg4, arg5, arg6;
+ zval **args_a[7] = {0},
+ ***args = &args_a[0];
+ int i;
+ int variant; /* number of args of the set() overload */
+ CALENDAR_METHOD_INIT_VARS;
+
+ /* must come before zpp because zpp would convert the args in the stack to 0 */
+ if (ZEND_NUM_ARGS() > (getThis() ? 6 : 7) ||
+ zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_set: too many arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+ if (!getThis()) {
+ args++;
+ }
+ variant = ZEND_NUM_ARGS() - (getThis() ? 0 : 1);
+ while (variant > 2 && Z_TYPE_PP(args[variant - 1]) == IS_NULL) {
+ variant--;
+ }
+
+ if (variant == 4 ||
+ zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "Oll|llll", &object, Calendar_ce_ptr, &arg1, &arg2, &arg3, &arg4,
+ &arg5, &arg6) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_set: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ for (i = 0; i < variant; i++) {
+ if (Z_LVAL_PP(args[i]) < INT32_MIN || Z_LVAL_PP(args[i]) > INT32_MAX) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_set: at least one of the arguments has an absolute "
+ "value that is too large", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+ }
+
+ if (variant == 2 && (arg1 < 0 || arg1 >= UCAL_FIELD_COUNT)) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_set: invalid field", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ if (variant == 2) {
+ co->ucal->set((UCalendarDateFields)arg1, (int32_t)arg2);
+ } else if (variant == 3) {
+ co->ucal->set((int32_t)arg1, (int32_t)arg2, (int32_t)arg3);
+ } else if (variant == 5) {
+ co->ucal->set((int32_t)arg1, (int32_t)arg2, (int32_t)arg3, (int32_t)arg4, (int32_t)arg5);
+ } else if (variant == 6) {
+ co->ucal->set((int32_t)arg1, (int32_t)arg2, (int32_t)arg3, (int32_t)arg4, (int32_t)arg5, (int32_t)arg6);
+ }
+
+ RETURN_TRUE;
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_roll)
+{
+ long field,
+ value;
+ zval **args_a[3] = {0},
+ ***args = &args_a[0];
+ zend_bool bool_variant_val = (zend_bool)-1;
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (ZEND_NUM_ARGS() > (getThis() ? 2 :3) ||
+ zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_set: too many arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+ if (!getThis()) {
+ args++;
+ }
+ if (args[1] != NULL && Z_TYPE_PP(args[1]) == IS_BOOL) {
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "Olb", &object, Calendar_ce_ptr, &field, &bool_variant_val)
+ == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_roll: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+ bool_variant_val = Z_BVAL_PP(args[1]);
+ } else if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "Oll", &object, Calendar_ce_ptr, &field, &value) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_roll: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (field < 0 || field >= UCAL_FIELD_COUNT) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_roll: invalid field", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+ if (bool_variant_val == (zend_bool)-1 &&
+ (value < INT32_MIN || value > INT32_MAX)) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_roll: value out of bounds", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ if (bool_variant_val != (zend_bool)-1) {
+ co->ucal->roll((UCalendarDateFields)field, (UBool)bool_variant_val,
+ CALENDAR_ERROR_CODE(co));
+ } else {
+ co->ucal->roll((UCalendarDateFields)field, (int32_t)value,
+ CALENDAR_ERROR_CODE(co));
+ }
+ INTL_METHOD_CHECK_STATUS(co, "intlcal_roll: Error calling ICU Calendar::roll");
+
+ RETURN_TRUE;
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_clear)
+{
+ zval **args_a[2] = {0},
+ ***args = &args_a[0];
+ long field;
+ int variant;
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (ZEND_NUM_ARGS() > (getThis() ? 1 : 2) ||
+ zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_clear: too many arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+ if (!getThis()) {
+ args++;
+ }
+ if (args[0] == NULL || Z_TYPE_PP(args[0]) == IS_NULL) {
+ zval *dummy; /* we know it's null */
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
+ getThis(), "O|z", &object, Calendar_ce_ptr, &dummy) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_clear: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+ variant = 0;
+ } else if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
+ getThis(), "Ol", &object, Calendar_ce_ptr, &field) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_clear: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ } else if (field < 0 || field >= UCAL_FIELD_COUNT) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_clear: invalid field", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ } else {
+ variant = 1;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ if (variant == 0) {
+ co->ucal->clear();
+ } else {
+ co->ucal->clear((UCalendarDateFields)field);
+ }
+
+ RETURN_TRUE;
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_field_difference)
+{
+ long field;
+ double when;
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "Odl", &object, Calendar_ce_ptr, &when, &field) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_field_difference: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (field < 0 || field >= UCAL_FIELD_COUNT) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_field_difference: invalid field", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ int32_t result = co->ucal->fieldDifference((UDate)when,
+ (UCalendarDateFields)field, CALENDAR_ERROR_CODE(co));
+ INTL_METHOD_CHECK_STATUS(co,
+ "intlcal_field_difference: Call to ICU method has failed");
+
+ RETURN_LONG((long)result);
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_get_actual_maximum)
+{
+ _php_intlcal_field_uec_ret_in32t_method(&Calendar::getActualMaximum,
+ "intlcal_get_actual_maximum", INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_get_actual_minimum)
+{
+ _php_intlcal_field_uec_ret_in32t_method(&Calendar::getActualMinimum,
+ "intlcal_get_actual_minimum", INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+
+#if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 44
+U_CFUNC PHP_FUNCTION(intlcal_get_day_of_week_type)
+{
+ long dow;
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "Ol", &object, Calendar_ce_ptr, &dow) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_get_day_of_week_type: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (dow < UCAL_SUNDAY || dow > UCAL_SATURDAY) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_get_day_of_week_type: invalid day of week", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ int32_t result = co->ucal->getDayOfWeekType(
+ (UCalendarDaysOfWeek)dow, CALENDAR_ERROR_CODE(co));
+ INTL_METHOD_CHECK_STATUS(co,
+ "intlcal_get_day_of_week_type: Call to ICU method has failed");
+
+ RETURN_LONG((long)result);
+}
+#endif
+
+U_CFUNC PHP_FUNCTION(intlcal_get_first_day_of_week)
+{
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "O", &object, Calendar_ce_ptr) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_get_first_day_of_week: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ int32_t result = co->ucal->getFirstDayOfWeek(CALENDAR_ERROR_CODE(co));
+ INTL_METHOD_CHECK_STATUS(co,
+ "intlcal_get_first_day_of_week: Call to ICU method has failed");
+
+ RETURN_LONG((long)result);
+}
+
+static void _php_intlcal_field_ret_in32t_method(
+ int32_t (Calendar::*func)(UCalendarDateFields) const,
+ const char *method_name,
+ INTERNAL_FUNCTION_PARAMETERS)
+{
+ long field;
+ char *message;
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "Ol", &object, Calendar_ce_ptr, &field) == FAILURE) {
+ spprintf(&message, 0, "%s: bad arguments", method_name);
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, message, 1 TSRMLS_CC);
+ efree(message);
+ RETURN_FALSE;
+ }
+
+ if (field < 0 || field >= UCAL_FIELD_COUNT) {
+ spprintf(&message, 0, "%s: invalid field", method_name);
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, message, 1 TSRMLS_CC);
+ efree(message);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ int32_t result = (co->ucal->*func)((UCalendarDateFields)field);
+ INTL_METHOD_CHECK_STATUS(co, "Call to ICU method has failed");
+
+ RETURN_LONG((long)result);
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_get_greatest_minimum)
+{
+ _php_intlcal_field_ret_in32t_method(&Calendar::getGreatestMinimum,
+ "intlcal_get_greatest_minimum", INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_get_least_maximum)
+{
+ _php_intlcal_field_ret_in32t_method(&Calendar::getLeastMaximum,
+ "intlcal_get_least_maximum", INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_get_locale)
+{
+ long locale_type;
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "Ol", &object, Calendar_ce_ptr, &locale_type) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_get_locale: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (locale_type != ULOC_ACTUAL_LOCALE && locale_type != ULOC_VALID_LOCALE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_get_locale: invalid locale type", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ Locale locale = co->ucal->getLocale((ULocDataLocaleType)locale_type,
+ CALENDAR_ERROR_CODE(co));
+ INTL_METHOD_CHECK_STATUS(co,
+ "intlcal_get_locale: Call to ICU method has failed");
+
+ RETURN_STRING(locale.getName(), 1);
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_get_maximum)
+{
+ _php_intlcal_field_ret_in32t_method(&Calendar::getMaximum,
+ "intlcal_get_maximum", INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_get_minimal_days_in_first_week)
+{
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "O", &object, Calendar_ce_ptr) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_get_minimal_days_in_first_week: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ uint8_t result = co->ucal->getMinimalDaysInFirstWeek();
+ INTL_METHOD_CHECK_STATUS(co,
+ "intlcal_get_first_day_of_week: Call to ICU method has failed");
+
+ RETURN_LONG((long)result);
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_get_minimum)
+{
+ _php_intlcal_field_ret_in32t_method(&Calendar::getMinimum,
+ "intlcal_get_minimum", INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_get_time_zone)
+{
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "O", &object, Calendar_ce_ptr) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_get_time_zone: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ TimeZone *tz = co->ucal->getTimeZone().clone();
+ if (tz == NULL) {
+ intl_errors_set(CALENDAR_ERROR_P(co), U_MEMORY_ALLOCATION_ERROR,
+ "intlcal_get_time_zone: could not clone TimeZone", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ timezone_object_construct(tz, return_value, 1 TSRMLS_CC);
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_get_type)
+{
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "O", &object, Calendar_ce_ptr) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_get_type: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ RETURN_STRING(co->ucal->getType(), 1);
+}
+
+#if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 44
+U_CFUNC PHP_FUNCTION(intlcal_get_weekend_transition)
+{
+ long dow;
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "Ol", &object, Calendar_ce_ptr, &dow) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_get_weekend_transition: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (dow < UCAL_SUNDAY || dow > UCAL_SATURDAY) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_get_weekend_transition: invalid day of week", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ int32_t res = co->ucal->getWeekendTransition((UCalendarDaysOfWeek)dow,
+ CALENDAR_ERROR_CODE(co));
+ INTL_METHOD_CHECK_STATUS(co, "intlcal_get_weekend_transition: "
+ "Error calling ICU method");
+
+ RETURN_LONG((long)res);
+}
+#endif
+
+U_CFUNC PHP_FUNCTION(intlcal_in_daylight_time)
+{
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "O", &object, Calendar_ce_ptr) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_in_daylight_time: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ UBool ret = co->ucal->inDaylightTime(CALENDAR_ERROR_CODE(co));
+ INTL_METHOD_CHECK_STATUS(co, "intlcal_in_daylight_time: "
+ "Error calling ICU method");
+
+ RETURN_BOOL((int)ret);
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_is_equivalent_to)
+{
+ zval *other_object;
+ Calendar_object *other_co;
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "OO", &object, Calendar_ce_ptr, &other_object, Calendar_ce_ptr)
+ == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_is_equivalent_to: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ other_co = (Calendar_object*)zend_object_store_get_object(other_object TSRMLS_CC);
+ if (other_co->ucal == NULL) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "intlcal_is_equivalent_to:"
+ " Other IntlCalendar is unconstructed", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ RETURN_BOOL((int)co->ucal->isEquivalentTo(*other_co->ucal));
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_is_lenient)
+{
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "O", &object, Calendar_ce_ptr) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_is_lenient: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ RETURN_BOOL((int)co->ucal->isLenient());
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_is_set)
+{
+ long field;
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "Ol", &object, Calendar_ce_ptr, &field) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_is_set: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (field < 0 || field >= UCAL_FIELD_COUNT) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_is_set: invalid field", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ RETURN_BOOL((int)co->ucal->isSet((UCalendarDateFields)field));
+}
+
+#if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 44
+U_CFUNC PHP_FUNCTION(intlcal_is_weekend)
+{
+ double date;
+ zval *rawDate = NULL;
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters_ex(ZEND_PARSE_PARAMS_QUIET,
+ ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "O|z!", &object, Calendar_ce_ptr, &rawDate) == FAILURE
+ || (rawDate != NULL &&
+ zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "O|d", &object, Calendar_ce_ptr, &date) == FAILURE)) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_is_weekend: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ if (rawDate == NULL) {
+ RETURN_BOOL((int)co->ucal->isWeekend());
+ } else {
+ UBool ret = co->ucal->isWeekend((UDate)date, CALENDAR_ERROR_CODE(co));
+ INTL_METHOD_CHECK_STATUS(co, "intlcal_is_weekend: "
+ "Error calling ICU method");
+ RETURN_BOOL((int)ret);
+ }
+}
+#endif
+
+
+U_CFUNC PHP_FUNCTION(intlcal_set_first_day_of_week)
+{
+ long dow;
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "Ol", &object, Calendar_ce_ptr, &dow) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_set_first_day_of_week: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (dow < UCAL_SUNDAY || dow > UCAL_SATURDAY) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_set_first_day_of_week: invalid day of week", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ co->ucal->setFirstDayOfWeek((UCalendarDaysOfWeek)dow);
+
+ RETURN_TRUE;
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_set_lenient)
+{
+ zend_bool is_lenient;
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "Ob", &object, Calendar_ce_ptr, &is_lenient) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_set_lenient: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ co->ucal->setLenient((UBool) is_lenient);
+
+ RETURN_TRUE;
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_set_minimal_days_in_first_week)
+{
+ long num_days;
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "Ol", &object, Calendar_ce_ptr, &num_days) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_set_minimal_days_in_first_week: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (num_days < 1 || num_days > 7) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_set_minimal_days_in_first_week: invalid number of days; "
+ "must be between 1 and 7", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ co->ucal->setMinimalDaysInFirstWeek((uint8_t)num_days);
+
+ RETURN_TRUE;
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_equals)
+{
+ zval *other_object;
+ Calendar_object *other_co;
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "OO", &object, Calendar_ce_ptr, &other_object, Calendar_ce_ptr)
+ == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_equals: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+ other_co = (Calendar_object *) zend_object_store_get_object(other_object TSRMLS_CC);
+ if (other_co->ucal == NULL) {
+ intl_errors_set(&co->err, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_equals: The second IntlCalendar is unconstructed", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ UBool result = co->ucal->equals(*other_co->ucal, CALENDAR_ERROR_CODE(co));
+ INTL_METHOD_CHECK_STATUS(co, "intlcal_equals: error calling ICU Calendar::equals");
+
+ RETURN_BOOL((int)result);
+}
+
+#if U_ICU_VERSION_MAJOR_NUM >= 49
+
+U_CFUNC PHP_FUNCTION(intlcal_get_repeated_wall_time_option)
+{
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "O", &object, Calendar_ce_ptr) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_get_repeated_wall_time_option: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ RETURN_LONG(co->ucal->getRepeatedWallTimeOption());
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_get_skipped_wall_time_option)
+{
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "O", &object, Calendar_ce_ptr) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_get_skipped_wall_time_option: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ RETURN_LONG(co->ucal->getSkippedWallTimeOption());
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_set_repeated_wall_time_option)
+{
+ long option;
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "Ol", &object, Calendar_ce_ptr, &option) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_set_repeated_wall_time_option: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (option != UCAL_WALLTIME_FIRST && option != UCAL_WALLTIME_LAST) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_set_repeated_wall_time_option: invalid option", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ co->ucal->setRepeatedWallTimeOption((UCalendarWallTimeOption)option);
+
+ RETURN_TRUE;
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_set_skipped_wall_time_option)
+{
+ long option;
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "Ol", &object, Calendar_ce_ptr, &option) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_set_skipped_wall_time_option: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (option != UCAL_WALLTIME_FIRST && option != UCAL_WALLTIME_LAST
+ && option != UCAL_WALLTIME_NEXT_VALID) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_set_skipped_wall_time_option: invalid option", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ co->ucal->setSkippedWallTimeOption((UCalendarWallTimeOption)option);
+
+ RETURN_TRUE;
+}
+
+#endif
+
+U_CFUNC PHP_FUNCTION(intlcal_from_date_time)
+{
+ zval **zv_arg,
+ *zv_datetime = NULL,
+ *zv_timestamp = NULL;
+ php_date_obj *datetime;
+ char *locale_str = NULL;
+ int locale_str_len;
+ TimeZone *timeZone;
+ UErrorCode status = U_ZERO_ERROR;
+ Calendar *cal;
+ intl_error_reset(NULL TSRMLS_CC);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|s!",
+ &zv_arg, &locale_str, &locale_str_len) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_from_date_time: bad arguments", 0 TSRMLS_CC);
+ RETURN_NULL();
+ }
+
+ if (!(Z_TYPE_PP(zv_arg) == IS_OBJECT && instanceof_function(
+ Z_OBJCE_PP(zv_arg), php_date_get_date_ce() TSRMLS_CC))) {
+ ALLOC_INIT_ZVAL(zv_datetime);
+ object_init_ex(zv_datetime, php_date_get_date_ce());
+ zend_call_method_with_1_params(&zv_datetime, NULL, NULL, "__construct",
+ NULL, *zv_arg);
+ if (EG(exception)) {
+ zend_object_store_ctor_failed(zv_datetime TSRMLS_CC);
+ goto error;
+ }
+ } else {
+ zv_datetime = *zv_arg;
+ }
+
+ datetime = (php_date_obj*)zend_object_store_get_object(zv_datetime TSRMLS_CC);
+ if (!datetime->time) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_from_date_time: DateTime object is unconstructed",
+ 0 TSRMLS_CC);
+ goto error;
+ }
+
+ zend_call_method_with_0_params(&zv_datetime, php_date_get_date_ce(),
+ NULL, "gettimestamp", &zv_timestamp);
+ if (!zv_timestamp || Z_TYPE_P(zv_timestamp) != IS_LONG) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_from_date_time: bad DateTime; call to "
+ "DateTime::getTimestamp() failed", 0 TSRMLS_CC);
+ goto error;
+ }
+
+ if (!datetime->time->is_localtime) {
+ timeZone = TimeZone::getGMT()->clone();
+ } else {
+ timeZone = timezone_convert_datetimezone(datetime->time->zone_type,
+ datetime, 1, NULL, "intlcal_from_date_time" TSRMLS_CC);
+ if (timeZone == NULL) {
+ goto error;
+ }
+ }
+
+ if (!locale_str) {
+ locale_str = const_cast<char*>(intl_locale_get_default(TSRMLS_C));
+ }
+
+ cal = Calendar::createInstance(timeZone,
+ Locale::createFromName(locale_str), status);
+ if (cal == NULL) {
+ delete timeZone;
+ intl_error_set(NULL, status, "intlcal_from_date_time: "
+ "error creating ICU Calendar object", 0 TSRMLS_CC);
+ goto error;
+ }
+ cal->setTime(((UDate)Z_LVAL_P(zv_timestamp)) * 1000., status);
+ if (U_FAILURE(status)) {
+ /* time zone was adopted by cal; should not be deleted here */
+ delete cal;
+ intl_error_set(NULL, status, "intlcal_from_date_time: "
+ "error creating ICU Calendar::setTime()", 0 TSRMLS_CC);
+ goto error;
+ }
+
+ calendar_object_create(return_value, cal TSRMLS_CC);
+
+error:
+ if (zv_datetime != *zv_arg) {
+ zval_ptr_dtor(&zv_datetime);
+ }
+ if (zv_timestamp) {
+ zval_ptr_dtor(&zv_timestamp);
+ }
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_to_date_time)
+{
+ zval *retval = NULL;
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",
+ &object, Calendar_ce_ptr) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_to_date_time: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ /* There are no exported functions in ext/date to this
+ * in a more native fashion */
+ double date = co->ucal->getTime(CALENDAR_ERROR_CODE(co)) / 1000.;
+ int64_t ts;
+ char ts_str[sizeof("@-9223372036854775808")];
+ int ts_str_len;
+ zval ts_zval = zval_used_for_init;
+
+ INTL_METHOD_CHECK_STATUS(co, "Call to ICU method has failed");
+
+ if (date > (double)U_INT64_MAX || date < (double)U_INT64_MIN) {
+ intl_errors_set(CALENDAR_ERROR_P(co), U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_to_date_time: The calendar date is out of the "
+ "range for a 64-bit integer", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ ts = (int64_t)date;
+
+ ts_str_len = slprintf(ts_str, sizeof(ts_str), "@%I64d", ts);
+ ZVAL_STRINGL(&ts_zval, ts_str, ts_str_len, 0);
+
+ /* Now get the time zone */
+ const TimeZone& tz = co->ucal->getTimeZone();
+ zval *timezone_zval = timezone_convert_to_datetimezone(
+ &tz, CALENDAR_ERROR_P(co), "intlcal_to_date_time" TSRMLS_CC);
+ if (timezone_zval == NULL) {
+ RETURN_FALSE;
+ }
+
+ /* resources allocated from now on */
+
+ /* Finally, instantiate object and call constructor */
+ object_init_ex(return_value, php_date_get_date_ce());
+ zend_call_method_with_2_params(&return_value, NULL, NULL, "__construct",
+ NULL, &ts_zval, timezone_zval);
+ if (EG(exception)) {
+ intl_errors_set(CALENDAR_ERROR_P(co), U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_to_date_time: DateTime constructor has thrown exception",
+ 1 TSRMLS_CC);
+ zend_object_store_ctor_failed(return_value TSRMLS_CC);
+ zval_ptr_dtor(&return_value);
+
+ RETVAL_FALSE;
+ goto error;
+ }
+
+ /* due to bug #40743, we have to set the time zone again */
+ zend_call_method_with_1_params(&return_value, NULL, NULL, "settimezone",
+ &retval, timezone_zval);
+ if (retval == NULL || Z_TYPE_P(retval) == IS_BOOL) {
+ intl_errors_set(CALENDAR_ERROR_P(co), U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_to_date_time: call to DateTime::setTimeZone has failed",
+ 1 TSRMLS_CC);
+ zval_ptr_dtor(&return_value);
+ RETVAL_FALSE;
+ goto error;
+ }
+
+error:
+ zval_ptr_dtor(&timezone_zval);
+ if (retval != NULL) {
+ zval_ptr_dtor(&retval);
+ }
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_get_error_code)
+{
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",
+ &object, Calendar_ce_ptr) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_get_error_code: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ /* Fetch the object (without resetting its last error code ). */
+ co = (Calendar_object*)zend_object_store_get_object(object TSRMLS_CC);
+ if (co == NULL)
+ RETURN_FALSE;
+
+ RETURN_LONG((long)CALENDAR_ERROR_CODE(co));
+}
+
+U_CFUNC PHP_FUNCTION(intlcal_get_error_message)
+{
+ const char* message = NULL;
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",
+ &object, Calendar_ce_ptr) == FAILURE) {
+ intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlcal_get_error_message: bad arguments", 0 TSRMLS_CC );
+ RETURN_FALSE;
+ }
+
+
+ /* Fetch the object (without resetting its last error code ). */
+ co = (Calendar_object*)zend_object_store_get_object(object TSRMLS_CC);
+ if (co == NULL)
+ RETURN_FALSE;
+
+ /* Return last error message. */
+ message = intl_error_get_message(CALENDAR_ERROR_P(co) TSRMLS_CC);
+ RETURN_STRING(message, 0);
+}
diff --git a/ext/intl/calendar/calendar_methods.h b/ext/intl/calendar/calendar_methods.h
new file mode 100644
index 0000000000..dfd0bbeeaf
--- /dev/null
+++ b/ext/intl/calendar/calendar_methods.h
@@ -0,0 +1,114 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@netcabo.pt> |
+ +----------------------------------------------------------------------+
+ */
+
+#ifndef CALENDAR_METHODS_H
+#define CALENDAR_METHODS_H
+
+#include <php.h>
+
+PHP_METHOD(IntlCalendar, __construct);
+
+PHP_FUNCTION(intlcal_create_instance);
+
+PHP_FUNCTION(intlcal_get_keyword_values_for_locale);
+
+PHP_FUNCTION(intlcal_get_now);
+
+PHP_FUNCTION(intlcal_get_available_locales);
+
+PHP_FUNCTION(intlcal_get);
+
+PHP_FUNCTION(intlcal_get_time);
+
+PHP_FUNCTION(intlcal_set_time);
+
+PHP_FUNCTION(intlcal_add);
+
+PHP_FUNCTION(intlcal_set_time_zone);
+
+PHP_FUNCTION(intlcal_after);
+
+PHP_FUNCTION(intlcal_before);
+
+PHP_FUNCTION(intlcal_set);
+
+PHP_FUNCTION(intlcal_roll);
+
+PHP_FUNCTION(intlcal_clear);
+
+PHP_FUNCTION(intlcal_field_difference);
+
+PHP_FUNCTION(intlcal_get_actual_maximum);
+
+PHP_FUNCTION(intlcal_get_actual_minimum);
+
+PHP_FUNCTION(intlcal_get_day_of_week_type);
+
+PHP_FUNCTION(intlcal_get_first_day_of_week);
+
+PHP_FUNCTION(intlcal_get_greatest_minimum);
+
+PHP_FUNCTION(intlcal_get_least_maximum);
+
+PHP_FUNCTION(intlcal_get_locale);
+
+PHP_FUNCTION(intlcal_get_maximum);
+
+PHP_FUNCTION(intlcal_get_minimal_days_in_first_week);
+
+PHP_FUNCTION(intlcal_get_minimum);
+
+PHP_FUNCTION(intlcal_get_time_zone);
+
+PHP_FUNCTION(intlcal_get_type);
+
+PHP_FUNCTION(intlcal_get_weekend_transition);
+
+PHP_FUNCTION(intlcal_in_daylight_time);
+
+PHP_FUNCTION(intlcal_is_equivalent_to);
+
+PHP_FUNCTION(intlcal_is_lenient);
+
+PHP_FUNCTION(intlcal_is_set);
+
+PHP_FUNCTION(intlcal_is_weekend);
+
+PHP_FUNCTION(intlcal_set_first_day_of_week);
+
+PHP_FUNCTION(intlcal_set_lenient);
+
+PHP_FUNCTION(intlcal_set_minimal_days_in_first_week);
+
+PHP_FUNCTION(intlcal_equals);
+
+PHP_FUNCTION(intlcal_get_repeated_wall_time_option);
+
+PHP_FUNCTION(intlcal_get_skipped_wall_time_option);
+
+PHP_FUNCTION(intlcal_set_repeated_wall_time_option);
+
+PHP_FUNCTION(intlcal_set_skipped_wall_time_option);
+
+PHP_FUNCTION(intlcal_from_date_time);
+
+PHP_FUNCTION(intlcal_to_date_time);
+
+PHP_FUNCTION(intlcal_get_error_code);
+
+PHP_FUNCTION(intlcal_get_error_message);
+
+#endif /* #ifndef CALENDAR_METHODS_H */
diff --git a/ext/intl/calendar/gregoriancalendar_methods.cpp b/ext/intl/calendar/gregoriancalendar_methods.cpp
new file mode 100644
index 0000000000..08b894964c
--- /dev/null
+++ b/ext/intl/calendar/gregoriancalendar_methods.cpp
@@ -0,0 +1,255 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "../intl_cppshims.h"
+
+#include <unicode/locid.h>
+#include <unicode/calendar.h>
+#include <unicode/gregocal.h>
+extern "C" {
+#include "../php_intl.h"
+#define USE_TIMEZONE_POINTER 1
+#include "../timezone/timezone_class.h"
+#define USE_CALENDAR_POINTER 1
+#include "calendar_class.h"
+#include <ext/date/php_date.h>
+}
+
+static inline GregorianCalendar *fetch_greg(Calendar_object *co) {
+ return (GregorianCalendar*)co->ucal;
+}
+
+static void _php_intlgregcal_constructor_body(INTERNAL_FUNCTION_PARAMETERS)
+{
+ zval **tz_object = NULL;
+ zval **args_a[6] = {0},
+ ***args = &args_a[0];
+ char *locale = NULL;
+ int locale_len;
+ long largs[6];
+ UErrorCode status = U_ZERO_ERROR;
+ int variant;
+ intl_error_reset(NULL TSRMLS_CC);
+
+ // parameter number validation / variant determination
+ if (ZEND_NUM_ARGS() > 6 ||
+ zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlgregcal_create_instance: too many arguments", 0 TSRMLS_CC);
+ RETURN_NULL();
+ }
+ for (variant = ZEND_NUM_ARGS();
+ variant > 0 && Z_TYPE_PP(args[variant - 1]) == IS_NULL;
+ variant--) {}
+ if (variant == 4) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlgregcal_create_instance: no variant with 4 arguments "
+ "(excluding trailing NULLs)", 0 TSRMLS_CC);
+ RETURN_NULL();
+ }
+
+ // argument parsing
+ if (variant <= 2) {
+ if (zend_parse_parameters(MIN(ZEND_NUM_ARGS(), 2) TSRMLS_CC,
+ "|Z!s!", &tz_object, &locale, &locale_len) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlgregcal_create_instance: bad arguments", 0 TSRMLS_CC);
+ RETURN_NULL();
+ }
+ }
+ if (variant > 2 && zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
+ "lll|lll", &largs[0], &largs[1], &largs[2], &largs[3], &largs[4],
+ &largs[5]) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlgregcal_create_instance: bad arguments", 0 TSRMLS_CC);
+ RETURN_NULL();
+ }
+
+ // instantion of ICU object
+ GregorianCalendar *gcal = NULL;
+
+ if (variant <= 2) {
+ // From timezone and locale (0 to 2 arguments)
+ TimeZone *tz = timezone_process_timezone_argument(tz_object, NULL,
+ "intlgregcal_create_instance" TSRMLS_CC);
+ if (tz == NULL) {
+ RETURN_NULL();
+ }
+ if (!locale) {
+ locale = const_cast<char*>(intl_locale_get_default(TSRMLS_C));
+ }
+
+ gcal = new GregorianCalendar(tz, Locale::createFromName(locale),
+ status);
+ if (U_FAILURE(status)) {
+ intl_error_set(NULL, status, "intlgregcal_create_instance: error "
+ "creating ICU GregorianCalendar from time zone and locale", 0 TSRMLS_CC);
+ if (gcal) {
+ delete gcal;
+ }
+ delete tz;
+ RETURN_NULL();
+ }
+ } else {
+ // From date/time (3, 5 or 6 arguments)
+ for (int i = 0; i < variant; i++) {
+ if (largs[i] < INT32_MIN || largs[i] > INT32_MAX) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlgregcal_create_instance: at least one of the arguments"
+ " has an absolute value that is too large", 0 TSRMLS_CC);
+ RETURN_NULL();
+ }
+ }
+
+ if (variant == 3) {
+ gcal = new GregorianCalendar((int32_t)largs[0], (int32_t)largs[1],
+ (int32_t)largs[2], status);
+ } else if (variant == 5) {
+ gcal = new GregorianCalendar((int32_t)largs[0], (int32_t)largs[1],
+ (int32_t)largs[2], (int32_t)largs[3], (int32_t)largs[4], status);
+ } else if (variant == 6) {
+ gcal = new GregorianCalendar((int32_t)largs[0], (int32_t)largs[1],
+ (int32_t)largs[2], (int32_t)largs[3], (int32_t)largs[4], (int32_t)largs[5],
+ status);
+ }
+ if (U_FAILURE(status)) {
+ intl_error_set(NULL, status, "intlgregcal_create_instance: error "
+ "creating ICU GregorianCalendar from date", 0 TSRMLS_CC);
+ if (gcal) {
+ delete gcal;
+ }
+ RETURN_NULL();
+ }
+
+ timelib_tzinfo *tzinfo = get_timezone_info(TSRMLS_C);
+#if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 42
+ UnicodeString tzstr = UnicodeString::fromUTF8(StringPiece(tzinfo->name));
+#else
+ UnicodeString tzstr = UnicodeString(tzinfo->name,
+ strlen(tzinfo->name), US_INV);
+#endif
+ if (tzstr.isBogus()) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlgregcal_create_instance: could not create UTF-8 string "
+ "from PHP's default timezone name (see date_default_timezone_get())",
+ 0 TSRMLS_CC);
+ delete gcal;
+ RETURN_NULL();
+ }
+
+ TimeZone *tz = TimeZone::createTimeZone(tzstr);
+ gcal->adoptTimeZone(tz);
+ }
+
+ Calendar_object *co = (Calendar_object*)zend_object_store_get_object(
+ return_value TSRMLS_CC);
+ co->ucal = gcal;
+}
+
+U_CFUNC PHP_FUNCTION(intlgregcal_create_instance)
+{
+ zval orig;
+ intl_error_reset(NULL TSRMLS_CC);
+
+ object_init_ex(return_value, GregorianCalendar_ce_ptr);
+ orig = *return_value;
+
+ _php_intlgregcal_constructor_body(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+
+ if (Z_TYPE_P(return_value) == IS_NULL) {
+ zend_object_store_ctor_failed(&orig TSRMLS_CC);
+ zval_dtor(&orig);
+ }
+}
+
+U_CFUNC PHP_METHOD(IntlGregorianCalendar, __construct)
+{
+ zval orig_this = *getThis();
+ intl_error_reset(NULL TSRMLS_CC);
+
+ return_value = getThis();
+ //changes this to IS_NULL (without first destroying) if there's an error
+ _php_intlgregcal_constructor_body(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+
+ if (Z_TYPE_P(return_value) == IS_NULL) {
+ zend_object_store_ctor_failed(&orig_this TSRMLS_CC);
+ zval_dtor(&orig_this);
+ }
+}
+
+U_CFUNC PHP_FUNCTION(intlgregcal_set_gregorian_change)
+{
+ double date;
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "Od", &object, GregorianCalendar_ce_ptr, &date) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlgregcal_set_gregorian_change: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ fetch_greg(co)->setGregorianChange(date, CALENDAR_ERROR_CODE(co));
+ INTL_METHOD_CHECK_STATUS(co, "intlgregcal_set_gregorian_change: error "
+ "calling ICU method");
+
+ RETURN_TRUE;
+}
+
+U_CFUNC PHP_FUNCTION(intlgregcal_get_gregorian_change)
+{
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "O", &object, GregorianCalendar_ce_ptr) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlgregcal_get_gregorian_change: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ RETURN_DOUBLE((double)fetch_greg(co)->getGregorianChange());
+}
+
+U_CFUNC PHP_FUNCTION(intlgregcal_is_leap_year)
+{
+ long year;
+ CALENDAR_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "Ol", &object, GregorianCalendar_ce_ptr, &year) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlgregcal_is_leap_year: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (year < INT32_MIN || year > INT32_MAX) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intlgregcal_is_leap_year: year out of bounds", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ CALENDAR_METHOD_FETCH_OBJECT;
+
+ RETURN_BOOL((int)fetch_greg(co)->isLeapYear((int32_t)year));
+}
diff --git a/ext/intl/calendar/gregoriancalendar_methods.h b/ext/intl/calendar/gregoriancalendar_methods.h
new file mode 100644
index 0000000000..f911752cc7
--- /dev/null
+++ b/ext/intl/calendar/gregoriancalendar_methods.h
@@ -0,0 +1,32 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+ */
+
+#ifndef GREORIANCALENDAR_METHODS_H
+#define GREORIANCALENDAR_METHODS_H
+
+#include <php.h>
+
+PHP_FUNCTION(intlgregcal_create_instance);
+
+PHP_METHOD(IntlGregorianCalendar, __construct);
+
+PHP_FUNCTION(intlgregcal_set_gregorian_change);
+
+PHP_FUNCTION(intlgregcal_get_gregorian_change);
+
+PHP_FUNCTION(intlgregcal_is_leap_year);
+
+#endif
diff --git a/ext/intl/collator/collator_convert.c b/ext/intl/collator/collator_convert.c
index e989d4c65a..2a3ac10fbf 100644
--- a/ext/intl/collator/collator_convert.c
+++ b/ext/intl/collator/collator_convert.c
@@ -139,7 +139,7 @@ void collator_convert_hash_from_utf8_to_utf16( HashTable* hash, UErrorCode* stat
zend_hash_internal_pointer_reset( hash );
while( ( hashKeyType = zend_hash_get_current_key( hash, &hashKey, &hashIndex, 0 ) )
- != HASH_KEY_NON_EXISTANT )
+ != HASH_KEY_NON_EXISTENT )
{
/* Convert current hash item from UTF-8 to UTF-16LE. */
collator_convert_hash_item_from_utf8_to_utf16(
@@ -164,7 +164,7 @@ void collator_convert_hash_from_utf16_to_utf8( HashTable* hash, UErrorCode* stat
zend_hash_internal_pointer_reset( hash );
while( ( hashKeyType = zend_hash_get_current_key( hash, &hashKey, &hashIndex, 0 ) )
- != HASH_KEY_NON_EXISTANT )
+ != HASH_KEY_NON_EXISTENT )
{
/* Convert current hash item from UTF-16LE to UTF-8. */
collator_convert_hash_item_from_utf16_to_utf8(
diff --git a/ext/intl/collator/collator_create.c b/ext/intl/collator/collator_create.c
index b2a9968af4..7ed4c53439 100644
--- a/ext/intl/collator/collator_create.c
+++ b/ext/intl/collator/collator_create.c
@@ -27,7 +27,7 @@
/* {{{ */
static void collator_ctor(INTERNAL_FUNCTION_PARAMETERS)
{
- char* locale;
+ const char* locale;
int locale_len = 0;
zval* object;
Collator_object* co;
@@ -48,7 +48,7 @@ static void collator_ctor(INTERNAL_FUNCTION_PARAMETERS)
COLLATOR_METHOD_FETCH_OBJECT;
if(locale_len == 0) {
- locale = INTL_G(default_locale);
+ locale = intl_locale_get_default(TSRMLS_C);
}
/* Open ICU collator. */
diff --git a/ext/intl/collator/collator_sort.c b/ext/intl/collator/collator_sort.c
index 0785111c96..04a24f013e 100644
--- a/ext/intl/collator/collator_sort.c
+++ b/ext/intl/collator/collator_sort.c
@@ -78,6 +78,7 @@ static int collator_regular_compare_function(zval *result, zval *op1, zval *op2
intl_errors_set_custom_msg( COLLATOR_ERROR_P( co ),
"Object not initialized", 0 TSRMLS_CC );
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "Object not initialized");
+
}
/* Compare the strings using ICU. */
diff --git a/ext/intl/common/common_date.cpp b/ext/intl/common/common_date.cpp
new file mode 100644
index 0000000000..ee998818d9
--- /dev/null
+++ b/ext/intl/common/common_date.cpp
@@ -0,0 +1,250 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+#include "../intl_cppshims.h"
+
+#include <unicode/calendar.h>
+
+extern "C" {
+#include "../php_intl.h"
+#define USE_CALENDAR_POINTER 1
+#include "../calendar/calendar_class.h"
+#include <ext/date/php_date.h>
+}
+
+#ifndef INFINITY
+#define INFINITY (DBL_MAX+DBL_MAX)
+#endif
+
+#ifndef NAN
+#define NAN (INFINITY-INFINITY)
+#endif
+
+/* {{{ timezone_convert_datetimezone
+ * The timezone in DateTime and DateTimeZone is not unified. */
+U_CFUNC TimeZone *timezone_convert_datetimezone(int type,
+ void *object,
+ int is_datetime,
+ intl_error *outside_error,
+ const char *func TSRMLS_DC)
+{
+ char *id = NULL,
+ offset_id[] = "GMT+00:00";
+ int id_len = 0;
+ char *message;
+ TimeZone *timeZone;
+
+ switch (type) {
+ case TIMELIB_ZONETYPE_ID:
+ id = is_datetime
+ ? ((php_date_obj*)object)->time->tz_info->name
+ : ((php_timezone_obj*)object)->tzi.tz->name;
+ id_len = strlen(id);
+ break;
+ case TIMELIB_ZONETYPE_OFFSET: {
+ int offset_mins = is_datetime
+ ? -((php_date_obj*)object)->time->z
+ : -(int)((php_timezone_obj*)object)->tzi.utc_offset,
+ hours = offset_mins / 60,
+ minutes = offset_mins - hours * 60;
+ minutes *= minutes > 0 ? 1 : -1;
+
+ if (offset_mins <= -24 * 60 || offset_mins >= 24 * 60) {
+ spprintf(&message, 0, "%s: object has an time zone offset "
+ "that's too large", func);
+ intl_errors_set(outside_error, U_ILLEGAL_ARGUMENT_ERROR,
+ message, 1 TSRMLS_CC);
+ efree(message);
+ return NULL;
+ }
+
+ id = offset_id;
+ id_len = slprintf(id, sizeof(offset_id), "GMT%+03d:%02d",
+ hours, minutes);
+ break;
+ }
+ case TIMELIB_ZONETYPE_ABBR:
+ id = is_datetime
+ ? ((php_date_obj*)object)->time->tz_abbr
+ : ((php_timezone_obj*)object)->tzi.z.abbr;
+ id_len = strlen(id);
+ break;
+ }
+
+ UnicodeString s = UnicodeString(id, id_len, US_INV);
+ timeZone = TimeZone::createTimeZone(s);
+#if U_ICU_VERSION_MAJOR_NUM >= 49
+ if (*timeZone == TimeZone::getUnknown()) {
+#else
+ UnicodeString resultingId;
+ timeZone->getID(resultingId);
+ if (resultingId == UnicodeString("Etc/Unknown", -1, US_INV)
+ || resultingId == UnicodeString("GMT", -1, US_INV)) {
+#endif
+ spprintf(&message, 0, "%s: time zone id '%s' "
+ "extracted from ext/date DateTimeZone not recognized", func, id);
+ intl_errors_set(outside_error, U_ILLEGAL_ARGUMENT_ERROR,
+ message, 1 TSRMLS_CC);
+ efree(message);
+ delete timeZone;
+ return NULL;
+ }
+ return timeZone;
+}
+/* }}} */
+
+U_CFUNC int intl_datetime_decompose(zval *z, double *millis, TimeZone **tz,
+ intl_error *err, const char *func TSRMLS_DC)
+{
+ zval retval;
+ zval *zfuncname;
+ char *message;
+
+ if (err && U_FAILURE(err->code)) {
+ return FAILURE;
+ }
+
+ if (millis) {
+ *millis = NAN;
+ }
+ if (tz) {
+ *tz = NULL;
+ }
+
+ if (millis) {
+ INIT_ZVAL(retval);
+ MAKE_STD_ZVAL(zfuncname);
+ ZVAL_STRING(zfuncname, "getTimestamp", 1);
+ if (call_user_function(NULL, &(z), zfuncname, &retval, 0, NULL TSRMLS_CC)
+ != SUCCESS || Z_TYPE(retval) != IS_LONG) {
+ spprintf(&message, 0, "%s: error calling ::getTimeStamp() on the "
+ "object", func);
+ intl_errors_set(err, U_INTERNAL_PROGRAM_ERROR,
+ message, 1 TSRMLS_CC);
+ efree(message);
+ zval_ptr_dtor(&zfuncname);
+ return FAILURE;
+ }
+
+ *millis = U_MILLIS_PER_SECOND * (double)Z_LVAL(retval);
+ zval_ptr_dtor(&zfuncname);
+ }
+
+ if (tz) {
+ php_date_obj *datetime;
+ datetime = (php_date_obj*)zend_object_store_get_object(z TSRMLS_CC);
+ if (!datetime->time) {
+ spprintf(&message, 0, "%s: the DateTime object is not properly "
+ "initialized", func);
+ intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR,
+ message, 1 TSRMLS_CC);
+ efree(message);
+ return FAILURE;
+ }
+ if (!datetime->time->is_localtime) {
+ *tz = TimeZone::getGMT()->clone();
+ } else {
+ *tz = timezone_convert_datetimezone(datetime->time->zone_type,
+ datetime, 1, NULL, func TSRMLS_CC);
+ if (*tz == NULL) {
+ spprintf(&message, 0, "%s: could not convert DateTime's "
+ "time zone", func);
+ intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR,
+ message, 1 TSRMLS_CC);
+ efree(message);
+ return FAILURE;
+ }
+ }
+ }
+
+ return SUCCESS;
+}
+
+U_CFUNC double intl_zval_to_millis(zval *z, intl_error *err, const char *func TSRMLS_DC)
+{
+ double rv = NAN;
+ long lv;
+ int type;
+ char *message;
+
+ if (err && U_FAILURE(err->code)) {
+ return NAN;
+ }
+
+ switch (Z_TYPE_P(z)) {
+ case IS_STRING:
+ type = is_numeric_string(Z_STRVAL_P(z), Z_STRLEN_P(z), &lv, &rv, 0);
+ if (type == IS_DOUBLE) {
+ rv *= U_MILLIS_PER_SECOND;
+ } else if (type == IS_LONG) {
+ rv = U_MILLIS_PER_SECOND * (double)lv;
+ } else {
+ spprintf(&message, 0, "%s: string '%s' is not numeric, "
+ "which would be required for it to be a valid date", func,
+ Z_STRVAL_P(z));
+ intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR,
+ message, 1 TSRMLS_CC);
+ efree(message);
+ }
+ break;
+ case IS_LONG:
+ rv = U_MILLIS_PER_SECOND * (double)Z_LVAL_P(z);
+ break;
+ case IS_DOUBLE:
+ rv = U_MILLIS_PER_SECOND * Z_DVAL_P(z);
+ break;
+ case IS_OBJECT:
+ if (instanceof_function(Z_OBJCE_P(z), php_date_get_date_ce() TSRMLS_CC)) {
+ intl_datetime_decompose(z, &rv, NULL, err, func TSRMLS_CC);
+ } else if (instanceof_function(Z_OBJCE_P(z), Calendar_ce_ptr TSRMLS_CC)) {
+ Calendar_object *co = (Calendar_object *)
+ zend_object_store_get_object(z TSRMLS_CC );
+ if (co->ucal == NULL) {
+ spprintf(&message, 0, "%s: IntlCalendar object is not properly "
+ "constructed", func);
+ intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR,
+ message, 1 TSRMLS_CC);
+ efree(message);
+ } else {
+ UErrorCode status = UErrorCode();
+ rv = (double)co->ucal->getTime(status);
+ if (U_FAILURE(status)) {
+ spprintf(&message, 0, "%s: call to internal "
+ "Calendar::getTime() has failed", func);
+ intl_errors_set(err, status, message, 1 TSRMLS_CC);
+ efree(message);
+ }
+ }
+ } else {
+ /* TODO: try with cast(), get() to obtain a number */
+ spprintf(&message, 0, "%s: invalid object type for date/time "
+ "(only IntlCalendar and DateTime permitted)", func);
+ intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR,
+ message, 1 TSRMLS_CC);
+ efree(message);
+ }
+ break;
+ default:
+ spprintf(&message, 0, "%s: invalid PHP type for date", func);
+ intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR,
+ message, 1 TSRMLS_CC);
+ efree(message);
+ break;
+ }
+
+ return rv;
+}
+
diff --git a/ext/intl/common/common_date.h b/ext/intl/common/common_date.h
new file mode 100644
index 0000000000..d2396cbf5a
--- /dev/null
+++ b/ext/intl/common/common_date.h
@@ -0,0 +1,40 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef COMMON_DATE_H
+#define COMMON_DATE_H
+
+#include <unicode/umachine.h>
+
+U_CDECL_BEGIN
+#include <php.h>
+#include "../intl_error.h"
+U_CDECL_END
+
+#ifdef __cplusplus
+
+#include <unicode/timezone.h>
+
+U_CFUNC TimeZone *timezone_convert_datetimezone(int type, void *object, int is_datetime, intl_error *outside_error, const char *func TSRMLS_DC);
+U_CFUNC int intl_datetime_decompose(zval *z, double *millis, TimeZone **tz,
+ intl_error *err, const char *func TSRMLS_DC);
+
+#endif
+
+U_CFUNC double intl_zval_to_millis(zval *z, intl_error *err, const char *func TSRMLS_DC);
+
+#endif /* COMMON_DATE_H */
+
diff --git a/ext/intl/common/common_enum.cpp b/ext/intl/common/common_enum.cpp
new file mode 100644
index 0000000000..3ba7855827
--- /dev/null
+++ b/ext/intl/common/common_enum.cpp
@@ -0,0 +1,342 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "../intl_cppshims.h"
+
+// Fix build on Windows/old versions of ICU
+#include <stdio.h>
+
+#include "common_enum.h"
+
+extern "C" {
+#include <zend_interfaces.h>
+#include <zend_exceptions.h>
+}
+
+zend_class_entry *IntlIterator_ce_ptr;
+zend_object_handlers IntlIterator_handlers;
+
+void zoi_with_current_dtor(zend_object_iterator *iter TSRMLS_DC)
+{
+ zoi_with_current *zoiwc = (zoi_with_current*)iter;
+
+ if (zoiwc->wrapping_obj) {
+ /* we have to copy the pointer because zoiwc->wrapping_obj may be
+ * changed midway the execution of zval_ptr_dtor() */
+ zval *zwo = zoiwc->wrapping_obj;
+
+ /* object is still here, we can rely on it to call this again and
+ * destroy this object */
+ zval_ptr_dtor(&zwo);
+ } else {
+ /* Object not here anymore (we've been called by the object free handler)
+ * Note that the iterator wrapper objects (that also depend on this
+ * structure) call this function earlier, in the destruction phase, which
+ * precedes the object free phase. Therefore there's no risk on this
+ * function being called by the iterator wrapper destructor function and
+ * not finding the memory of this iterator allocated anymore. */
+ iter->funcs->invalidate_current(iter TSRMLS_CC);
+ zoiwc->destroy_it(iter TSRMLS_CC);
+ efree(iter);
+ }
+}
+
+U_CFUNC int zoi_with_current_valid(zend_object_iterator *iter TSRMLS_DC)
+{
+ return ((zoi_with_current*)iter)->current != NULL ? SUCCESS : FAILURE;
+}
+
+U_CFUNC void zoi_with_current_get_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC)
+{
+ *data = &((zoi_with_current*)iter)->current;
+}
+
+U_CFUNC void zoi_with_current_invalidate_current(zend_object_iterator *iter TSRMLS_DC)
+{
+ zoi_with_current *zoi_iter = (zoi_with_current*)iter;
+ if (zoi_iter->current) {
+ zval_ptr_dtor(&zoi_iter->current);
+ zoi_iter->current = NULL; //valid would return FAILURE now
+ }
+}
+
+static void string_enum_current_move_forward(zend_object_iterator *iter TSRMLS_DC)
+{
+ zoi_with_current *zoi_iter = (zoi_with_current*)iter;
+ INTLITERATOR_METHOD_INIT_VARS;
+
+ iter->funcs->invalidate_current(iter TSRMLS_CC);
+
+ object = zoi_iter->wrapping_obj;
+ INTLITERATOR_METHOD_FETCH_OBJECT_NO_CHECK;
+
+ int32_t result_length;
+ const char *result = ((StringEnumeration*)iter->data)->next(
+ &result_length, INTLITERATOR_ERROR_CODE(ii));
+
+ intl_error_set_code(NULL, INTLITERATOR_ERROR_CODE(ii) TSRMLS_CC);
+ if (U_FAILURE(INTLITERATOR_ERROR_CODE(ii))) {
+ intl_errors_set_custom_msg(INTL_DATA_ERROR_P(ii),
+ "Error fetching next iteration element", 0 TSRMLS_CC);
+ } else if (result) {
+ MAKE_STD_ZVAL(zoi_iter->current);
+ ZVAL_STRINGL(zoi_iter->current, result, result_length, 1);
+ } //else we've reached the end of the enum, nothing more is required
+}
+
+static void string_enum_rewind(zend_object_iterator *iter TSRMLS_DC)
+{
+ zoi_with_current *zoi_iter = (zoi_with_current*)iter;
+ INTLITERATOR_METHOD_INIT_VARS;
+
+ if (zoi_iter->current) {
+ iter->funcs->invalidate_current(iter TSRMLS_CC);
+ }
+
+ object = zoi_iter->wrapping_obj;
+ INTLITERATOR_METHOD_FETCH_OBJECT_NO_CHECK;
+
+ ((StringEnumeration*)iter->data)->reset(INTLITERATOR_ERROR_CODE(ii));
+
+ intl_error_set_code(NULL, INTLITERATOR_ERROR_CODE(ii) TSRMLS_CC);
+ if (U_FAILURE(INTLITERATOR_ERROR_CODE(ii))) {
+ intl_errors_set_custom_msg(INTL_DATA_ERROR_P(ii),
+ "Error resetting enumeration", 0 TSRMLS_CC);
+ } else {
+ iter->funcs->move_forward(iter TSRMLS_CC);
+ }
+}
+
+static void string_enum_destroy_it(zend_object_iterator *iter TSRMLS_DC)
+{
+ delete (StringEnumeration*)iter->data;
+}
+
+static zend_object_iterator_funcs string_enum_object_iterator_funcs = {
+ zoi_with_current_dtor,
+ zoi_with_current_valid,
+ zoi_with_current_get_current_data,
+ NULL,
+ string_enum_current_move_forward,
+ string_enum_rewind,
+ zoi_with_current_invalidate_current
+};
+
+U_CFUNC void IntlIterator_from_StringEnumeration(StringEnumeration *se, zval *object TSRMLS_DC)
+{
+ IntlIterator_object *ii;
+ object_init_ex(object, IntlIterator_ce_ptr);
+ ii = (IntlIterator_object*)zend_object_store_get_object(object TSRMLS_CC);
+ ii->iterator = (zend_object_iterator*)emalloc(sizeof(zoi_with_current));
+ ii->iterator->data = (void*)se;
+ ii->iterator->funcs = &string_enum_object_iterator_funcs;
+ ii->iterator->index = 0;
+ ((zoi_with_current*)ii->iterator)->destroy_it = string_enum_destroy_it;
+ ((zoi_with_current*)ii->iterator)->wrapping_obj = object;
+ ((zoi_with_current*)ii->iterator)->current = NULL;
+}
+
+static void IntlIterator_objects_free(zend_object *object TSRMLS_DC)
+{
+ IntlIterator_object *ii = (IntlIterator_object*) object;
+
+ if (ii->iterator) {
+ zval **wrapping_objp = &((zoi_with_current*)ii->iterator)->wrapping_obj;
+ *wrapping_objp = NULL;
+ ii->iterator->funcs->dtor(ii->iterator TSRMLS_CC);
+ }
+ intl_error_reset(INTLITERATOR_ERROR_P(ii) TSRMLS_CC);
+
+ zend_object_std_dtor(&ii->zo TSRMLS_CC);
+
+ efree(ii);
+}
+
+static zend_object_iterator *IntlIterator_get_iterator(
+ zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
+{
+ if (by_ref) {
+ zend_throw_exception(NULL,
+ "Iteration by reference is not supported", 0 TSRMLS_CC);
+ return NULL;
+ }
+
+ IntlIterator_object *ii = (IntlIterator_object*)
+ zend_object_store_get_object(object TSRMLS_CC);
+
+ if (ii->iterator == NULL) {
+ zend_throw_exception(NULL,
+ "The IntlIterator is not properly constructed", 0 TSRMLS_CC);
+ return NULL;
+ }
+
+ zval_add_ref(&object);
+
+ return ii->iterator;
+}
+
+static zend_object_value IntlIterator_object_create(zend_class_entry *ce TSRMLS_DC)
+{
+ zend_object_value retval;
+ IntlIterator_object *intern;
+
+ intern = (IntlIterator_object*)ecalloc(1, sizeof(IntlIterator_object));
+
+ zend_object_std_init(&intern->zo, ce TSRMLS_CC);
+#if PHP_VERSION_ID < 50399
+ zend_hash_copy(intern->zo.properties, &(ce->default_properties),
+ (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval*));
+#else
+ object_properties_init((zend_object*) intern, ce);
+#endif
+ intl_error_init(INTLITERATOR_ERROR_P(intern) TSRMLS_CC);
+ intern->iterator = NULL;
+
+ retval.handle = zend_objects_store_put(
+ intern,
+ (zend_objects_store_dtor_t)zend_objects_destroy_object,
+ (zend_objects_free_object_storage_t)IntlIterator_objects_free,
+ NULL TSRMLS_CC);
+
+ retval.handlers = &IntlIterator_handlers;
+
+ return retval;
+}
+
+static PHP_METHOD(IntlIterator, current)
+{
+ zval **data;
+ INTLITERATOR_METHOD_INIT_VARS;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "IntlIterator::current: bad arguments", 0 TSRMLS_CC);
+ return;
+ }
+
+ INTLITERATOR_METHOD_FETCH_OBJECT;
+ ii->iterator->funcs->get_current_data(ii->iterator, &data TSRMLS_CC);
+ if (data && *data) {
+ RETURN_ZVAL(*data, 1, 0);
+ }
+}
+
+static PHP_METHOD(IntlIterator, key)
+{
+ INTLITERATOR_METHOD_INIT_VARS;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "IntlIterator::key: bad arguments", 0 TSRMLS_CC);
+ return;
+ }
+
+ INTLITERATOR_METHOD_FETCH_OBJECT;
+
+ if (ii->iterator->funcs->get_current_key) {
+ ii->iterator->funcs->get_current_key(ii->iterator, return_value TSRMLS_CC);
+ } else {
+ RETURN_LONG(ii->iterator->index);
+ }
+}
+
+static PHP_METHOD(IntlIterator, next)
+{
+ INTLITERATOR_METHOD_INIT_VARS;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "IntlIterator::next: bad arguments", 0 TSRMLS_CC);
+ return;
+ }
+
+ INTLITERATOR_METHOD_FETCH_OBJECT;
+ ii->iterator->funcs->move_forward(ii->iterator TSRMLS_CC);
+ /* foreach also advances the index after the last iteration,
+ * so I see no problem in incrementing the index here unconditionally */
+ ii->iterator->index++;
+}
+
+static PHP_METHOD(IntlIterator, rewind)
+{
+ INTLITERATOR_METHOD_INIT_VARS;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "IntlIterator::rewind: bad arguments", 0 TSRMLS_CC);
+ return;
+ }
+
+ INTLITERATOR_METHOD_FETCH_OBJECT;
+ if (ii->iterator->funcs->rewind) {
+ ii->iterator->funcs->rewind(ii->iterator TSRMLS_CC);
+ } else {
+ intl_errors_set(INTLITERATOR_ERROR_P(ii), U_UNSUPPORTED_ERROR,
+ "IntlIterator::rewind: rewind not supported", 0 TSRMLS_CC);
+ }
+}
+
+static PHP_METHOD(IntlIterator, valid)
+{
+ INTLITERATOR_METHOD_INIT_VARS;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "IntlIterator::valid: bad arguments", 0 TSRMLS_CC);
+ return;
+ }
+
+ INTLITERATOR_METHOD_FETCH_OBJECT;
+ RETURN_BOOL(ii->iterator->funcs->valid(ii->iterator TSRMLS_CC) == SUCCESS);
+}
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_se_void, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+static zend_function_entry IntlIterator_class_functions[] = {
+ PHP_ME(IntlIterator, current, ainfo_se_void, ZEND_ACC_PUBLIC)
+ PHP_ME(IntlIterator, key, ainfo_se_void, ZEND_ACC_PUBLIC)
+ PHP_ME(IntlIterator, next, ainfo_se_void, ZEND_ACC_PUBLIC)
+ PHP_ME(IntlIterator, rewind, ainfo_se_void, ZEND_ACC_PUBLIC)
+ PHP_ME(IntlIterator, valid, ainfo_se_void, ZEND_ACC_PUBLIC)
+ PHP_FE_END
+};
+
+
+/* {{{ intl_register_IntlIterator_class
+ * Initialize 'IntlIterator' class
+ */
+U_CFUNC void intl_register_IntlIterator_class(TSRMLS_D)
+{
+ zend_class_entry ce;
+
+ /* Create and register 'IntlIterator' class. */
+ INIT_CLASS_ENTRY(ce, "IntlIterator", IntlIterator_class_functions);
+ ce.create_object = IntlIterator_object_create;
+ IntlIterator_ce_ptr = zend_register_internal_class(&ce TSRMLS_CC);
+ IntlIterator_ce_ptr->get_iterator = IntlIterator_get_iterator;
+ zend_class_implements(IntlIterator_ce_ptr TSRMLS_CC, 1,
+ zend_ce_iterator);
+
+ memcpy(&IntlIterator_handlers, zend_get_std_object_handlers(),
+ sizeof IntlIterator_handlers);
+ IntlIterator_handlers.clone_obj = NULL;
+
+}
diff --git a/ext/intl/common/common_enum.h b/ext/intl/common/common_enum.h
new file mode 100644
index 0000000000..4c6abdb8f5
--- /dev/null
+++ b/ext/intl/common/common_enum.h
@@ -0,0 +1,77 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Vadim Savchuk <vsavchuk@productengine.com> |
+ | Dmitry Lakhtyuk <dlakhtyuk@productengine.com> |
+ +----------------------------------------------------------------------+
+ */
+
+#ifndef INTL_COMMON_ENUM_H
+#define INTL_COMMON_ENUM_H
+
+#include <unicode/umachine.h>
+#ifdef __cplusplus
+#include <unicode/strenum.h>
+extern "C" {
+#include <math.h>
+#endif
+#include <php.h>
+#include "../intl_error.h"
+#include "../intl_data.h"
+#ifdef __cplusplus
+}
+#endif
+
+#define INTLITERATOR_ERROR(ii) (ii)->err
+#define INTLITERATOR_ERROR_P(ii) &(INTLITERATOR_ERROR(ii))
+
+#define INTLITERATOR_ERROR_CODE(ii) INTL_ERROR_CODE(INTLITERATOR_ERROR(ii))
+#define INTLITERATOR_ERROR_CODE_P(ii) &(INTL_ERROR_CODE(INTLITERATOR_ERROR(ii)))
+
+#define INTLITERATOR_METHOD_INIT_VARS INTL_METHOD_INIT_VARS(IntlIterator, ii)
+#define INTLITERATOR_METHOD_FETCH_OBJECT_NO_CHECK INTL_METHOD_FETCH_OBJECT(IntlIterator, ii)
+#define INTLITERATOR_METHOD_FETCH_OBJECT\
+ object = getThis(); \
+ INTLITERATOR_METHOD_FETCH_OBJECT_NO_CHECK; \
+ if (ii->iterator == NULL) { \
+ intl_errors_set(&ii->err, U_ILLEGAL_ARGUMENT_ERROR, "Found unconstructed IntlIterator", 0 TSRMLS_CC); \
+ RETURN_FALSE; \
+ }
+
+typedef struct {
+ zend_object zo;
+ intl_error err;
+ zend_object_iterator *iterator;
+} IntlIterator_object;
+
+typedef struct {
+ zend_object_iterator zoi;
+ zval *current;
+ zval *wrapping_obj;
+ void (*destroy_it)(zend_object_iterator *iterator TSRMLS_DC);
+} zoi_with_current;
+
+extern zend_class_entry *IntlIterator_ce_ptr;
+extern zend_object_handlers IntlIterator_handlers;
+
+U_CFUNC void zoi_with_current_dtor(zend_object_iterator *iter TSRMLS_DC);
+U_CFUNC int zoi_with_current_valid(zend_object_iterator *iter TSRMLS_DC);
+U_CFUNC void zoi_with_current_get_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC);
+U_CFUNC void zoi_with_current_invalidate_current(zend_object_iterator *iter TSRMLS_DC);
+
+#ifdef __cplusplus
+U_CFUNC void IntlIterator_from_StringEnumeration(StringEnumeration *se, zval *object TSRMLS_DC);
+#endif
+
+U_CFUNC void intl_register_IntlIterator_class(TSRMLS_D);
+
+#endif // INTL_COMMON_ENUM_H
diff --git a/ext/intl/common/common_error.c b/ext/intl/common/common_error.c
index 282172224c..a0ee7c145f 100644
--- a/ext/intl/common/common_error.c
+++ b/ext/intl/common/common_error.c
@@ -240,9 +240,7 @@ void intl_expose_icu_error_codes( INIT_FUNC_ARGS )
INTL_EXPOSE_CONST( U_IDNA_ACE_PREFIX_ERROR );
INTL_EXPOSE_CONST( U_IDNA_VERIFICATION_ERROR );
INTL_EXPOSE_CONST( U_IDNA_LABEL_TOO_LONG_ERROR );
-#if U_ICU_VERSION_MAJOR_NUM > 3 || U_ICU_VERSION_MAJOR_NUM == 3 && U_ICU_VERSION_MINOR_NUM >= 6
INTL_EXPOSE_CONST( U_IDNA_ZERO_LENGTH_LABEL_ERROR );
-#endif
#if U_ICU_VERSION_MAJOR_NUM > 3 || U_ICU_VERSION_MAJOR_NUM == 3 && U_ICU_VERSION_MINOR_NUM >= 8
INTL_EXPOSE_CONST( U_IDNA_DOMAIN_NAME_TOO_LONG_ERROR );
#endif
diff --git a/ext/intl/config.m4 b/ext/intl/config.m4
index 0477c7f59d..4630a302ef 100644
--- a/ext/intl/config.m4
+++ b/ext/intl/config.m4
@@ -20,6 +20,7 @@ if test "$PHP_INTL" != "no"; then
PHP_NEW_EXTENSION(intl, php_intl.c \
intl_error.c \
intl_convert.c \
+ intl_convertcpp.cpp \
collator/collator.c \
collator/collator_class.c \
collator/collator_sort.c \
@@ -31,6 +32,9 @@ if test "$PHP_INTL" != "no"; then
collator/collator_is_numeric.c \
collator/collator_error.c \
common/common_error.c \
+ common/common_enum.cpp \
+ common/common_date.cpp \
+ converter/converter.c \
formatter/formatter.c \
formatter/formatter_main.c \
formatter/formatter_class.c \
@@ -49,7 +53,11 @@ if test "$PHP_INTL" != "no"; then
dateformat/dateformat_attr.c \
dateformat/dateformat_data.c \
dateformat/dateformat_format.c \
+ dateformat/dateformat_format_object.cpp \
dateformat/dateformat_parse.c \
+ dateformat/dateformat_create.cpp \
+ dateformat/dateformat_attrcpp.cpp \
+ dateformat/dateformat_helpers.cpp \
msgformat/msgformat.c \
msgformat/msgformat_attr.c \
msgformat/msgformat_class.c \
@@ -65,9 +73,21 @@ if test "$PHP_INTL" != "no"; then
transliterator/transliterator.c \
transliterator/transliterator_class.c \
transliterator/transliterator_methods.c \
+ timezone/timezone_class.cpp \
+ timezone/timezone_methods.cpp \
+ calendar/calendar_class.cpp \
+ calendar/calendar_methods.cpp \
+ calendar/gregoriancalendar_methods.cpp \
+ breakiterator/breakiterator_class.cpp \
+ breakiterator/breakiterator_iterators.cpp \
+ breakiterator/breakiterator_methods.cpp \
+ breakiterator/rulebasedbreakiterator_methods.cpp \
+ breakiterator/codepointiterator_internal.cpp \
+ breakiterator/codepointiterator_methods.cpp \
idn/idn.c \
- $icu_spoof_src, $ext_shared,,$ICU_INCS)
+ $icu_spoof_src, $ext_shared,,$ICU_INCS -Wno-write-strings)
PHP_ADD_BUILD_DIR($ext_builddir/collator)
+ PHP_ADD_BUILD_DIR($ext_builddir/converter)
PHP_ADD_BUILD_DIR($ext_builddir/common)
PHP_ADD_BUILD_DIR($ext_builddir/formatter)
PHP_ADD_BUILD_DIR($ext_builddir/normalizer)
@@ -77,6 +97,9 @@ if test "$PHP_INTL" != "no"; then
PHP_ADD_BUILD_DIR($ext_builddir/grapheme)
PHP_ADD_BUILD_DIR($ext_builddir/resourcebundle)
PHP_ADD_BUILD_DIR($ext_builddir/transliterator)
+ PHP_ADD_BUILD_DIR($ext_builddir/timezone)
+ PHP_ADD_BUILD_DIR($ext_builddir/calendar)
PHP_ADD_BUILD_DIR($ext_builddir/idn)
PHP_ADD_BUILD_DIR($ext_builddir/spoofchecker)
+ PHP_ADD_BUILD_DIR($ext_builddir/breakiterator)
fi
diff --git a/ext/intl/config.w32 b/ext/intl/config.w32
index 437fedb7d3..22cde6bd6d 100644
--- a/ext/intl/config.w32
+++ b/ext/intl/config.w32
@@ -7,7 +7,7 @@ if (PHP_INTL != "no") {
if (CHECK_LIB("icuuc.lib", "intl", PHP_INTL) &&
CHECK_HEADER_ADD_INCLUDE("unicode/utf.h", "CFLAGS_INTL")) {
// always build as shared - zend_strtod.c/ICU type conflict
- EXTENSION("intl", "php_intl.c intl_convert.c intl_error.c ", true,
+ EXTENSION("intl", "php_intl.c intl_convert.c intl_convertcpp.cpp intl_error.c ", true,
"/I \"" + configure_module_dirname + "\"");
ADD_SOURCES(configure_module_dirname + "/collator", "\
collator.c \
@@ -23,6 +23,11 @@ if (PHP_INTL != "no") {
", "intl");
ADD_SOURCES(configure_module_dirname + "/common", "\
common_error.c \
+ common_enum.cpp \
+ common_date.cpp \
+ ", "intl");
+ ADD_SOURCES(configure_module_dirname + "/converter", "\
+ converter.c \
", "intl");
ADD_SOURCES(configure_module_dirname + "/formatter", "\
formatter.c \
@@ -60,8 +65,12 @@ if (PHP_INTL != "no") {
dateformat_class.c \
dateformat_attr.c \
dateformat_format.c \
+ dateformat_format_object.cpp \
dateformat_parse.c \
dateformat_data.c \
+ dateformat_attrcpp.cpp \
+ dateformat_helpers.cpp \
+ dateformat_create.cpp \
", "intl");
ADD_SOURCES(configure_module_dirname + "/idn", "\
idn.c",
@@ -87,7 +96,29 @@ if (PHP_INTL != "no") {
transliterator_class.c \
transliterator_methods.c",
"intl");
+
+ ADD_SOURCES(configure_module_dirname + "/timezone", "\
+ timezone_class.cpp \
+ timezone_methods.cpp",
+ "intl");
+
+ ADD_SOURCES(configure_module_dirname + "/calendar", "\
+ calendar_methods.cpp \
+ gregoriancalendar_methods.cpp \
+ calendar_class.cpp",
+ "intl");
+
+ ADD_SOURCES(configure_module_dirname + "/breakiterator", "\
+ breakiterator_class.cpp \
+ breakiterator_methods.cpp \
+ breakiterator_iterators.cpp \
+ rulebasedbreakiterator_methods.cpp \
+ codepointiterator_internal.cpp \
+ codepointiterator_methods.cpp ",
+ "intl");
+
ADD_FLAG("LIBS_INTL", "icudt.lib icuin.lib icuio.lib icule.lib iculx.lib");
+ ADD_FLAG("CFLAGS_INTL", "/EHsc");
AC_DEFINE("HAVE_INTL", 1, "Internationalization support enabled");
} else {
WARNING("intl not enabled; libraries and/or headers not found");
diff --git a/ext/intl/converter/converter.c b/ext/intl/converter/converter.c
new file mode 100644
index 0000000000..5f2d1e7fa7
--- /dev/null
+++ b/ext/intl/converter/converter.c
@@ -0,0 +1,1173 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Sara Golemon <pollita@php.net> |
+ +----------------------------------------------------------------------+
+ */
+
+#include "converter.h"
+#include "zend_exceptions.h"
+
+#include <unicode/utypes.h>
+#include <unicode/ucnv.h>
+#include <unicode/ustring.h>
+
+#include "../intl_error.h"
+
+typedef struct _php_converter_object {
+ zend_object obj;
+#ifdef ZTS
+ void ***tsrm_ls;
+#endif
+ UConverter *src, *dest;
+ zend_fcall_info to_cb, from_cb;
+ zend_fcall_info_cache to_cache, from_cache;
+ intl_error error;
+} php_converter_object;
+
+static zend_class_entry *php_converter_ce;
+static zend_object_handlers php_converter_object_handlers;
+
+#define CONV_GET(pzv) ((php_converter_object*)zend_objects_get_address((pzv) TSRMLS_CC))
+#define THROW_UFAILURE(obj, fname, error) php_converter_throw_failure(obj, error TSRMLS_CC, \
+ fname "() returned error %ld: %s", (long)error, u_errorName(error))
+
+/* {{{ php_converter_throw_failure */
+static inline void php_converter_throw_failure(php_converter_object *objval, UErrorCode error TSRMLS_DC, const char *format, ...) {
+ intl_error *err = objval ? &(objval->error) : NULL;
+ char message[1024];
+ va_list vargs;
+
+ va_start(vargs, format);
+ vsnprintf(message, sizeof(message), format, vargs);
+ va_end(vargs);
+
+ intl_errors_set(err, error, message, 1 TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ php_converter_default_callback */
+static void php_converter_default_callback(zval *return_value, zval *zobj, long reason, zval *error TSRMLS_DC) {
+ /* Basic functionality so children can call parent::toUCallback() */
+ switch (reason) {
+ case UCNV_UNASSIGNED:
+ case UCNV_ILLEGAL:
+ case UCNV_IRREGULAR:
+ {
+ php_converter_object *objval = (php_converter_object*)CONV_GET(zobj);
+ char chars[127];
+ int8_t chars_len = sizeof(chars);
+ UErrorCode error = U_ZERO_ERROR;
+
+ /* Yes, this is fairly wasteful at first glance,
+ * but considering that the alternative is to store
+ * what's sent into setSubstChars() and the fact
+ * that this is an extremely unlikely codepath
+ * I'd rather take the CPU hit here, than waste time
+ * storing a value I'm unlikely to use.
+ */
+ ucnv_getSubstChars(objval->src, chars, &chars_len, &error);
+ if (U_FAILURE(error)) {
+ THROW_UFAILURE(objval, "ucnv_getSubstChars", error);
+ chars[0] = 0x1A;
+ chars[1] = 0;
+ chars_len = 1;
+ }
+ RETVAL_STRINGL(chars, chars_len, 1);
+ }
+ }
+ zval_dtor(error);
+ ZVAL_LONG(error, U_ZERO_ERROR);
+}
+/* }}} */
+
+/* {{{ proto void UConverter::toUCallback(long $reason,
+ string $source, string $codeUnits,
+ long &$error) */
+ZEND_BEGIN_ARG_INFO_EX(php_converter_toUCallback_arginfo, 0, ZEND_RETURN_VALUE, 4)
+ ZEND_ARG_INFO(0, reason)
+ ZEND_ARG_INFO(0, source)
+ ZEND_ARG_INFO(0, codeUnits)
+ ZEND_ARG_INFO(1, error)
+ZEND_END_ARG_INFO();
+static PHP_METHOD(UConverter, toUCallback) {
+ long reason;
+ zval *source, *codeUnits, *error;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lzzz",
+ &reason, &source, &codeUnits, &error) == FAILURE) {
+ return;
+ }
+
+ php_converter_default_callback(return_value, getThis(), reason, error TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto void UConverter::fromUCallback(long $reason,
+ Array $source, long $codePoint,
+ long &$error) */
+ZEND_BEGIN_ARG_INFO_EX(php_converter_fromUCallback_arginfo, 0, ZEND_RETURN_VALUE, 4)
+ ZEND_ARG_INFO(0, reason)
+ ZEND_ARG_INFO(0, source)
+ ZEND_ARG_INFO(0, codePoint)
+ ZEND_ARG_INFO(1, error)
+ZEND_END_ARG_INFO();
+static PHP_METHOD(UConverter, fromUCallback) {
+ long reason;
+ zval *source, *codePoint, *error;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lzzz",
+ &reason, &source, &codePoint, &error) == FAILURE) {
+ return;
+ }
+
+ php_converter_default_callback(return_value, getThis(), reason, error TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ php_converter_check_limits */
+static inline zend_bool php_converter_check_limits(php_converter_object *objval, long available, long needed TSRMLS_DC) {
+ if (available < needed) {
+ php_converter_throw_failure(objval, U_BUFFER_OVERFLOW_ERROR TSRMLS_CC, "Buffer overrun %ld bytes needed, %ld available", needed, available);
+ return 0;
+ }
+ return 1;
+}
+/* }}} */
+
+#define TARGET_CHECK(cnvargs, needed) php_converter_check_limits(objval, cnvargs->targetLimit - cnvargs->target, needed TSRMLS_CC)
+
+/* {{{ php_converter_append_toUnicode_target */
+static void php_converter_append_toUnicode_target(zval *val, UConverterToUnicodeArgs *args, php_converter_object *objval TSRMLS_DC) {
+ switch (Z_TYPE_P(val)) {
+ case IS_NULL:
+ /* Code unit is being skipped */
+ return;
+ case IS_LONG:
+ {
+ long lval = Z_LVAL_P(val);
+ if ((lval < 0) || (lval > 0x10FFFF)) {
+ php_converter_throw_failure(objval, U_ILLEGAL_ARGUMENT_ERROR TSRMLS_CC, "Invalid codepoint U+%04lx", lval);
+ return;
+ }
+ if (lval > 0xFFFF) {
+ /* Supplemental planes U+010000 - U+10FFFF */
+ if (TARGET_CHECK(args, 2)) {
+ /* TODO: Find the ICU call which does this properly */
+ *(args->target++) = (UChar)(((lval - 0x10000) >> 10) | 0xD800);
+ *(args->target++) = (UChar)(((lval - 0x10000) & 0x3FF) | 0xDC00);
+ }
+ return;
+ }
+ /* Non-suggogate BMP codepoint */
+ if (TARGET_CHECK(args, 1)) {
+ *(args->target++) = (UChar)lval;
+ }
+ return;
+ }
+ case IS_STRING:
+ {
+ const char *strval = Z_STRVAL_P(val);
+ int i = 0, strlen = Z_STRLEN_P(val);
+
+ while((i != strlen) && TARGET_CHECK(args, 1)) {
+ UChar c;
+ U8_NEXT(strval, i, strlen, c);
+ *(args->target++) = c;
+ }
+ return;
+ }
+ case IS_ARRAY:
+ {
+ HashTable *ht = Z_ARRVAL_P(val);
+ HashPosition pos;
+ zval **tmpzval;
+
+ for(zend_hash_internal_pointer_reset_ex(ht, &pos);
+ zend_hash_get_current_data_ex(ht, (void**)&tmpzval, &pos) == SUCCESS;
+ zend_hash_move_forward_ex(ht, &pos)) {
+ php_converter_append_toUnicode_target(*tmpzval, args, objval TSRMLS_CC);
+ }
+ return;
+ }
+ default:
+ php_converter_throw_failure(objval, U_ILLEGAL_ARGUMENT_ERROR TSRMLS_CC,
+ "toUCallback() specified illegal type for substitution character");
+ }
+}
+/* }}} */
+
+/* {{{ php_converter_to_u_callback */
+static void php_converter_to_u_callback(const void *context,
+ UConverterToUnicodeArgs *args,
+ const char *codeUnits, int32_t length,
+ UConverterCallbackReason reason,
+ UErrorCode *pErrorCode) {
+ php_converter_object *objval = (php_converter_object*)context;
+ zval *zreason, *zsource, *zcodeunits, *zerror, *retval = NULL;
+ zval **zargs[4];
+#ifdef ZTS
+ TSRMLS_D = objval->tsrm_ls;
+#endif
+
+ MAKE_STD_ZVAL(zreason);
+ ZVAL_LONG(zreason, reason);
+ zargs[0] = &zreason;
+
+ MAKE_STD_ZVAL(zsource);
+ ZVAL_STRINGL(zsource, args->source, args->sourceLimit - args->source, 1);
+ zargs[1] = &zsource;
+
+ MAKE_STD_ZVAL(zcodeunits);
+ ZVAL_STRINGL(zcodeunits, codeUnits, length, 1);
+ zargs[2] = &zcodeunits;
+
+ MAKE_STD_ZVAL(zerror);
+ ZVAL_LONG(zerror, *pErrorCode);
+ zargs[3] = &zerror;
+
+ objval->to_cb.param_count = 4;
+ objval->to_cb.params = zargs;
+ objval->to_cb.retval_ptr_ptr = &retval;
+ objval->to_cb.no_separation = 0;
+ if (zend_call_function(&(objval->to_cb), &(objval->to_cache) TSRMLS_CC) == FAILURE) {
+ /* Unlikely */
+ php_converter_throw_failure(objval, U_INTERNAL_PROGRAM_ERROR TSRMLS_CC, "Unexpected failure calling toUCallback()");
+ } else if (retval) {
+ php_converter_append_toUnicode_target(retval, args, objval TSRMLS_CC);
+ zval_ptr_dtor(&retval);
+ }
+
+ if (Z_TYPE_P(zerror) == IS_LONG) {
+ *pErrorCode = Z_LVAL_P(zerror);
+ }
+
+ zval_ptr_dtor(&zreason);
+ zval_ptr_dtor(&zsource);
+ zval_ptr_dtor(&zcodeunits);
+ zval_ptr_dtor(&zerror);
+}
+/* }}} */
+
+/* {{{ php_converter_append_fromUnicode_target */
+static void php_converter_append_fromUnicode_target(zval *val, UConverterFromUnicodeArgs *args, php_converter_object *objval TSRMLS_DC) {
+ switch (Z_TYPE_P(val)) {
+ case IS_NULL:
+ /* Ignore */
+ return;
+ case IS_LONG:
+ if (TARGET_CHECK(args, 1)) {
+ *(args->target++) = Z_LVAL_P(val);
+ }
+ return;
+ case IS_STRING:
+ {
+ int vallen = Z_STRLEN_P(val);
+ if (TARGET_CHECK(args, vallen)) {
+ memcpy(args->target, Z_STRVAL_P(val), vallen);
+ args->target += vallen;
+ }
+ return;
+ }
+ case IS_ARRAY:
+ {
+ HashTable *ht = Z_ARRVAL_P(val);
+ HashPosition pos;
+ zval **tmpzval;
+ for(zend_hash_internal_pointer_reset_ex(ht, &pos);
+ zend_hash_get_current_data_ex(ht, (void**)&tmpzval, &pos) == SUCCESS;
+ zend_hash_move_forward_ex(ht, &pos)) {
+ php_converter_append_fromUnicode_target(*tmpzval, args, objval TSRMLS_CC);
+ }
+ return;
+ }
+ default:
+ php_converter_throw_failure(objval, U_ILLEGAL_ARGUMENT_ERROR TSRMLS_CC, "fromUCallback() specified illegal type for substitution character");
+ }
+}
+/* }}} */
+
+/* {{{ php_converter_from_u_callback */
+static void php_converter_from_u_callback(const void *context,
+ UConverterFromUnicodeArgs *args,
+ const UChar *codeUnits, int32_t length, UChar32 codePoint,
+ UConverterCallbackReason reason,
+ UErrorCode *pErrorCode) {
+ php_converter_object *objval = (php_converter_object*)context;
+ zval *zreason, *zsource, *zcodepoint, *zerror, *retval = NULL;
+ zval **zargs[4];
+ int i;
+#ifdef ZTS
+ TSRMLS_D = objval->tsrm_ls;
+#endif
+
+ MAKE_STD_ZVAL(zreason);
+ ZVAL_LONG(zreason, reason);
+ zargs[0] = &zreason;
+
+ MAKE_STD_ZVAL(zsource);
+ array_init(zsource);
+ i = 0;
+ while (i < length) {
+ UChar32 c;
+ U16_NEXT(codeUnits, i, length, c);
+ add_next_index_long(zsource, c);
+ }
+ zargs[1] = &zsource;
+
+ MAKE_STD_ZVAL(zcodepoint);
+ ZVAL_LONG(zcodepoint, codePoint);
+ zargs[2] = &zcodepoint;
+
+ MAKE_STD_ZVAL(zerror);
+ ZVAL_LONG(zerror, *pErrorCode);
+ zargs[3] = &zerror;
+
+ objval->from_cb.param_count = 4;
+ objval->from_cb.params = zargs;
+ objval->from_cb.retval_ptr_ptr = &retval;
+ objval->from_cb.no_separation = 0;
+ if (zend_call_function(&(objval->from_cb), &(objval->from_cache) TSRMLS_CC) == FAILURE) {
+ /* Unlikely */
+ php_converter_throw_failure(objval, U_INTERNAL_PROGRAM_ERROR TSRMLS_CC, "Unexpected failure calling fromUCallback()");
+ } else if (retval) {
+ php_converter_append_fromUnicode_target(retval, args, objval TSRMLS_CC);
+ zval_ptr_dtor(&retval);
+ }
+
+ if (Z_TYPE_P(zerror) == IS_LONG) {
+ *pErrorCode = Z_LVAL_P(zerror);
+ }
+
+ zval_ptr_dtor(&zreason);
+ zval_ptr_dtor(&zsource);
+ zval_ptr_dtor(&zcodepoint);
+ zval_ptr_dtor(&zerror);
+}
+/* }}} */
+
+/* {{{ php_converter_set_callbacks */
+static inline zend_bool php_converter_set_callbacks(php_converter_object *objval, UConverter *cnv TSRMLS_DC) {
+ zend_bool ret = 1;
+ UErrorCode error = U_ZERO_ERROR;
+
+ if (objval->obj.ce == php_converter_ce) {
+ /* Short-circuit having to go through method calls and data marshalling
+ * when we're using default behavior
+ */
+ return 1;
+ }
+
+ ucnv_setToUCallBack(cnv, (UConverterToUCallback)php_converter_to_u_callback, (const void*)objval,
+ NULL, NULL, &error);
+ if (U_FAILURE(error)) {
+ THROW_UFAILURE(objval, "ucnv_setToUCallBack", error);
+ ret = 0;
+ }
+
+ error = U_ZERO_ERROR;
+ ucnv_setFromUCallBack(cnv, (UConverterFromUCallback)php_converter_from_u_callback, (const void*)objval,
+ NULL, NULL, &error);
+ if (U_FAILURE(error)) {
+ THROW_UFAILURE(objval, "ucnv_setFromUCallBack", error);
+ ret = 0;
+ }
+ return ret;
+}
+/* }}} */
+
+/* {{{ php_converter_set_encoding */
+static zend_bool php_converter_set_encoding(php_converter_object *objval,
+ UConverter **pcnv,
+ const char *enc, int enc_len
+ TSRMLS_DC) {
+ UErrorCode error = U_ZERO_ERROR;
+ UConverter *cnv = ucnv_open(enc, &error);
+
+ if (error == U_AMBIGUOUS_ALIAS_WARNING) {
+ UErrorCode getname_error = U_ZERO_ERROR;
+ const char *actual_encoding = ucnv_getName(cnv, &getname_error);
+ if (U_FAILURE(getname_error)) {
+ /* Should never happen */
+ actual_encoding = "(unknown)";
+ }
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Ambiguous encoding specified, using %s", actual_encoding);
+ } else if (U_FAILURE(error)) {
+ if (objval) {
+ THROW_UFAILURE(objval, "ucnv_open", error);
+ } else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error setting encoding: %d - %s", (int)error, u_errorName(error));
+ }
+ return 0;
+ }
+
+ if (objval && !php_converter_set_callbacks(objval, cnv TSRMLS_CC)) {
+ return 0;
+ }
+
+ if (*pcnv) {
+ ucnv_close(*pcnv);
+ }
+ *pcnv = cnv;
+ return 1;
+}
+/* }}} */
+
+/* {{{ php_converter_do_set_encoding */
+ZEND_BEGIN_ARG_INFO_EX(php_converter_set_encoding_arginfo, 0, ZEND_RETURN_VALUE, 1)
+ ZEND_ARG_INFO(0, encoding)
+ZEND_END_ARG_INFO();
+static void php_converter_do_set_encoding(UConverter *cnv, INTERNAL_FUNCTION_PARAMETERS) {
+ php_converter_object *objval = CONV_GET(getThis());
+ char *enc;
+ int enc_len;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &enc, &enc_len) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "Bad arguments, "
+ "expected one string argument", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+ intl_errors_reset(&objval->error TSRMLS_CC);
+
+ RETURN_BOOL(php_converter_set_encoding(objval, &(objval->src), enc, enc_len TSRMLS_CC));
+}
+/* }}} */
+
+/* {{{ proto bool UConverter::setSourceEncoding(string encoding) */
+static PHP_METHOD(UConverter, setSourceEncoding) {
+ php_converter_object *objval = CONV_GET(getThis());
+ php_converter_do_set_encoding(objval->src, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+/* }}} */
+
+/* {{{ proto bool UConverter::setDestinationEncoding(string encoding) */
+static PHP_METHOD(UConverter, setDestinationEncoding) {
+ php_converter_object *objval = CONV_GET(getThis());
+ php_converter_do_set_encoding(objval->dest, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+/* }}} */
+
+/* {{{ php_converter_do_get_encoding */
+ZEND_BEGIN_ARG_INFO_EX(php_converter_get_encoding_arginfo, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO();
+static void php_converter_do_get_encoding(php_converter_object *objval, UConverter *cnv, INTERNAL_FUNCTION_PARAMETERS) {
+ const char *name;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "Expected no arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ intl_errors_reset(&objval->error TSRMLS_CC);
+
+ if (!cnv) {
+ RETURN_NULL();
+ }
+
+ name = ucnv_getName(cnv, &objval->error.code);
+ if (U_FAILURE(objval->error.code)) {
+ THROW_UFAILURE(objval, "ucnv_getName()", objval->error.code);
+ RETURN_FALSE;
+ }
+
+ RETURN_STRING(name, 1);
+}
+/* }}} */
+
+/* {{{ proto string UConverter::getSourceEncoding() */
+static PHP_METHOD(UConverter, getSourceEncoding) {
+ php_converter_object *objval = CONV_GET(getThis());
+ php_converter_do_get_encoding(objval, objval->src, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+/* }}} */
+
+/* {{{ proto string UConverter::getDestinationEncoding() */
+static PHP_METHOD(UConverter, getDestinationEncoding) {
+ php_converter_object *objval = CONV_GET(getThis());
+ php_converter_do_get_encoding(objval, objval->dest, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+/* }}} */
+
+/* {{{ php_converter_do_get_type */
+ZEND_BEGIN_ARG_INFO_EX(php_converter_get_type_arginfo, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO();
+static void php_converter_do_get_type(php_converter_object *objval, UConverter *cnv, INTERNAL_FUNCTION_PARAMETERS) {
+ UConverterType t;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "Expected no arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+ intl_errors_reset(&objval->error TSRMLS_CC);
+
+ if (!cnv) {
+ RETURN_NULL();
+ }
+
+ t = ucnv_getType(cnv);
+ if (U_FAILURE(objval->error.code)) {
+ THROW_UFAILURE(objval, "ucnv_getType", objval->error.code);
+ RETURN_FALSE;
+ }
+
+ RETURN_LONG(t);
+}
+/* }}} */
+
+/* {{{ proto long UConverter::getSourceType() */
+static PHP_METHOD(UConverter, getSourceType) {
+ php_converter_object *objval = CONV_GET(getThis());
+ php_converter_do_get_type(objval, objval->src, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+/* }}} */
+
+/* {{{ proto long UConverter::getDestinationType() */
+static PHP_METHOD(UConverter, getDestinationType) {
+ php_converter_object *objval = CONV_GET(getThis());
+ php_converter_do_get_type(objval, objval->dest, INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+/* }}} */
+
+/* {{{ php_converter_resolve_callback */
+static void php_converter_resolve_callback(zval *zobj,
+ php_converter_object *objval,
+ const char *callback_name,
+ zend_fcall_info *finfo,
+ zend_fcall_info_cache *fcache TSRMLS_DC) {
+ char *errstr = NULL;
+ zval caller;
+
+ array_init(&caller);
+ Z_ADDREF_P(zobj);
+ add_index_zval(&caller, 0, zobj);
+ add_index_string(&caller, 1, callback_name, 1);
+ if (zend_fcall_info_init(&caller, 0, finfo, fcache, NULL, &errstr TSRMLS_CC) == FAILURE) {
+ php_converter_throw_failure(objval, U_INTERNAL_PROGRAM_ERROR TSRMLS_CC, "Error setting converter callback: %s", errstr);
+ }
+ zval_dtor(&caller);
+ if (errstr) {
+ efree(errstr);
+ }
+}
+/* }}} */
+
+/* {{{ proto void UConverter::__construct([string dest = 'utf-8',[string src = 'utf-8']]) */
+ZEND_BEGIN_ARG_INFO_EX(php_converter_arginfo, 0, ZEND_RETURN_VALUE, 0)
+ ZEND_ARG_INFO(0, destination_encoding)
+ ZEND_ARG_INFO(0, source_encoding)
+ZEND_END_ARG_INFO();
+
+static PHP_METHOD(UConverter, __construct) {
+ php_converter_object *objval = CONV_GET(getThis());
+ char *src = "utf-8";
+ int src_len = sizeof("utf-8") - 1;
+ char *dest = src;
+ int dest_len = src_len;
+
+ intl_error_reset(NULL TSRMLS_CC);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!",
+ &dest, &dest_len, &src, &src_len) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "UConverter::__construct(): bad arguments", 0 TSRMLS_CC);
+ return;
+ }
+
+ php_converter_set_encoding(objval, &(objval->src), src, src_len TSRMLS_CC);
+ php_converter_set_encoding(objval, &(objval->dest), dest, dest_len TSRMLS_CC);
+ php_converter_resolve_callback(getThis(), objval, "toUCallback", &(objval->to_cb), &(objval->to_cache) TSRMLS_CC);
+ php_converter_resolve_callback(getThis(), objval, "fromUCallback", &(objval->from_cb), &(objval->from_cache) TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto bool UConverter::setSubstChars(string $chars) */
+ZEND_BEGIN_ARG_INFO_EX(php_converter_setSubstChars_arginfo, 0, ZEND_RETURN_VALUE, 1)
+ ZEND_ARG_INFO(0, chars)
+ZEND_END_ARG_INFO();
+
+static PHP_METHOD(UConverter, setSubstChars) {
+ php_converter_object *objval = CONV_GET(getThis());
+ char *chars;
+ int chars_len, ret = 1;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &chars, &chars_len) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "UConverter::setSubstChars(): bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+ intl_errors_reset(&objval->error TSRMLS_CC);
+
+ if (objval->src) {
+ UErrorCode error = U_ZERO_ERROR;
+ ucnv_setSubstChars(objval->src, chars, chars_len, &error);
+ if (U_FAILURE(error)) {
+ THROW_UFAILURE(objval, "ucnv_setSubstChars", error);
+ ret = 0;
+ }
+ } else {
+ php_converter_throw_failure(objval, U_INVALID_STATE_ERROR TSRMLS_CC, "Source Converter has not been initialized yet");
+ ret = 0;
+ }
+
+ if (objval->dest) {
+ UErrorCode error = U_ZERO_ERROR;
+ ucnv_setSubstChars(objval->dest, chars, chars_len, &error);
+ if (U_FAILURE(error)) {
+ THROW_UFAILURE(objval, "ucnv_setSubstChars", error);
+ ret = 0;
+ }
+ } else {
+ php_converter_throw_failure(objval, U_INVALID_STATE_ERROR TSRMLS_CC, "Destination Converter has not been initialized yet");
+ ret = 0;
+ }
+
+ RETURN_BOOL(ret);
+}
+/* }}} */
+
+/* {{{ proto string UConverter::getSubstChars() */
+ZEND_BEGIN_ARG_INFO_EX(php_converter_getSubstChars_arginfo, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO();
+
+static PHP_METHOD(UConverter, getSubstChars) {
+ php_converter_object *objval = CONV_GET(getThis());
+ char chars[127];
+ int8_t chars_len = sizeof(chars);
+ UErrorCode error = U_ZERO_ERROR;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "UConverter::getSubstChars(): expected no arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+ intl_errors_reset(&objval->error TSRMLS_CC);
+
+ if (!objval->src) {
+ RETURN_NULL();
+ }
+
+ /* src and dest get the same subst chars set,
+ * so it doesn't really matter which one we read from
+ */
+ ucnv_getSubstChars(objval->src, chars, &chars_len, &error);
+ if (U_FAILURE(error)) {
+ THROW_UFAILURE(objval, "ucnv_getSubstChars", error);
+ RETURN_FALSE;
+ }
+
+ RETURN_STRINGL(chars, chars_len, 1);
+}
+/* }}} */
+
+/* {{{ php_converter_do_convert */
+static zend_bool php_converter_do_convert(UConverter *dest_cnv, char **pdest, int32_t *pdest_len,
+ UConverter *src_cnv, const char *src, int32_t src_len,
+ php_converter_object *objval
+ TSRMLS_DC) {
+ UErrorCode error = U_ZERO_ERROR;
+ int32_t dest_len,
+ temp_len;
+ char *dest;
+ UChar *temp;
+
+ if (!src_cnv || !dest_cnv) {
+ php_converter_throw_failure(objval, U_INVALID_STATE_ERROR TSRMLS_CC,
+ "Internal converters not initialized");
+ return 0;
+ }
+
+ /* Get necessary buffer size first */
+ temp_len = 1 + ucnv_toUChars(src_cnv, NULL, 0, src, src_len, &error);
+ if (U_FAILURE(error) && error != U_BUFFER_OVERFLOW_ERROR) {
+ THROW_UFAILURE(objval, "ucnv_toUChars", error);
+ return 0;
+ }
+ temp = safe_emalloc(sizeof(UChar), temp_len, sizeof(UChar));
+
+ /* Convert to intermediate UChar* array */
+ error = U_ZERO_ERROR;
+ temp_len = ucnv_toUChars(src_cnv, temp, temp_len, src, src_len, &error);
+ if (U_FAILURE(error)) {
+ THROW_UFAILURE(objval, "ucnv_toUChars", error);
+ efree(temp);
+ return 0;
+ }
+ temp[temp_len] = 0;
+
+ /* Get necessary output buffer size */
+ dest_len = 1 + ucnv_fromUChars(dest_cnv, NULL, 0, temp, temp_len, &error);
+ if (U_FAILURE(error) && error != U_BUFFER_OVERFLOW_ERROR) {
+ THROW_UFAILURE(objval, "ucnv_fromUChars", error);
+ efree(temp);
+ return 0;
+ }
+ dest = safe_emalloc(sizeof(char), dest_len, sizeof(char));
+
+ /* Convert to final encoding */
+ error = U_ZERO_ERROR;
+ dest_len = ucnv_fromUChars(dest_cnv, dest, dest_len, temp, temp_len, &error);
+ efree(temp);
+ if (U_FAILURE(error)) {
+ THROW_UFAILURE(objval, "ucnv_fromUChars", error);
+ efree(dest);
+ return 0;
+ }
+
+ *pdest = dest;
+ if (pdest_len) {
+ *pdest_len = dest_len;
+ }
+
+ return 1;
+}
+/* }}} */
+
+/* {{{ proto string UConverter::reasonText(long reason) */
+#define UCNV_REASON_CASE(v) case (UCNV_ ## v) : RETURN_STRINGL( "REASON_" #v , sizeof( "REASON_" #v ) - 1, 1);
+ZEND_BEGIN_ARG_INFO_EX(php_converter_reasontext_arginfo, 0, ZEND_RETURN_VALUE, 0)
+ ZEND_ARG_INFO(0, reason)
+ZEND_END_ARG_INFO();
+static PHP_METHOD(UConverter, reasonText) {
+ long reason;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &reason) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "UConverter::reasonText(): bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+ intl_error_reset(NULL TSRMLS_CC);
+
+ switch (reason) {
+ UCNV_REASON_CASE(UNASSIGNED)
+ UCNV_REASON_CASE(ILLEGAL)
+ UCNV_REASON_CASE(IRREGULAR)
+ UCNV_REASON_CASE(RESET)
+ UCNV_REASON_CASE(CLOSE)
+ UCNV_REASON_CASE(CLONE)
+ default:
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown UConverterCallbackReason: %ld", reason);
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
+/* {{{ proto string UConverter::convert(string str[, bool reverse]) */
+ZEND_BEGIN_ARG_INFO_EX(php_converter_convert_arginfo, 0, ZEND_RETURN_VALUE, 1)
+ ZEND_ARG_INFO(0, str)
+ ZEND_ARG_INFO(0, reverse)
+ZEND_END_ARG_INFO();
+
+static PHP_METHOD(UConverter, convert) {
+ php_converter_object *objval = CONV_GET(getThis());
+ char *str, *dest;
+ int str_len, dest_len;
+ zend_bool reverse = 0;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b",
+ &str, &str_len, &reverse) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "UConverter::convert(): bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+ intl_errors_reset(&objval->error TSRMLS_CC);
+
+ if (php_converter_do_convert(reverse ? objval->src : objval->dest,
+ &dest, &dest_len,
+ reverse ? objval->dest : objval->src,
+ str, str_len,
+ objval TSRMLS_CC)) {
+ RETURN_STRINGL(dest, dest_len, 0);
+ } else {
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
+/* {{{ proto string UConverter::transcode(string $str, string $toEncoding, string $fromEncoding[, Array $options = array()]) */
+ZEND_BEGIN_ARG_INFO_EX(php_converter_transcode_arginfo, 0, ZEND_RETURN_VALUE, 3)
+ ZEND_ARG_INFO(0, str)
+ ZEND_ARG_INFO(0, toEncoding)
+ ZEND_ARG_INFO(0, fromEncoding)
+ ZEND_ARG_ARRAY_INFO(0, options, 1)
+ZEND_END_ARG_INFO();
+
+static PHP_METHOD(UConverter, transcode) {
+ char *str, *src, *dest;
+ int str_len, src_len, dest_len;
+ zval *options = NULL;
+ UConverter *src_cnv = NULL, *dest_cnv = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|a!",
+ &str, &str_len, &dest, &dest_len, &src, &src_len, &options) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "UConverter::transcode(): bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+ intl_error_reset(NULL TSRMLS_CC);
+
+ if (php_converter_set_encoding(NULL, &src_cnv, src, src_len TSRMLS_CC) &&
+ php_converter_set_encoding(NULL, &dest_cnv, dest, dest_len TSRMLS_CC)) {
+ char *out = NULL;
+ int out_len = 0;
+ UErrorCode error = U_ZERO_ERROR;
+
+ if (options && zend_hash_num_elements(Z_ARRVAL_P(options))) {
+ zval **tmpzval;
+
+ if (U_SUCCESS(error) &&
+ zend_hash_find(Z_ARRVAL_P(options), "from_subst", sizeof("from_subst"), (void**)&tmpzval) == SUCCESS &&
+ Z_TYPE_PP(tmpzval) == IS_STRING) {
+ error = U_ZERO_ERROR;
+ ucnv_setSubstChars(src_cnv, Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval) & 0x7F, &error);
+ }
+ if (U_SUCCESS(error) &&
+ zend_hash_find(Z_ARRVAL_P(options), "to_subst", sizeof("to_subst"), (void**)&tmpzval) == SUCCESS &&
+ Z_TYPE_PP(tmpzval) == IS_STRING) {
+ error = U_ZERO_ERROR;
+ ucnv_setSubstChars(dest_cnv, Z_STRVAL_PP(tmpzval), Z_STRLEN_PP(tmpzval) & 0x7F, &error);
+ }
+ }
+
+ if (U_SUCCESS(error) &&
+ php_converter_do_convert(dest_cnv, &out, &out_len, src_cnv, str, str_len, NULL TSRMLS_CC)) {
+ RETVAL_STRINGL(out, out_len, 0);
+ }
+
+ if (U_FAILURE(error)) {
+ THROW_UFAILURE(NULL, "transcode", error);
+ RETVAL_FALSE;
+ }
+ } else {
+ RETVAL_FALSE;
+ }
+
+ if (src_cnv) {
+ ucnv_close(src_cnv);
+ }
+ if (dest_cnv) {
+ ucnv_close(dest_cnv);
+ }
+}
+/* }}} */
+
+/* {{{ proto int UConverter::getErrorCode() */
+ZEND_BEGIN_ARG_INFO_EX(php_converter_geterrorcode_arginfo, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO();
+static PHP_METHOD(UConverter, getErrorCode) {
+ php_converter_object *objval = CONV_GET(getThis());
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "UConverter::getErrorCode(): expected no arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ RETURN_LONG(intl_error_get_code(&(objval->error) TSRMLS_CC));
+}
+/* }}} */
+
+/* {{{ proto string UConverter::getErrorMessage() */
+ZEND_BEGIN_ARG_INFO_EX(php_converter_geterrormsg_arginfo, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO();
+static PHP_METHOD(UConverter, getErrorMessage) {
+ php_converter_object *objval = CONV_GET(getThis());
+ char *message = intl_error_get_message(&(objval->error) TSRMLS_CC);
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "UConverter::getErrorMessage(): expected no arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (message) {
+ RETURN_STRING(message, 1);
+ } else {
+ RETURN_NULL();
+ }
+}
+/* }}} */
+
+/* {{{ proto array UConverter::getAvailable() */
+ZEND_BEGIN_ARG_INFO_EX(php_converter_getavailable_arginfo, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO();
+static PHP_METHOD(UConverter, getAvailable) {
+ int32_t i,
+ count = ucnv_countAvailable();
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "UConverter::getErrorMessage(): expected no arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+ intl_error_reset(NULL TSRMLS_CC);
+
+ array_init(return_value);
+ for(i = 0; i < count; i++) {
+ const char *name = ucnv_getAvailableName(i);
+ add_next_index_string(return_value, name, 1);
+ }
+}
+/* }}} */
+
+/* {{{ proto array UConverter::getAliases(string name) */
+ZEND_BEGIN_ARG_INFO_EX(php_converter_getaliases_arginfo, 0, ZEND_RETURN_VALUE, 0)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO();
+static PHP_METHOD(UConverter, getAliases) {
+ char *name;
+ int name_len;
+ UErrorCode error = U_ZERO_ERROR;
+ uint16_t i, count;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "UConverter::getAliases(): bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+ intl_error_reset(NULL TSRMLS_CC);
+
+ count = ucnv_countAliases(name, &error);
+ if (U_FAILURE(error)) {
+ THROW_UFAILURE(NULL, "ucnv_countAliases", error);
+ RETURN_FALSE;
+ }
+
+ array_init(return_value);
+ for(i = 0; i < count; i++) {
+ const char *alias;
+
+ error = U_ZERO_ERROR;
+ alias = ucnv_getAlias(name, i, &error);
+ if (U_FAILURE(error)) {
+ THROW_UFAILURE(NULL, "ucnv_getAlias", error);
+ zval_dtor(return_value);
+ RETURN_NULL();
+ }
+ add_next_index_string(return_value, alias, 1);
+ }
+}
+/* }}} */
+
+/* {{{ proto array UConverter::getStandards() */
+ZEND_BEGIN_ARG_INFO_EX(php_converter_getstandards_arginfo, 0, ZEND_RETURN_VALUE, 0)
+ZEND_END_ARG_INFO();
+static PHP_METHOD(UConverter, getStandards) {
+ uint16_t i, count;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "UConverter::getStandards(): expected no arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+ intl_error_reset(NULL TSRMLS_CC);
+
+ array_init(return_value);
+ count = ucnv_countStandards();
+ for(i = 0; i < count; i++) {
+ UErrorCode error = U_ZERO_ERROR;
+ const char *name = ucnv_getStandard(i, &error);
+ if (U_FAILURE(error)) {
+ THROW_UFAILURE(NULL, "ucnv_getStandard", error);
+ zval_dtor(return_value);
+ RETURN_NULL();
+ }
+ add_next_index_string(return_value, name, 1);
+ }
+}
+/* }}} */
+
+static zend_function_entry php_converter_methods[] = {
+ PHP_ME(UConverter, __construct, php_converter_arginfo, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
+
+ /* Encoding selection */
+ PHP_ME(UConverter, setSourceEncoding, php_converter_set_encoding_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(UConverter, setDestinationEncoding, php_converter_set_encoding_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(UConverter, getSourceEncoding, php_converter_get_encoding_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(UConverter, getDestinationEncoding, php_converter_get_encoding_arginfo, ZEND_ACC_PUBLIC)
+
+ /* Introspection for algorithmic converters */
+ PHP_ME(UConverter, getSourceType, php_converter_get_type_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(UConverter, getDestinationType, php_converter_get_type_arginfo, ZEND_ACC_PUBLIC)
+
+ /* Basic codeunit error handling */
+ PHP_ME(UConverter, getSubstChars, php_converter_getSubstChars_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(UConverter, setSubstChars, php_converter_setSubstChars_arginfo, ZEND_ACC_PUBLIC)
+
+ /* Default callback handlers */
+ PHP_ME(UConverter, toUCallback, php_converter_toUCallback_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(UConverter, fromUCallback, php_converter_fromUCallback_arginfo, ZEND_ACC_PUBLIC)
+
+ /* Core conversion workhorses */
+ PHP_ME(UConverter, convert, php_converter_convert_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(UConverter, transcode, php_converter_transcode_arginfo, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+
+ /* Error inspection */
+ PHP_ME(UConverter, getErrorCode, php_converter_geterrorcode_arginfo, ZEND_ACC_PUBLIC)
+ PHP_ME(UConverter, getErrorMessage, php_converter_geterrormsg_arginfo, ZEND_ACC_PUBLIC)
+
+ /* Ennumeration and lookup */
+ PHP_ME(UConverter, reasonText, php_converter_reasontext_arginfo, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+ PHP_ME(UConverter, getAvailable, php_converter_getavailable_arginfo, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+ PHP_ME(UConverter, getAliases, php_converter_getaliases_arginfo, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+ PHP_ME(UConverter, getStandards, php_converter_getstandards_arginfo, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+ { NULL, NULL, NULL }
+};
+
+/* {{{ Converter create/clone/destroy */
+static void php_converter_free_object(php_converter_object *objval TSRMLS_DC) {
+ if (objval->src) {
+ ucnv_close(objval->src);
+ }
+
+ if (objval->dest) {
+ ucnv_close(objval->dest);
+ }
+
+ intl_error_reset(&(objval->error) TSRMLS_CC);
+ zend_object_std_dtor(&(objval->obj) TSRMLS_CC);
+
+ efree(objval);
+}
+
+static zend_object_value php_converter_object_ctor(zend_class_entry *ce, php_converter_object **pobjval TSRMLS_DC) {
+ php_converter_object *objval;
+ zend_object_value retval;
+
+ objval = ecalloc(1, sizeof(php_converter_object));
+ objval->obj.ce = ce;
+
+#ifdef ZTS
+ objval->tsrm_ls = TSRMLS_C;
+#endif
+ intl_error_init(&(objval->error) TSRMLS_CC);
+
+ retval.handle = zend_objects_store_put(objval, NULL, (zend_objects_free_object_storage_t)php_converter_free_object, NULL TSRMLS_CC);
+ retval.handlers = &php_converter_object_handlers;
+ *pobjval = objval;
+
+ return retval;
+}
+
+static zend_object_value php_converter_create_object(zend_class_entry *ce TSRMLS_DC) {
+ php_converter_object *objval = NULL;
+ zend_object_value retval = php_converter_object_ctor(ce, &objval TSRMLS_CC);
+
+ object_properties_init(&(objval->obj), ce);
+
+ return retval;
+}
+
+static zend_object_value php_converter_clone_object(zval *object TSRMLS_DC) {
+ php_converter_object *objval, *oldobj = (php_converter_object*)zend_objects_get_address(object TSRMLS_CC);
+ zend_object_value retval = php_converter_object_ctor(Z_OBJCE_P(object), &objval TSRMLS_CC);
+ UErrorCode error = U_ZERO_ERROR;
+
+ intl_errors_reset(&oldobj->error TSRMLS_CC);
+
+ objval->src = ucnv_safeClone(oldobj->src, NULL, NULL, &error);
+ if (U_SUCCESS(error)) {
+ error = U_ZERO_ERROR;
+ objval->dest = ucnv_safeClone(oldobj->dest, NULL, NULL, &error);
+ }
+ if (U_FAILURE(error)) {
+ char *err_msg;
+ THROW_UFAILURE(oldobj, "ucnv_safeClone", error);
+
+ err_msg = intl_error_get_message(&oldobj->error TSRMLS_CC);
+ zend_throw_exception(NULL, err_msg, 0 TSRMLS_CC);
+ efree(err_msg);
+
+ return retval;
+ }
+
+ /* Update contexts for converter error handlers */
+ php_converter_set_callbacks(objval, objval->src TSRMLS_CC);
+ php_converter_set_callbacks(objval, objval->dest TSRMLS_CC);
+
+ zend_objects_clone_members(&(objval->obj), retval, &(oldobj->obj), Z_OBJ_HANDLE_P(object) TSRMLS_CC);
+
+ /* Newly cloned object deliberately does not inherit error state from original object */
+
+ return retval;
+}
+/* }}} */
+
+#define CONV_REASON_CONST(v) zend_declare_class_constant_long(php_converter_ce, "REASON_" #v, sizeof("REASON_" #v) - 1, UCNV_ ## v TSRMLS_CC)
+#define CONV_TYPE_CONST(v) zend_declare_class_constant_long(php_converter_ce, #v , sizeof(#v) - 1, UCNV_ ## v TSRMLS_CC)
+
+/* {{{ php_converter_minit */
+int php_converter_minit(INIT_FUNC_ARGS) {
+ zend_class_entry ce;
+
+ INIT_CLASS_ENTRY(ce, "UConverter", php_converter_methods);
+ php_converter_ce = zend_register_internal_class(&ce TSRMLS_CC);
+ php_converter_ce->create_object = php_converter_create_object;
+ memcpy(&php_converter_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ php_converter_object_handlers.clone_obj = php_converter_clone_object;
+
+ /* enum UConverterCallbackReason */
+ CONV_REASON_CONST(UNASSIGNED);
+ CONV_REASON_CONST(ILLEGAL);
+ CONV_REASON_CONST(IRREGULAR);
+ CONV_REASON_CONST(RESET);
+ CONV_REASON_CONST(CLOSE);
+ CONV_REASON_CONST(CLONE);
+
+ /* enum UConverterType */
+ CONV_TYPE_CONST(UNSUPPORTED_CONVERTER);
+ CONV_TYPE_CONST(SBCS);
+ CONV_TYPE_CONST(DBCS);
+ CONV_TYPE_CONST(MBCS);
+ CONV_TYPE_CONST(LATIN_1);
+ CONV_TYPE_CONST(UTF8);
+ CONV_TYPE_CONST(UTF16_BigEndian);
+ CONV_TYPE_CONST(UTF16_LittleEndian);
+ CONV_TYPE_CONST(UTF32_BigEndian);
+ CONV_TYPE_CONST(UTF32_LittleEndian);
+ CONV_TYPE_CONST(EBCDIC_STATEFUL);
+ CONV_TYPE_CONST(ISO_2022);
+ CONV_TYPE_CONST(LMBCS_1);
+ CONV_TYPE_CONST(LMBCS_2);
+ CONV_TYPE_CONST(LMBCS_3);
+ CONV_TYPE_CONST(LMBCS_4);
+ CONV_TYPE_CONST(LMBCS_5);
+ CONV_TYPE_CONST(LMBCS_6);
+ CONV_TYPE_CONST(LMBCS_8);
+ CONV_TYPE_CONST(LMBCS_11);
+ CONV_TYPE_CONST(LMBCS_16);
+ CONV_TYPE_CONST(LMBCS_17);
+ CONV_TYPE_CONST(LMBCS_18);
+ CONV_TYPE_CONST(LMBCS_19);
+ CONV_TYPE_CONST(LMBCS_LAST);
+ CONV_TYPE_CONST(HZ);
+ CONV_TYPE_CONST(SCSU);
+ CONV_TYPE_CONST(ISCII);
+ CONV_TYPE_CONST(US_ASCII);
+ CONV_TYPE_CONST(UTF7);
+ CONV_TYPE_CONST(BOCU1);
+ CONV_TYPE_CONST(UTF16);
+ CONV_TYPE_CONST(UTF32);
+ CONV_TYPE_CONST(CESU8);
+ CONV_TYPE_CONST(IMAP_MAILBOX);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/ext/intl/converter/converter.h b/ext/intl/converter/converter.h
new file mode 100644
index 0000000000..bd316fcf98
--- /dev/null
+++ b/ext/intl/converter/converter.h
@@ -0,0 +1,28 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Sara Golemon <pollita@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef PHP_INTL_CONVERTER_H
+#define PHP_INTL_CONVERTER_H
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+
+int php_converter_minit(INIT_FUNC_ARGS);
+
+#endif /* PHP_INTL_CONVERTER_H */
diff --git a/ext/intl/dateformat/dateformat.c b/ext/intl/dateformat/dateformat.c
index 8aded18bd6..fb83eeef05 100644
--- a/ext/intl/dateformat/dateformat.c
+++ b/ext/intl/dateformat/dateformat.c
@@ -17,12 +17,9 @@
#include "config.h"
#endif
-#include <unicode/ustring.h>
#include <unicode/udat.h>
-#include <unicode/ucal.h>
#include "php_intl.h"
-#include "intl_convert.h"
#include "dateformat_class.h"
#include "dateformat.h"
@@ -67,157 +64,6 @@ void dateformat_register_constants( INIT_FUNC_ARGS )
}
/* }}} */
-/* {{{ */
-static void datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS)
-{
- char* locale;
- int locale_len = 0;
- zval* object;
- long date_type = 0;
- long time_type = 0;
- long calendar = UCAL_GREGORIAN;
- char* timezone_str = NULL;
- int timezone_str_len = 0;
- char* pattern_str = NULL;
- int pattern_str_len = 0;
- UChar* svalue = NULL; /* UTF-16 pattern_str */
- int slength = 0;
- UChar* timezone_utf16 = NULL; /* UTF-16 timezone_str */
- int timezone_utf16_len = 0;
- UCalendar ucal_obj = NULL;
- IntlDateFormatter_object* dfo;
-
- intl_error_reset( NULL TSRMLS_CC );
- object = return_value;
- /* Parse parameters. */
- if( zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "sll|sls",
- &locale, &locale_len, &date_type, &time_type, &timezone_str, &timezone_str_len, &calendar,&pattern_str, &pattern_str_len ) == FAILURE )
- {
- intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: unable to parse input parameters", 0 TSRMLS_CC );
- zval_dtor(return_value);
- RETURN_NULL();
- }
-
- INTL_CHECK_LOCALE_LEN_OBJ(locale_len, return_value);
-
- if (calendar != UCAL_TRADITIONAL && calendar != UCAL_GREGORIAN) {
- intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: "
- "invalid value for calendar type; it must be one of "
- "IntlDateFormatter::TRADITIONAL (locale's default calendar) "
- "or IntlDateFormatter::GREGORIAN", 0 TSRMLS_CC);
- goto error;
- }
-
- DATE_FORMAT_METHOD_FETCH_OBJECT_NO_CHECK;
-
- if (DATE_FORMAT_OBJECT(dfo) != NULL) {
- intl_errors_set(INTL_DATA_ERROR_P(dfo), U_ILLEGAL_ARGUMENT_ERROR,
- "datefmt_create: cannot call constructor twice", 0 TSRMLS_CC);
- return;
- }
-
- /* Convert pattern (if specified) to UTF-16. */
- if( pattern_str && pattern_str_len>0 ){
- intl_convert_utf8_to_utf16(&svalue, &slength,
- pattern_str, pattern_str_len, &INTL_DATA_ERROR_CODE(dfo));
- if (U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) {
- /* object construction -> only set global error */
- intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: "
- "error converting pattern to UTF-16", 0 TSRMLS_CC);
- goto error;
- }
- }
-
- /* resources allocated from now on */
-
- /* Convert pattern (if specified) to UTF-16. */
- if( timezone_str && timezone_str_len >0 ){
- intl_convert_utf8_to_utf16(&timezone_utf16, &timezone_utf16_len,
- timezone_str, timezone_str_len, &INTL_DATA_ERROR_CODE(dfo));
- if (U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) {
- intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: "
- "error converting timezone_str to UTF-16", 0 TSRMLS_CC);
- goto error;
- }
- }
-
- if(locale_len == 0) {
- locale = INTL_G(default_locale);
- }
-
- if( pattern_str && pattern_str_len>0 ){
- DATE_FORMAT_OBJECT(dfo) = udat_open(UDAT_IGNORE, UDAT_IGNORE, locale, timezone_utf16, timezone_utf16_len, svalue, slength, &INTL_DATA_ERROR_CODE(dfo));
- } else {
- DATE_FORMAT_OBJECT(dfo) = udat_open(time_type, date_type, locale, timezone_utf16, timezone_utf16_len, svalue, slength, &INTL_DATA_ERROR_CODE(dfo));
- }
-
- if (!U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) {
- if (calendar != UCAL_TRADITIONAL) {
- ucal_obj = ucal_open(timezone_utf16, timezone_utf16_len, locale,
- calendar, &INTL_DATA_ERROR_CODE(dfo));
- if (!U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) {
- udat_setCalendar(DATE_FORMAT_OBJECT(dfo), ucal_obj);
- ucal_close(ucal_obj);
- } else {
- intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create"
- ": error opening calendar", 0 TSRMLS_CC);
- goto error;
- }
- }
- } else {
- intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: date "
- "formatter creation failed", 0 TSRMLS_CC);
- goto error;
- }
-
- /* Set the class variables */
- dfo->date_type = date_type;
- dfo->time_type = time_type;
- dfo->calendar = calendar;
- if( timezone_str && timezone_str_len > 0){
- dfo->timezone_id = estrndup( timezone_str, timezone_str_len);
- }
-
-error:
- if (svalue) {
- efree(svalue);
- }
- if (timezone_utf16) {
- efree(timezone_utf16);
- }
- if (U_FAILURE(intl_error_get_code(NULL TSRMLS_CC))) {
- /* free_object handles partially constructed instances fine */
- zval_dtor(return_value);
- RETVAL_NULL();
- }
-}
-/* }}} */
-
-/* {{{ proto IntlDateFormatter IntlDateFormatter::create(string $locale, long date_type, long time_type[, string $timezone_str, long $calendar, string $pattern] )
- * Create formatter. }}} */
-/* {{{ proto IntlDateFormatter datefmt_create(string $locale, long date_type, long time_type[, string $timezone_str, long $calendar, string $pattern] )
-
- * Create formatter.
- */
-PHP_FUNCTION( datefmt_create )
-{
- object_init_ex( return_value, IntlDateFormatter_ce_ptr );
- datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU);
-}
-/* }}} */
-
-/* {{{ proto void IntlDateFormatter::__construct(string $locale, long date_type, long time_type[, string $timezone_str, long $calendar, string $pattern])
- * IntlDateFormatter object constructor.
- */
-PHP_METHOD( IntlDateFormatter, __construct )
-{
- /* return_value param is being changed, therefore we will always return
- * NULL here */
- return_value = getThis();
- datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU);
-}
-/* }}} */
-
/* {{{ proto int IntlDateFormatter::getErrorCode()
* Get formatter's last error code. }}} */
/* {{{ proto int datefmt_get_error_code( IntlDateFormatter $nf )
diff --git a/ext/intl/dateformat/dateformat_attr.c b/ext/intl/dateformat/dateformat_attr.c
index b8c5f25e3a..bf6b544667 100644
--- a/ext/intl/dateformat/dateformat_attr.c
+++ b/ext/intl/dateformat/dateformat_attr.c
@@ -25,39 +25,6 @@
#include <unicode/ustring.h>
#include <unicode/udat.h>
-#include <unicode/ucal.h>
-
-static void internal_set_calendar(IntlDateFormatter_object *dfo, char* timezone_id, int timezone_id_len, int calendar, zval* return_value TSRMLS_DC){
- int timezone_utf16_len = 0;
- UChar* timezone_utf16 = NULL; /* timezone_id in UTF-16 */
- char* locale = NULL;
-
- UCalendar* ucal_obj = NULL;
-
- /* check for the validity of value of calendar passed */
- intl_error_reset( NULL TSRMLS_CC );
- if( calendar > 1){
- intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
- "datefmt_set_calendar: calendar value specified is out of valid range", 0 TSRMLS_CC);
- RETURN_FALSE;
- }
-
- /* Convert timezone to UTF-16. */
- intl_convert_utf8_to_utf16(&timezone_utf16, &timezone_utf16_len, timezone_id, timezone_id_len, &INTL_DATA_ERROR_CODE(dfo));
- INTL_METHOD_CHECK_STATUS(dfo, "Error converting timezone to UTF-16" );
-
- /* Get the locale for the dateformatter */
- locale = (char *)udat_getLocaleByType(DATE_FORMAT_OBJECT(dfo), ULOC_ACTUAL_LOCALE, &INTL_DATA_ERROR_CODE(dfo));
-
- /* Set the calendar if passed */
- ucal_obj = ucal_open(timezone_utf16, timezone_utf16_len, locale, calendar, &INTL_DATA_ERROR_CODE(dfo) );
- udat_setCalendar( DATE_FORMAT_OBJECT(dfo), ucal_obj );
- INTL_METHOD_CHECK_STATUS(dfo, "Error setting the calendar.");
-
- if( timezone_utf16){
- efree(timezone_utf16);
- }
-}
/* {{{ proto unicode IntlDateFormatter::getDateType( )
* Get formatter datetype. }}} */
@@ -111,97 +78,6 @@ PHP_FUNCTION( datefmt_get_timetype )
}
/* }}} */
-
-/* {{{ proto unicode IntlDateFormatter::getCalendar( )
- * Get formatter calendar. }}} */
-/* {{{ proto string datefmt_get_calendar( IntlDateFormatter $mf )
- * Get formatter calendar.
- */
-PHP_FUNCTION( datefmt_get_calendar )
-{
- DATE_FORMAT_METHOD_INIT_VARS;
-
- /* Parse parameters. */
- if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, IntlDateFormatter_ce_ptr ) == FAILURE )
- {
- intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
- "datefmt_get_calendar: unable to parse input params", 0 TSRMLS_CC );
- RETURN_FALSE;
- }
-
- /* Fetch the object. */
- DATE_FORMAT_METHOD_FETCH_OBJECT;
-
- INTL_METHOD_CHECK_STATUS(dfo, "Error getting formatter calendar." );
-
- RETURN_LONG(dfo->calendar);
-}
-/* }}} */
-
-/* {{{ proto unicode IntlDateFormatter::getTimeZoneId( )
- * Get formatter timezone_id. }}} */
-/* {{{ proto string datefmt_get_timezone_id( IntlDateFormatter $mf )
- * Get formatter timezone_id.
- */
-PHP_FUNCTION( datefmt_get_timezone_id )
-{
- DATE_FORMAT_METHOD_INIT_VARS;
-
- /* Parse parameters. */
- if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, IntlDateFormatter_ce_ptr ) == FAILURE )
- {
- intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
- "datefmt_get_timezone_id: unable to parse input params", 0 TSRMLS_CC );
- RETURN_FALSE;
- }
-
- /* Fetch the object. */
- DATE_FORMAT_METHOD_FETCH_OBJECT;
-
- INTL_METHOD_CHECK_STATUS(dfo, "Error getting formatter timezone_id." );
-
- if( dfo->timezone_id ){
- RETURN_STRING((char*)dfo->timezone_id, TRUE );
- }else{
- RETURN_NULL();
- }
-}
-
-/* {{{ proto boolean IntlDateFormatter::setTimeZoneId( $timezone_id)
- * Set formatter timezone_id. }}} */
-/* {{{ proto boolean datefmt_set_timezone_id( IntlDateFormatter $mf,$timezone_id)
- * Set formatter timezone_id.
- */
-PHP_FUNCTION( datefmt_set_timezone_id )
-{
- char* timezone_id = NULL;
- int timezone_id_len = 0;
-
- DATE_FORMAT_METHOD_INIT_VARS;
-
- /* Parse parameters. */
- if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &object, IntlDateFormatter_ce_ptr,&timezone_id, &timezone_id_len) == FAILURE )
- {
- intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
- "datefmt_set_timezone_id: unable to parse input params", 0 TSRMLS_CC );
- RETURN_FALSE;
- }
-
- /* Fetch the object. */
- DATE_FORMAT_METHOD_FETCH_OBJECT;
-
- /* set the timezone for the calendar */
- internal_set_calendar( dfo, timezone_id, timezone_id_len, dfo->calendar, return_value TSRMLS_CC );
-
- /* Set the IntlDateFormatter variable */
- if( dfo->timezone_id ){
- efree(dfo->timezone_id);
- }
- dfo->timezone_id = estrndup(timezone_id, timezone_id_len);
-
- RETURN_TRUE;
-}
-
/* {{{ proto string IntlDateFormatter::getPattern( )
* Get formatter pattern. }}} */
/* {{{ proto string datefmt_get_pattern( IntlDateFormatter $mf )
@@ -370,43 +246,3 @@ PHP_FUNCTION( datefmt_set_lenient )
udat_setLenient(DATE_FORMAT_OBJECT(dfo), (UBool)isLenient );
}
/* }}} */
-
-/* {{{ proto bool IntlDateFormatter::setPattern( int $calendar )
- * Set formatter calendar. }}} */
-/* {{{ proto bool datefmt_set_calendar( IntlDateFormatter $mf, int $calendar )
- * Set formatter calendar.
- */
-PHP_FUNCTION( datefmt_set_calendar )
-{
- long calendar = 0;
-
- DATE_FORMAT_METHOD_INIT_VARS;
-
- /* Parse parameters. */
- if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Ol",
- &object, IntlDateFormatter_ce_ptr, &calendar ) == FAILURE ) {
- intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
- "datefmt_set_calendar: unable to parse input params", 0 TSRMLS_CC);
- RETURN_FALSE;
- }
-
- /* check for the validity of value of calendar passed */
- intl_error_reset( NULL TSRMLS_CC );
- if (calendar > 1) {
- intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
- "datefmt_set_calendar: calendar value specified is out of valid range", 0 TSRMLS_CC);
- RETURN_FALSE;
- }
-
- DATE_FORMAT_METHOD_FETCH_OBJECT;
-
- internal_set_calendar( dfo, dfo->timezone_id, strlen(dfo->timezone_id), calendar, return_value TSRMLS_CC );
-
- /* Set the calendar value in the IntlDateFormatter object */
- dfo->calendar = calendar;
-
- RETURN_TRUE;
-}
-/* }}} */
-
-
diff --git a/ext/intl/dateformat/dateformat_attr.h b/ext/intl/dateformat/dateformat_attr.h
index bf28824d63..6fe82a6e00 100644
--- a/ext/intl/dateformat/dateformat_attr.h
+++ b/ext/intl/dateformat/dateformat_attr.h
@@ -21,11 +21,7 @@
//PHP_FUNCTION( datefmt_get_timezone );
PHP_FUNCTION( datefmt_get_datetype );
PHP_FUNCTION( datefmt_get_timetype );
-PHP_FUNCTION( datefmt_get_calendar );
-PHP_FUNCTION( datefmt_set_calendar );
PHP_FUNCTION( datefmt_get_locale );
-PHP_FUNCTION( datefmt_get_timezone_id );
-PHP_FUNCTION( datefmt_set_timezone_id );
PHP_FUNCTION( datefmt_get_pattern );
PHP_FUNCTION( datefmt_set_pattern );
PHP_FUNCTION( datefmt_is_lenient );
diff --git a/ext/intl/dateformat/dateformat_attrcpp.cpp b/ext/intl/dateformat/dateformat_attrcpp.cpp
new file mode 100644
index 0000000000..b68abec659
--- /dev/null
+++ b/ext/intl/dateformat/dateformat_attrcpp.cpp
@@ -0,0 +1,261 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+#include "../intl_cppshims.h"
+
+#include <unicode/timezone.h>
+#include <unicode/calendar.h>
+#include <unicode/datefmt.h>
+
+extern "C" {
+#include "../php_intl.h"
+#include "dateformat_class.h"
+#include "dateformat_attrcpp.h"
+#define USE_TIMEZONE_POINTER 1
+#include "../timezone/timezone_class.h"
+#define USE_CALENDAR_POINTER 1
+#include "../calendar/calendar_class.h"
+}
+
+#include "../intl_convertcpp.h"
+#include "dateformat_helpers.h"
+
+static inline DateFormat *fetch_datefmt(IntlDateFormatter_object *dfo) {
+ return (DateFormat *)dfo->datef_data.udatf;
+}
+
+/* {{{ proto string IntlDateFormatter::getTimeZoneId()
+ * Get formatter timezone_id. }}} */
+/* {{{ proto string datefmt_get_timezone_id(IntlDateFormatter $mf)
+ * Get formatter timezone_id.
+ */
+U_CFUNC PHP_FUNCTION(datefmt_get_timezone_id)
+{
+ DATE_FORMAT_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",
+ &object, IntlDateFormatter_ce_ptr ) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_get_timezone_"
+ "id: unable to parse input params", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ DATE_FORMAT_METHOD_FETCH_OBJECT;
+
+ UnicodeString res = UnicodeString();
+ fetch_datefmt(dfo)->getTimeZone().getID(res);
+ intl_charFromString(res, &Z_STRVAL_P(return_value),
+ &Z_STRLEN_P(return_value), &INTL_DATA_ERROR_CODE(dfo));
+ INTL_METHOD_CHECK_STATUS(dfo, "Could not convert time zone id to UTF-8");
+
+ Z_TYPE_P(return_value) = IS_STRING;
+}
+
+/* {{{ proto IntlTimeZone IntlDateFormatter::getTimeZone()
+ * Get formatter timezone. }}} */
+/* {{{ proto IntlTimeZone datefmt_get_timezone(IntlDateFormatter $mf)
+ * Get formatter timezone.
+ */
+U_CFUNC PHP_FUNCTION(datefmt_get_timezone)
+{
+ DATE_FORMAT_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",
+ &object, IntlDateFormatter_ce_ptr ) == FAILURE) {
+ intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "datefmt_get_timezone: unable to parse input params", 0 TSRMLS_CC );
+ RETURN_FALSE;
+ }
+
+ DATE_FORMAT_METHOD_FETCH_OBJECT;
+
+ const TimeZone& tz = fetch_datefmt(dfo)->getTimeZone();
+ TimeZone *tz_clone = tz.clone();
+ if (tz_clone == NULL) {
+ intl_errors_set(INTL_DATA_ERROR_P(dfo), U_MEMORY_ALLOCATION_ERROR,
+ "datefmt_get_timezone: Out of memory when cloning time zone",
+ 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ object_init_ex(return_value, TimeZone_ce_ptr);
+ timezone_object_construct(tz_clone, return_value, 1 TSRMLS_CC);
+}
+
+U_CFUNC PHP_FUNCTION(datefmt_set_timezone_id)
+{
+ php_error_docref0(NULL TSRMLS_CC, E_DEPRECATED,
+ "Use datefmt_set_timezone() instead, which also accepts a plain "
+ "time zone identifier and for which this function is now an "
+ "alias");
+ PHP_FN(datefmt_set_timezone)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+
+/* {{{ proto boolean IntlDateFormatter::setTimeZone(mixed $timezone)
+ * Set formatter's timezone. }}} */
+/* {{{ proto boolean datefmt_set_timezone_id(IntlDateFormatter $mf, $timezone_id)
+ * Set formatter timezone_id.
+ */
+U_CFUNC PHP_FUNCTION(datefmt_set_timezone)
+{
+ zval **timezone_zv;
+ TimeZone *timezone;
+
+ DATE_FORMAT_METHOD_INIT_VARS;
+
+ if ( zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "OZ", &object, IntlDateFormatter_ce_ptr, &timezone_zv) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_set_timezone: "
+ "unable to parse input params", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ DATE_FORMAT_METHOD_FETCH_OBJECT;
+
+ timezone = timezone_process_timezone_argument(timezone_zv,
+ INTL_DATA_ERROR_P(dfo), "datefmt_set_timezone" TSRMLS_CC);
+ if (timezone == NULL) {
+ RETURN_FALSE;
+ }
+
+ fetch_datefmt(dfo)->adoptTimeZone(timezone);
+}
+
+/* {{{ proto int IntlDateFormatter::getCalendar( )
+ * Get formatter calendar type. }}} */
+/* {{{ proto int datefmt_get_calendar(IntlDateFormatter $mf)
+ * Get formatter calendar type.
+ */
+U_CFUNC PHP_FUNCTION(datefmt_get_calendar)
+{
+ DATE_FORMAT_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",
+ &object, IntlDateFormatter_ce_ptr ) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "datefmt_get_calendar: unable to parse input params", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ DATE_FORMAT_METHOD_FETCH_OBJECT;
+
+ if (dfo->calendar == -1) {
+ /* an IntlCalendar was provided to the constructor */
+ RETURN_FALSE;
+ }
+
+ RETURN_LONG(dfo->calendar);
+}
+/* }}} */
+
+/* {{{ proto IntlCalendar IntlDateFormatter::getCalendarObject()
+ * Get formatter calendar. }}} */
+/* {{{ proto IntlCalendar datefmt_get_calendar_object(IntlDateFormatter $mf)
+ * Get formatter calendar.
+ */
+U_CFUNC PHP_FUNCTION(datefmt_get_calendar_object)
+{
+ DATE_FORMAT_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",
+ &object, IntlDateFormatter_ce_ptr ) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "datefmt_get_calendar_object: unable to parse input params",
+ 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ DATE_FORMAT_METHOD_FETCH_OBJECT;
+
+ const Calendar *cal = fetch_datefmt(dfo)->getCalendar();
+ if (cal == NULL) {
+ RETURN_NULL();
+ }
+
+ Calendar *cal_clone = cal->clone();
+ if (cal_clone == NULL) {
+ intl_errors_set(INTL_DATA_ERROR_P(dfo), U_MEMORY_ALLOCATION_ERROR,
+ "datefmt_get_calendar_object: Out of memory when cloning "
+ "calendar", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ calendar_object_create(return_value, cal_clone TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ proto bool IntlDateFormatter::setCalendar(mixed $calendar)
+ * Set formatter's calendar. }}} */
+/* {{{ proto bool datefmt_set_calendar(IntlDateFormatter $mf, mixed $calendar)
+ * Set formatter's calendar.
+ */
+U_CFUNC PHP_FUNCTION(datefmt_set_calendar)
+{
+ zval *calendar_zv;
+ DATE_FORMAT_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oz",
+ &object, IntlDateFormatter_ce_ptr, &calendar_zv) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "datefmt_set_calendar: unable to parse input params", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ DATE_FORMAT_METHOD_FETCH_OBJECT;
+
+ Calendar *cal;
+ long cal_type;
+ bool cal_owned;
+ Locale locale = Locale::createFromName(dfo->requested_locale);
+ // getting the actual locale from the DateFormat is not enough
+ // because we would have lost modifiers such as @calendar. We
+ // must store the requested locale on object creation
+
+ if (datefmt_process_calendar_arg(calendar_zv, locale,
+ "datefmt_set_calendar", INTL_DATA_ERROR_P(dfo), cal, cal_type,
+ cal_owned TSRMLS_CC) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ if (cal_owned) {
+ /* a non IntlCalendar was specified, we want to keep the timezone */
+ TimeZone *old_timezone = fetch_datefmt(dfo)->getTimeZone().clone();
+ if (old_timezone == NULL) {
+ intl_errors_set(INTL_DATA_ERROR_P(dfo), U_MEMORY_ALLOCATION_ERROR,
+ "datefmt_set_calendar: Out of memory when cloning calendar",
+ 0 TSRMLS_CC);
+ delete cal;
+ RETURN_FALSE;
+ }
+ cal->adoptTimeZone(old_timezone);
+ } else {
+ cal = cal->clone();
+ if (cal == NULL) {
+ intl_errors_set(INTL_DATA_ERROR_P(dfo), U_MEMORY_ALLOCATION_ERROR,
+ "datefmt_set_calendar: Out of memory when cloning calendar",
+ 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+ }
+
+ fetch_datefmt(dfo)->adoptCalendar(cal);
+
+ dfo->calendar = cal_type;
+
+ RETURN_TRUE;
+}
+/* }}} */
+
diff --git a/ext/intl/dateformat/dateformat_attrcpp.h b/ext/intl/dateformat/dateformat_attrcpp.h
new file mode 100644
index 0000000000..408232f940
--- /dev/null
+++ b/ext/intl/dateformat/dateformat_attrcpp.h
@@ -0,0 +1,35 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef DATEFORMAT_ATTRCPP_H
+#define DATEFORMAT_ATTRCPP_H
+
+PHP_FUNCTION(datefmt_get_timezone_id);
+
+PHP_FUNCTION(datefmt_set_timezone_id);
+
+PHP_FUNCTION(datefmt_get_timezone);
+
+PHP_FUNCTION(datefmt_set_timezone);
+
+PHP_FUNCTION(datefmt_get_calendar);
+
+PHP_FUNCTION(datefmt_set_calendar);
+
+PHP_FUNCTION(datefmt_get_calendar_object);
+
+#endif /* DATEFORMAT_ATTRCPP_H */
+
diff --git a/ext/intl/dateformat/dateformat_class.c b/ext/intl/dateformat/dateformat_class.c
index 49f316f787..211c87f59f 100644
--- a/ext/intl/dateformat/dateformat_class.c
+++ b/ext/intl/dateformat/dateformat_class.c
@@ -19,9 +19,11 @@
#include "php_intl.h"
#include "dateformat_data.h"
#include "dateformat_format.h"
+#include "dateformat_format_object.h"
#include "dateformat_parse.h"
#include "dateformat.h"
#include "dateformat_attr.h"
+#include "dateformat_attrcpp.h"
#include <zend_exceptions.h>
@@ -46,12 +48,12 @@ void IntlDateFormatter_object_free( zend_object *object TSRMLS_DC )
zend_object_std_dtor( &dfo->zo TSRMLS_CC );
- dateformat_data_free( &dfo->datef_data TSRMLS_CC );
-
- if( dfo->timezone_id ){
- efree(dfo->timezone_id);
+ if (dfo->requested_locale) {
+ efree( dfo->requested_locale );
}
+ dateformat_data_free( &dfo->datef_data TSRMLS_CC );
+
efree( dfo );
}
/* }}} */
@@ -66,10 +68,10 @@ zend_object_value IntlDateFormatter_object_create(zend_class_entry *ce TSRMLS_DC
dateformat_data_init( &intern->datef_data TSRMLS_CC );
zend_object_std_init( &intern->zo, ce TSRMLS_CC );
object_properties_init(&intern->zo, ce);
- intern->date_type = 0;
- intern->time_type = 0;
- intern->calendar = 1; /* Gregorian calendar */
- intern->timezone_id = NULL;
+ intern->date_type = 0;
+ intern->time_type = 0;
+ intern->calendar = -1;
+ intern->requested_locale = NULL;
retval.handle = zend_objects_store_put(
intern,
@@ -127,6 +129,12 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_intldateformatter_format, 0, 0, 0)
ZEND_ARG_INFO(0, array)
ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO_EX(arginfo_intldateformatter_format_object, 0, 0, 1)
+ ZEND_ARG_INFO(0, object)
+ ZEND_ARG_INFO(0, format)
+ ZEND_ARG_INFO(0, locale)
+ZEND_END_ARG_INFO()
+
ZEND_BEGIN_ARG_INFO(arginfo_intldateformatter_getdatetype, 0)
ZEND_END_ARG_INFO()
@@ -165,15 +173,19 @@ static zend_function_entry IntlDateFormatter_class_functions[] = {
PHP_NAMED_FE( getDateType, ZEND_FN( datefmt_get_datetype ), arginfo_intldateformatter_getdatetype )
PHP_NAMED_FE( getTimeType, ZEND_FN( datefmt_get_timetype ), arginfo_intldateformatter_getdatetype )
PHP_NAMED_FE( getCalendar, ZEND_FN( datefmt_get_calendar ), arginfo_intldateformatter_getdatetype )
+ PHP_NAMED_FE( getCalendarObject, ZEND_FN( datefmt_get_calendar_object ), arginfo_intldateformatter_getdatetype )
PHP_NAMED_FE( setCalendar, ZEND_FN( datefmt_set_calendar ), arginfo_intldateformatter_setcalendar )
PHP_NAMED_FE( getTimeZoneId, ZEND_FN( datefmt_get_timezone_id ), arginfo_intldateformatter_getdatetype )
PHP_NAMED_FE( setTimeZoneId, ZEND_FN( datefmt_set_timezone_id ), arginfo_intldateformatter_settimezoneid )
+ PHP_NAMED_FE( getTimeZone, ZEND_FN( datefmt_get_timezone ), arginfo_intldateformatter_getdatetype )
+ PHP_NAMED_FE( setTimeZone, ZEND_FN( datefmt_set_timezone ), arginfo_intldateformatter_settimezoneid )
PHP_NAMED_FE( setPattern, ZEND_FN( datefmt_set_pattern ), arginfo_intldateformatter_setpattern )
PHP_NAMED_FE( getPattern, ZEND_FN( datefmt_get_pattern ), arginfo_intldateformatter_getdatetype )
PHP_NAMED_FE( getLocale, ZEND_FN( datefmt_get_locale ), arginfo_intldateformatter_getdatetype )
PHP_NAMED_FE( setLenient, ZEND_FN( datefmt_set_lenient ), arginfo_intldateformatter_setlenient )
PHP_NAMED_FE( isLenient, ZEND_FN( datefmt_is_lenient ), arginfo_intldateformatter_getdatetype )
PHP_NAMED_FE( format, ZEND_FN( datefmt_format ), arginfo_intldateformatter_format )
+ PHP_ME_MAPPING( formatObject, datefmt_format_object, arginfo_intldateformatter_format_object, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
PHP_NAMED_FE( parse, ZEND_FN( datefmt_parse), datefmt_parse_args )
PHP_NAMED_FE( localtime, ZEND_FN( datefmt_localtime ), datefmt_parse_args )
PHP_NAMED_FE( getErrorCode, ZEND_FN( datefmt_get_error_code ), arginfo_intldateformatter_getdatetype )
diff --git a/ext/intl/dateformat/dateformat_class.h b/ext/intl/dateformat/dateformat_class.h
index d58abe42f5..b4304660e2 100644
--- a/ext/intl/dateformat/dateformat_class.h
+++ b/ext/intl/dateformat/dateformat_class.h
@@ -24,12 +24,12 @@
#include "dateformat_data.h"
typedef struct {
- zend_object zo;
- dateformat_data datef_data;
- int date_type ;
- int time_type ;
- int calendar ;
- char* timezone_id;
+ zend_object zo;
+ dateformat_data datef_data;
+ int date_type;
+ int time_type;
+ int calendar;
+ char *requested_locale;
} IntlDateFormatter_object;
void dateformat_register_IntlDateFormatter_class( TSRMLS_D );
diff --git a/ext/intl/dateformat/dateformat_create.cpp b/ext/intl/dateformat/dateformat_create.cpp
new file mode 100644
index 0000000000..a2899f7974
--- /dev/null
+++ b/ext/intl/dateformat/dateformat_create.cpp
@@ -0,0 +1,193 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Kirti Velankar <kirtig@yahoo-inc.com> |
+ | Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+#include "../intl_cppshims.h"
+
+#include <unicode/timezone.h>
+#include <unicode/calendar.h>
+#include <unicode/datefmt.h>
+
+extern "C" {
+#include <unicode/ustring.h>
+#include <unicode/udat.h>
+
+#include "php_intl.h"
+#include "dateformat_create.h"
+#include "dateformat_class.h"
+#define USE_TIMEZONE_POINTER 1
+#include "../timezone/timezone_class.h"
+#include "../intl_convert.h"
+}
+
+#include "dateformat_helpers.h"
+
+/* {{{ */
+static void datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS)
+{
+ zval *object;
+
+ const char *locale_str;
+ int locale_len = 0;
+ Locale locale;
+ long date_type = 0;
+ long time_type = 0;
+ zval *calendar_zv = NULL;
+ Calendar *calendar = NULL;
+ long calendar_type;
+ bool calendar_owned;
+ zval **timezone_zv = NULL;
+ TimeZone *timezone = NULL;
+ bool explicit_tz;
+ char* pattern_str = NULL;
+ int pattern_str_len = 0;
+ UChar* svalue = NULL; /* UTF-16 pattern_str */
+ int slength = 0;
+ IntlDateFormatter_object* dfo;
+
+ intl_error_reset(NULL TSRMLS_CC);
+ object = return_value;
+ /* Parse parameters. */
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sll|Zzs",
+ &locale_str, &locale_len, &date_type, &time_type, &timezone_zv,
+ &calendar_zv, &pattern_str, &pattern_str_len) == FAILURE) {
+ intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: "
+ "unable to parse input parameters", 0 TSRMLS_CC);
+ zval_dtor(return_value);
+ RETURN_NULL();
+ }
+
+ INTL_CHECK_LOCALE_LEN_OBJ(locale_len, return_value);
+ if (locale_len == 0) {
+ locale_str = intl_locale_get_default(TSRMLS_C);
+ }
+ locale = Locale::createFromName(locale_str);
+
+ DATE_FORMAT_METHOD_FETCH_OBJECT_NO_CHECK;
+
+ if (DATE_FORMAT_OBJECT(dfo) != NULL) {
+ intl_errors_set(INTL_DATA_ERROR_P(dfo), U_ILLEGAL_ARGUMENT_ERROR,
+ "datefmt_create: cannot call constructor twice", 0 TSRMLS_CC);
+ return;
+ }
+
+ /* process calendar */
+ if (datefmt_process_calendar_arg(calendar_zv, locale, "datefmt_create",
+ INTL_DATA_ERROR_P(dfo), calendar, calendar_type,
+ calendar_owned TSRMLS_CC)
+ == FAILURE) {
+ goto error;
+ }
+
+ /* process timezone */
+ explicit_tz = timezone_zv != NULL && Z_TYPE_PP(timezone_zv) != IS_NULL;
+
+ if (explicit_tz || calendar_owned ) {
+ //we have an explicit time zone or a non-object calendar
+ timezone = timezone_process_timezone_argument(timezone_zv,
+ INTL_DATA_ERROR_P(dfo), "datefmt_create" TSRMLS_CC);
+ if (timezone == NULL) {
+ goto error;
+ }
+ }
+
+ /* Convert pattern (if specified) to UTF-16. */
+ if (pattern_str && pattern_str_len > 0) {
+ intl_convert_utf8_to_utf16(&svalue, &slength,
+ pattern_str, pattern_str_len, &INTL_DATA_ERROR_CODE(dfo));
+ if (U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) {
+ /* object construction -> only set global error */
+ intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: "
+ "error converting pattern to UTF-16", 0 TSRMLS_CC);
+ goto error;
+ }
+ }
+
+ if (pattern_str && pattern_str_len > 0) {
+ DATE_FORMAT_OBJECT(dfo) = udat_open(UDAT_IGNORE, UDAT_IGNORE,
+ locale_str, NULL, 0, svalue, slength,
+ &INTL_DATA_ERROR_CODE(dfo));
+ } else {
+ DATE_FORMAT_OBJECT(dfo) = udat_open((UDateFormatStyle)time_type,
+ (UDateFormatStyle)date_type, locale_str, NULL, 0, svalue,
+ slength, &INTL_DATA_ERROR_CODE(dfo));
+ }
+
+ if (!U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) {
+ DateFormat *df = (DateFormat*)DATE_FORMAT_OBJECT(dfo);
+ if (calendar_owned) {
+ df->adoptCalendar(calendar);
+ calendar_owned = false;
+ } else {
+ df->setCalendar(*calendar);
+ }
+
+ if (timezone != NULL) {
+ df->adoptTimeZone(timezone);
+ }
+ } else {
+ intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: date "
+ "formatter creation failed", 0 TSRMLS_CC);
+ goto error;
+ }
+
+ /* Set the class variables */
+ dfo->date_type = date_type;
+ dfo->time_type = time_type;
+ dfo->calendar = calendar_type;
+ dfo->requested_locale = estrdup(locale_str);
+
+error:
+ if (svalue) {
+ efree(svalue);
+ }
+ if (timezone != NULL && DATE_FORMAT_OBJECT(dfo) == NULL) {
+ delete timezone;
+ }
+ if (calendar != NULL && calendar_owned) {
+ delete calendar;
+ }
+ if (U_FAILURE(intl_error_get_code(NULL TSRMLS_CC))) {
+ /* free_object handles partially constructed instances fine */
+ zval_dtor(return_value);
+ RETVAL_NULL();
+ }
+}
+/* }}} */
+
+/* {{{ proto IntlDateFormatter IntlDateFormatter::create(string $locale, long date_type, long time_type[, string $timezone_str, long $calendar, string $pattern] )
+ * Create formatter. }}} */
+/* {{{ proto IntlDateFormatter datefmt_create(string $locale, long date_type, long time_type[, string $timezone_str, long $calendar, string $pattern)
+ * Create formatter.
+ */
+U_CFUNC PHP_FUNCTION( datefmt_create )
+{
+ object_init_ex( return_value, IntlDateFormatter_ce_ptr );
+ datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+/* }}} */
+
+/* {{{ proto void IntlDateFormatter::__construct(string $locale, long date_type, long time_type[, string $timezone_str, long $calendar, string $pattern])
+ * IntlDateFormatter object constructor.
+ */
+U_CFUNC PHP_METHOD( IntlDateFormatter, __construct )
+{
+ /* return_value param is being changed, therefore we will always return
+ * NULL here */
+ return_value = getThis();
+ datefmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+}
+/* }}} */
diff --git a/ext/intl/dateformat/dateformat_create.h b/ext/intl/dateformat/dateformat_create.h
new file mode 100644
index 0000000000..47e67c2f45
--- /dev/null
+++ b/ext/intl/dateformat/dateformat_create.h
@@ -0,0 +1,25 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+*/
+#ifndef DATE_FORMATTER_H
+#define DATE_FORMATTER_H
+
+#include <php.h>
+
+PHP_FUNCTION( datefmt_create );
+PHP_METHOD( IntlDateFormatter, __construct );
+void dateformat_register_constants( INIT_FUNC_ARGS );
+
+#endif // DATE_FORMATTER_H
diff --git a/ext/intl/dateformat/dateformat_format.c b/ext/intl/dateformat/dateformat_format.c
index 4d03d924c8..ffae15518b 100644
--- a/ext/intl/dateformat/dateformat_format.c
+++ b/ext/intl/dateformat/dateformat_format.c
@@ -21,13 +21,13 @@
#include <unicode/ustring.h>
#include <unicode/ucal.h>
-#include "php_intl.h"
-#include "intl_convert.h"
+#include "../php_intl.h"
+#include "../intl_convert.h"
+#include "../common/common_date.h"
#include "dateformat.h"
#include "dateformat_class.h"
#include "dateformat_format.h"
#include "dateformat_data.h"
-#include "ext/date/php_date.h"
/* {{{
* Internal function which calls the udat_format
@@ -59,20 +59,38 @@ static void internal_format(IntlDateFormatter_object *dfo, UDate timestamp, zval
/* {{{
* Internal function which fetches an element from the passed array for the key_name passed
*/
-static double internal_get_arr_ele(IntlDateFormatter_object *dfo, HashTable* hash_arr, char* key_name TSRMLS_DC)
+static int32_t internal_get_arr_ele(IntlDateFormatter_object *dfo,
+ HashTable* hash_arr, char* key_name, intl_error *err TSRMLS_DC)
{
- zval** ele_value = NULL;
- UDate result = -1;
-
- if( zend_hash_find( hash_arr, key_name, strlen(key_name) + 1, (void **)&ele_value ) == SUCCESS ){
- if( Z_TYPE_PP(ele_value)!= IS_LONG ){
- intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
- "datefmt_format: parameter array does not contain a long element.", 0 TSRMLS_CC );
- }else{
- result = Z_LVAL_PP(ele_value);
+ zval **ele_value = NULL;
+ int32_t result = 0;
+ char *message;
+
+ if (U_FAILURE(err->code)) {
+ return result;
+ }
+
+ if (zend_hash_find(hash_arr, key_name, strlen(key_name) + 1,
+ (void **)&ele_value) == SUCCESS) {
+ if(Z_TYPE_PP(ele_value) != IS_LONG) {
+ spprintf(&message, 0, "datefmt_format: parameter array contains "
+ "a non-integer element for key '%s'", key_name);
+ intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, message, 1 TSRMLS_CC);
+ efree(message);
+ } else {
+ if (Z_LVAL_PP(ele_value) > INT32_MAX ||
+ Z_LVAL_PP(ele_value) < INT32_MIN) {
+ spprintf(&message, 0, "datefmt_format: value %ld is out of "
+ "bounds for a 32-bit integer in key '%s'",
+ Z_LVAL_PP(ele_value), key_name);
+ intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, message, 1 TSRMLS_CC);
+ efree(message);
+ } else {
+ result = Z_LVAL_PP(ele_value);
+ }
}
}
- /* printf("\n Inside internal_get_arr_ele key_name= %s, result = %g \n", key_name, result); */
+
return result;
}
/* }}} */
@@ -80,41 +98,51 @@ static double internal_get_arr_ele(IntlDateFormatter_object *dfo, HashTable* has
/* {{{
* Internal function which sets UCalendar from the passed array and retrieves timestamp
*/
-static UDate internal_get_timestamp(IntlDateFormatter_object *dfo, HashTable* hash_arr TSRMLS_DC)
+static UDate internal_get_timestamp(IntlDateFormatter_object *dfo,
+ HashTable *hash_arr TSRMLS_DC)
{
- long year =0;
- long month =0;
- long hour =0;
- long minute =0;
- long second =0;
- long wday =0;
- long yday =0;
- long mday =0;
- UBool isInDST = FALSE;
- UCalendar *pcal;
+ int32_t year,
+ month,
+ hour,
+ minute,
+ second,
+ mday;
+ UCalendar *pcal;
+ UDate result;
+ intl_error *err = &dfo->datef_data.error;
+
+#define INTL_GET_ELEM(elem) \
+ internal_get_arr_ele(dfo, hash_arr, (elem), err TSRMLS_CC)
/* Fetch values from the incoming array */
- year = internal_get_arr_ele( dfo, hash_arr, CALENDAR_YEAR TSRMLS_CC) + 1900; /* tm_year is years since 1900 */
+ year = INTL_GET_ELEM(CALENDAR_YEAR) + 1900; /* tm_year is years since 1900 */
/* Month in ICU and PHP starts from January =0 */
- month = internal_get_arr_ele( dfo, hash_arr, CALENDAR_MON TSRMLS_CC);
- hour = internal_get_arr_ele( dfo, hash_arr, CALENDAR_HOUR TSRMLS_CC);
- minute = internal_get_arr_ele( dfo, hash_arr, CALENDAR_MIN TSRMLS_CC);
- second = internal_get_arr_ele( dfo, hash_arr, CALENDAR_SEC TSRMLS_CC);
- wday = internal_get_arr_ele( dfo, hash_arr, CALENDAR_WDAY TSRMLS_CC);
- yday = internal_get_arr_ele( dfo, hash_arr, CALENDAR_YDAY TSRMLS_CC);
- isInDST = internal_get_arr_ele( dfo, hash_arr, CALENDAR_ISDST TSRMLS_CC);
+ month = INTL_GET_ELEM(CALENDAR_MON);
+ hour = INTL_GET_ELEM(CALENDAR_HOUR);
+ minute = INTL_GET_ELEM(CALENDAR_MIN);
+ second = INTL_GET_ELEM(CALENDAR_SEC);
/* For the ucal_setDateTime() function, this is the 'date' value */
- mday = internal_get_arr_ele( dfo, hash_arr, CALENDAR_MDAY TSRMLS_CC);
+ mday = INTL_GET_ELEM(CALENDAR_MDAY);
- pcal = udat_getCalendar(DATE_FORMAT_OBJECT(dfo));
- /* set the incoming values for the calendar */
- ucal_setDateTime( pcal, year, month, mday, hour, minute, second, &INTL_DATA_ERROR_CODE(dfo));
- if( INTL_DATA_ERROR_CODE(dfo) != U_ZERO_ERROR){
+#undef INTL_GET_ELEM
+
+ pcal = ucal_clone(udat_getCalendar(DATE_FORMAT_OBJECT(dfo)),
+ &INTL_DATA_ERROR_CODE(dfo));
+
+ if (INTL_DATA_ERROR_CODE(dfo) != U_ZERO_ERROR) {
+ intl_errors_set(err, INTL_DATA_ERROR_CODE(dfo), "datefmt_format: "
+ "error cloning calendar", 0 TSRMLS_CC);
return 0;
}
-
+
+ /* set the incoming values for the calendar */
+ ucal_setDateTime(pcal, year, month, mday, hour, minute, second, &INTL_DATA_ERROR_CODE(dfo));
+ /* actually, ucal_setDateTime cannot fail */
+
/* Fetch the timestamp from the UCalendar */
- return ucal_getMillis(pcal, &INTL_DATA_ERROR_CODE(dfo) );
+ result = ucal_getMillis(pcal, &INTL_DATA_ERROR_CODE(dfo));
+ ucal_close(pcal);
+ return result;
}
@@ -124,70 +152,39 @@ static UDate internal_get_timestamp(IntlDateFormatter_object *dfo, HashTable* ha
* Format the time value as a string. }}}*/
PHP_FUNCTION(datefmt_format)
{
- UDate timestamp =0;
- UDate p_timestamp =0;
- HashTable* hash_arr = NULL;
- zval* zarg = NULL;
+ UDate timestamp = 0;
+ HashTable *hash_arr = NULL;
+ zval *zarg = NULL;
DATE_FORMAT_METHOD_INIT_VARS;
/* Parse parameters. */
- if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oz", &object, IntlDateFormatter_ce_ptr,&zarg ) == FAILURE )
- {
- intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_format: unable to parse input params", 0 TSRMLS_CC );
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oz",
+ &object, IntlDateFormatter_ce_ptr, &zarg) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_format: unable "
+ "to parse input params", 0 TSRMLS_CC );
RETURN_FALSE;
}
- /* Fetch the object. */
DATE_FORMAT_METHOD_FETCH_OBJECT;
- switch(Z_TYPE_P(zarg) ){
- case IS_LONG:
- p_timestamp = Z_LVAL_P(zarg) ;
- timestamp = p_timestamp * 1000;
- break;
- case IS_DOUBLE:
- /* timestamp*1000 since ICU expects it in milliseconds */
- p_timestamp = Z_DVAL_P(zarg) ;
- timestamp = p_timestamp * 1000;
- break;
- case IS_ARRAY:
- hash_arr = Z_ARRVAL_P(zarg);
- if( !hash_arr || zend_hash_num_elements( hash_arr ) == 0 )
- RETURN_FALSE;
-
- timestamp = internal_get_timestamp(dfo, hash_arr TSRMLS_CC);
- INTL_METHOD_CHECK_STATUS( dfo, "datefmt_format: Date formatting failed" )
- break;
- case IS_OBJECT: {
- zend_class_entry *date_ce = php_date_get_date_ce();
- zval retval;
- zval *zfuncname;
- if(!instanceof_function(Z_OBJCE_P(zarg), date_ce TSRMLS_CC)) {
- intl_errors_set(INTL_DATA_ERROR_P(dfo), U_ILLEGAL_ARGUMENT_ERROR, "datefmt_format: object must be an instance of DateTime", 0 TSRMLS_CC );
- RETURN_FALSE;
- }
- INIT_ZVAL(retval);
- MAKE_STD_ZVAL(zfuncname);
- ZVAL_STRING(zfuncname, "getTimestamp", 1);
- if(call_user_function(NULL, &zarg, zfuncname, &retval, 0, NULL TSRMLS_CC) != SUCCESS || Z_TYPE(retval) != IS_LONG) {
- intl_errors_set(INTL_DATA_ERROR_P(dfo), U_ILLEGAL_ARGUMENT_ERROR, "datefmt_format: cannot get timestamp", 0 TSRMLS_CC );
- zval_ptr_dtor(&zfuncname);
- RETURN_FALSE;
- }
- zval_ptr_dtor(&zfuncname);
- p_timestamp = Z_LVAL(retval);
- timestamp = p_timestamp*1000;
+ if (Z_TYPE_P(zarg) == IS_ARRAY) {
+ hash_arr = Z_ARRVAL_P(zarg);
+ if (!hash_arr || zend_hash_num_elements(hash_arr) == 0) {
+ RETURN_FALSE;
}
- break;
- default:
- intl_errors_set( INTL_DATA_ERROR_P(dfo), U_ILLEGAL_ARGUMENT_ERROR,
- "datefmt_format: takes either an array or an integer timestamp value or a DateTime object", 0 TSRMLS_CC );
+
+ timestamp = internal_get_timestamp(dfo, hash_arr TSRMLS_CC);
+ INTL_METHOD_CHECK_STATUS(dfo, "datefmt_format: date formatting failed")
+ } else {
+ timestamp = intl_zval_to_millis(zarg, INTL_DATA_ERROR_P(dfo),
+ "datefmt_format" TSRMLS_CC);
+ if (U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) {
RETURN_FALSE;
+ }
}
-
- internal_format( dfo, timestamp, return_value TSRMLS_CC);
+ internal_format( dfo, timestamp, return_value TSRMLS_CC);
}
/* }}} */
diff --git a/ext/intl/dateformat/dateformat_format_object.cpp b/ext/intl/dateformat/dateformat_format_object.cpp
new file mode 100644
index 0000000000..e8981faa26
--- /dev/null
+++ b/ext/intl/dateformat/dateformat_format_object.cpp
@@ -0,0 +1,230 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+#include "../intl_cppshims.h"
+
+#include <unicode/calendar.h>
+#include <unicode/gregocal.h>
+#include <unicode/datefmt.h>
+#include <unicode/smpdtfmt.h>
+#include <unicode/locid.h>
+
+#include "../intl_convertcpp.h"
+
+extern "C" {
+#include "../php_intl.h"
+#include "../locale/locale.h"
+#define USE_CALENDAR_POINTER 1
+#include "../calendar/calendar_class.h"
+#include <ext/date/php_date.h>
+#include "../common/common_date.h"
+}
+
+static const DateFormat::EStyle valid_styles[] = {
+ DateFormat::kNone,
+ DateFormat::kFull,
+ DateFormat::kLong,
+ DateFormat::kMedium,
+ DateFormat::kShort,
+ DateFormat::kFullRelative,
+ DateFormat::kLongRelative,
+ DateFormat::kMediumRelative,
+ DateFormat::kShortRelative,
+};
+
+static bool valid_format(zval **z) {
+ if (Z_TYPE_PP(z) == IS_LONG) {
+ long lval = Z_LVAL_PP(z);
+ for (int i = 0; i < sizeof(valid_styles) / sizeof(*valid_styles); i++) {
+ if ((long)valid_styles[i] == lval) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+U_CFUNC PHP_FUNCTION(datefmt_format_object)
+{
+ zval *object,
+ **format = NULL;
+ const char *locale_str = NULL;
+ int locale_len;
+ bool pattern = false;
+ UDate date;
+ TimeZone *timeZone = NULL;
+ UErrorCode status = U_ZERO_ERROR;
+ DateFormat *df = NULL;
+ Calendar *cal = NULL;
+ DateFormat::EStyle dateStyle = DateFormat::kDefault,
+ timeStyle = DateFormat::kDefault;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o|Zs!",
+ &object, &format, &locale_str, &locale_len) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ if (!locale_str) {
+ locale_str = intl_locale_get_default(TSRMLS_C);
+ }
+
+ if (format == NULL || Z_TYPE_PP(format) == IS_NULL) {
+ //nothing
+ } else if (Z_TYPE_PP(format) == IS_ARRAY) {
+ HashTable *ht = Z_ARRVAL_PP(format);
+ HashPosition pos = {0};
+ zval **z;
+ if (zend_hash_num_elements(ht) != 2) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "datefmt_format_object: bad format; if array, it must have "
+ "two elements", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ zend_hash_internal_pointer_reset_ex(ht, &pos);
+ zend_hash_get_current_data_ex(ht, (void**)&z, &pos);
+ if (!valid_format(z)) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "datefmt_format_object: bad format; the date format (first "
+ "element of the array) is not valid", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+ dateStyle = (DateFormat::EStyle)Z_LVAL_PP(z);
+
+ zend_hash_move_forward_ex(ht, &pos);
+ zend_hash_get_current_data_ex(ht, (void**)&z, &pos);
+ if (!valid_format(z)) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "datefmt_format_object: bad format; the time format ("
+ "second element of the array) is not valid", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+ timeStyle = (DateFormat::EStyle)Z_LVAL_PP(z);
+ } else if (Z_TYPE_PP(format) == IS_LONG) {
+ if (!valid_format(format)) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "datefmt_format_object: the date/time format type is invalid",
+ 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+ dateStyle = timeStyle = (DateFormat::EStyle)Z_LVAL_PP(format);
+ } else {
+ convert_to_string_ex(format);
+ if (Z_STRLEN_PP(format) == 0) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "datefmt_format_object: the format is empty", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+ pattern = true;
+ }
+
+ //there's no support for relative time in ICU yet
+ timeStyle = (DateFormat::EStyle)(timeStyle & ~DateFormat::kRelative);
+
+ zend_class_entry *instance_ce = Z_OBJCE_P(object);
+ if (instanceof_function(instance_ce, Calendar_ce_ptr TSRMLS_CC)) {
+ Calendar *obj_cal = calendar_fetch_native_calendar(object TSRMLS_CC);
+ if (obj_cal == NULL) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "datefmt_format_object: bad IntlCalendar instance: "
+ "not initialized properly", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+ timeZone = obj_cal->getTimeZone().clone();
+ date = obj_cal->getTime(status);
+ if (U_FAILURE(status)) {
+ intl_error_set(NULL, status,
+ "datefmt_format_object: error obtaining instant from "
+ "IntlCalendar", 0 TSRMLS_CC);
+ RETVAL_FALSE;
+ goto cleanup;
+ }
+ cal = obj_cal->clone();
+ } else if (instanceof_function(instance_ce, php_date_get_date_ce() TSRMLS_CC)) {
+ if (intl_datetime_decompose(object, &date, &timeZone, NULL,
+ "datefmt_format_object" TSRMLS_CC) == FAILURE) {
+ RETURN_FALSE;
+ }
+ cal = new GregorianCalendar(Locale::createFromName(locale_str), status);
+ if (U_FAILURE(status)) {
+ intl_error_set(NULL, status,
+ "datefmt_format_object: could not create GregorianCalendar",
+ 0 TSRMLS_CC);
+ RETVAL_FALSE;
+ goto cleanup;
+ }
+ } else {
+ intl_error_set(NULL, status, "datefmt_format_object: the passed object "
+ "must be an instance of either IntlCalendar or DateTime",
+ 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (pattern) {
+ df = new SimpleDateFormat(
+ UnicodeString(Z_STRVAL_PP(format), Z_STRLEN_PP(format),
+ UnicodeString::kInvariant),
+ Locale::createFromName(locale_str),
+ status);
+
+ if (U_FAILURE(status)) {
+ intl_error_set(NULL, status,
+ "datefmt_format_object: could not create SimpleDateFormat",
+ 0 TSRMLS_CC);
+ RETVAL_FALSE;
+ goto cleanup;
+ }
+ } else {
+ df = DateFormat::createDateTimeInstance(dateStyle, timeStyle,
+ Locale::createFromName(locale_str));
+
+ if (df == NULL) { /* according to ICU sources, this should never happen */
+ intl_error_set(NULL, status,
+ "datefmt_format_object: could not create DateFormat",
+ 0 TSRMLS_CC);
+ RETVAL_FALSE;
+ goto cleanup;
+ }
+ }
+
+ //must be in this order (or have the cal adopt the tz)
+ df->adoptCalendar(cal);
+ cal = NULL;
+ df->adoptTimeZone(timeZone);
+ timeZone = NULL;
+
+ {
+ UnicodeString result = UnicodeString();
+ df->format(date, result);
+
+ Z_TYPE_P(return_value) = IS_STRING;
+ if (intl_charFromString(result, &Z_STRVAL_P(return_value),
+ &Z_STRLEN_P(return_value), &status) == FAILURE) {
+ intl_error_set(NULL, status,
+ "datefmt_format_object: error converting result to UTF-8",
+ 0 TSRMLS_CC);
+ RETVAL_FALSE;
+ goto cleanup;
+ }
+ }
+
+
+cleanup:
+ delete df;
+ delete timeZone;
+ delete cal;
+}
diff --git a/ext/intl/dateformat/dateformat_format_object.h b/ext/intl/dateformat/dateformat_format_object.h
new file mode 100644
index 0000000000..d80ea87e0f
--- /dev/null
+++ b/ext/intl/dateformat/dateformat_format_object.h
@@ -0,0 +1,19 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+ */
+
+#include <php.h>
+
+PHP_FUNCTION(datefmt_format_object);
diff --git a/ext/intl/dateformat/dateformat_helpers.cpp b/ext/intl/dateformat/dateformat_helpers.cpp
new file mode 100644
index 0000000000..74758bbec9
--- /dev/null
+++ b/ext/intl/dateformat/dateformat_helpers.cpp
@@ -0,0 +1,106 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+#include "../intl_cppshims.h"
+
+#include <unicode/calendar.h>
+#include <unicode/gregocal.h>
+
+#include "dateformat_helpers.h"
+
+extern "C" {
+#include "../php_intl.h"
+#include <Zend/zend_operators.h>
+#define USE_CALENDAR_POINTER 1
+#include "../calendar/calendar_class.h"
+}
+
+int datefmt_process_calendar_arg(zval* calendar_zv,
+ Locale const& locale,
+ const char *func_name,
+ intl_error *err,
+ Calendar*& cal,
+ long& cal_int_type,
+ bool& calendar_owned TSRMLS_DC)
+{
+ char *msg;
+ UErrorCode status = UErrorCode();
+
+ if (calendar_zv == NULL || Z_TYPE_P(calendar_zv) == IS_NULL) {
+
+ // default requested
+ cal = new GregorianCalendar(locale, status);
+ calendar_owned = true;
+
+ cal_int_type = UCAL_GREGORIAN;
+
+ } else if (Z_TYPE_P(calendar_zv) == IS_LONG) {
+
+ long v = Z_LVAL_P(calendar_zv);
+ if (v != (long)UCAL_TRADITIONAL && v != (long)UCAL_GREGORIAN) {
+ spprintf(&msg, 0, "%s: invalid value for calendar type; it must be "
+ "one of IntlDateFormatter::TRADITIONAL (locale's default "
+ "calendar) or IntlDateFormatter::GREGORIAN. "
+ "Alternatively, it can be an IntlCalendar object",
+ func_name);
+ intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, msg, 1 TSRMLS_CC);
+ efree(msg);
+ return FAILURE;
+ } else if (v == (long)UCAL_TRADITIONAL) {
+ cal = Calendar::createInstance(locale, status);
+ } else { //UCAL_GREGORIAN
+ cal = new GregorianCalendar(locale, status);
+ }
+ calendar_owned = true;
+
+ cal_int_type = Z_LVAL_P(calendar_zv);
+
+ } else if (Z_TYPE_P(calendar_zv) == IS_OBJECT &&
+ instanceof_function_ex(Z_OBJCE_P(calendar_zv),
+ Calendar_ce_ptr, 0 TSRMLS_CC)) {
+
+ cal = calendar_fetch_native_calendar(calendar_zv TSRMLS_CC);
+ if (cal == NULL) {
+ spprintf(&msg, 0, "%s: Found unconstructed IntlCalendar object",
+ func_name);
+ intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, msg, 1 TSRMLS_CC);
+ efree(msg);
+ return FAILURE;
+ }
+ calendar_owned = false;
+
+ cal_int_type = -1;
+
+ } else {
+ spprintf(&msg, 0, "%s: Invalid calendar argument; should be an integer "
+ "or an IntlCalendar instance", func_name);
+ intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, msg, 1 TSRMLS_CC);
+ efree(msg);
+ return FAILURE;
+ }
+
+ if (cal == NULL && !U_FAILURE(status)) {
+ status = U_MEMORY_ALLOCATION_ERROR;
+ }
+ if (U_FAILURE(status)) {
+ spprintf(&msg, 0, "%s: Failure instantiating calendar", func_name);
+ intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, msg, 1 TSRMLS_CC);
+ efree(msg);
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
diff --git a/ext/intl/dateformat/dateformat_helpers.h b/ext/intl/dateformat/dateformat_helpers.h
new file mode 100644
index 0000000000..bded0b7d78
--- /dev/null
+++ b/ext/intl/dateformat/dateformat_helpers.h
@@ -0,0 +1,39 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef DATEFORMAT_HELPERS_H
+#define DATEFORMAT_HELPERS_H
+
+#ifndef __cplusplus
+#error For C++ only
+#endif
+
+#include <unicode/calendar.h>
+
+extern "C" {
+#include "../php_intl.h"
+}
+
+int datefmt_process_calendar_arg(zval* calendar_zv,
+ Locale const& locale,
+ const char *func_name,
+ intl_error *err,
+ Calendar*& cal,
+ long& cal_int_type,
+ bool& calendar_owned TSRMLS_DC);
+
+#endif /* DATEFORMAT_HELPERS_H */
+
diff --git a/ext/intl/dateformat/dateformat_parse.c b/ext/intl/dateformat/dateformat_parse.c
index 4193e89017..9930778546 100644
--- a/ext/intl/dateformat/dateformat_parse.c
+++ b/ext/intl/dateformat/dateformat_parse.c
@@ -62,7 +62,7 @@ static void internal_parse_to_timestamp(IntlDateFormatter_object *dfo, char* tex
}
/* }}} */
-static void add_to_localtime_arr( IntlDateFormatter_object *dfo, zval* return_value, UCalendar parsed_calendar, long calendar_field, char* key_name TSRMLS_DC)
+static void add_to_localtime_arr( IntlDateFormatter_object *dfo, zval* return_value, const UCalendar *parsed_calendar, long calendar_field, char* key_name TSRMLS_DC)
{
long calendar_field_val = ucal_get( parsed_calendar, calendar_field, &INTL_DATA_ERROR_CODE(dfo));
INTL_METHOD_CHECK_STATUS( dfo, "Date parsing - localtime failed : could not get a field from calendar" );
@@ -83,7 +83,7 @@ static void add_to_localtime_arr( IntlDateFormatter_object *dfo, zval* return_va
*/
static void internal_parse_to_localtime(IntlDateFormatter_object *dfo, char* text_to_parse, int32_t text_len, int32_t *parse_pos, zval *return_value TSRMLS_DC)
{
- UCalendar* parsed_calendar = NULL;
+ UCalendar *parsed_calendar = NULL;
UChar* text_utf16 = NULL;
int32_t text_utf16_len = 0;
long isInDST = 0;
@@ -92,7 +92,7 @@ static void internal_parse_to_localtime(IntlDateFormatter_object *dfo, char* tex
intl_convert_utf8_to_utf16(&text_utf16, &text_utf16_len, text_to_parse, text_len, &INTL_DATA_ERROR_CODE(dfo));
INTL_METHOD_CHECK_STATUS(dfo, "Error converting timezone to UTF-16" );
- parsed_calendar = udat_getCalendar(DATE_FORMAT_OBJECT(dfo));
+ parsed_calendar = (UCalendar *)udat_getCalendar(DATE_FORMAT_OBJECT(dfo));
udat_parseCalendar( DATE_FORMAT_OBJECT(dfo), parsed_calendar, text_utf16, text_utf16_len, parse_pos, &INTL_DATA_ERROR_CODE(dfo));
if (text_utf16) {
diff --git a/ext/intl/formatter/formatter_main.c b/ext/intl/formatter/formatter_main.c
index 5cb6483326..0a568472c4 100644
--- a/ext/intl/formatter/formatter_main.c
+++ b/ext/intl/formatter/formatter_main.c
@@ -27,7 +27,7 @@
/* {{{ */
static void numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS)
{
- char* locale;
+ const char* locale;
char* pattern = NULL;
int locale_len = 0, pattern_len = 0;
long style;
@@ -56,7 +56,7 @@ static void numfmt_ctor(INTERNAL_FUNCTION_PARAMETERS)
}
if(locale_len == 0) {
- locale = INTL_G(default_locale);
+ locale = intl_locale_get_default(TSRMLS_C);
}
/* Create an ICU number formatter. */
diff --git a/ext/intl/grapheme/grapheme.h b/ext/intl/grapheme/grapheme.h
index c0e697ac1e..756ce9173e 100644
--- a/ext/intl/grapheme/grapheme.h
+++ b/ext/intl/grapheme/grapheme.h
@@ -19,7 +19,6 @@
#include <php.h>
#include <unicode/utypes.h>
-#include <unicode/ubrk.h>
PHP_FUNCTION(grapheme_strlen);
PHP_FUNCTION(grapheme_strpos);
diff --git a/ext/intl/intl_convertcpp.cpp b/ext/intl/intl_convertcpp.cpp
new file mode 100644
index 0000000000..f699a3c61c
--- /dev/null
+++ b/ext/intl/intl_convertcpp.cpp
@@ -0,0 +1,89 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#include "intl_cppshims.h"
+
+#include "intl_convertcpp.h"
+#include <unicode/ustring.h>
+extern "C" {
+#include <php.h>
+}
+
+/* {{{ intl_stringFromChar */
+int intl_stringFromChar(UnicodeString &ret, char *str, int32_t str_len, UErrorCode *status)
+{
+ //the number of UTF-16 code units is not larger than that of UTF-8 code
+ //units, + 1 for the terminator
+ int32_t capacity = str_len + 1;
+
+ //no check necessary -- if NULL will fail ahead
+ UChar *utf16 = ret.getBuffer(capacity);
+ int32_t utf16_len = 0;
+ *status = U_ZERO_ERROR;
+ u_strFromUTF8WithSub(utf16, ret.getCapacity(), &utf16_len,
+ str, str_len, U_SENTINEL /* no substitution */, NULL,
+ status);
+ ret.releaseBuffer(utf16_len);
+ if (U_FAILURE(*status)) {
+ ret.setToBogus();
+ return FAILURE;
+ }
+ return SUCCESS;
+}
+/* }}} */
+
+/* {{{ intl_charFromString
+ * faster than doing intl_convert_utf16_to_utf8(&res, &res_len,
+ * from.getBuffer(), from.length(), &status),
+ * but consumes more memory */
+int intl_charFromString(const UnicodeString &from, char **res, int *res_len, UErrorCode *status)
+{
+ if (from.isBogus()) {
+ return FAILURE;
+ }
+
+ //the number of UTF-8 code units is not larger than that of UTF-16 code
+ //units * 3 + 1 for the terminator
+ int32_t capacity = from.length() * 3 + 1;
+
+ if (from.isEmpty()) {
+ *res = (char*)emalloc(1);
+ **res = '\0';
+ *res_len = 0;
+ return SUCCESS;
+ }
+
+ *res = (char*)emalloc(capacity);
+ *res_len = 0; //tbd
+
+ const UChar *utf16buf = from.getBuffer();
+ int32_t actual_len;
+ u_strToUTF8WithSub(*res, capacity - 1, &actual_len, utf16buf, from.length(),
+ U_SENTINEL, NULL, status);
+
+ if (U_FAILURE(*status)) {
+ efree(*res);
+ *res = NULL;
+ return FAILURE;
+ }
+ (*res)[actual_len] = '\0';
+ *res_len = (int)actual_len;
+
+ return SUCCESS;
+}
+/* }}} */
diff --git a/ext/intl/intl_convertcpp.h b/ext/intl/intl_convertcpp.h
new file mode 100644
index 0000000000..89d4209dd3
--- /dev/null
+++ b/ext/intl/intl_convertcpp.h
@@ -0,0 +1,32 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef INTL_CONVERTCPP_H
+#define INTL_CONVERTCPP_H
+
+#ifndef __cplusplus
+#error Should be included only in C++ Files
+#endif
+
+#include <unicode/unistr.h>
+
+int intl_stringFromChar(UnicodeString &ret, char *str, int32_t str_len, UErrorCode *status);
+
+int intl_charFromString(const UnicodeString &from, char **res, int *res_len, UErrorCode *status);
+
+#endif /* INTL_CONVERTCPP_H */
diff --git a/ext/intl/intl_cppshims.h b/ext/intl/intl_cppshims.h
new file mode 100644
index 0000000000..e58ec3bd45
--- /dev/null
+++ b/ext/intl/intl_cppshims.h
@@ -0,0 +1,34 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef INTL_CPPSHIMS_H
+#define INTL_CPPSHIMS_H
+
+#ifndef __cplusplus
+#error For inclusion form C++ files only
+#endif
+
+#ifdef _MSC_VER
+//This is only required for old versions of ICU only
+#include <stdio.h>
+
+#include <math.h>
+
+/* avoid redefinition of int8_t, also defined in unicode/pwin32.h */
+#define _MSC_STDINT_H_ 1
+#endif
+
+#endif
diff --git a/ext/intl/intl_error.c b/ext/intl/intl_error.c
index 9c2e13dfd5..99b1c6001c 100644
--- a/ext/intl/intl_error.c
+++ b/ext/intl/intl_error.c
@@ -21,12 +21,16 @@
#endif
#include <php.h>
+#include <zend_exceptions.h>
#include "php_intl.h"
#include "intl_error.h"
+#include "intl_convert.h"
ZEND_EXTERN_MODULE_GLOBALS( intl )
+static zend_class_entry *IntlException_ce_ptr;
+
/* {{{ intl_error* intl_g_error_get()
* Return global error structure.
*/
@@ -102,8 +106,11 @@ 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 ) {
+ if( INTL_G( error_level ) )
+ php_error_docref( NULL TSRMLS_CC, INTL_G( error_level ), "%s", msg );
+ if( INTL_G( use_exceptions ) )
+ zend_throw_exception_ex( IntlException_ce_ptr, 0 TSRMLS_CC, "%s", msg );
}
if( !err && !( err = intl_g_error_get( TSRMLS_C ) ) )
return;
@@ -223,6 +230,96 @@ void intl_errors_set_code( intl_error* err, UErrorCode err_code TSRMLS_DC )
}
/* }}} */
+void intl_register_IntlException_class( TSRMLS_D )
+{
+ zend_class_entry ce,
+ *default_exception_ce;
+
+ default_exception_ce = zend_exception_get_default( TSRMLS_C );
+
+ /* Create and register 'IntlException' class. */
+ INIT_CLASS_ENTRY_EX( ce, "IntlException", sizeof( "IntlException" ) - 1, NULL );
+ IntlException_ce_ptr = zend_register_internal_class_ex( &ce,
+ default_exception_ce, NULL TSRMLS_CC );
+ IntlException_ce_ptr->create_object = default_exception_ce->create_object;
+}
+
+smart_str intl_parse_error_to_string( UParseError* pe )
+{
+ smart_str ret = {0};
+ char *buf;
+ int u8len;
+ UErrorCode status;
+ int any = 0;
+
+ assert( pe != NULL );
+
+ smart_str_appends( &ret, "parse error " );
+ if( pe->line > 0 )
+ {
+ smart_str_appends( &ret, "on line " );
+ smart_str_append_long( &ret, (long ) pe->line );
+ any = 1;
+ }
+ if( pe->offset >= 0 ) {
+ if( any )
+ smart_str_appends( &ret, ", " );
+ else
+ smart_str_appends( &ret, "at " );
+
+ smart_str_appends( &ret, "offset " );
+ smart_str_append_long( &ret, (long ) pe->offset );
+ any = 1;
+ }
+
+ if (pe->preContext[0] != 0 ) {
+ if( any )
+ smart_str_appends( &ret, ", " );
+
+ smart_str_appends( &ret, "after \"" );
+ intl_convert_utf16_to_utf8( &buf, &u8len, pe->preContext, -1, &status );
+ if( U_FAILURE( status ) )
+ {
+ smart_str_appends( &ret, "(could not convert parser error pre-context to UTF-8)" );
+ }
+ else {
+ smart_str_appendl( &ret, buf, u8len );
+ efree( buf );
+ }
+ smart_str_appends( &ret, "\"" );
+ any = 1;
+ }
+
+ if( pe->postContext[0] != 0 )
+ {
+ if( any )
+ smart_str_appends( &ret, ", " );
+
+ smart_str_appends( &ret, "before or at \"" );
+ intl_convert_utf16_to_utf8( &buf, &u8len, pe->postContext, -1, &status );
+ if( U_FAILURE( status ) )
+ {
+ smart_str_appends( &ret, "(could not convert parser error post-context to UTF-8)" );
+ }
+ else
+ {
+ smart_str_appendl( &ret, buf, u8len );
+ efree( buf );
+ }
+ smart_str_appends( &ret, "\"" );
+ any = 1;
+ }
+
+ if( !any )
+ {
+ smart_str_free( &ret );
+ smart_str_appends( &ret, "no parse error" );
+ }
+
+ smart_str_0( &ret );
+ return ret;
+}
+
/*
* Local variables:
* tab-width: 4
diff --git a/ext/intl/intl_error.h b/ext/intl/intl_error.h
index 3adae85474..4d8eb79327 100644
--- a/ext/intl/intl_error.h
+++ b/ext/intl/intl_error.h
@@ -20,6 +20,8 @@
#define INTL_ERROR_H
#include <unicode/utypes.h>
+#include <unicode/parseerr.h>
+#include <ext/standard/php_smart_str.h>
#define INTL_ERROR_CODE(e) (e).code
@@ -44,4 +46,10 @@ void intl_errors_set_custom_msg( intl_error* err, char* msg, int copyMsg
void intl_errors_set_code( intl_error* err, UErrorCode err_code TSRMLS_DC );
void intl_errors_set( intl_error* err, UErrorCode code, char* msg, int copyMsg TSRMLS_DC );
+// Other error helpers
+smart_str intl_parse_error_to_string( UParseError* pe );
+
+// exported to be called on extension MINIT
+void intl_register_IntlException_class( TSRMLS_D );
+
#endif // INTL_ERROR_H
diff --git a/ext/intl/locale/locale_methods.c b/ext/intl/locale/locale_methods.c
index 9c5b09a7bc..21b5847f2d 100644
--- a/ext/intl/locale/locale_methods.c
+++ b/ext/intl/locale/locale_methods.c
@@ -121,7 +121,7 @@ static int16_t findOffset(const char* const* list, const char* key)
}
/*}}}*/
-static char* getPreferredTag(char* gf_tag)
+static char* getPreferredTag(const char* gf_tag)
{
char* result = NULL;
int grOffset = 0;
@@ -175,7 +175,7 @@ static int getStrrtokenPos(char* str, int savedPos)
* returns -1 if no singleton
* strtok equivalent search for singleton
*/
-static int getSingletonPos(char* str)
+static int getSingletonPos(const char* str)
{
int result =-1;
int i=0;
@@ -211,10 +211,7 @@ static int getSingletonPos(char* str)
Get default locale */
PHP_NAMED_FUNCTION(zif_locale_get_default)
{
- if( INTL_G(default_locale) == NULL ) {
- INTL_G(default_locale) = pestrdup( uloc_getDefault(), 1);
- }
- RETURN_STRING( INTL_G(default_locale), TRUE );
+ RETURN_STRING( intl_locale_get_default( TSRMLS_C ), TRUE );
}
/* }}} */
@@ -254,7 +251,7 @@ PHP_NAMED_FUNCTION(zif_locale_set_default)
* common code shared by get_primary_language,get_script or get_region or get_variant
* result = 0 if error, 1 if successful , -1 if no value
*/
-static char* get_icu_value_internal( char* loc_name , char* tag_name, int* result , int fromParseLocale)
+static char* get_icu_value_internal( const char* loc_name , char* tag_name, int* result , int fromParseLocale)
{
char* tag_value = NULL;
int32_t tag_value_len = 512;
@@ -284,7 +281,7 @@ static char* get_icu_value_internal( char* loc_name , char* tag_name, int* resul
/* Handle singletons */
if( strcmp(tag_name , LOC_LANG_TAG)==0 ){
if( strlen(loc_name)>1 && (isIDPrefix(loc_name) ==1 ) ){
- return loc_name;
+ return (char *)loc_name;
}
}
@@ -373,7 +370,7 @@ static char* get_icu_value_internal( char* loc_name , char* tag_name, int* resul
static void get_icu_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAMETERS)
{
- char* loc_name = NULL;
+ const char* loc_name = NULL;
int loc_name_len = 0;
char* tag_value = NULL;
@@ -396,7 +393,7 @@ static void get_icu_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAMETERS)
}
if(loc_name_len == 0) {
- loc_name = INTL_G(default_locale);
+ loc_name = intl_locale_get_default(TSRMLS_C);
}
/* Call ICU get */
@@ -468,10 +465,10 @@ PHP_FUNCTION(locale_get_primary_language )
}}} */
static void get_icu_disp_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAMETERS)
{
- char* loc_name = NULL;
+ const char* loc_name = NULL;
int loc_name_len = 0;
- char* disp_loc_name = NULL;
+ const char* disp_loc_name = NULL;
int disp_loc_name_len = 0;
int free_loc_name = 0;
@@ -502,7 +499,7 @@ static void get_icu_disp_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAME
}
if(loc_name_len == 0) {
- loc_name = INTL_G(default_locale);
+ loc_name = intl_locale_get_default(TSRMLS_C);
}
if( strcmp(tag_name, DISP_NAME) != 0 ){
@@ -524,7 +521,7 @@ static void get_icu_disp_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAME
/* Check if disp_loc_name passed , if not use default locale */
if( !disp_loc_name){
- disp_loc_name = estrdup(INTL_G(default_locale));
+ disp_loc_name = estrdup(intl_locale_get_default(TSRMLS_C));
free_loc_name = 1;
}
@@ -564,7 +561,7 @@ static void get_icu_disp_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAME
efree( mod_loc_name );
}
if (free_loc_name) {
- efree(disp_loc_name);
+ efree((void *)disp_loc_name);
disp_loc_name = NULL;
}
RETURN_FALSE;
@@ -575,7 +572,7 @@ static void get_icu_disp_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAME
efree( mod_loc_name );
}
if (free_loc_name) {
- efree(disp_loc_name);
+ efree((void *)disp_loc_name);
disp_loc_name = NULL;
}
/* Convert display locale name from UTF-16 to UTF-8. */
@@ -669,10 +666,10 @@ PHP_FUNCTION( locale_get_keywords )
UEnumeration* e = NULL;
UErrorCode status = U_ZERO_ERROR;
- const char* kw_key = NULL;
+ const char* kw_key = NULL;
int32_t kw_key_len = 0;
- char* loc_name = NULL;
+ const char* loc_name = NULL;
int loc_name_len = 0;
/*
@@ -696,7 +693,7 @@ PHP_FUNCTION( locale_get_keywords )
}
if(loc_name_len == 0) {
- loc_name = INTL_G(default_locale);
+ loc_name = intl_locale_get_default(TSRMLS_C);
}
/* Get the keywords */
@@ -719,7 +716,7 @@ PHP_FUNCTION( locale_get_keywords )
kw_value = erealloc( kw_value , kw_value_len+1);
}
if (U_FAILURE(status)) {
- intl_error_set( NULL, FAILURE, "locale_get_keywords: Error encountered while getting the keyword value for the keyword", 0 TSRMLS_CC );
+ intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "locale_get_keywords: Error encountered while getting the keyword value for the keyword", 0 TSRMLS_CC );
if( kw_value){
efree( kw_value );
}
@@ -977,12 +974,12 @@ PHP_FUNCTION(locale_compose)
* e.g. for locale='en_US-x-prv1-prv2-prv3'
* returns a pointer to the string 'prv1-prv2-prv3'
*/
-static char* get_private_subtags(char* loc_name)
+static char* get_private_subtags(const char* loc_name)
{
char* result =NULL;
int singletonPos = 0;
int len =0;
- char* mod_loc_name =NULL;
+ const char* mod_loc_name =NULL;
if( loc_name && (len = strlen(loc_name)>0 ) ){
mod_loc_name = loc_name ;
@@ -1022,7 +1019,7 @@ static char* get_private_subtags(char* loc_name)
/* {{{ code used by locale_parse
*/
-static int add_array_entry(char* loc_name, zval* hash_arr, char* key_name TSRMLS_DC)
+static int add_array_entry(const char* loc_name, zval* hash_arr, char* key_name TSRMLS_DC)
{
char* key_value = NULL;
char* cur_key_name = NULL;
@@ -1087,7 +1084,7 @@ static int add_array_entry(char* loc_name, zval* hash_arr, char* key_name TSRMLS
*/
PHP_FUNCTION(locale_parse)
{
- char* loc_name = NULL;
+ const char* loc_name = NULL;
int loc_name_len = 0;
int grOffset = 0;
@@ -1103,7 +1100,7 @@ PHP_FUNCTION(locale_parse)
}
if(loc_name_len == 0) {
- loc_name = INTL_G(default_locale);
+ loc_name = intl_locale_get_default(TSRMLS_C);
}
array_init( return_value );
@@ -1131,8 +1128,8 @@ PHP_FUNCTION(locale_parse)
*/
PHP_FUNCTION(locale_get_all_variants)
{
- char* loc_name = NULL;
- int loc_name_len = 0;
+ const char* loc_name = NULL;
+ int loc_name_len = 0;
int result = 0;
char* token = NULL;
@@ -1151,7 +1148,7 @@ PHP_FUNCTION(locale_get_all_variants)
}
if(loc_name_len == 0) {
- loc_name = INTL_G(default_locale);
+ loc_name = intl_locale_get_default(TSRMLS_C);
}
@@ -1185,10 +1182,10 @@ PHP_FUNCTION(locale_get_all_variants)
/*{{{
* Converts to lower case and also replaces all hyphens with the underscore
*/
-static int strToMatch(char* str ,char *retstr)
+static int strToMatch(const char* str ,char *retstr)
{
char* anchor = NULL;
- char* anchor1 = NULL;
+ const char* anchor1 = NULL;
int result = 0;
int len = 0;
@@ -1228,7 +1225,7 @@ PHP_FUNCTION(locale_filter_matches)
{
char* lang_tag = NULL;
int lang_tag_len = 0;
- char* loc_range = NULL;
+ const char* loc_range = NULL;
int loc_range_len = 0;
int result = 0;
@@ -1257,7 +1254,7 @@ PHP_FUNCTION(locale_filter_matches)
}
if(loc_range_len == 0) {
- loc_range = INTL_G(default_locale);
+ loc_range = intl_locale_get_default(TSRMLS_C);
}
if( strcmp(loc_range,"*")==0){
@@ -1404,7 +1401,7 @@ static void array_cleanup( char* arr[] , int arr_size)
* returns the lookup result to lookup_loc_range_src_php
* internal function
*/
-static char* lookup_loc_range(char* loc_range, HashTable* hash_arr, int canonicalize TSRMLS_DC)
+static char* lookup_loc_range(const char* loc_range, HashTable* hash_arr, int canonicalize TSRMLS_DC)
{
int i = 0;
int cur_arr_len = 0;
@@ -1526,7 +1523,7 @@ PHP_FUNCTION(locale_lookup)
{
char* fallback_loc = NULL;
int fallback_loc_len = 0;
- char* loc_range = NULL;
+ const char* loc_range = NULL;
int loc_range_len = 0;
zval* arr = NULL;
@@ -1543,7 +1540,7 @@ PHP_FUNCTION(locale_lookup)
}
if(loc_range_len == 0) {
- loc_range = INTL_G(default_locale);
+ loc_range = intl_locale_get_default(TSRMLS_C);
}
hash_arr = HASH_OF(arr);
diff --git a/ext/intl/msgformat/msgformat.c b/ext/intl/msgformat/msgformat.c
index e3fb9425a9..7d8cd958e3 100644
--- a/ext/intl/msgformat/msgformat.c
+++ b/ext/intl/msgformat/msgformat.c
@@ -28,7 +28,7 @@
/* {{{ */
static void msgfmt_ctor(INTERNAL_FUNCTION_PARAMETERS)
{
- char* locale;
+ const char* locale;
char* pattern;
int locale_len = 0, pattern_len = 0;
UChar* spattern = NULL;
@@ -61,7 +61,7 @@ static void msgfmt_ctor(INTERNAL_FUNCTION_PARAMETERS)
}
if(locale_len == 0) {
- locale = INTL_G(default_locale);
+ locale = intl_locale_get_default(TSRMLS_C);
}
#ifdef MSG_FORMAT_QUOTE_APOS
diff --git a/ext/intl/msgformat/msgformat_attr.c b/ext/intl/msgformat/msgformat_attr.c
index ed2dae27d1..c333a24ee1 100644
--- a/ext/intl/msgformat/msgformat_attr.c
+++ b/ext/intl/msgformat/msgformat_attr.c
@@ -102,6 +102,12 @@ PHP_FUNCTION( msgfmt_set_pattern )
}
mfo->mf_data.orig_format = estrndup(value, value_len);
mfo->mf_data.orig_format_len = value_len;
+ /* invalidate cached format types */
+ if (mfo->mf_data.arg_types) {
+ zend_hash_destroy(mfo->mf_data.arg_types);
+ efree(mfo->mf_data.arg_types);
+ mfo->mf_data.arg_types = NULL;
+ }
RETURN_TRUE;
}
diff --git a/ext/intl/msgformat/msgformat_data.c b/ext/intl/msgformat/msgformat_data.c
index 527c1d4d17..5d49054473 100644
--- a/ext/intl/msgformat/msgformat_data.c
+++ b/ext/intl/msgformat/msgformat_data.c
@@ -31,8 +31,10 @@ void msgformat_data_init( msgformat_data* mf_data TSRMLS_DC )
if( !mf_data )
return;
- mf_data->umsgf = NULL;
- mf_data->orig_format = NULL;
+ mf_data->umsgf = NULL;
+ mf_data->orig_format = NULL;
+ mf_data->arg_types = NULL;
+ mf_data->tz_set = 0;
intl_error_reset( &mf_data->error TSRMLS_CC );
}
/* }}} */
@@ -40,21 +42,27 @@ void msgformat_data_init( msgformat_data* mf_data TSRMLS_DC )
/* {{{ void msgformat_data_free( msgformat_data* mf_data )
* Clean up memory allocated for msgformat_data
*/
-void msgformat_data_free( msgformat_data* mf_data TSRMLS_DC )
+void msgformat_data_free(msgformat_data* mf_data TSRMLS_DC)
{
- if( !mf_data )
+ if (!mf_data)
return;
- if( mf_data->umsgf )
- umsg_close( mf_data->umsgf );
+ if (mf_data->umsgf)
+ umsg_close(mf_data->umsgf);
- if(mf_data->orig_format) {
+ if (mf_data->orig_format) {
efree(mf_data->orig_format);
mf_data->orig_format = NULL;
}
+ if (mf_data->arg_types) {
+ zend_hash_destroy(mf_data->arg_types);
+ efree(mf_data->arg_types);
+ mf_data->arg_types = NULL;
+ }
+
mf_data->umsgf = NULL;
- intl_error_reset( &mf_data->error TSRMLS_CC );
+ intl_error_reset(&mf_data->error TSRMLS_CC);
}
/* }}} */
diff --git a/ext/intl/msgformat/msgformat_data.h b/ext/intl/msgformat/msgformat_data.h
index 6479888f8f..51d7687a3a 100644
--- a/ext/intl/msgformat/msgformat_data.h
+++ b/ext/intl/msgformat/msgformat_data.h
@@ -31,6 +31,8 @@ typedef struct {
UMessageFormat* umsgf;
char* orig_format;
ulong orig_format_len;
+ HashTable* arg_types;
+ int tz_set; /* if we've already the time zone in sub-formats */
} msgformat_data;
msgformat_data* msgformat_data_create( TSRMLS_D );
diff --git a/ext/intl/msgformat/msgformat_format.c b/ext/intl/msgformat/msgformat_format.c
index 9a18ac0a70..55ec9e84ba 100644
--- a/ext/intl/msgformat/msgformat_format.c
+++ b/ext/intl/msgformat/msgformat_format.c
@@ -32,51 +32,34 @@
#endif
/* {{{ */
-static void msgfmt_do_format(MessageFormatter_object *mfo, zval *args, zval *return_value TSRMLS_DC)
+static void msgfmt_do_format(MessageFormatter_object *mfo, zval *args, zval *return_value TSRMLS_DC)
{
- zval **fargs;
int count;
UChar* formatted = NULL;
int formatted_len = 0;
- HashPosition pos;
- int i;
+ HashTable *args_copy;
count = zend_hash_num_elements(Z_ARRVAL_P(args));
- if(count < umsg_format_arg_count(MSG_FORMAT_OBJECT(mfo))) {
- /* Not enough aguments for format! */
- intl_error_set( INTL_DATA_ERROR_P(mfo), U_ILLEGAL_ARGUMENT_ERROR,
- "msgfmt_format: not enough parameters", 0 TSRMLS_CC );
- RETVAL_FALSE;
- return;
- }
-
- fargs = safe_emalloc(count, sizeof(zval *), 0);
+ ALLOC_HASHTABLE(args_copy);
+ zend_hash_init(args_copy, count, NULL, ZVAL_PTR_DTOR, 0);
+ zend_hash_copy(args_copy, Z_ARRVAL_P(args), (copy_ctor_func_t)zval_add_ref,
+ NULL, sizeof(zval*));
- zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(args), &pos);
- for(i=0;i<count;i++) {
- zval **val;
- zend_hash_get_current_data_ex(Z_ARRVAL_P(args), (void **)&val, &pos);
- fargs[i] = *val;
- Z_ADDREF_P(fargs[i]);
- /* TODO: needs refcount increase here? */
- zend_hash_move_forward_ex(Z_ARRVAL_P(args), &pos);
- }
+ umsg_format_helper(mfo, args_copy, &formatted, &formatted_len TSRMLS_CC);
- umsg_format_helper(MSG_FORMAT_OBJECT(mfo), count, fargs, &formatted, &formatted_len, &INTL_DATA_ERROR_CODE(mfo) TSRMLS_CC);
-
- for(i=0;i<count;i++) {
- zval_ptr_dtor(&fargs[i]);
- }
+ zend_hash_destroy(args_copy);
+ efree(args_copy);
- efree(fargs);
-
- if (formatted && U_FAILURE( INTL_DATA_ERROR_CODE(mfo) ) ) {
+ if (formatted && U_FAILURE(INTL_DATA_ERROR_CODE(mfo))) {
efree(formatted);
}
- INTL_METHOD_CHECK_STATUS( mfo, "Number formatting failed" );
- INTL_METHOD_RETVAL_UTF8( mfo, formatted, formatted_len, 1 );
+ if (U_FAILURE(INTL_DATA_ERROR_CODE(mfo))) {
+ RETURN_FALSE;
+ } else {
+ INTL_METHOD_RETVAL_UTF8(mfo, formatted, formatted_len, 1);
+ }
}
/* }}} */
@@ -120,7 +103,7 @@ PHP_FUNCTION( msgfmt_format_message )
int spattern_len = 0;
char *pattern = NULL;
int pattern_len = 0;
- char *slocale = NULL;
+ const char *slocale = NULL;
int slocale_len = 0;
MessageFormatter_object mf = {0};
MessageFormatter_object *mfo = &mf;
@@ -151,7 +134,7 @@ PHP_FUNCTION( msgfmt_format_message )
}
if(slocale_len == 0) {
- slocale = INTL_G(default_locale);
+ slocale = intl_locale_get_default(TSRMLS_C);
}
#ifdef MSG_FORMAT_QUOTE_APOS
diff --git a/ext/intl/msgformat/msgformat_helpers.cpp b/ext/intl/msgformat/msgformat_helpers.cpp
index 1895de2c86..f75fd91dce 100644
--- a/ext/intl/msgformat/msgformat_helpers.cpp
+++ b/ext/intl/msgformat/msgformat_helpers.cpp
@@ -18,9 +18,20 @@
#include "config.h"
#endif
-#include <math.h>
+#include "../intl_cppshims.h"
+
+#include <limits.h>
#include <unicode/msgfmt.h>
#include <unicode/chariter.h>
+#include <unicode/ustdio.h>
+#include <unicode/timezone.h>
+#include <unicode/datefmt.h>
+#include <unicode/calendar.h>
+
+#include <vector>
+
+#include "../intl_convertcpp.h"
+#include "../common/common_date.h"
extern "C" {
#include "php_intl.h"
@@ -28,8 +39,14 @@ extern "C" {
#include "msgformat_format.h"
#include "msgformat_helpers.h"
#include "intl_convert.h"
+#define USE_TIMEZONE_POINTER
+#include "../timezone/timezone_class.h"
}
+#if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 48
+#define HAS_MESSAGE_PATTERN 1
+#endif
+
U_NAMESPACE_BEGIN
/**
* This class isolates our access to private internal methods of
@@ -40,96 +57,581 @@ class MessageFormatAdapter {
public:
static const Formattable::Type* getArgTypeList(const MessageFormat& m,
int32_t& count);
+#ifdef HAS_MESSAGE_PATTERN
+ static const MessagePattern getMessagePattern(MessageFormat* m);
+#endif
};
+
const Formattable::Type*
MessageFormatAdapter::getArgTypeList(const MessageFormat& m,
int32_t& count) {
return m.getArgTypeList(count);
}
+
+#ifdef HAS_MESSAGE_PATTERN
+const MessagePattern
+MessageFormatAdapter::getMessagePattern(MessageFormat* m) {
+ return m->msgPattern;
+}
+#endif
U_NAMESPACE_END
-U_CFUNC int32_t umsg_format_arg_count(UMessageFormat *fmt)
+U_CFUNC int32_t umsg_format_arg_count(UMessageFormat *fmt)
{
int32_t fmt_count = 0;
MessageFormatAdapter::getArgTypeList(*(const MessageFormat*)fmt, fmt_count);
return fmt_count;
}
-U_CFUNC void umsg_format_helper(UMessageFormat *fmt, int arg_count, zval **args, UChar **formatted, int *formatted_len, UErrorCode *status TSRMLS_DC)
+static HashTable *umsg_get_numeric_types(MessageFormatter_object *mfo,
+ intl_error& err TSRMLS_DC)
{
- int fmt_count = 0;
- const Formattable::Type* argTypes =
- MessageFormatAdapter::getArgTypeList(*(const MessageFormat*)fmt, fmt_count);
- Formattable* fargs = new Formattable[fmt_count ? fmt_count : 1];
+ HashTable *ret;
+ int32_t parts_count;
- for(int32_t i = 0; i < fmt_count; ++i) {
- UChar *stringVal = NULL;
- int stringLen = 0;
- int64_t tInt64 = 0;
+ if (U_FAILURE(err.code)) {
+ return NULL;
+ }
- switch(argTypes[i]) {
- case Formattable::kDate:
- convert_to_long_ex(&args[i]);
- fargs[i].setDate(U_MILLIS_PER_SECOND * (double)Z_LVAL_P(args[i]));
- break;
+ if (mfo->mf_data.arg_types) {
+ /* already cached */
+ return mfo->mf_data.arg_types;
+ }
- case Formattable::kDouble:
- convert_to_double_ex(&args[i]);
- fargs[i].setDouble(Z_DVAL_P(args[i]));
- break;
-
- case Formattable::kLong:
- convert_to_long_ex(&args[i]);
- fargs[i].setLong(Z_LVAL_P(args[i]));
- break;
+ const Formattable::Type *types = MessageFormatAdapter::getArgTypeList(
+ *(MessageFormat*)mfo->mf_data.umsgf, parts_count);
+
+ /* Hash table will store Formattable::Type objects directly,
+ * so no need for destructor */
+ ALLOC_HASHTABLE(ret);
+ zend_hash_init(ret, parts_count, NULL, NULL, 0);
+
+ for (int i = 0; i < parts_count; i++) {
+ const Formattable::Type t = types[i];
+ if (zend_hash_index_update(ret, (ulong)i, (void*)&t, sizeof(t), NULL)
+ == FAILURE) {
+ intl_errors_set(&err, U_MEMORY_ALLOCATION_ERROR,
+ "Write to argument types hash table failed", 0 TSRMLS_CC);
+ break;
+ }
+ }
+
+ if (U_FAILURE(err.code)) {
+ zend_hash_destroy(ret);
+ efree(ret);
+
+ return NULL;
+ }
+
+ mfo->mf_data.arg_types = ret;
- case Formattable::kInt64:
- if(Z_TYPE_P(args[i]) == IS_DOUBLE) {
- tInt64 = (int64_t)Z_DVAL_P(args[i]);
- } else if(Z_TYPE_P(args[i]) == IS_LONG) {
- tInt64 = (int64_t)Z_LVAL_P(args[i]);
+ return ret;
+}
+
+#ifdef HAS_MESSAGE_PATTERN
+static HashTable *umsg_parse_format(MessageFormatter_object *mfo,
+ const MessagePattern& mp,
+ intl_error& err TSRMLS_DC)
+{
+ HashTable *ret;
+ int32_t parts_count;
+
+ if (U_FAILURE(err.code)) {
+ return NULL;
+ }
+
+ if (!((MessageFormat *)mfo->mf_data.umsgf)->usesNamedArguments()) {
+ return umsg_get_numeric_types(mfo, err TSRMLS_CC);
+ }
+
+ if (mfo->mf_data.arg_types) {
+ /* already cached */
+ return mfo->mf_data.arg_types;
+ }
+
+ /* Hash table will store Formattable::Type objects directly,
+ * so no need for destructor */
+ ALLOC_HASHTABLE(ret);
+ zend_hash_init(ret, 32, NULL, NULL, 0);
+
+ parts_count = mp.countParts();
+
+ // See MessageFormat::cacheExplicitFormats()
+ /*
+ * Looking through the pattern, go to each arg_start part type.
+ * The arg-typeof that tells us the argument type (simple, complicated)
+ * then the next part is either the arg_name or arg number
+ * and then if it's simple after that there could be a part-type=arg-type
+ * while substring will tell us number, spellout, etc.
+ * If the next thing isn't an arg-type then assume string.
+ */
+ /* The last two "parts" can at most be ARG_LIMIT and MSG_LIMIT
+ * which we need not examine. */
+ for (int32_t i = 0; i < parts_count - 2 && U_SUCCESS(err.code); i++) {
+ MessagePattern::Part p = mp.getPart(i);
+
+ if (p.getType() != UMSGPAT_PART_TYPE_ARG_START) {
+ continue;
+ }
+
+ MessagePattern::Part name_part = mp.getPart(++i); /* Getting name, advancing i */
+ Formattable::Type type,
+ *storedType;
+
+ if (name_part.getType() == UMSGPAT_PART_TYPE_ARG_NAME) {
+ UnicodeString argName = mp.getSubstring(name_part);
+ if (zend_hash_find(ret, (char*)argName.getBuffer(), argName.length(),
+ (void**)&storedType) == FAILURE) {
+ /* not found already; create new entry in HT */
+ Formattable::Type bogusType = Formattable::kObject;
+ if (zend_hash_update(ret, (char*)argName.getBuffer(), argName.length(),
+ (void*)&bogusType, sizeof(bogusType), (void**)&storedType) == FAILURE) {
+ intl_errors_set(&err, U_MEMORY_ALLOCATION_ERROR,
+ "Write to argument types hash table failed", 0 TSRMLS_CC);
+ continue;
+ }
+ }
+ } else if (name_part.getType() == UMSGPAT_PART_TYPE_ARG_NUMBER) {
+ int32_t argNumber = name_part.getValue();
+ if (argNumber < 0) {
+ intl_errors_set(&err, U_INVALID_FORMAT_ERROR,
+ "Found part with negative number", 0 TSRMLS_CC);
+ continue;
+ }
+ if (zend_hash_index_find(ret, (ulong)argNumber, (void**)&storedType)
+ == FAILURE) {
+ /* not found already; create new entry in HT */
+ Formattable::Type bogusType = Formattable::kObject;
+ if (zend_hash_index_update(ret, (ulong)argNumber, (void*)&bogusType,
+ sizeof(bogusType), (void**)&storedType) == FAILURE) {
+ intl_errors_set(&err, U_MEMORY_ALLOCATION_ERROR,
+ "Write to argument types hash table failed", 0 TSRMLS_CC);
+ continue;
+ }
+ }
+ } else {
+ intl_errors_set(&err, U_INVALID_FORMAT_ERROR, "Invalid part type encountered", 0 TSRMLS_CC);
+ continue;
+ }
+
+ UMessagePatternArgType argType = p.getArgType();
+ /* No type specified, treat it as a string */
+ if (argType == UMSGPAT_ARG_TYPE_NONE) {
+ type = Formattable::kString;
+ } else { /* Some type was specified, might be simple or complicated */
+ if (argType == UMSGPAT_ARG_TYPE_SIMPLE) {
+ /* For a SIMPLE arg, after the name part, there should be
+ * an ARG_TYPE part whose string value tells us what to do */
+ MessagePattern::Part type_part = mp.getPart(++i); /* Getting type, advancing i */
+ if (type_part.getType() == UMSGPAT_PART_TYPE_ARG_TYPE) {
+ UnicodeString typeString = mp.getSubstring(type_part);
+ /* This is all based on the rules in the docs for MessageFormat
+ * @see http://icu-project.org/apiref/icu4c/classMessageFormat.html */
+ if (typeString == "number") {
+ MessagePattern::Part style_part = mp.getPart(i + 1); /* Not advancing i */
+ if (style_part.getType() == UMSGPAT_PART_TYPE_ARG_STYLE) {
+ UnicodeString styleString = mp.getSubstring(style_part);
+ if (styleString == "integer") {
+ type = Formattable::kInt64;
+ } else if (styleString == "currency") {
+ type = Formattable::kDouble;
+ } else if (styleString == "percent") {
+ type = Formattable::kDouble;
+ } else { /* some style invalid/unknown to us */
+ type = Formattable::kDouble;
+ }
+ } else { // if missing style, part, make it a double
+ type = Formattable::kDouble;
+ }
+ } else if ((typeString == "date") || (typeString == "time")) {
+ type = Formattable::kDate;
+ } else if ((typeString == "spellout") || (typeString == "ordinal")
+ || (typeString == "duration")) {
+ type = Formattable::kDouble;
+ }
} else {
- SEPARATE_ZVAL_IF_NOT_REF(&args[i]);
- convert_scalar_to_number( args[i] TSRMLS_CC );
- tInt64 = (Z_TYPE_P(args[i]) == IS_DOUBLE)?(int64_t)Z_DVAL_P(args[i]):Z_LVAL_P(args[i]);
+ /* If there's no UMSGPAT_PART_TYPE_ARG_TYPE right after a
+ * UMSGPAT_ARG_TYPE_SIMPLE argument, then the pattern
+ * is broken. */
+ intl_errors_set(&err, U_PARSE_ERROR,
+ "Expected UMSGPAT_PART_TYPE_ARG_TYPE part following "
+ "UMSGPAT_ARG_TYPE_SIMPLE part", 0 TSRMLS_CC);
+ continue;
+ }
+ } else if (argType == UMSGPAT_ARG_TYPE_PLURAL) {
+ type = Formattable::kDouble;
+ } else if (argType == UMSGPAT_ARG_TYPE_CHOICE) {
+ type = Formattable::kDouble;
+ } else if (argType == UMSGPAT_ARG_TYPE_SELECT) {
+ type = Formattable::kString;
+ } else {
+ type = Formattable::kString;
+ }
+ } /* was type specified? */
+
+ /* We found a different type for the same arg! */
+ if (*storedType != Formattable::kObject && *storedType != type) {
+ intl_errors_set(&err, U_ARGUMENT_TYPE_MISMATCH,
+ "Inconsistent types declared for an argument", 0 TSRMLS_CC);
+ continue;
+ }
+
+ *storedType = type;
+ } /* visiting each part */
+
+ if (U_FAILURE(err.code)) {
+ zend_hash_destroy(ret);
+ efree(ret);
+
+ return NULL;
+ }
+
+ mfo->mf_data.arg_types = ret;
+
+ return ret;
+}
+#endif
+
+static HashTable *umsg_get_types(MessageFormatter_object *mfo,
+ intl_error& err TSRMLS_DC)
+{
+ MessageFormat *mf = (MessageFormat *)mfo->mf_data.umsgf;
+
+#ifdef HAS_MESSAGE_PATTERN
+ const MessagePattern mp = MessageFormatAdapter::getMessagePattern(mf);
+
+ return umsg_parse_format(mfo, mp, err TSRMLS_CC);
+#else
+ if (mf->usesNamedArguments()) {
+ intl_errors_set(&err, U_UNSUPPORTED_ERROR,
+ "This extension supports named arguments only on ICU 4.8+",
+ 0 TSRMLS_CC);
+ return NULL;
+ }
+ return umsg_get_numeric_types(mfo, err TSRMLS_CC);
+#endif
+}
+
+static void umsg_set_timezone(MessageFormatter_object *mfo,
+ intl_error& err TSRMLS_DC)
+{
+ MessageFormat *mf = (MessageFormat *)mfo->mf_data.umsgf;
+ TimeZone *used_tz = NULL;
+ const Format **formats;
+ int32_t count;
+
+ /* Unfortanely, this cannot change the time zone for arguments that
+ * appear inside complex formats because ::getFormats() returns NULL
+ * for all uncached formats, which is the case for complex formats
+ * unless they were set via one of the ::setFormat() methods */
+
+ if (mfo->mf_data.tz_set) {
+ return; /* already done */
+ }
+
+ formats = mf->getFormats(count);
+
+ if (formats == NULL) {
+ intl_errors_set(&err, U_MEMORY_ALLOCATION_ERROR,
+ "Out of memory retrieving subformats", 0 TSRMLS_CC);
+ }
+
+ for (int i = 0; U_SUCCESS(err.code) && i < count; i++) {
+ DateFormat* df = dynamic_cast<DateFormat*>(
+ const_cast<Format *>(formats[i]));
+ if (df == NULL) {
+ continue;
+ }
+
+ if (used_tz == NULL) {
+ zval nullzv = zval_used_for_init,
+ *zvptr = &nullzv;
+ used_tz = timezone_process_timezone_argument(&zvptr, &err,
+ "msgfmt_format" TSRMLS_CC);
+ if (used_tz == NULL) {
+ continue;
+ }
+ }
+
+ df->setTimeZone(*used_tz);
+ }
+
+ if (U_SUCCESS(err.code)) {
+ mfo->mf_data.tz_set = 1;
+ }
+}
+
+U_CFUNC void umsg_format_helper(MessageFormatter_object *mfo,
+ HashTable *args,
+ UChar **formatted,
+ int *formatted_len TSRMLS_DC)
+{
+ int arg_count = zend_hash_num_elements(args);
+ std::vector<Formattable> fargs;
+ std::vector<UnicodeString> farg_names;
+ MessageFormat *mf = (MessageFormat *)mfo->mf_data.umsgf;
+ HashTable *types;
+ intl_error& err = INTL_DATA_ERROR(mfo);
+
+ if (U_FAILURE(err.code)) {
+ return;
+ }
+
+ types = umsg_get_types(mfo, err TSRMLS_CC);
+
+ umsg_set_timezone(mfo, err TSRMLS_CC);
+
+ fargs.resize(arg_count);
+ farg_names.resize(arg_count);
+
+ int argNum = 0;
+ HashPosition pos;
+ zval **elem;
+
+ // Key related variables
+ int key_type;
+ char *str_index;
+ uint str_len;
+ ulong num_index;
+
+ for (zend_hash_internal_pointer_reset_ex(args, &pos);
+ U_SUCCESS(err.code) &&
+ (key_type = zend_hash_get_current_key_ex(
+ args, &str_index, &str_len, &num_index, 0, &pos),
+ zend_hash_get_current_data_ex(args, (void **)&elem, &pos)
+ ) == SUCCESS;
+ zend_hash_move_forward_ex(args, &pos), argNum++)
+ {
+ Formattable& formattable = fargs[argNum];
+ UnicodeString& key = farg_names[argNum];
+ Formattable::Type argType = Formattable::kObject, //unknown
+ *storedArgType = NULL;
+
+ /* Process key and retrieve type */
+ if (key_type == HASH_KEY_IS_LONG) {
+ /* includes case where index < 0 because it's exposed as unsigned */
+ if (num_index > (ulong)INT32_MAX) {
+ intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR,
+ "Found negative or too large array key", 0 TSRMLS_CC);
+ continue;
+ }
+
+ UChar temp[16];
+ int32_t len = u_sprintf(temp, "%u", (uint32_t)num_index);
+ key.append(temp, len);
+
+ zend_hash_index_find(types, (ulong)num_index, (void**)&storedArgType);
+ } else { //string; assumed to be in UTF-8
+ intl_stringFromChar(key, str_index, str_len-1, &err.code);
+
+ if (U_FAILURE(err.code)) {
+ char *message;
+ spprintf(&message, 0,
+ "Invalid UTF-8 data in argument key: '%s'", str_index);
+ intl_errors_set(&err, err.code, message, 1 TSRMLS_CC);
+ efree(message);
+ continue;
+ }
+
+ zend_hash_find(types, (char*)key.getBuffer(), key.length(),
+ (void**)&storedArgType);
+ }
+
+ if (storedArgType != NULL) {
+ argType = *storedArgType;
+ }
+
+ /* Convert zval to formattable according to message format type
+ * or (as a fallback) the zval type */
+ if (argType != Formattable::kObject) {
+ switch (argType) {
+ case Formattable::kString:
+ {
+ string_arg:
+ /* This implicitly converts objects
+ * Note that our vectors will leak if object conversion fails
+ * and PHP ends up with a fatal error and calls longjmp
+ * as a result of that.
+ */
+ convert_to_string_ex(elem);
+
+ UnicodeString *text = new UnicodeString();
+ intl_stringFromChar(*text,
+ Z_STRVAL_PP(elem), Z_STRLEN_PP(elem), &err.code);
+
+ if (U_FAILURE(err.code)) {
+ char *message;
+ spprintf(&message, 0, "Invalid UTF-8 data in string argument: "
+ "'%s'", Z_STRVAL_PP(elem));
+ intl_errors_set(&err, err.code, message, 1 TSRMLS_CC);
+ efree(message);
+ delete text;
+ continue;
+ }
+ formattable.adoptString(text);
+ break;
}
- fargs[i].setInt64(tInt64);
+ case Formattable::kDouble:
+ {
+ double d;
+ if (Z_TYPE_PP(elem) == IS_DOUBLE) {
+ d = Z_DVAL_PP(elem);
+ } else if (Z_TYPE_PP(elem) == IS_LONG) {
+ d = (double)Z_LVAL_PP(elem);
+ } else {
+ SEPARATE_ZVAL_IF_NOT_REF(elem);
+ convert_scalar_to_number(*elem TSRMLS_CC);
+ d = (Z_TYPE_PP(elem) == IS_DOUBLE)
+ ? Z_DVAL_PP(elem)
+ : (double)Z_LVAL_PP(elem);
+ }
+ formattable.setDouble(d);
+ break;
+ }
+ case Formattable::kLong:
+ {
+ int32_t tInt32 = 0;
+retry_klong:
+ if (Z_TYPE_PP(elem) == IS_DOUBLE) {
+ if (Z_DVAL_PP(elem) > (double)INT32_MAX ||
+ Z_DVAL_PP(elem) < (double)INT32_MIN) {
+ intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR,
+ "Found PHP float with absolute value too large for "
+ "32 bit integer argument", 0 TSRMLS_CC);
+ } else {
+ tInt32 = (int32_t)Z_DVAL_PP(elem);
+ }
+ } else if (Z_TYPE_PP(elem) == IS_LONG) {
+ if (Z_LVAL_PP(elem) > INT32_MAX ||
+ Z_LVAL_PP(elem) < INT32_MIN) {
+ intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR,
+ "Found PHP integer with absolute value too large "
+ "for 32 bit integer argument", 0 TSRMLS_CC);
+ } else {
+ tInt32 = (int32_t)Z_LVAL_PP(elem);
+ }
+ } else {
+ SEPARATE_ZVAL_IF_NOT_REF(elem);
+ convert_scalar_to_number(*elem TSRMLS_CC);
+ goto retry_klong;
+ }
+ formattable.setLong(tInt32);
+ break;
+ }
+ case Formattable::kInt64:
+ {
+ int64_t tInt64 = 0;
+retry_kint64:
+ if (Z_TYPE_PP(elem) == IS_DOUBLE) {
+ if (Z_DVAL_PP(elem) > (double)U_INT64_MAX ||
+ Z_DVAL_PP(elem) < (double)U_INT64_MIN) {
+ intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR,
+ "Found PHP float with absolute value too large for "
+ "64 bit integer argument", 0 TSRMLS_CC);
+ } else {
+ tInt64 = (int64_t)Z_DVAL_PP(elem);
+ }
+ } else if (Z_TYPE_PP(elem) == IS_LONG) {
+ /* assume long is not wider than 64 bits */
+ tInt64 = (int64_t)Z_LVAL_PP(elem);
+ } else {
+ SEPARATE_ZVAL_IF_NOT_REF(elem);
+ convert_scalar_to_number(*elem TSRMLS_CC);
+ goto retry_kint64;
+ }
+ formattable.setInt64(tInt64);
+ break;
+ }
+ case Formattable::kDate:
+ {
+ double dd = intl_zval_to_millis(*elem, &err, "msgfmt_format" TSRMLS_CC);
+ if (U_FAILURE(err.code)) {
+ char *message, *key_char;
+ int key_len;
+ UErrorCode status = UErrorCode();
+ if (intl_charFromString(key, &key_char, &key_len,
+ &status) == SUCCESS) {
+ spprintf(&message, 0, "The argument for key '%s' "
+ "cannot be used as a date or time", key_char);
+ intl_errors_set(&err, err.code, message, 1 TSRMLS_CC);
+ efree(key_char);
+ efree(message);
+ }
+ continue;
+ }
+ formattable.setDate(dd);
+ break;
+ }
+ default:
+ intl_errors_set(&err, U_ILLEGAL_ARGUMENT_ERROR,
+ "Found unsupported argument type", 0 TSRMLS_CC);
+ break;
+ }
+ } else {
+ /* We couldn't find any information about the argument in the pattern, this
+ * means it's an extra argument. So convert it to a number if it's a number or
+ * bool or null and to a string if it's anything else except arrays . */
+ switch (Z_TYPE_PP(elem)) {
+ case IS_DOUBLE:
+ formattable.setDouble(Z_DVAL_PP(elem));
break;
-
- case Formattable::kString:
- convert_to_string_ex(&args[i]);
- intl_convert_utf8_to_utf16(&stringVal, &stringLen, Z_STRVAL_P(args[i]), Z_STRLEN_P(args[i]), status);
- if(U_FAILURE(*status)){
- delete[] fargs;
- return;
+ case IS_BOOL:
+ convert_to_long_ex(elem);
+ /* Intentional fallthrough */
+ case IS_LONG:
+ formattable.setInt64((int64_t)Z_LVAL_PP(elem));
+ break;
+ case IS_NULL:
+ formattable.setInt64((int64_t)0);
+ break;
+ case IS_STRING:
+ case IS_OBJECT:
+ goto string_arg;
+ default:
+ {
+ char *message, *key_char;
+ int key_len;
+ UErrorCode status = UErrorCode();
+ if (intl_charFromString(key, &key_char, &key_len,
+ &status) == SUCCESS) {
+ spprintf(&message, 0, "No strategy to convert the "
+ "value given for the argument with key '%s' "
+ "is available", key_char);
+ intl_errors_set(&err,
+ U_ILLEGAL_ARGUMENT_ERROR, message, 1 TSRMLS_CC);
+ efree(key_char);
+ efree(message);
+ }
}
- fargs[i].setString(stringVal);
- efree(stringVal);
- break;
-
- case Formattable::kArray:
- case Formattable::kObject:
- *status = U_UNSUPPORTED_ERROR;
- delete[] fargs;
- return;
- }
+ }
+ }
+ } // visiting each argument
+
+ if (U_FAILURE(err.code)) {
+ return;
}
- UnicodeString resultStr;
- FieldPosition fieldPosition(0);
-
- /* format the message */
- ((const MessageFormat*)fmt)->format(fargs, fmt_count, resultStr, fieldPosition, *status);
+ UnicodeString resultStr;
+ FieldPosition fieldPosition(0);
- delete[] fargs;
+ /* format the message */
+ mf->format(farg_names.empty() ? NULL : &farg_names[0],
+ fargs.empty() ? NULL : &fargs[0], arg_count, resultStr, err.code);
- if(U_FAILURE(*status)){
- return;
- }
+ if (U_FAILURE(err.code)) {
+ intl_errors_set(&err, err.code,
+ "Call to ICU MessageFormat::format() has failed", 0 TSRMLS_CC);
+ return;
+ }
*formatted_len = resultStr.length();
*formatted = eumalloc(*formatted_len+1);
- resultStr.extract(*formatted, *formatted_len+1, *status);
+ resultStr.extract(*formatted, *formatted_len+1, err.code);
+ if (U_FAILURE(err.code)) {
+ intl_errors_set(&err, err.code,
+ "Error copying format() result", 0 TSRMLS_CC);
+ return;
+ }
}
#define cleanup_zvals() for(int j=i;j>=0;j--) { zval_ptr_dtor((*args)+i); }
@@ -154,15 +656,11 @@ U_CFUNC void umsg_parse_helper(UMessageFormat *fmt, int *count, zval ***args, UC
int stmp_len;
ALLOC_INIT_ZVAL((*args)[i]);
-
+
switch(fargs[i].getType()) {
case Formattable::kDate:
aDate = ((double)fargs[i].getDate())/U_MILLIS_PER_SECOND;
- if(aDate > LONG_MAX || aDate < -LONG_MAX) {
- ZVAL_DOUBLE((*args)[i], aDate<0?ceil(aDate):floor(aDate));
- } else {
- ZVAL_LONG((*args)[i], (long)aDate);
- }
+ ZVAL_DOUBLE((*args)[i], aDate);
break;
case Formattable::kDouble:
diff --git a/ext/intl/msgformat/msgformat_helpers.h b/ext/intl/msgformat/msgformat_helpers.h
index 30c7e3930f..e6eda087d2 100644
--- a/ext/intl/msgformat/msgformat_helpers.h
+++ b/ext/intl/msgformat/msgformat_helpers.h
@@ -17,9 +17,9 @@
#ifndef MSG_FORMAT_HELPERS_H
#define MSG_FORMAT_HELPERS_H
-int32_t umsg_format_arg_count(UMessageFormat *fmt);
-void umsg_format_helper(UMessageFormat *fmt, int arg_count, zval **args,
- UChar **formatted, int *formatted_len, UErrorCode *status TSRMLS_DC);
+int32_t umsg_format_arg_count(UMessageFormat *fmt);
+void umsg_format_helper(MessageFormatter_object *mfo, HashTable *args,
+ UChar **formatted, int *formatted_len TSRMLS_DC);
void umsg_parse_helper(UMessageFormat *fmt, int *count, zval ***args,
UChar *source, int source_len, UErrorCode *status);
#endif // MSG_FORMAT_HELPERS_H
diff --git a/ext/intl/msgformat/msgformat_parse.c b/ext/intl/msgformat/msgformat_parse.c
index f540b1d0c4..14a6363424 100644
--- a/ext/intl/msgformat/msgformat_parse.c
+++ b/ext/intl/msgformat/msgformat_parse.c
@@ -93,7 +93,7 @@ PHP_FUNCTION( msgfmt_parse_message )
int spattern_len = 0;
char *pattern = NULL;
int pattern_len = 0;
- char *slocale = NULL;
+ const char *slocale = NULL;
int slocale_len = 0;
char *source = NULL;
int src_len = 0;
@@ -126,7 +126,7 @@ PHP_FUNCTION( msgfmt_parse_message )
}
if(slocale_len == 0) {
- slocale = INTL_G(default_locale);
+ slocale = intl_locale_get_default(TSRMLS_C);
}
#ifdef MSG_FORMAT_QUOTE_APOS
diff --git a/ext/intl/php_intl.c b/ext/intl/php_intl.c
index 90e3573c1b..65e53c8b5e 100644
--- a/ext/intl/php_intl.c
+++ b/ext/intl/php_intl.c
@@ -34,6 +34,8 @@
#include "collator/collator_create.h"
#include "collator/collator_error.h"
+#include "converter/converter.h"
+
#include "formatter/formatter.h"
#include "formatter/formatter_class.h"
#include "formatter/formatter_attr.h"
@@ -41,6 +43,8 @@
#include "formatter/formatter_main.h"
#include "formatter/formatter_parse.h"
+#include "grapheme/grapheme.h"
+
#include "msgformat/msgformat.h"
#include "msgformat/msgformat_class.h"
#include "msgformat/msgformat_attr.h"
@@ -58,7 +62,9 @@
#include "dateformat/dateformat.h"
#include "dateformat/dateformat_class.h"
#include "dateformat/dateformat_attr.h"
+#include "dateformat/dateformat_attrcpp.h"
#include "dateformat/dateformat_format.h"
+#include "dateformat/dateformat_format_object.h"
#include "dateformat/dateformat_parse.h"
#include "dateformat/dateformat_data.h"
@@ -68,6 +74,16 @@
#include "transliterator/transliterator_class.h"
#include "transliterator/transliterator_methods.h"
+#include "timezone/timezone_class.h"
+#include "timezone/timezone_methods.h"
+
+#include "calendar/calendar_class.h"
+#include "calendar/calendar_methods.h"
+#include "calendar/gregoriancalendar_methods.h"
+
+#include "breakiterator/breakiterator_class.h"
+#include "breakiterator/breakiterator_iterators.h"
+
#include "idn/idn.h"
#if U_ICU_VERSION_MAJOR_NUM * 1000 + U_ICU_VERSION_MINOR_NUM >= 4002
@@ -79,8 +95,10 @@
#include "msgformat/msgformat.h"
#include "common/common_error.h"
+#include "common/common_enum.h"
#include <unicode/uloc.h>
+#include <unicode/uclean.h>
#include <ext/standard/info.h>
#include "php_ini.h"
@@ -98,6 +116,14 @@
ZEND_DECLARE_MODULE_GLOBALS( intl )
+const char *intl_locale_get_default( TSRMLS_D )
+{
+ if( INTL_G(default_locale) == NULL ) {
+ return uloc_getDefault();
+ }
+ return INTL_G(default_locale);
+}
+
/* {{{ Arguments info */
ZEND_BEGIN_ARG_INFO_EX(collator_static_0_args, 0, 0, 0)
ZEND_END_ARG_INFO()
@@ -313,6 +339,11 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_datefmt_set_pattern, 0, 0, 2)
ZEND_ARG_INFO(0, pattern)
ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO_EX(arginfo_datefmt_set_timezone, 0, 0, 2)
+ ZEND_ARG_INFO(0, mf)
+ ZEND_ARG_INFO(0, timezone)
+ZEND_END_ARG_INFO()
+
ZEND_BEGIN_ARG_INFO_EX(arginfo_datefmt_set_calendar, 0, 0, 2)
ZEND_ARG_INFO(0, mf)
ZEND_ARG_INFO(0, calendar)
@@ -323,6 +354,13 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_datefmt_format, 0, 0, 0)
ZEND_ARG_INFO(0, array)
ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO_EX(arginfo_datefmt_format_object, 0, 0, 1)
+ ZEND_ARG_INFO(0, object)
+ ZEND_ARG_INFO(0, format)
+ ZEND_ARG_INFO(0, locale)
+ZEND_END_ARG_INFO()
+
+
ZEND_BEGIN_ARG_INFO_EX(arginfo_datefmt_create, 0, 0, 3)
ZEND_ARG_INFO(0, locale)
ZEND_ARG_INFO(0, date_type)
@@ -402,6 +440,194 @@ ZEND_BEGIN_ARG_INFO_EX( arginfo_transliterator_error, 0, 0, 1 )
ZEND_ARG_OBJ_INFO( 0, trans, Transliterator, 0 )
ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO_EX( arginfo_tz_idarg_static, 0, 0, 1 )
+ ZEND_ARG_INFO( 0, zoneId )
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( arginfo_tz_from_date_time_zone, 0, 0, 1 )
+ ZEND_ARG_OBJ_INFO( 0, dateTimeZone, IntlDateTimeZone, 0 )
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( arginfo_tz_create_enumeration, 0, 0, 0 )
+ ZEND_ARG_INFO( 0, countryOrRawOffset )
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( arginfo_tz_count_equivalent_ids, 0, 0, 1 )
+ ZEND_ARG_INFO( 0, zoneId )
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( arginfo_tz_create_time_zone_id_enumeration, 0, 0, 1 )
+ ZEND_ARG_INFO( 0, zoneType )
+ ZEND_ARG_INFO( 0, region )
+ ZEND_ARG_INFO( 0, rawOffset )
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( arginfo_tz_get_canonical_id, 0, 0, 1 )
+ ZEND_ARG_INFO( 0, zoneId )
+ ZEND_ARG_INFO( 1, isSystemID )
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( arginfo_tz_get_equivalent_id, 0, 0, 2 )
+ ZEND_ARG_INFO( 0, zoneId )
+ ZEND_ARG_INFO( 0, index )
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( arginfo_tz_get_offset, 0, 0, 5 )
+ ZEND_ARG_OBJ_INFO( 0, timeZone, IntlTimeZone, 0 )
+ ZEND_ARG_INFO( 0, date )
+ ZEND_ARG_INFO( 0, local )
+ ZEND_ARG_INFO( 1, rawOffset )
+ ZEND_ARG_INFO( 1, dstOffset )
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( arginfo_tz_has_same_rules, 0, 0, 1 )
+ ZEND_ARG_OBJ_INFO( 0, timeZone, IntlTimeZone, 0 )
+ ZEND_ARG_OBJ_INFO( 0, otherTimeZone, IntlTimeZone, 0 )
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( arginfo_tz_get_display_name, 0, 0, 1 )
+ ZEND_ARG_OBJ_INFO( 0, timeZone, IntlTimeZone, 0 )
+ ZEND_ARG_INFO( 0, isDaylight )
+ ZEND_ARG_INFO( 0, style )
+ ZEND_ARG_INFO( 0, locale )
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( arginfo_tz_only_tz, 0, 0, 1 )
+ ZEND_ARG_OBJ_INFO( 0, timeZone, IntlTimeZone, 0 )
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( arginfo_tz_void, 0, 0, 0 )
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( ainfo_cal_create_instance, 0, 0, 0 )
+ ZEND_ARG_INFO( 0, timeZone )
+ ZEND_ARG_INFO( 0, locale )
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( ainfo_cal_only_cal, 0, 0, 1 )
+ ZEND_ARG_OBJ_INFO( 0, calendar, IntlCalendar, 0 )
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( ainfo_cal_void, 0, 0, 0 )
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( ainfo_cal_field, 0, 0, 2 )
+ ZEND_ARG_OBJ_INFO( 0, calendar, IntlCalendar, 0 )
+ ZEND_ARG_INFO( 0, field )
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( ainfo_cal_dow, 0, 0, 2 )
+ ZEND_ARG_OBJ_INFO( 0, calendar, IntlCalendar, 0 )
+ ZEND_ARG_INFO( 0, dayOfWeek )
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( ainfo_cal_other_cal, 0, 0, 2 )
+ ZEND_ARG_OBJ_INFO( 0, calendar, IntlCalendar, 0 )
+ ZEND_ARG_OBJ_INFO( 0, otherCalendar, IntlCalendar, 0 )
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( ainfo_cal_date, 0, 0, 2 )
+ ZEND_ARG_OBJ_INFO( 0, calendar, IntlCalendar, 0 )
+ ZEND_ARG_INFO( 0, date )
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( ainfo_cal_date_optional, 0, 0, 1 )
+ ZEND_ARG_OBJ_INFO( 0, calendar, IntlCalendar, 0 )
+ ZEND_ARG_INFO( 0, date )
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( ainfo_cal_get_keyword_values_for_locale, 0, 0, 3)
+ ZEND_ARG_INFO( 0, key )
+ ZEND_ARG_INFO( 0, locale )
+ ZEND_ARG_INFO( 0, commonlyUsed )
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( ainfo_cal_add, 0, 0, 3 )
+ ZEND_ARG_OBJ_INFO( 0, calendar, IntlCalendar, 0 )
+ ZEND_ARG_INFO( 0, field )
+ ZEND_ARG_INFO( 0, amount )
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( ainfo_cal_set_time_zone, 0, 0, 2 )
+ ZEND_ARG_OBJ_INFO( 0, calendar, IntlCalendar, 0 )
+ ZEND_ARG_INFO( 0, timeZone )
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( ainfo_cal_set, 0, 0, 3 )
+ ZEND_ARG_OBJ_INFO( 0, calendar, IntlCalendar, 0 )
+ ZEND_ARG_INFO( 0, fieldOrYear )
+ ZEND_ARG_INFO( 0, valueOrMonth )
+ ZEND_ARG_INFO( 0, dayOfMonth )
+ ZEND_ARG_INFO( 0, hour )
+ ZEND_ARG_INFO( 0, minute )
+ ZEND_ARG_INFO( 0, second )
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( ainfo_cal_roll, 0, 0, 2 )
+ ZEND_ARG_OBJ_INFO( 0, calendar, IntlCalendar, 0 )
+ ZEND_ARG_INFO( 0, field )
+ ZEND_ARG_INFO( 0, amountOrUpOrDown )
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( ainfo_cal_clear, 0, 0, 1 )
+ ZEND_ARG_OBJ_INFO( 0, calendar, IntlCalendar, 0 )
+ ZEND_ARG_INFO( 0, field )
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( ainfo_cal_field_difference, 0, 0, 3 )
+ ZEND_ARG_OBJ_INFO( 0, calendar, IntlCalendar, 0 )
+ ZEND_ARG_INFO( 0, when )
+ ZEND_ARG_INFO( 0, field )
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( ainfo_cal_get_locale, 0, 0, 2 )
+ ZEND_ARG_OBJ_INFO( 0, calendar, IntlCalendar, 0 )
+ ZEND_ARG_INFO( 0, localeType )
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( ainfo_cal_set_lenient, 0, 0, 2 )
+ ZEND_ARG_OBJ_INFO( 0, calendar, IntlCalendar, 0 )
+ ZEND_ARG_INFO( 0, isLenient )
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( ainfo_cal_set_minimal_days_in_first_week, 0, 0, 2 )
+ ZEND_ARG_OBJ_INFO( 0, calendar, IntlCalendar, 0 )
+ ZEND_ARG_INFO( 0, numberOfDays )
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_cal_from_date_time, 0, 0, 1)
+ ZEND_ARG_INFO(0, dateTime)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( ainfo_cal_wall_time_option, 0, 0, 2 )
+ ZEND_ARG_OBJ_INFO( 0, calendar, IntlCalendar, 0 )
+ ZEND_ARG_INFO( 0, wallTimeOption )
+ZEND_END_ARG_INFO()
+
+/* Gregorian Calendar */
+ZEND_BEGIN_ARG_INFO_EX( ainfo_gregcal_create_instance, 0, 0, 0 )
+ ZEND_ARG_INFO(0, timeZoneOrYear)
+ ZEND_ARG_INFO(0, localeOrMonth)
+ ZEND_ARG_INFO(0, dayOfMonth)
+ ZEND_ARG_INFO(0, hour)
+ ZEND_ARG_INFO(0, minute)
+ ZEND_ARG_INFO(0, second)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( ainfo_gregcal_is_leap_year, 0, 0, 2 )
+ ZEND_ARG_OBJ_INFO( 0, calendar, IntlGregorianCalendar, 0 )
+ ZEND_ARG_INFO( 0, year )
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( ainfo_gregcal_only_gregcal, 0, 0, 1 )
+ ZEND_ARG_OBJ_INFO( 0, calendar, IntlGregorianCalendar, 0 )
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX( ainfo_gregcal_set_gregorian_change, 0, 0, 2 )
+ ZEND_ARG_OBJ_INFO( 0, calendar, IntlGregorianCalendar, 0 )
+ ZEND_ARG_INFO( 0, date )
+ZEND_END_ARG_INFO()
+
/* }}} */
/* {{{ intl_functions
@@ -484,15 +710,19 @@ zend_function_entry intl_functions[] = {
PHP_FE( datefmt_get_datetype, arginfo_msgfmt_get_locale )
PHP_FE( datefmt_get_timetype, arginfo_msgfmt_get_locale )
PHP_FE( datefmt_get_calendar, arginfo_msgfmt_get_locale )
+ PHP_FE( datefmt_get_calendar_object, arginfo_msgfmt_get_locale )
PHP_FE( datefmt_set_calendar, arginfo_datefmt_set_calendar )
PHP_FE( datefmt_get_locale, arginfo_msgfmt_get_locale )
PHP_FE( datefmt_get_timezone_id, arginfo_msgfmt_get_locale )
- PHP_FE( datefmt_set_timezone_id, arginfo_msgfmt_get_locale )
+ PHP_FE( datefmt_set_timezone_id, arginfo_datefmt_set_timezone )
+ PHP_FE( datefmt_get_timezone, arginfo_msgfmt_get_locale )
+ PHP_FE( datefmt_set_timezone, arginfo_datefmt_set_timezone )
PHP_FE( datefmt_get_pattern, arginfo_msgfmt_get_locale )
PHP_FE( datefmt_set_pattern, arginfo_datefmt_set_pattern )
PHP_FE( datefmt_is_lenient, arginfo_msgfmt_get_locale )
PHP_FE( datefmt_set_lenient, arginfo_msgfmt_get_locale )
PHP_FE( datefmt_format, arginfo_datefmt_format )
+ PHP_FE( datefmt_format_object, arginfo_datefmt_format_object )
PHP_FE( datefmt_parse, datefmt_parse_args )
PHP_FE( datefmt_localtime , datefmt_parse_args )
PHP_FE( datefmt_get_error_code, arginfo_msgfmt_get_error_code )
@@ -530,6 +760,97 @@ zend_function_entry intl_functions[] = {
PHP_FE( transliterator_get_error_code, arginfo_transliterator_error )
PHP_FE( transliterator_get_error_message, arginfo_transliterator_error )
+ /* TimeZone functions */
+ PHP_FE( intltz_create_time_zone, arginfo_tz_idarg_static )
+ PHP_FE( intltz_from_date_time_zone, arginfo_tz_from_date_time_zone )
+ PHP_FE( intltz_create_default, arginfo_tz_void )
+ PHP_FE( intltz_get_id, arginfo_tz_only_tz )
+ PHP_FE( intltz_get_gmt, arginfo_tz_void )
+#if U_ICU_VERSION_MAJOR_NUM >= 49
+ PHP_FE( intltz_get_unknown, arginfo_tz_void )
+#endif
+ PHP_FE( intltz_create_enumeration, arginfo_tz_create_enumeration )
+ PHP_FE( intltz_count_equivalent_ids, arginfo_tz_idarg_static )
+#if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 48
+ PHP_FE( intltz_create_time_zone_id_enumeration, arginfo_tz_create_time_zone_id_enumeration )
+#endif
+ PHP_FE( intltz_get_canonical_id, arginfo_tz_get_canonical_id )
+#if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 48
+ PHP_FE( intltz_get_region, arginfo_tz_idarg_static )
+#endif
+ PHP_FE( intltz_get_tz_data_version, arginfo_tz_void )
+ PHP_FE( intltz_get_equivalent_id, arginfo_tz_get_equivalent_id )
+ PHP_FE( intltz_use_daylight_time, arginfo_tz_only_tz )
+ PHP_FE( intltz_get_offset, arginfo_tz_get_offset )
+ PHP_FE( intltz_get_raw_offset, arginfo_tz_only_tz )
+ PHP_FE( intltz_has_same_rules, arginfo_tz_has_same_rules )
+ PHP_FE( intltz_get_display_name, arginfo_tz_get_display_name )
+ PHP_FE( intltz_get_dst_savings, arginfo_tz_only_tz )
+ PHP_FE( intltz_to_date_time_zone, arginfo_tz_only_tz )
+ PHP_FE( intltz_get_error_code, arginfo_tz_only_tz )
+ PHP_FE( intltz_get_error_message, arginfo_tz_only_tz )
+
+ PHP_FE( intlcal_create_instance, ainfo_cal_create_instance )
+#if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 42
+ PHP_FE( intlcal_get_keyword_values_for_locale, ainfo_cal_get_keyword_values_for_locale )
+#endif
+ PHP_FE( intlcal_get_now, ainfo_cal_void )
+ PHP_FE( intlcal_get_available_locales, ainfo_cal_void )
+ PHP_FE( intlcal_get, ainfo_cal_field )
+ PHP_FE( intlcal_get_time, ainfo_cal_only_cal )
+ PHP_FE( intlcal_set_time, ainfo_cal_date )
+ PHP_FE( intlcal_add, ainfo_cal_add )
+ PHP_FE( intlcal_set_time_zone, ainfo_cal_set_time_zone )
+ PHP_FE( intlcal_after, ainfo_cal_other_cal )
+ PHP_FE( intlcal_before, ainfo_cal_other_cal )
+ PHP_FE( intlcal_set, ainfo_cal_set )
+ PHP_FE( intlcal_roll, ainfo_cal_roll )
+ PHP_FE( intlcal_clear, ainfo_cal_clear )
+ PHP_FE( intlcal_field_difference, ainfo_cal_field_difference )
+ PHP_FE( intlcal_get_actual_maximum, ainfo_cal_field )
+ PHP_FE( intlcal_get_actual_minimum, ainfo_cal_field )
+#if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 44
+ PHP_FE( intlcal_get_day_of_week_type, ainfo_cal_dow )
+#endif
+ PHP_FE( intlcal_get_first_day_of_week, ainfo_cal_only_cal )
+ PHP_FE( intlcal_get_greatest_minimum, ainfo_cal_field )
+ PHP_FE( intlcal_get_least_maximum, ainfo_cal_field )
+ PHP_FE( intlcal_get_locale, ainfo_cal_get_locale )
+ PHP_FE( intlcal_get_maximum, ainfo_cal_field )
+ PHP_FE( intlcal_get_minimal_days_in_first_week, ainfo_cal_only_cal )
+ PHP_FE( intlcal_get_minimum, ainfo_cal_field )
+ PHP_FE( intlcal_get_time_zone, ainfo_cal_only_cal )
+ PHP_FE( intlcal_get_type, ainfo_cal_only_cal )
+#if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 44
+ PHP_FE( intlcal_get_weekend_transition, ainfo_cal_dow )
+#endif
+ PHP_FE( intlcal_in_daylight_time, ainfo_cal_only_cal )
+ PHP_FE( intlcal_is_equivalent_to, ainfo_cal_other_cal )
+ PHP_FE( intlcal_is_lenient, ainfo_cal_only_cal )
+ PHP_FE( intlcal_is_set, ainfo_cal_field )
+#if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 44
+ PHP_FE( intlcal_is_weekend, ainfo_cal_date_optional )
+#endif
+ PHP_FE( intlcal_set_first_day_of_week, ainfo_cal_dow )
+ PHP_FE( intlcal_set_lenient, ainfo_cal_set_lenient )
+ PHP_FE( intlcal_set_minimal_days_in_first_week, ainfo_cal_set_minimal_days_in_first_week )
+ PHP_FE( intlcal_equals, ainfo_cal_other_cal )
+ PHP_FE( intlcal_from_date_time, ainfo_cal_from_date_time )
+ PHP_FE( intlcal_to_date_time, ainfo_cal_only_cal )
+#if U_ICU_VERSION_MAJOR_NUM >= 49
+ PHP_FE( intlcal_get_repeated_wall_time_option, ainfo_cal_only_cal )
+ PHP_FE( intlcal_get_skipped_wall_time_option, ainfo_cal_only_cal )
+ PHP_FE( intlcal_set_repeated_wall_time_option, ainfo_cal_wall_time_option )
+ PHP_FE( intlcal_set_skipped_wall_time_option, ainfo_cal_wall_time_option )
+#endif
+ PHP_FE( intlcal_get_error_code, ainfo_cal_only_cal )
+ PHP_FE( intlcal_get_error_message, ainfo_cal_only_cal )
+
+ PHP_FE( intlgregcal_create_instance, ainfo_gregcal_create_instance )
+ PHP_FE( intlgregcal_set_gregorian_change, ainfo_gregcal_set_gregorian_change )
+ PHP_FE( intlgregcal_get_gregorian_change, ainfo_gregcal_only_gregcal )
+ PHP_FE( intlgregcal_is_leap_year, ainfo_gregcal_is_leap_year )
+
/* common functions */
PHP_FE( intl_get_error_code, intl_0_args )
PHP_FE( intl_get_error_message, intl_0_args )
@@ -540,16 +861,14 @@ 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)
-
+ STD_PHP_INI_ENTRY("intl.use_exceptions", "0", PHP_INI_ALL, OnUpdateBool, use_exceptions, zend_intl_globals, intl_globals)
PHP_INI_END()
/* }}} */
-
static PHP_GINIT_FUNCTION(intl);
/* {{{ intl_module_entry */
@@ -640,6 +959,12 @@ PHP_MINIT_FUNCTION( intl )
/* Register Transliterator constants */
transliterator_register_constants( INIT_FUNC_ARGS_PASSTHRU );
+ /* Register 'IntlTimeZone' PHP class */
+ timezone_register_IntlTimeZone_class( TSRMLS_C );
+
+ /* Register 'IntlCalendar' PHP class */
+ calendar_register_IntlCalendar_class( TSRMLS_C );
+
/* Expose ICU error codes to PHP scripts. */
intl_expose_icu_error_codes( INIT_FUNC_ARGS_PASSTHRU );
@@ -653,25 +978,44 @@ PHP_MINIT_FUNCTION( intl )
/* Expose Spoofchecker constants to PHP scripts */
spoofchecker_register_constants( INIT_FUNC_ARGS_PASSTHRU );
#endif
+
+ /* Register 'IntlException' PHP class */
+ intl_register_IntlException_class( TSRMLS_C );
+
+ /* Register 'IntlIterator' PHP class */
+ intl_register_IntlIterator_class( TSRMLS_C );
+
+ /* Register 'BreakIterator' class */
+ breakiterator_register_BreakIterator_class( TSRMLS_C );
+
+ /* Register 'IntlPartsIterator' class */
+ breakiterator_register_IntlPartsIterator_class( TSRMLS_C );
+
/* Global error handling. */
intl_error_init( NULL TSRMLS_CC );
- /* Set the default_locale value */
- if( INTL_G(default_locale) == NULL ) {
- INTL_G(default_locale) = pestrdup(uloc_getDefault(), 1) ;
- }
+ /* 'Converter' class for codepage conversions */
+ php_converter_minit(INIT_FUNC_ARGS_PASSTHRU);
return SUCCESS;
}
/* }}} */
+#define EXPLICIT_CLEANUP_ENV_VAR "INTL_EXPLICIT_CLEANUP"
+
/* {{{ PHP_MSHUTDOWN_FUNCTION
*/
PHP_MSHUTDOWN_FUNCTION( intl )
{
+ const char *cleanup;
/* For the default locale php.ini setting */
UNREGISTER_INI_ENTRIES();
+ cleanup = getenv(EXPLICIT_CLEANUP_ENV_VAR);
+ if (cleanup != NULL && !(cleanup[0] == '0' && cleanup[1] == '\0')) {
+ u_cleanup();
+ }
+
return SUCCESS;
}
/* }}} */
@@ -680,10 +1024,6 @@ PHP_MSHUTDOWN_FUNCTION( intl )
*/
PHP_RINIT_FUNCTION( intl )
{
- /* Set the default_locale value */
- if( INTL_G(default_locale) == NULL ) {
- INTL_G(default_locale) = pestrdup(uloc_getDefault(), 1) ;
- }
return SUCCESS;
}
/* }}} */
diff --git a/ext/intl/php_intl.h b/ext/intl/php_intl.h
index 4ede069e2a..7a7112317d 100644
--- a/ext/intl/php_intl.h
+++ b/ext/intl/php_intl.h
@@ -22,8 +22,13 @@
#include <php.h>
+/* Even if we're included from C++, don't introduce C++ definitions
+ * because we were included with extern "C". The effect would be that
+ * when the headers defined any method, they would do so with C linkage */
+#undef U_SHOW_CPLUSPLUS_API
+#define U_SHOW_CPLUSPLUS_API 0
#include "collator/collator_sort.h"
-#include "grapheme/grapheme.h"
+#include <unicode/ubrk.h>
#include "intl_error.h"
extern zend_module_entry intl_module_entry;
@@ -46,6 +51,7 @@ ZEND_BEGIN_MODULE_GLOBALS(intl)
UBreakIterator* grapheme_iterator;
intl_error g_error;
long error_level;
+ zend_bool use_exceptions;
ZEND_END_MODULE_GLOBALS(intl)
/* Macro to access request-wide global variables. */
@@ -63,6 +69,8 @@ PHP_RINIT_FUNCTION(intl);
PHP_RSHUTDOWN_FUNCTION(intl);
PHP_MINFO_FUNCTION(intl);
+const char *intl_locale_get_default( TSRMLS_D );
+
#define PHP_INTL_VERSION "1.1.0"
#endif /* PHP_INTL_H */
diff --git a/ext/intl/resourcebundle/resourcebundle_class.c b/ext/intl/resourcebundle/resourcebundle_class.c
index 7c1a5c28b8..dc1212431a 100644
--- a/ext/intl/resourcebundle/resourcebundle_class.c
+++ b/ext/intl/resourcebundle/resourcebundle_class.c
@@ -79,13 +79,11 @@ static zend_object_value ResourceBundle_object_create( zend_class_entry *ce TSRM
/* {{{ ResourceBundle_ctor */
static void resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS)
{
- char * bundlename;
- int bundlename_len = 0;
- char * locale;
- int locale_len = 0;
- zend_bool fallback = 1;
-
- char * pbuf;
+ const char *bundlename;
+ int bundlename_len = 0;
+ const char *locale;
+ int locale_len = 0;
+ zend_bool fallback = 1;
zval *object = return_value;
ResourceBundle_object *rb = (ResourceBundle_object *) zend_object_store_get_object( object TSRMLS_CC);
@@ -104,7 +102,7 @@ static void resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS)
INTL_CHECK_LOCALE_LEN_OBJ(locale_len, return_value);
if (locale == NULL) {
- locale = INTL_G(default_locale);
+ locale = intl_locale_get_default(TSRMLS_C);
}
if (fallback) {
@@ -117,6 +115,7 @@ static void resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS)
if (!fallback && (INTL_DATA_ERROR_CODE(rb) == U_USING_FALLBACK_WARNING ||
INTL_DATA_ERROR_CODE(rb) == U_USING_DEFAULT_WARNING)) {
+ char *pbuf;
intl_errors_set_code(NULL, INTL_DATA_ERROR_CODE(rb) TSRMLS_CC);
spprintf(&pbuf, 0, "resourcebundle_ctor: Cannot load libICU resource "
"'%s' without fallback from %s to %s",
@@ -164,7 +163,6 @@ static void resourcebundle_array_fetch(zval *object, zval *offset, zval *return_
{
int32_t meindex = 0;
char * mekey = NULL;
- long mekeylen;
zend_bool is_numeric = 0;
char *pbuf;
ResourceBundle_object *rb;
@@ -178,7 +176,6 @@ static void resourcebundle_array_fetch(zval *object, zval *offset, zval *return_
rb->child = ures_getByIndex( rb->me, meindex, rb->child, &INTL_DATA_ERROR_CODE(rb) );
} else if(Z_TYPE_P(offset) == IS_STRING) {
mekey = Z_STRVAL_P(offset);
- mekeylen = Z_STRLEN_P(offset);
rb->child = ures_getByKey(rb->me, mekey, rb->child, &INTL_DATA_ERROR_CODE(rb) );
} else {
intl_errors_set(INTL_DATA_ERROR_P(rb), U_ILLEGAL_ARGUMENT_ERROR,
diff --git a/ext/intl/resourcebundle/resourcebundle_iterator.c b/ext/intl/resourcebundle/resourcebundle_iterator.c
index 16e1b92879..78236fda5d 100644
--- a/ext/intl/resourcebundle/resourcebundle_iterator.c
+++ b/ext/intl/resourcebundle/resourcebundle_iterator.c
@@ -101,21 +101,18 @@ static void resourcebundle_iterator_current( zend_object_iterator *iter, zval **
/* }}} */
/* {{{ resourcebundle_iterator_key */
-static int resourcebundle_iterator_key( zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC )
+static void resourcebundle_iterator_key( zend_object_iterator *iter, zval *key TSRMLS_DC )
{
ResourceBundle_iterator *iterator = (ResourceBundle_iterator *) iter;
if (!iterator->current) {
resourcebundle_iterator_read( iterator TSRMLS_CC);
}
+
if (iterator->is_table) {
- *str_key = estrdup( iterator->currentkey );
- *str_key_len = strlen( iterator->currentkey ) + 1;
- return HASH_KEY_IS_STRING;
- }
- else {
- *int_key = iterator->i;
- return HASH_KEY_IS_LONG;
+ ZVAL_STRING(key, iterator->currentkey, 1);
+ } else {
+ ZVAL_LONG(key, iterator->i);
}
}
/* }}} */
diff --git a/ext/intl/tests/badargs.phpt b/ext/intl/tests/badargs.phpt
index 264af73acc..b2120977f3 100644
--- a/ext/intl/tests/badargs.phpt
+++ b/ext/intl/tests/badargs.phpt
@@ -13,7 +13,10 @@ foreach($funcs as $func) {
if($rfunc->getNumberOfRequiredParameters() == 0) {
continue;
}
- $res = $func($arg);
+
+ try {
+ $res = $func($arg);
+ } catch (Exception $e) { continue; }
if($res != false) {
echo "$func: ";
var_dump($res);
diff --git a/ext/intl/tests/breakiter___construct.phpt b/ext/intl/tests/breakiter___construct.phpt
new file mode 100644
index 0000000000..a818075a30
--- /dev/null
+++ b/ext/intl/tests/breakiter___construct.phpt
@@ -0,0 +1,14 @@
+--TEST--
+IntlBreakIterator::__construct() should not be callable
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+new IntlBreakIterator();
+--EXPECTF--
+
+Fatal error: Call to private IntlBreakIterator::__construct() from invalid context in %s on line %d
diff --git a/ext/intl/tests/breakiter___construct_error.phpt b/ext/intl/tests/breakiter___construct_error.phpt
new file mode 100644
index 0000000000..770f1403c7
--- /dev/null
+++ b/ext/intl/tests/breakiter___construct_error.phpt
@@ -0,0 +1,38 @@
+--TEST--
+IntlRuleBasedBreakIterator::__construct(): arg errors
+--SKIPIF--
+<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+<?php if(version_compare(INTL_ICU_VERSION, '4.8') < 0) print 'skip ICU >= 4.8 only'; ?>
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+//missing ; at the end:
+var_dump(new IntlRuleBasedBreakIterator('[\p{Letter}\uFFFD]+;[:number:]+'));
+var_dump(new IntlRuleBasedBreakIterator());
+var_dump(new IntlRuleBasedBreakIterator(1,2,3));
+var_dump(new IntlRuleBasedBreakIterator('[\p{Letter}\uFFFD]+;[:number:]+;', array()));
+var_dump(new IntlRuleBasedBreakIterator('[\p{Letter}\uFFFD]+;[:number:]+;', true));
+
+--EXPECTF--
+
+Warning: IntlRuleBasedBreakIterator::__construct(): rbbi_create_instance: unable to create RuleBasedBreakIterator from rules (parse error on line 1, offset 31) in %s on line %d
+NULL
+
+Warning: IntlRuleBasedBreakIterator::__construct() expects at least 1 parameter, 0 given in %s on line %d
+
+Warning: IntlRuleBasedBreakIterator::__construct(): rbbi_create_instance: bad arguments in %s on line %d
+NULL
+
+Warning: IntlRuleBasedBreakIterator::__construct() expects at most 2 parameters, 3 given in %s on line %d
+
+Warning: IntlRuleBasedBreakIterator::__construct(): rbbi_create_instance: bad arguments in %s on line %d
+NULL
+
+Warning: IntlRuleBasedBreakIterator::__construct() expects parameter 2 to be boolean, array given in %s on line %d
+
+Warning: IntlRuleBasedBreakIterator::__construct(): rbbi_create_instance: bad arguments in %s on line %d
+NULL
+
+Warning: IntlRuleBasedBreakIterator::__construct(): rbbi_create_instance: unable to create instance from compiled rules in %s on line %d
+NULL
diff --git a/ext/intl/tests/breakiter_clone_basic.phpt b/ext/intl/tests/breakiter_clone_basic.phpt
new file mode 100644
index 0000000000..d838f81217
--- /dev/null
+++ b/ext/intl/tests/breakiter_clone_basic.phpt
@@ -0,0 +1,27 @@
+--TEST--
+IntlBreakIterator: clone handler
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$bi = new IntlRuleBasedBreakIterator('[\p{Letter}\uFFFD]+;[:number:]+;');
+$bi_clone = clone $bi;
+var_dump(get_class($bi), get_class($bi_clone));
+var_dump($bi == $bi_clone);
+
+$bi->setText('foobar');
+$bi_clone = clone $bi;
+var_dump(get_class($bi), get_class($bi_clone));
+var_dump($bi == $bi_clone);
+
+--EXPECT--
+string(26) "IntlRuleBasedBreakIterator"
+string(26) "IntlRuleBasedBreakIterator"
+bool(true)
+string(26) "IntlRuleBasedBreakIterator"
+string(26) "IntlRuleBasedBreakIterator"
+bool(true)
diff --git a/ext/intl/tests/breakiter_createCodePointInstance_basic.phpt b/ext/intl/tests/breakiter_createCodePointInstance_basic.phpt
new file mode 100644
index 0000000000..a43e82760c
--- /dev/null
+++ b/ext/intl/tests/breakiter_createCodePointInstance_basic.phpt
@@ -0,0 +1,43 @@
+--TEST--
+IntlBreakIterator::createCodePointInstance(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+
+$text = 'ตัวอย่างข้อความ';
+
+$codepoint_it = IntlBreakIterator::createCodePointInstance();
+var_dump(get_class($codepoint_it));
+$codepoint_it->setText($text);
+
+print_r(iterator_to_array($codepoint_it));
+
+?>
+==DONE==
+--EXPECT--
+string(26) "IntlCodePointBreakIterator"
+Array
+(
+ [0] => 0
+ [1] => 3
+ [2] => 6
+ [3] => 9
+ [4] => 12
+ [5] => 15
+ [6] => 18
+ [7] => 21
+ [8] => 24
+ [9] => 27
+ [10] => 30
+ [11] => 33
+ [12] => 36
+ [13] => 39
+ [14] => 42
+ [15] => 45
+)
+==DONE==
diff --git a/ext/intl/tests/breakiter_createCodePointInstance_error.phpt b/ext/intl/tests/breakiter_createCodePointInstance_error.phpt
new file mode 100644
index 0000000000..90228e128f
--- /dev/null
+++ b/ext/intl/tests/breakiter_createCodePointInstance_error.phpt
@@ -0,0 +1,18 @@
+--TEST--
+IntlBreakIterator::createCodePointInstance(): bad arguments
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+var_dump(IntlBreakIterator::createCodePointInstance(array()));
+--EXPECTF--
+
+Warning: IntlBreakIterator::createCodePointInstance() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlBreakIterator::createCodePointInstance(): breakiter_create_code_point_instance: bad arguments in %s on line %d
+NULL
+
diff --git a/ext/intl/tests/breakiter_current_basic.phpt b/ext/intl/tests/breakiter_current_basic.phpt
new file mode 100644
index 0000000000..2ce6da7697
--- /dev/null
+++ b/ext/intl/tests/breakiter_current_basic.phpt
@@ -0,0 +1,28 @@
+--TEST--
+IntlBreakIterator::current(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+
+$bi = IntlBreakIterator::createWordInstance('pt');
+var_dump($bi->current());
+$bi->setText('foo bar trans zoo bee');
+
+var_dump($bi->first());
+var_dump($bi->current());
+var_dump($bi->next());
+var_dump($bi->current());
+?>
+==DONE==
+--EXPECT--
+int(0)
+int(0)
+int(0)
+int(3)
+int(3)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/breakiter_factories_basic.phpt b/ext/intl/tests/breakiter_factories_basic.phpt
new file mode 100644
index 0000000000..dcfcedef0c
--- /dev/null
+++ b/ext/intl/tests/breakiter_factories_basic.phpt
@@ -0,0 +1,46 @@
+--TEST--
+IntlBreakIterator factories: basic tests
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "ja");
+
+$m = array('createWordInstance', 'createLineInstance', 'createCharacterInstance',
+ 'createSentenceInstance', 'createTitleInstance');
+
+$t = 'Frase 1... Frase 2'.
+
+$o1 = $o2 = null;
+foreach ($m as $method) {
+ echo "===== $method =====\n";
+ $o1 = call_user_func(array('IntlBreakIterator', $method), 'ja');
+ var_dump($o1 == $o2);
+ $o2 = call_user_func(array('IntlBreakIterator', $method), NULL);
+ var_dump($o1 == $o2);
+ echo "\n";
+}
+--EXPECT--
+===== createWordInstance =====
+bool(false)
+bool(true)
+
+===== createLineInstance =====
+bool(false)
+bool(true)
+
+===== createCharacterInstance =====
+bool(false)
+bool(true)
+
+===== createSentenceInstance =====
+bool(false)
+bool(true)
+
+===== createTitleInstance =====
+bool(false)
+bool(true)
+
diff --git a/ext/intl/tests/breakiter_factories_error.phpt b/ext/intl/tests/breakiter_factories_error.phpt
new file mode 100644
index 0000000000..c35339f7a0
--- /dev/null
+++ b/ext/intl/tests/breakiter_factories_error.phpt
@@ -0,0 +1,43 @@
+--TEST--
+IntlBreakIterator factory methods: argument errors
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+var_dump(IntlBreakIterator::createWordInstance(array()));
+var_dump(IntlBreakIterator::createSentenceInstance(NULL, 2));
+var_dump(IntlBreakIterator::createCharacterInstance(NULL, 2));
+var_dump(IntlBreakIterator::createTitleInstance(NULL, 2));
+var_dump(IntlBreakIterator::createLineInstance(NULL, 2));
+
+
+--EXPECTF--
+
+Warning: IntlBreakIterator::createWordInstance() expects parameter 1 to be string, array given in %s on line %d
+
+Warning: IntlBreakIterator::createWordInstance(): breakiter_create_word_instance: bad arguments in %s on line %d
+NULL
+
+Warning: IntlBreakIterator::createSentenceInstance() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: IntlBreakIterator::createSentenceInstance(): breakiter_create_sentence_instance: bad arguments in %s on line %d
+NULL
+
+Warning: IntlBreakIterator::createCharacterInstance() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: IntlBreakIterator::createCharacterInstance(): breakiter_create_character_instance: bad arguments in %s on line %d
+NULL
+
+Warning: IntlBreakIterator::createTitleInstance() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: IntlBreakIterator::createTitleInstance(): breakiter_create_title_instance: bad arguments in %s on line %d
+NULL
+
+Warning: IntlBreakIterator::createLineInstance() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: IntlBreakIterator::createLineInstance(): breakiter_create_line_instance: bad arguments in %s on line %d
+NULL
diff --git a/ext/intl/tests/breakiter_first_basic.phpt b/ext/intl/tests/breakiter_first_basic.phpt
new file mode 100644
index 0000000000..364d5f2fa6
--- /dev/null
+++ b/ext/intl/tests/breakiter_first_basic.phpt
@@ -0,0 +1,22 @@
+--TEST--
+IntlBreakIterator::first(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$bi = IntlBreakIterator::createWordInstance('pt');
+$bi->setText('foo bar trans');
+
+var_dump($bi->current());
+var_dump($bi->next());
+var_dump($bi->first());
+var_dump($bi->current());
+--EXPECT--
+int(0)
+int(3)
+int(0)
+int(0)
diff --git a/ext/intl/tests/breakiter_first_last_previous_current_error.phpt b/ext/intl/tests/breakiter_first_last_previous_current_error.phpt
new file mode 100644
index 0000000000..2ab681228e
--- /dev/null
+++ b/ext/intl/tests/breakiter_first_last_previous_current_error.phpt
@@ -0,0 +1,39 @@
+--TEST--
+IntlBreakIterator::first()/last()/previous()/current(): arg errors
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$bi = new IntlRuleBasedBreakIterator('[\p{Letter}\uFFFD]+;[:number:]+;');
+$bi->setText("\x80sdfé\x90d888 dfsa9");
+
+var_dump($bi->first(1));
+var_dump($bi->last(1));
+var_dump($bi->previous(1));
+var_dump($bi->current(1));
+
+--EXPECTF--
+
+Warning: IntlBreakIterator::first() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlBreakIterator::first(): breakiter_first: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlBreakIterator::last() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlBreakIterator::last(): breakiter_last: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlBreakIterator::previous() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlBreakIterator::previous(): breakiter_previous: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlBreakIterator::current() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlBreakIterator::current(): breakiter_current: bad arguments in %s on line %d
+bool(false)
diff --git a/ext/intl/tests/breakiter_following_basic.phpt b/ext/intl/tests/breakiter_following_basic.phpt
new file mode 100644
index 0000000000..30798d99a3
--- /dev/null
+++ b/ext/intl/tests/breakiter_following_basic.phpt
@@ -0,0 +1,24 @@
+--TEST--
+IntlBreakIterator::following(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+
+$bi = IntlBreakIterator::createWordInstance('pt');
+$bi->setText('foo bar trans zoo bee');
+
+var_dump($bi->following(5));
+var_dump($bi->following(50));
+var_dump($bi->following(-1));
+?>
+==DONE==
+--EXPECT--
+int(7)
+int(-1)
+int(0)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/breakiter_following_preceding_isBoundary_error.phpt b/ext/intl/tests/breakiter_following_preceding_isBoundary_error.phpt
new file mode 100644
index 0000000000..5550ccf0a0
--- /dev/null
+++ b/ext/intl/tests/breakiter_following_preceding_isBoundary_error.phpt
@@ -0,0 +1,51 @@
+--TEST--
+IntlBreakIterator::following()/preceding()/isBoundary(): arg errors
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$bi = new IntlRuleBasedBreakIterator('[\p{Letter}\uFFFD]+;[:number:]+;');
+$bi->setText("\x80sdfé\x90d888 dfsa9");
+
+var_dump($bi->following(1, 2));
+var_dump($bi->following(array()));
+var_dump($bi->preceding(1, 2));
+var_dump($bi->preceding(array()));
+var_dump($bi->isBoundary(1, 2));
+var_dump($bi->isBoundary(array()));
+
+--EXPECTF--
+
+Warning: IntlBreakIterator::following() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: IntlBreakIterator::following(): breakiter_following: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlBreakIterator::following() expects parameter 1 to be long, array given in %s on line %d
+
+Warning: IntlBreakIterator::following(): breakiter_following: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlBreakIterator::preceding() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: IntlBreakIterator::preceding(): breakiter_preceding: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlBreakIterator::preceding() expects parameter 1 to be long, array given in %s on line %d
+
+Warning: IntlBreakIterator::preceding(): breakiter_preceding: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlBreakIterator::isBoundary() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: IntlBreakIterator::isBoundary(): breakiter_is_boundary: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlBreakIterator::isBoundary() expects parameter 1 to be long, array given in %s on line %d
+
+Warning: IntlBreakIterator::isBoundary(): breakiter_is_boundary: bad arguments in %s on line %d
+bool(false)
diff --git a/ext/intl/tests/breakiter_getLocale_basic.phpt b/ext/intl/tests/breakiter_getLocale_basic.phpt
new file mode 100644
index 0000000000..b0112cc847
--- /dev/null
+++ b/ext/intl/tests/breakiter_getLocale_basic.phpt
@@ -0,0 +1,21 @@
+--TEST--
+IntlBreakIterator::getLocale(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+
+$bi = IntlBreakIterator::createSentenceInstance('pt');
+
+var_dump($bi->getLocale(0));
+var_dump($bi->getLocale(1));
+?>
+==DONE==
+--EXPECT--
+string(4) "root"
+string(4) "root"
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/breakiter_getLocale_error.phpt b/ext/intl/tests/breakiter_getLocale_error.phpt
new file mode 100644
index 0000000000..9acd08ab63
--- /dev/null
+++ b/ext/intl/tests/breakiter_getLocale_error.phpt
@@ -0,0 +1,33 @@
+--TEST--
+IntlBreakIterator::getLocale(): arg errors
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$bi = new IntlRuleBasedBreakIterator('[\p{Letter}\uFFFD]+;[:number:]+;');
+$bi->setText("\x80sdfé\x90d888 dfsa9");
+
+var_dump($bi->getLocale(1, 2));
+var_dump($bi->getLocale(array()));
+var_dump($bi->getLocale());
+
+--EXPECTF--
+
+Warning: IntlBreakIterator::getLocale() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: IntlBreakIterator::getLocale(): breakiter_get_locale: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlBreakIterator::getLocale() expects parameter 1 to be long, array given in %s on line %d
+
+Warning: IntlBreakIterator::getLocale(): breakiter_get_locale: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlBreakIterator::getLocale() expects exactly 1 parameter, 0 given in %s on line %d
+
+Warning: IntlBreakIterator::getLocale(): breakiter_get_locale: bad arguments in %s on line %d
+bool(false)
diff --git a/ext/intl/tests/breakiter_getPartsIterator_basic.phpt b/ext/intl/tests/breakiter_getPartsIterator_basic.phpt
new file mode 100644
index 0000000000..36ad80d5fb
--- /dev/null
+++ b/ext/intl/tests/breakiter_getPartsIterator_basic.phpt
@@ -0,0 +1,37 @@
+--TEST--
+IntlBreakIterator::getPartsIterator(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+
+$bi = IntlBreakIterator::createWordInstance('pt');
+$pi = $bi->getPartsIterator();
+var_dump(get_class($pi));
+print_r(iterator_to_array($pi));
+
+$bi->setText("foo bar");
+$pi = $bi->getPartsIterator();
+var_dump(get_class($pi->getBreakIterator()));
+print_r(iterator_to_array($pi));
+var_dump($pi->getRuleStatus());
+?>
+==DONE==
+--EXPECT--
+string(17) "IntlPartsIterator"
+Array
+(
+)
+string(26) "IntlRuleBasedBreakIterator"
+Array
+(
+ [0] => foo
+ [1] =>
+ [2] => bar
+)
+int(0)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/breakiter_getPartsIterator_error.phpt b/ext/intl/tests/breakiter_getPartsIterator_error.phpt
new file mode 100644
index 0000000000..9737618033
--- /dev/null
+++ b/ext/intl/tests/breakiter_getPartsIterator_error.phpt
@@ -0,0 +1,33 @@
+--TEST--
+IntlBreakIterator::getPartsIterator(): bad args
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+
+$it = IntlBreakIterator::createWordInstance(NULL);
+var_dump($it->getPartsIterator(array()));
+var_dump($it->getPartsIterator(1, 2));
+var_dump($it->getPartsIterator(-1));
+
+?>
+==DONE==
+--EXPECTF--
+
+Warning: IntlBreakIterator::getPartsIterator() expects parameter 1 to be long, array given in %s on line %d
+
+Warning: IntlBreakIterator::getPartsIterator(): breakiter_get_parts_iterator: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlBreakIterator::getPartsIterator() expects at most 1 parameter, 2 given in %s on line %d
+
+Warning: IntlBreakIterator::getPartsIterator(): breakiter_get_parts_iterator: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlBreakIterator::getPartsIterator(): breakiter_get_parts_iterator: bad key type in %s on line %d
+bool(false)
+==DONE==
diff --git a/ext/intl/tests/breakiter_getPartsIterator_var1.phpt b/ext/intl/tests/breakiter_getPartsIterator_var1.phpt
new file mode 100644
index 0000000000..7bbd27ea45
--- /dev/null
+++ b/ext/intl/tests/breakiter_getPartsIterator_var1.phpt
@@ -0,0 +1,60 @@
+--TEST--
+IntlBreakIterator::getPartsIterator(): argument variations
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+
+$text = 'foo bar tao';
+
+$it = IntlBreakIterator::createWordInstance(NULL);
+$it->setText($text);
+
+var_dump(iterator_to_array($it->getPartsIterator(IntlPartsIterator::KEY_SEQUENTIAL)));
+var_dump(iterator_to_array($it->getPartsIterator(IntlPartsIterator::KEY_LEFT)));
+var_dump(iterator_to_array($it->getPartsIterator(IntlPartsIterator::KEY_RIGHT)));
+
+?>
+==DONE==
+--EXPECT--
+array(5) {
+ [0]=>
+ string(3) "foo"
+ [1]=>
+ string(1) " "
+ [2]=>
+ string(3) "bar"
+ [3]=>
+ string(1) " "
+ [4]=>
+ string(3) "tao"
+}
+array(5) {
+ [0]=>
+ string(3) "foo"
+ [4]=>
+ string(1) " "
+ [5]=>
+ string(3) "bar"
+ [8]=>
+ string(1) " "
+ [9]=>
+ string(3) "tao"
+}
+array(5) {
+ [3]=>
+ string(3) "foo"
+ [5]=>
+ string(1) " "
+ [8]=>
+ string(3) "bar"
+ [9]=>
+ string(1) " "
+ [12]=>
+ string(3) "tao"
+}
+==DONE==
diff --git a/ext/intl/tests/breakiter_getText_basic.phpt b/ext/intl/tests/breakiter_getText_basic.phpt
new file mode 100644
index 0000000000..0e5a26c16a
--- /dev/null
+++ b/ext/intl/tests/breakiter_getText_basic.phpt
@@ -0,0 +1,17 @@
+--TEST--
+IntlBreakIterator::getText(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$bi = IntlBreakIterator::createWordInstance('pt');
+var_dump($bi->getText());
+$bi->setText('foo bar');
+var_dump($bi->getText());
+--EXPECTF--
+NULL
+string(7) "foo bar"
diff --git a/ext/intl/tests/breakiter_getText_error.phpt b/ext/intl/tests/breakiter_getText_error.phpt
new file mode 100644
index 0000000000..91e9919c15
--- /dev/null
+++ b/ext/intl/tests/breakiter_getText_error.phpt
@@ -0,0 +1,19 @@
+--TEST--
+IntlBreakIterator::getText(): arg errors
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$bi = new IntlRuleBasedBreakIterator('[\p{Letter}]+;');
+var_dump($bi->getText(array()));
+
+--EXPECTF--
+
+Warning: IntlBreakIterator::getText() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlBreakIterator::getText(): breakiter_get_text: bad arguments in %s on line %d
+bool(false)
diff --git a/ext/intl/tests/breakiter_isBoundary_basic.phpt b/ext/intl/tests/breakiter_isBoundary_basic.phpt
new file mode 100644
index 0000000000..1f416630a0
--- /dev/null
+++ b/ext/intl/tests/breakiter_isBoundary_basic.phpt
@@ -0,0 +1,28 @@
+--TEST--
+IntlBreakIterator::isBoundary(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+
+$bi = IntlBreakIterator::createWordInstance('pt');
+$bi->setText('foo bar trans zoo bee');
+
+var_dump($bi->isBoundary(0));
+var_dump($bi->isBoundary(7));
+var_dump($bi->isBoundary(-1));
+var_dump($bi->isBoundary(1));
+var_dump($bi->isBoundary(50));
+?>
+==DONE==
+--EXPECT--
+bool(true)
+bool(true)
+bool(false)
+bool(false)
+bool(false)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/breakiter_last_basic.phpt b/ext/intl/tests/breakiter_last_basic.phpt
new file mode 100644
index 0000000000..cf816c3670
--- /dev/null
+++ b/ext/intl/tests/breakiter_last_basic.phpt
@@ -0,0 +1,20 @@
+--TEST--
+IntlBreakIterator::last(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$bi = IntlBreakIterator::createWordInstance('pt');
+$bi->setText('foo bar trans');
+
+var_dump($bi->current());
+var_dump($bi->last());
+var_dump($bi->current());
+--EXPECTF--
+int(0)
+int(13)
+int(13)
diff --git a/ext/intl/tests/breakiter_next_basic.phpt b/ext/intl/tests/breakiter_next_basic.phpt
new file mode 100644
index 0000000000..4deb4144e3
--- /dev/null
+++ b/ext/intl/tests/breakiter_next_basic.phpt
@@ -0,0 +1,30 @@
+--TEST--
+IntlBreakIterator::next(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+
+$bi = IntlBreakIterator::createWordInstance('pt');
+$bi->setText('foo bar trans zoo bee');
+
+var_dump($bi->first());
+var_dump($bi->next());
+var_dump($bi->next(2));
+var_dump($bi->next(-1));
+var_dump($bi->next(0));
+var_dump($bi->next(NULL));
+?>
+==DONE==
+--EXPECT--
+int(0)
+int(3)
+int(7)
+int(4)
+int(4)
+int(7)
+==DONE==
diff --git a/ext/intl/tests/breakiter_next_error.phpt b/ext/intl/tests/breakiter_next_error.phpt
new file mode 100644
index 0000000000..ed718bc2a5
--- /dev/null
+++ b/ext/intl/tests/breakiter_next_error.phpt
@@ -0,0 +1,27 @@
+--TEST--
+IntlBreakIterator::next(): arg errors
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$bi = new IntlRuleBasedBreakIterator('[\p{Letter}\uFFFD]+;[:number:]+;');
+$bi->setText("\x80sdfé\x90d888 dfsa9");
+
+var_dump($bi->next(1, 2));
+var_dump($bi->next(array()));
+
+--EXPECTF--
+
+Warning: IntlBreakIterator::next() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: IntlBreakIterator::next(): breakiter_next: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlBreakIterator::next() expects parameter 1 to be long, array given in %s on line %d
+
+Warning: IntlBreakIterator::next(): breakiter_next: bad arguments in %s on line %d
+bool(false)
diff --git a/ext/intl/tests/breakiter_preceding_basic.phpt b/ext/intl/tests/breakiter_preceding_basic.phpt
new file mode 100644
index 0000000000..6fa8dd7fa7
--- /dev/null
+++ b/ext/intl/tests/breakiter_preceding_basic.phpt
@@ -0,0 +1,24 @@
+--TEST--
+IntlBreakIterator::preceding(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+
+$bi = IntlBreakIterator::createWordInstance('pt');
+$bi->setText('foo bar trans zoo bee');
+
+var_dump($bi->preceding(5));
+var_dump($bi->preceding(50));
+var_dump($bi->preceding(-1));
+?>
+==DONE==
+--EXPECT--
+int(4)
+int(21)
+int(0)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/breakiter_previous_basic.phpt b/ext/intl/tests/breakiter_previous_basic.phpt
new file mode 100644
index 0000000000..c3343af57c
--- /dev/null
+++ b/ext/intl/tests/breakiter_previous_basic.phpt
@@ -0,0 +1,22 @@
+--TEST--
+IntlBreakIterator::previous(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+
+$bi = IntlBreakIterator::createWordInstance('pt');
+$bi->setText('foo bar trans');
+
+var_dump($bi->last());
+var_dump($bi->previous());
+?>
+==DONE==
+--EXPECT--
+int(13)
+int(8)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/breakiter_setText_basic.phpt b/ext/intl/tests/breakiter_setText_basic.phpt
new file mode 100644
index 0000000000..a5e4f86b65
--- /dev/null
+++ b/ext/intl/tests/breakiter_setText_basic.phpt
@@ -0,0 +1,36 @@
+--TEST--
+IntlBreakIterator::setText(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+class A {
+function __tostring() { return 'aaa'; }
+}
+
+$bi = IntlBreakIterator::createWordInstance('pt');
+var_dump($bi->setText('foo bar'));
+var_dump($bi->getText());
+var_dump($bi->setText(1));
+var_dump($bi->getText());
+var_dump($bi->setText(new A));
+var_dump($bi->getText());
+
+/* setText resets the pointer */
+var_dump($bi->next());
+var_dump($bi->setText('foo bar'));
+var_dump($bi->current());
+--EXPECT--
+bool(true)
+string(7) "foo bar"
+bool(true)
+string(1) "1"
+bool(true)
+string(3) "aaa"
+int(3)
+bool(true)
+int(0)
diff --git a/ext/intl/tests/breakiter_setText_error.phpt b/ext/intl/tests/breakiter_setText_error.phpt
new file mode 100644
index 0000000000..a7a73a08d8
--- /dev/null
+++ b/ext/intl/tests/breakiter_setText_error.phpt
@@ -0,0 +1,44 @@
+--TEST--
+IntlBreakIterator::setText(): arg errors
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$bi = new IntlRuleBasedBreakIterator('[\p{Letter}]+;');
+var_dump($bi->setText());
+var_dump($bi->setText(array()));
+var_dump($bi->setText(1,2));
+
+class A {
+function __destruct() { var_dump('destructed'); throw new Exception('e'); }
+function __tostring() { return 'foo'; }
+}
+
+try {
+var_dump($bi->setText(new A));
+} catch (Exception $e) {
+var_dump($e->getMessage());
+}
+
+--EXPECTF--
+
+Warning: IntlBreakIterator::setText() expects exactly 1 parameter, 0 given in %s on line %d
+
+Warning: IntlBreakIterator::setText(): breakiter_set_text: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlBreakIterator::setText() expects parameter 1 to be string, array given in %s on line %d
+
+Warning: IntlBreakIterator::setText(): breakiter_set_text: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlBreakIterator::setText() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: IntlBreakIterator::setText(): breakiter_set_text: bad arguments in %s on line %d
+bool(false)
+string(10) "destructed"
+string(1) "e"
diff --git a/ext/intl/tests/bug50590.phpt b/ext/intl/tests/bug50590.phpt
index c39c333b23..4784d37877 100644
--- a/ext/intl/tests/bug50590.phpt
+++ b/ext/intl/tests/bug50590.phpt
@@ -1,5 +1,7 @@
--TEST--
Bug #50590 (IntlDateFormatter::parse result is limited to the integer range)
+--INI--
+date.timezone=Atlantic/Azores
--SKIPIF--
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
--FILE--
diff --git a/ext/intl/tests/bug58756_MessageFormatter.phpt b/ext/intl/tests/bug58756_MessageFormatter.phpt
new file mode 100644
index 0000000000..18566b666c
--- /dev/null
+++ b/ext/intl/tests/bug58756_MessageFormatter.phpt
@@ -0,0 +1,37 @@
+--TEST--
+Bug #58756: w.r.t MessageFormatter
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '51.2') >= 0)
+ die('skip for ICU < 51.2');
+?>
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+//ini_set("intl.default_locale", "nl");
+
+$time = 1247013673;
+
+ini_set('date.timezone', 'America/New_York');
+
+$msgf = new MessageFormatter('en_US', '{0,date,full} {0,time,h:m:s a V}');
+
+echo "date: " . date('l, F j, Y g:i:s A T', $time) . "\n";
+echo "msgf: " . $msgf->format(array($time)) . "\n";
+
+//NOT FIXED:
+/*$msgf = new MessageFormatter('en_US',
+'{1, select, date {{0,date,full}} other {{0,time,h:m:s a V}}}');
+
+echo "msgf2: ", $msgf->format(array($time, 'date')), " ",
+ $msgf->format(array($time, 'time')), "\n";
+*/
+
+?>
+==DONE==
+--EXPECT--
+date: Tuesday, July 7, 2009 8:41:13 PM EDT
+msgf: Tuesday, July 7, 2009 8:41:13 PM EDT
+==DONE==
diff --git a/ext/intl/tests/bug58756_MessageFormatter_variant2.phpt b/ext/intl/tests/bug58756_MessageFormatter_variant2.phpt
new file mode 100644
index 0000000000..4fcfdbc08c
--- /dev/null
+++ b/ext/intl/tests/bug58756_MessageFormatter_variant2.phpt
@@ -0,0 +1,37 @@
+--TEST--
+Bug #58756: w.r.t MessageFormatter
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '51.2') < 0)
+ die('skip for ICU >= 51.2');
+?>
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+//ini_set("intl.default_locale", "nl");
+
+$time = 1247013673;
+
+ini_set('date.timezone', 'America/New_York');
+
+$msgf = new MessageFormatter('en_US', '{0,date,full} {0,time,h:m:s a V}');
+
+echo "date: " . date('l, F j, Y g:i:s A T', $time) . "\n";
+echo "msgf: " . $msgf->format(array($time)) . "\n";
+
+//NOT FIXED:
+/*$msgf = new MessageFormatter('en_US',
+'{1, select, date {{0,date,full}} other {{0,time,h:m:s a V}}}');
+
+echo "msgf2: ", $msgf->format(array($time, 'date')), " ",
+ $msgf->format(array($time, 'time')), "\n";
+*/
+
+?>
+==DONE==
+--EXPECT--
+date: Tuesday, July 7, 2009 8:41:13 PM EDT
+msgf: Tuesday, July 7, 2009 8:41:13 PM usnyc
+==DONE==
diff --git a/ext/intl/tests/bug62017.phpt b/ext/intl/tests/bug62017.phpt
index 13c4fe5df0..50aeae4806 100644
--- a/ext/intl/tests/bug62017.phpt
+++ b/ext/intl/tests/bug62017.phpt
@@ -14,7 +14,7 @@ var_dump(
new IntlDateFormatter('', IntlDateFormatter::NONE, IntlDateFormatter::NONE, "Europe/Lisbon",
IntlDateFormatter::GREGORIAN, "\x80"));
--EXPECTF--
-Warning: datefmt_create(): datefmt_create: error converting timezone_str to UTF-16 in %s on line %d
+Warning: datefmt_create(): datefmt_create: Time zone identifier given is not a valid UTF-8 string in %s on line %d
NULL
Warning: IntlDateFormatter::__construct(): datefmt_create: error converting pattern to UTF-16 in %s on line %d
diff --git a/ext/intl/tests/bug62081.phpt b/ext/intl/tests/bug62081.phpt
index 7d9e2cec47..44ad4beec7 100644
--- a/ext/intl/tests/bug62081.phpt
+++ b/ext/intl/tests/bug62081.phpt
@@ -1,5 +1,7 @@
--TEST--
Bug #62081: IntlDateFormatter leaks memory if called twice
+--INI--
+date.timezone=Atlantic/Azores
--SKIPIF--
<?php
if (!extension_loaded('intl'))
@@ -7,8 +9,8 @@ if (!extension_loaded('intl'))
--FILE--
<?php
ini_set('intl.error_level', E_WARNING);
-$x = new IntlDateFormatter(1,1,1,1,1);
-var_dump($x->__construct(1,1,1,1,1));
+$x = new IntlDateFormatter('en', 1, 1);
+var_dump($x->__construct('en', 1, 1));
--EXPECTF--
Warning: IntlDateFormatter::__construct(): datefmt_create: cannot call constructor twice in %s on line %d
NULL
diff --git a/ext/intl/tests/bug62915.phpt b/ext/intl/tests/bug62915.phpt
new file mode 100644
index 0000000000..e541d72d63
--- /dev/null
+++ b/ext/intl/tests/bug62915.phpt
@@ -0,0 +1,24 @@
+--TEST--
+Bug #62915: incomplete cloning of IntlTimeZone objects
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+
+class foo extends IntlTimeZone {
+ public $foo = 'test';
+
+ public function __construct() { }
+}
+
+$x = new foo;
+
+try {
+ $z = clone $x;
+} catch (Exception $e) {
+ var_dump($e->getMessage());
+}
+--EXPECT--
+string(39) "Cannot clone unconstructed IntlTimeZone"
diff --git a/ext/intl/tests/calendar_add_basic.phpt b/ext/intl/tests/calendar_add_basic.phpt
new file mode 100644
index 0000000000..b0e44d5895
--- /dev/null
+++ b/ext/intl/tests/calendar_add_basic.phpt
@@ -0,0 +1,33 @@
+--TEST--
+IntlCalendar::add() basic test
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$time = strtotime('2012-02-29 00:00:00 +0000');
+$time2 = strtotime('2012-03-01 05:06:07 +0000');
+
+$intlcal = IntlCalendar::createInstance('UTC');
+$intlcal->setTime($time * 1000);
+$intlcal->add(IntlCalendar::FIELD_DAY_OF_MONTH, 1);
+$intlcal->add(IntlCalendar::FIELD_HOUR, 5);
+$intlcal->add(IntlCalendar::FIELD_MINUTE, 6);
+intlcal_add($intlcal, IntlCalendar::FIELD_SECOND, 7);
+
+var_dump(
+ (float)$time2*1000,
+ $intlcal->getTime());
+
+?>
+==DONE==
+--EXPECT--
+float(1330578367000)
+float(1330578367000)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_add_error.phpt b/ext/intl/tests/calendar_add_error.phpt
new file mode 100644
index 0000000000..2e5fadb4ec
--- /dev/null
+++ b/ext/intl/tests/calendar_add_error.phpt
@@ -0,0 +1,41 @@
+--TEST--
+IntlCalendar::add(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+var_dump($c->add(1, 2, 3));
+var_dump($c->add(-1, 2));
+var_dump($c->add(1));
+
+var_dump(intlcal_add($c, 1, 2, 3));
+var_dump(intlcal_add(1, 2, 3));
+--EXPECTF--
+
+Warning: IntlCalendar::add() expects exactly 2 parameters, 3 given in %s on line %d
+
+Warning: IntlCalendar::add(): intlcal_add: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::add(): intlcal_add: invalid field in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::add() expects exactly 2 parameters, 1 given in %s on line %d
+
+Warning: IntlCalendar::add(): intlcal_add: bad arguments in %s on line %d
+bool(false)
+
+Warning: intlcal_add() expects exactly 3 parameters, 4 given in %s on line %d
+
+Warning: intlcal_add(): intlcal_add: bad arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intlcal_add() must be an instance of IntlCalendar, integer given in %s on line %d
diff --git a/ext/intl/tests/calendar_before_after_error.phpt b/ext/intl/tests/calendar_before_after_error.phpt
new file mode 100644
index 0000000000..10011ef852
--- /dev/null
+++ b/ext/intl/tests/calendar_before_after_error.phpt
@@ -0,0 +1,57 @@
+--TEST--
+IntlCalendar::before()/after(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+function eh($errno, $errstr) {
+echo "error: $errno, $errstr\n";
+}
+set_error_handler('eh');
+
+var_dump($c->after());
+var_dump($c->before());
+
+var_dump($c->after(1));
+var_dump($c->before(1));
+
+var_dump($c->after($c, 1));
+var_dump($c->before($c, 1));
+
+var_dump(intlcal_after($c));
+var_dump(intlcal_before($c));
+--EXPECT--
+error: 2, IntlCalendar::after() expects exactly 1 parameter, 0 given
+error: 2, IntlCalendar::after(): intlcal_before/after: bad arguments
+bool(false)
+error: 2, IntlCalendar::before() expects exactly 1 parameter, 0 given
+error: 2, IntlCalendar::before(): intlcal_before/after: bad arguments
+bool(false)
+error: 4096, Argument 1 passed to IntlCalendar::after() must be an instance of IntlCalendar, integer given
+error: 2, IntlCalendar::after() expects parameter 1 to be IntlCalendar, integer given
+error: 2, IntlCalendar::after(): intlcal_before/after: bad arguments
+bool(false)
+error: 4096, Argument 1 passed to IntlCalendar::before() must be an instance of IntlCalendar, integer given
+error: 2, IntlCalendar::before() expects parameter 1 to be IntlCalendar, integer given
+error: 2, IntlCalendar::before(): intlcal_before/after: bad arguments
+bool(false)
+error: 2, IntlCalendar::after() expects exactly 1 parameter, 2 given
+error: 2, IntlCalendar::after(): intlcal_before/after: bad arguments
+bool(false)
+error: 2, IntlCalendar::before() expects exactly 1 parameter, 2 given
+error: 2, IntlCalendar::before(): intlcal_before/after: bad arguments
+bool(false)
+error: 2, intlcal_after() expects exactly 2 parameters, 1 given
+error: 2, intlcal_after(): intlcal_before/after: bad arguments
+bool(false)
+error: 2, intlcal_before() expects exactly 2 parameters, 1 given
+error: 2, intlcal_before(): intlcal_before/after: bad arguments
+bool(false)
diff --git a/ext/intl/tests/calendar_clear_basic.phpt b/ext/intl/tests/calendar_clear_basic.phpt
new file mode 100644
index 0000000000..f7e4371d92
--- /dev/null
+++ b/ext/intl/tests/calendar_clear_basic.phpt
@@ -0,0 +1,40 @@
+--TEST--
+IntlCalendar::clear() basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$intlcal = IntlCalendar::createInstance('UTC');
+var_dump($intlcal->clear());
+var_dump(
+ $intlcal->get(IntlCalendar::FIELD_YEAR),
+ $intlcal->get(IntlCalendar::FIELD_MONTH),
+ $intlcal->get(IntlCalendar::FIELD_DAY_OF_MONTH),
+ $intlcal->get(IntlCalendar::FIELD_HOUR),
+ $intlcal->get(IntlCalendar::FIELD_MINUTE),
+ $intlcal->get(IntlCalendar::FIELD_SECOND),
+ $intlcal->get(IntlCalendar::FIELD_MILLISECOND)
+);
+
+$intlcal2 = IntlCalendar::createInstance('Europe/Amsterdam');
+intlcal_clear($intlcal2, null);
+var_dump($intlcal2->getTime());
+
+?>
+==DONE==
+--EXPECT--
+bool(true)
+int(1970)
+int(0)
+int(1)
+int(0)
+int(0)
+int(0)
+int(0)
+float(-3600000)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_clear_error.phpt b/ext/intl/tests/calendar_clear_error.phpt
new file mode 100644
index 0000000000..9bde7e2c8d
--- /dev/null
+++ b/ext/intl/tests/calendar_clear_error.phpt
@@ -0,0 +1,31 @@
+--TEST--
+IntlCalendar::clear(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+var_dump($c->clear(1, 2));
+var_dump($c->clear(-1));
+
+var_dump(intlcal_clear($c, -1));
+var_dump(intlcal_clear(1, 2));
+--EXPECTF--
+
+Warning: IntlCalendar::clear(): intlcal_clear: too many arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::clear(): intlcal_clear: invalid field in %s on line %d
+bool(false)
+
+Warning: intlcal_clear(): intlcal_clear: invalid field in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intlcal_clear() must be an instance of IntlCalendar, integer given in %s on line %d
diff --git a/ext/intl/tests/calendar_clear_variation1.phpt b/ext/intl/tests/calendar_clear_variation1.phpt
new file mode 100644
index 0000000000..6adbcaa353
--- /dev/null
+++ b/ext/intl/tests/calendar_clear_variation1.phpt
@@ -0,0 +1,33 @@
+--TEST--
+IntlCalendar::clear() 1 arg variation
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$intlcal = IntlCalendar::createInstance('UTC');
+$intlcal->setTime(strtotime('2012-02-29 05:06:07 +0000') * 1000);
+//print_R($intlcal);
+var_dump($intlcal->isSet(IntlCalendar::FIELD_MONTH));
+var_dump($intlcal->clear(IntlCalendar::FIELD_MONTH));
+var_dump($intlcal->isSet(IntlCalendar::FIELD_MONTH));
+//print_R($intlcal);
+var_dump(
+ $intlcal->getTime(),
+ strtotime('2012-01-29 05:06:07 +0000') * 1000.
+);
+?>
+==DONE==
+--EXPECT--
+bool(true)
+bool(true)
+bool(false)
+float(1327813567000)
+float(1327813567000)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_const_field_field_count.phpt b/ext/intl/tests/calendar_const_field_field_count.phpt
new file mode 100644
index 0000000000..bae438fbbc
--- /dev/null
+++ b/ext/intl/tests/calendar_const_field_field_count.phpt
@@ -0,0 +1,13 @@
+--TEST--
+IntlCalendar::FIELD_FIELD_COUNT
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+var_dump(IntlCalendar::FIELD_FIELD_COUNT);
+--EXPECTF--
+int(%d)
diff --git a/ext/intl/tests/calendar_createInstance_basic.phpt b/ext/intl/tests/calendar_createInstance_basic.phpt
new file mode 100644
index 0000000000..e062030fec
--- /dev/null
+++ b/ext/intl/tests/calendar_createInstance_basic.phpt
@@ -0,0 +1,42 @@
+--TEST--
+IntlCalendar::createInstance() basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '4.8') < 0)
+ die('skip for ICU 4.8+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+date_default_timezone_set('Europe/Amsterdam');
+
+$cal = IntlCalendar::createInstance();
+print_R($cal->getTimeZone());
+print_R($cal->getLocale(Locale::ACTUAL_LOCALE));
+echo "\n";
+print_R($cal->getType());
+echo "\n";
+
+$timeMillis = $cal->getTime();
+$time = time();
+
+var_dump(abs($timeMillis - $time * 1000) < 1000);
+
+?>
+==DONE==
+
+--EXPECTF--
+IntlTimeZone Object
+(
+ [valid] => 1
+ [id] => Europe/Amsterdam
+ [rawOffset] => 3600000
+ [currentOffset] => %d
+)
+nl
+gregorian
+bool(true)
+==DONE==
diff --git a/ext/intl/tests/calendar_createInstance_error.phpt b/ext/intl/tests/calendar_createInstance_error.phpt
new file mode 100644
index 0000000000..bf655bee79
--- /dev/null
+++ b/ext/intl/tests/calendar_createInstance_error.phpt
@@ -0,0 +1,38 @@
+--TEST--
+IntlCalendar::createInstance: bad arguments
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+class X extends IntlTimeZone {
+function __construct() {}
+}
+
+var_dump(IntlCalendar::createInstance(1, 2, 3));
+var_dump(intlcal_create_instance(1, 2, 3));
+var_dump(intlcal_create_instance(new X, NULL));
+var_dump(intlcal_create_instance(NULL, array()));
+
+--EXPECTF--
+
+Warning: IntlCalendar::createInstance() expects at most 2 parameters, 3 given in %s on line %d
+
+Warning: IntlCalendar::createInstance(): intlcal_create_calendar: bad arguments in %s on line %d
+NULL
+
+Warning: intlcal_create_instance() expects at most 2 parameters, 3 given in %s on line %d
+
+Warning: intlcal_create_instance(): intlcal_create_calendar: bad arguments in %s on line %d
+NULL
+
+Warning: intlcal_create_instance(): intlcal_create_instance: passed IntlTimeZone is not properly constructed in %s on line %d
+NULL
+
+Warning: intlcal_create_instance() expects parameter 2 to be string, array given in %s on line %d
+
+Warning: intlcal_create_instance(): intlcal_create_calendar: bad arguments in %s on line %d
+NULL
diff --git a/ext/intl/tests/calendar_createInstance_variation1.phpt b/ext/intl/tests/calendar_createInstance_variation1.phpt
new file mode 100644
index 0000000000..138f2a2afd
--- /dev/null
+++ b/ext/intl/tests/calendar_createInstance_variation1.phpt
@@ -0,0 +1,84 @@
+--TEST--
+IntlCalendar::createInstance() argument variations
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '4.8') < 0)
+ die('skip for ICU 4.8+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+date_default_timezone_set('Europe/Amsterdam');
+
+$cal = intlcal_create_instance('Europe/Amsterdam');
+print_R($cal->getTimeZone());
+print_R($cal->getLocale(Locale::ACTUAL_LOCALE));
+echo "\n";
+
+$cal = intlcal_create_instance('Europe/Lisbon', null);
+print_R($cal->getTimeZone());
+print_R($cal->getLocale(Locale::ACTUAL_LOCALE));
+echo "\n";
+
+$cal = intlcal_create_instance(IntlTimeZone::createTimeZone('Europe/Lisbon'));
+print_R($cal->getTimeZone());
+print_R($cal->getLocale(Locale::ACTUAL_LOCALE));
+echo "\n";
+
+$cal = intlcal_create_instance(null, "pt");
+print_R($cal->getTimeZone());
+print_R($cal->getLocale(Locale::ACTUAL_LOCALE));
+echo "\n";
+
+$cal = intlcal_create_instance("Europe/Lisbon", "pt");
+print_R($cal->getTimeZone());
+print_R($cal->getLocale(Locale::ACTUAL_LOCALE));
+echo "\n";
+
+?>
+==DONE==
+--EXPECTF--
+IntlTimeZone Object
+(
+ [valid] => 1
+ [id] => Europe/Amsterdam
+ [rawOffset] => 3600000
+ [currentOffset] => %d
+)
+nl
+IntlTimeZone Object
+(
+ [valid] => 1
+ [id] => Europe/Lisbon
+ [rawOffset] => 0
+ [currentOffset] => %d
+)
+nl
+IntlTimeZone Object
+(
+ [valid] => 1
+ [id] => Europe/Lisbon
+ [rawOffset] => 0
+ [currentOffset] => %d
+)
+nl
+IntlTimeZone Object
+(
+ [valid] => 1
+ [id] => Europe/Amsterdam
+ [rawOffset] => 3600000
+ [currentOffset] => %d
+)
+pt
+IntlTimeZone Object
+(
+ [valid] => 1
+ [id] => Europe/Lisbon
+ [rawOffset] => 0
+ [currentOffset] => %d
+)
+pt
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_equals_before_after_basic.phpt b/ext/intl/tests/calendar_equals_before_after_basic.phpt
new file mode 100644
index 0000000000..50543ad0b4
--- /dev/null
+++ b/ext/intl/tests/calendar_equals_before_after_basic.phpt
@@ -0,0 +1,59 @@
+--TEST--
+IntlCalendar::equals(), ::before() and ::after() basic test
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$intlcal1 = new IntlGregorianCalendar(2012, 1, 29, 16, 59, 59);
+$intlcal2 = IntlCalendar::createInstance(null, '@calendar=japanese');
+$intlcal3 = new IntlGregorianCalendar(2012, 1, 29, 17, 00, 00);
+$intlcal2->setTime($intlcal1->getTime());
+
+var_dump($intlcal2->getType());
+
+var_dump("1 eq 1", $intlcal1->equals($intlcal1));
+
+var_dump("1 eq 2", $intlcal1->equals($intlcal2));
+var_dump("1 before 2", $intlcal1->before($intlcal2));
+var_dump("1 after 2", $intlcal1->after($intlcal2));
+
+var_dump("1 eq 3", $intlcal1->equals($intlcal3));
+var_dump("1 before 3", $intlcal1->before($intlcal3));
+var_dump("1 after 3", $intlcal1->after($intlcal3));
+
+var_dump("3 eq 2", intlcal_equals($intlcal3, $intlcal2));
+var_dump("3 before 2", intlcal_before($intlcal3, $intlcal2));
+var_dump("3 after 2", intlcal_after($intlcal3, $intlcal2));
+
+?>
+==DONE==
+--EXPECT--
+string(8) "japanese"
+string(6) "1 eq 1"
+bool(true)
+string(6) "1 eq 2"
+bool(true)
+string(10) "1 before 2"
+bool(false)
+string(9) "1 after 2"
+bool(false)
+string(6) "1 eq 3"
+bool(false)
+string(10) "1 before 3"
+bool(true)
+string(9) "1 after 3"
+bool(false)
+string(6) "3 eq 2"
+bool(false)
+string(10) "3 before 2"
+bool(false)
+string(9) "3 after 2"
+bool(true)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_equals_error.phpt b/ext/intl/tests/calendar_equals_error.phpt
new file mode 100644
index 0000000000..a947b42bfe
--- /dev/null
+++ b/ext/intl/tests/calendar_equals_error.phpt
@@ -0,0 +1,46 @@
+--TEST--
+IntlCalendar::equals(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+function eh($errno, $errstr) {
+echo "error: $errno, $errstr\n";
+}
+set_error_handler('eh');
+
+var_dump($c->equals());
+var_dump($c->equals(new stdclass));
+var_dump($c->equals(1, 2));
+
+var_dump(intlcal_equals($c, array()));
+var_dump(intlcal_equals(1, $c));
+
+--EXPECT--
+error: 2, IntlCalendar::equals() expects exactly 1 parameter, 0 given
+error: 2, IntlCalendar::equals(): intlcal_equals: bad arguments
+bool(false)
+error: 4096, Argument 1 passed to IntlCalendar::equals() must be an instance of IntlCalendar, instance of stdClass given
+error: 2, IntlCalendar::equals() expects parameter 1 to be IntlCalendar, object given
+error: 2, IntlCalendar::equals(): intlcal_equals: bad arguments
+bool(false)
+error: 4096, Argument 1 passed to IntlCalendar::equals() must be an instance of IntlCalendar, integer given
+error: 2, IntlCalendar::equals() expects exactly 1 parameter, 2 given
+error: 2, IntlCalendar::equals(): intlcal_equals: bad arguments
+bool(false)
+error: 4096, Argument 2 passed to intlcal_equals() must be an instance of IntlCalendar, array given
+error: 2, intlcal_equals() expects parameter 2 to be IntlCalendar, array given
+error: 2, intlcal_equals(): intlcal_equals: bad arguments
+bool(false)
+error: 4096, Argument 1 passed to intlcal_equals() must be an instance of IntlCalendar, integer given
+error: 2, intlcal_equals() expects parameter 1 to be IntlCalendar, integer given
+error: 2, intlcal_equals(): intlcal_equals: bad arguments
+bool(false)
diff --git a/ext/intl/tests/calendar_fieldDifference_basic.phpt b/ext/intl/tests/calendar_fieldDifference_basic.phpt
new file mode 100644
index 0000000000..3432420df4
--- /dev/null
+++ b/ext/intl/tests/calendar_fieldDifference_basic.phpt
@@ -0,0 +1,35 @@
+--TEST--
+IntlCalendar::fieldDifference() basic test
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$intlcal = IntlCalendar::createInstance('UTC');
+$intlcal->setTime(strtotime('2012-02-29 05:06:07 +0000') * 1000);
+var_dump(
+ $intlcal->fieldDifference(
+ strtotime('2012-02-29 06:06:08 +0000') * 1000,
+ IntlCalendar::FIELD_SECOND),
+ $intlcal->get(IntlCalendar::FIELD_HOUR_OF_DAY));
+
+
+$intlcal->setTime(strtotime('2012-02-29 05:06:07 +0000') * 1000);
+var_dump(
+ intlcal_field_difference(
+ $intlcal,
+ strtotime('2012-02-29 06:07:08 +0000') * 1000,
+ IntlCalendar::FIELD_MINUTE));
+?>
+==DONE==
+--EXPECT--
+int(3601)
+int(6)
+int(61)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_fieldDifference_error.phpt b/ext/intl/tests/calendar_fieldDifference_error.phpt
new file mode 100644
index 0000000000..ef7e4fc8dc
--- /dev/null
+++ b/ext/intl/tests/calendar_fieldDifference_error.phpt
@@ -0,0 +1,42 @@
+--TEST--
+IntlCalendar::fieldDifference(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+var_dump($c->fieldDifference($c, 2, 3));
+var_dump($c->fieldDifference(INF, 2));
+var_dump($c->fieldDifference(1));
+
+var_dump(intlcal_field_difference($c, 0, 1, 2));
+var_dump(intlcal_field_difference(1, 0, 1));
+
+--EXPECTF--
+
+Warning: IntlCalendar::fieldDifference() expects exactly 2 parameters, 3 given in %s on line %d
+
+Warning: IntlCalendar::fieldDifference(): intlcal_field_difference: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::fieldDifference(): intlcal_field_difference: Call to ICU method has failed in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::fieldDifference() expects exactly 2 parameters, 1 given in %s on line %d
+
+Warning: IntlCalendar::fieldDifference(): intlcal_field_difference: bad arguments in %s on line %d
+bool(false)
+
+Warning: intlcal_field_difference() expects exactly 3 parameters, 4 given in %s on line %d
+
+Warning: intlcal_field_difference(): intlcal_field_difference: bad arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intlcal_field_difference() must be an instance of IntlCalendar, integer given in %s on line %d
diff --git a/ext/intl/tests/calendar_fromDateTime_basic.phpt b/ext/intl/tests/calendar_fromDateTime_basic.phpt
new file mode 100644
index 0000000000..1863b7815c
--- /dev/null
+++ b/ext/intl/tests/calendar_fromDateTime_basic.phpt
@@ -0,0 +1,52 @@
+--TEST--
+IntlCalendar::fromDateTime(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl_NL");
+date_default_timezone_set('Europe/Lisbon');
+
+$cal = IntlCalendar::fromDateTime('2012-01-01 00:00:00 Europe/Rome');
+var_dump(
+ $cal->getTime(),
+ strtotime('2012-01-01 00:00:00 Europe/Rome') * 1000.,
+ $cal->getTimeZone()->getID(),
+ $cal->getLocale(1)
+);
+echo "\n";
+
+$cal = IntlCalendar::fromDateTime(new DateTime('2012-01-01 00:00:00 PST'), "pt_PT");
+var_dump(
+ $cal->getTime(),
+ strtotime('2012-01-01 00:00:00 PST') * 1000.,
+ $cal->getTimeZone()->getID(),
+ $cal->getLocale(1)
+);
+
+echo "\n";
+
+$cal = intlcal_from_date_time(new DateTime('2012-01-01 00:00:00 +03:40'));
+var_dump(
+ $cal->getTime(),
+ strtotime('2012-01-01 00:00:00 +03:40') * 1000.,
+ $cal->getTimeZone()->getID()
+);
+
+--EXPECTF--
+float(1325372400000)
+float(1325372400000)
+string(11) "Europe/Rome"
+string(5) "nl_NL"
+
+float(1325404800000)
+float(1325404800000)
+string(3) "PST"
+string(5) "pt_PT"
+
+float(1325362800000)
+float(1325362800000)
+string(%d) "GMT+03%S40"
diff --git a/ext/intl/tests/calendar_fromDateTime_error.phpt b/ext/intl/tests/calendar_fromDateTime_error.phpt
new file mode 100644
index 0000000000..2fbf7196f9
--- /dev/null
+++ b/ext/intl/tests/calendar_fromDateTime_error.phpt
@@ -0,0 +1,59 @@
+--TEST--
+IntlCalendar::fromDateTime(): errors
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+date_default_timezone_set('Europe/Lisbon');
+
+var_dump(IntlCalendar::fromDateTime());
+var_dump(IntlCalendar::fromDateTime(0,1,2));
+
+try {
+IntlCalendar::fromDateTime("foobar");
+} catch (Exception $e) {
+ echo "threw exception, OK";
+}
+class A extends DateTime {
+function __construct() {}
+}
+
+var_dump(IntlCalendar::fromDateTime(new A));
+
+$date = new DateTime('2012-01-01 00:00:00 +24:00');
+var_dump(IntlCalendar::fromDateTime($date));
+
+$date = new DateTime('2012-01-01 00:00:00 WEST');
+var_dump(IntlCalendar::fromDateTime($date));
+
+var_dump(intlcal_from_date_time());
+
+--EXPECTF--
+
+Warning: IntlCalendar::fromDateTime() expects at least 1 parameter, 0 given in %s on line %d
+
+Warning: IntlCalendar::fromDateTime(): intlcal_from_date_time: bad arguments in %s on line %d
+NULL
+
+Warning: IntlCalendar::fromDateTime() expects at most 2 parameters, 3 given in %s on line %d
+
+Warning: IntlCalendar::fromDateTime(): intlcal_from_date_time: bad arguments in %s on line %d
+NULL
+threw exception, OK
+Warning: IntlCalendar::fromDateTime(): intlcal_from_date_time: DateTime object is unconstructed in %s on line %d
+NULL
+
+Warning: IntlCalendar::fromDateTime(): intlcal_from_date_time: object has an time zone offset that's too large in %s on line %d
+NULL
+
+Warning: IntlCalendar::fromDateTime(): intlcal_from_date_time: time zone id 'WEST' extracted from ext/date DateTimeZone not recognized in %s on line %d
+NULL
+
+Warning: intlcal_from_date_time() expects at least 1 parameter, 0 given in %s on line %d
+
+Warning: intlcal_from_date_time(): intlcal_from_date_time: bad arguments in %s on line %d
+NULL
diff --git a/ext/intl/tests/calendar_getAvailableLocales_basic.phpt b/ext/intl/tests/calendar_getAvailableLocales_basic.phpt
new file mode 100644
index 0000000000..5d5b79c020
--- /dev/null
+++ b/ext/intl/tests/calendar_getAvailableLocales_basic.phpt
@@ -0,0 +1,23 @@
+--TEST--
+IntlCalendar::getAvailableLocales() basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$locales = IntlCalendar::getAvailableLocales();
+var_dump(count($locales) > 100);
+
+$locales = intlcal_get_available_locales();
+var_dump(in_array('pt', $locales));
+
+?>
+==DONE==
+--EXPECT--
+bool(true)
+bool(true)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_getAvailableLocales_error.phpt b/ext/intl/tests/calendar_getAvailableLocales_error.phpt
new file mode 100644
index 0000000000..e9edc468e5
--- /dev/null
+++ b/ext/intl/tests/calendar_getAvailableLocales_error.phpt
@@ -0,0 +1,24 @@
+--TEST--
+IntlCalendar::getAvailableLocales(): bad arguments
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+var_dump(intlcal_get_available_locales(1));
+var_dump(IntlCalendar::getAvailableLocales(2));
+
+--EXPECTF--
+
+Warning: intlcal_get_available_locales() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: intlcal_get_available_locales(): intlcal_get_available_locales: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::getAvailableLocales() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlCalendar::getAvailableLocales(): intlcal_get_available_locales: bad arguments in %s on line %d
+bool(false)
diff --git a/ext/intl/tests/calendar_getDayOfWeekType_basic.phpt b/ext/intl/tests/calendar_getDayOfWeekType_basic.phpt
new file mode 100644
index 0000000000..d5319f1471
--- /dev/null
+++ b/ext/intl/tests/calendar_getDayOfWeekType_basic.phpt
@@ -0,0 +1,34 @@
+--TEST--
+IntlCalendar::getDayOfWeekType() basic test
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '4.4') < 0)
+ die('skip for ICU 4.4+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$intlcal = IntlCalendar::createInstance('UTC');
+$intlcal->setTime(strtotime('2012-02-29 00:00:00 +0000') * 1000);
+var_dump(
+ intlcal_get_day_of_week_type($intlcal, IntlCalendar::DOW_SUNDAY),
+ $intlcal->getDayOfWeekType(IntlCalendar::DOW_MONDAY),
+ $intlcal->getDayOfWeekType(IntlCalendar::DOW_TUESDAY),
+ $intlcal->getDayOfWeekType(IntlCalendar::DOW_FRIDAY),
+ $intlcal->getDayOfWeekType(IntlCalendar::DOW_SATURDAY)
+);
+
+?>
+==DONE==
+--EXPECT--
+int(3)
+int(0)
+int(0)
+int(0)
+int(1)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_getDayOfWeekType_error.phpt b/ext/intl/tests/calendar_getDayOfWeekType_error.phpt
new file mode 100644
index 0000000000..3926655615
--- /dev/null
+++ b/ext/intl/tests/calendar_getDayOfWeekType_error.phpt
@@ -0,0 +1,44 @@
+--TEST--
+IntlCalendar::getDayOfWeekOfType(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '4.4') < 0)
+ die('skip for ICU 4.4+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+var_dump($c->getDayOfWeekType(1, 2));
+var_dump($c->getDayOfWeekType(0));
+var_dump($c->getDayOfWeekType());
+
+var_dump(intlcal_get_day_of_week_type($c, "foo"));
+var_dump(intlcal_get_day_of_week_type(1, 1));
+
+--EXPECTF--
+
+Warning: IntlCalendar::getDayOfWeekType() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: IntlCalendar::getDayOfWeekType(): intlcal_get_day_of_week_type: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::getDayOfWeekType(): intlcal_get_day_of_week_type: invalid day of week in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::getDayOfWeekType() expects exactly 1 parameter, 0 given in %s on line %d
+
+Warning: IntlCalendar::getDayOfWeekType(): intlcal_get_day_of_week_type: bad arguments in %s on line %d
+bool(false)
+
+Warning: intlcal_get_day_of_week_type() expects parameter 2 to be long, string given in %s on line %d
+
+Warning: intlcal_get_day_of_week_type(): intlcal_get_day_of_week_type: bad arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intlcal_get_day_of_week_type() must be an instance of IntlCalendar, integer given in %s on line %d
diff --git a/ext/intl/tests/calendar_getErrorCode_error.phpt b/ext/intl/tests/calendar_getErrorCode_error.phpt
new file mode 100644
index 0000000000..13aab81923
--- /dev/null
+++ b/ext/intl/tests/calendar_getErrorCode_error.phpt
@@ -0,0 +1,26 @@
+--TEST--
+IntlCalendar::getErrorCode(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+var_dump($c->getErrorCode(array()));
+
+var_dump(intlcal_get_error_code(null));
+
+--EXPECTF--
+
+Warning: IntlCalendar::getErrorCode() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlCalendar::getErrorCode(): intlcal_get_error_code: bad arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intlcal_get_error_code() must be an instance of IntlCalendar, null given in %s on line %d
diff --git a/ext/intl/tests/calendar_getErrorCode_getErrorMessage_basic.phpt b/ext/intl/tests/calendar_getErrorCode_getErrorMessage_basic.phpt
new file mode 100644
index 0000000000..71c053492f
--- /dev/null
+++ b/ext/intl/tests/calendar_getErrorCode_getErrorMessage_basic.phpt
@@ -0,0 +1,43 @@
+--TEST--
+IntlCalendar::getErrorCode(), ::getErrorMessage() basic test
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$intlcal = new IntlGregorianCalendar(2012, 1, 29);
+var_dump(
+ $intlcal->getErrorCode(),
+ intlcal_get_error_code($intlcal),
+ $intlcal->getErrorMessage(),
+ intlcal_get_error_message($intlcal)
+);
+$intlcal->add(IntlCalendar::FIELD_SECOND, 2147483647);
+$intlcal->fieldDifference(-PHP_INT_MAX, IntlCalendar::FIELD_SECOND);
+
+var_dump(
+ $intlcal->getErrorCode(),
+ intlcal_get_error_code($intlcal),
+ $intlcal->getErrorMessage(),
+ intlcal_get_error_message($intlcal)
+);
+?>
+==DONE==
+--EXPECTF--
+int(0)
+int(0)
+string(12) "U_ZERO_ERROR"
+string(12) "U_ZERO_ERROR"
+
+Warning: IntlCalendar::fieldDifference(): intlcal_field_difference: Call to ICU method has failed in %s on line %d
+int(1)
+int(1)
+string(81) "intlcal_field_difference: Call to ICU method has failed: U_ILLEGAL_ARGUMENT_ERROR"
+string(81) "intlcal_field_difference: Call to ICU method has failed: U_ILLEGAL_ARGUMENT_ERROR"
+==DONE==
diff --git a/ext/intl/tests/calendar_getErrorMessage_error.phpt b/ext/intl/tests/calendar_getErrorMessage_error.phpt
new file mode 100644
index 0000000000..6081833904
--- /dev/null
+++ b/ext/intl/tests/calendar_getErrorMessage_error.phpt
@@ -0,0 +1,26 @@
+--TEST--
+IntlCalendar::getErrorMessage(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+var_dump($c->getErrorMessage(array()));
+
+var_dump(intlcal_get_error_message(null));
+
+--EXPECTF--
+
+Warning: IntlCalendar::getErrorMessage() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlCalendar::getErrorMessage(): intlcal_get_error_message: bad arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intlcal_get_error_message() must be an instance of IntlCalendar, null given in %s on line %d
diff --git a/ext/intl/tests/calendar_getFirstDayOfWeek_basic.phpt b/ext/intl/tests/calendar_getFirstDayOfWeek_basic.phpt
new file mode 100644
index 0000000000..82a0bc85cc
--- /dev/null
+++ b/ext/intl/tests/calendar_getFirstDayOfWeek_basic.phpt
@@ -0,0 +1,20 @@
+--TEST--
+IntlCalendar::getFirstDayOfWeek() basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$intlcal = IntlCalendar::createInstance('UTC');
+var_dump($intlcal->getFirstDayOfWeek());
+var_dump(intlcal_get_first_day_of_week($intlcal));
+?>
+==DONE==
+--EXPECT--
+int(2)
+int(2)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_getFirstDayOfWeek_error.phpt b/ext/intl/tests/calendar_getFirstDayOfWeek_error.phpt
new file mode 100644
index 0000000000..e13b5138a7
--- /dev/null
+++ b/ext/intl/tests/calendar_getFirstDayOfWeek_error.phpt
@@ -0,0 +1,32 @@
+--TEST--
+IntlCalendar::getFirstDayOfWeek(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+var_dump($c->getFirstDayOfWeek(1));
+
+var_dump(intlcal_get_first_day_of_week($c, 1));
+var_dump(intlcal_get_first_day_of_week(1));
+
+--EXPECTF--
+
+Warning: IntlCalendar::getFirstDayOfWeek() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlCalendar::getFirstDayOfWeek(): intlcal_get_first_day_of_week: bad arguments in %s on line %d
+bool(false)
+
+Warning: intlcal_get_first_day_of_week() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: intlcal_get_first_day_of_week(): intlcal_get_first_day_of_week: bad arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intlcal_get_first_day_of_week() must be an instance of IntlCalendar, integer given in %s on line %d
diff --git a/ext/intl/tests/calendar_getKeywordValuesForLocale_basic.phpt b/ext/intl/tests/calendar_getKeywordValuesForLocale_basic.phpt
new file mode 100644
index 0000000000..dedfcea8fe
--- /dev/null
+++ b/ext/intl/tests/calendar_getKeywordValuesForLocale_basic.phpt
@@ -0,0 +1,36 @@
+--TEST--
+IntlCalendar::getKeywordValuesForLocale() basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '4.2') < 0)
+ die('skip for ICU 4.2+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+print_r(
+iterator_to_array(
+IntlCalendar::getKeywordValuesForLocale('calendar', 'pt', true)
+));
+echo "\n";
+
+$var = iterator_to_array(
+intlcal_get_keyword_values_for_locale('calendar', 'pt', false)
+);
+var_dump(count($var) > 8);
+var_dump(in_array('japanese', $var));
+
+?>
+==DONE==
+--EXPECT--
+Array
+(
+ [0] => gregorian
+)
+
+bool(true)
+bool(true)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_getKeywordValuesForLocale_error.phpt b/ext/intl/tests/calendar_getKeywordValuesForLocale_error.phpt
new file mode 100644
index 0000000000..2aa8002bd1
--- /dev/null
+++ b/ext/intl/tests/calendar_getKeywordValuesForLocale_error.phpt
@@ -0,0 +1,26 @@
+--TEST--
+IntlCalendar::getKeywordValuesForLocale(): bad arguments
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '4.2') < 0)
+ die('skip for ICU 4.2+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+var_dump(intlcal_get_keyword_values_for_locale(1, 2));
+var_dump(IntlCalendar::getKeywordValuesForLocale(1, 2, array()));
+
+--EXPECTF--
+
+Warning: intlcal_get_keyword_values_for_locale() expects exactly 3 parameters, 2 given in %s on line %d
+
+Warning: intlcal_get_keyword_values_for_locale(): intlcal_get_keyword_values_for_locale: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::getKeywordValuesForLocale() expects parameter 3 to be boolean, array given in %s on line %d
+
+Warning: IntlCalendar::getKeywordValuesForLocale(): intlcal_get_keyword_values_for_locale: bad arguments in %s on line %d
+bool(false)
diff --git a/ext/intl/tests/calendar_getLocale_basic.phpt b/ext/intl/tests/calendar_getLocale_basic.phpt
new file mode 100644
index 0000000000..63f846f9a8
--- /dev/null
+++ b/ext/intl/tests/calendar_getLocale_basic.phpt
@@ -0,0 +1,22 @@
+--TEST--
+IntlCalendar::getLocale() basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '4.8') < 0)
+ die('skip for ICU 4.8+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$intlcal = IntlCalendar::createInstance('UTC');
+var_dump($intlcal->getLocale(Locale::ACTUAL_LOCALE));
+var_dump(intlcal_get_locale($intlcal, Locale::VALID_LOCALE));
+?>
+==DONE==
+--EXPECT--
+string(2) "nl"
+string(5) "nl_NL"
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_getLocale_error.phpt b/ext/intl/tests/calendar_getLocale_error.phpt
new file mode 100644
index 0000000000..42970a9e7f
--- /dev/null
+++ b/ext/intl/tests/calendar_getLocale_error.phpt
@@ -0,0 +1,42 @@
+--TEST--
+IntlCalendar::getLocale(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+var_dump($c->getLocale());
+var_dump($c->getLocale(2));
+var_dump($c->getLocale(2, 3));
+
+var_dump(intlcal_get_locale($c));
+var_dump(intlcal_get_locale(1));
+
+--EXPECTF--
+
+Warning: IntlCalendar::getLocale() expects exactly 1 parameter, 0 given in %s on line %d
+
+Warning: IntlCalendar::getLocale(): intlcal_get_locale: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::getLocale(): intlcal_get_locale: invalid locale type in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::getLocale() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: IntlCalendar::getLocale(): intlcal_get_locale: bad arguments in %s on line %d
+bool(false)
+
+Warning: intlcal_get_locale() expects exactly 2 parameters, 1 given in %s on line %d
+
+Warning: intlcal_get_locale(): intlcal_get_locale: bad arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intlcal_get_locale() must be an instance of IntlCalendar, integer given in %s on line %d
diff --git a/ext/intl/tests/calendar_getMinimalDaysInFirstWeek_basic.phpt b/ext/intl/tests/calendar_getMinimalDaysInFirstWeek_basic.phpt
new file mode 100644
index 0000000000..eeaa3104a8
--- /dev/null
+++ b/ext/intl/tests/calendar_getMinimalDaysInFirstWeek_basic.phpt
@@ -0,0 +1,22 @@
+--TEST--
+IntlCalendar::getMinimalDaysInFirstWeek() basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '4.8') < 0)
+ die('skip for ICU 4.8+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$intlcal = IntlCalendar::createInstance('UTC');
+var_dump($intlcal->getMinimalDaysInFirstWeek());
+var_dump(intlcal_get_minimal_days_in_first_week($intlcal));
+?>
+==DONE==
+--EXPECT--
+int(4)
+int(4)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_getMinimalDaysInFirstWeek_error.phpt b/ext/intl/tests/calendar_getMinimalDaysInFirstWeek_error.phpt
new file mode 100644
index 0000000000..8e1971dc2b
--- /dev/null
+++ b/ext/intl/tests/calendar_getMinimalDaysInFirstWeek_error.phpt
@@ -0,0 +1,32 @@
+--TEST--
+IntlCalendar::getMinimalDaysInFirstWeek(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+var_dump($c->getMinimalDaysInFirstWeek(1));
+
+var_dump(intlcal_get_minimal_days_in_first_week($c, 1));
+var_dump(intlcal_get_minimal_days_in_first_week(1));
+
+--EXPECTF--
+
+Warning: IntlCalendar::getMinimalDaysInFirstWeek() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlCalendar::getMinimalDaysInFirstWeek(): intlcal_get_minimal_days_in_first_week: bad arguments in %s on line %d
+bool(false)
+
+Warning: intlcal_get_minimal_days_in_first_week() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: intlcal_get_minimal_days_in_first_week(): intlcal_get_minimal_days_in_first_week: bad arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intlcal_get_minimal_days_in_first_week() must be an instance of IntlCalendar, integer given in %s on line %d
diff --git a/ext/intl/tests/calendar_getNow_basic.phpt b/ext/intl/tests/calendar_getNow_basic.phpt
new file mode 100644
index 0000000000..18325dfa60
--- /dev/null
+++ b/ext/intl/tests/calendar_getNow_basic.phpt
@@ -0,0 +1,23 @@
+--TEST--
+IntlCalendar::getNow() basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$now = IntlCalendar::getNow();
+$proc_now = intlcal_get_now();
+$time = time();
+var_dump(abs($now - $proc_now) < 500);
+var_dump(abs($time * 1000 - $proc_now) < 1000);
+
+?>
+==DONE==
+--EXPECT--
+bool(true)
+bool(true)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_getNow_error.phpt b/ext/intl/tests/calendar_getNow_error.phpt
new file mode 100644
index 0000000000..31991bb591
--- /dev/null
+++ b/ext/intl/tests/calendar_getNow_error.phpt
@@ -0,0 +1,24 @@
+--TEST--
+IntlCalendar::getNow(): bad arguments
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+var_dump(intlcal_get_now(1));
+var_dump(IntlCalendar::getNow(2));
+
+--EXPECTF--
+
+Warning: intlcal_get_now() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: intlcal_get_now(): intlcal_get_now: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::getNow() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlCalendar::getNow(): intlcal_get_now: bad arguments in %s on line %d
+bool(false)
diff --git a/ext/intl/tests/calendar_getSkipped_RepeatedWallTimeOption_error.phpt b/ext/intl/tests/calendar_getSkipped_RepeatedWallTimeOption_error.phpt
new file mode 100644
index 0000000000..e07135586c
--- /dev/null
+++ b/ext/intl/tests/calendar_getSkipped_RepeatedWallTimeOption_error.phpt
@@ -0,0 +1,47 @@
+--TEST--
+IntlCalendar::getSkipped/RepeatedWallTimeOption(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '49') < 0)
+ die('skip for ICU 49+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+var_dump($c->getSkippedWallTimeOption(1));
+var_dump($c->getRepeatedWallTimeOption(1));
+
+var_dump(intlcal_get_skipped_wall_time_option($c, 1));
+var_dump(intlcal_get_repeated_wall_time_option($c, 1));
+
+var_dump(intlcal_get_skipped_wall_time_option(1));
+
+--EXPECTF--
+
+Warning: IntlCalendar::getSkippedWallTimeOption() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlCalendar::getSkippedWallTimeOption(): intlcal_get_skipped_wall_time_option: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::getRepeatedWallTimeOption() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlCalendar::getRepeatedWallTimeOption(): intlcal_get_repeated_wall_time_option: bad arguments in %s on line %d
+bool(false)
+
+Warning: intlcal_get_skipped_wall_time_option() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: intlcal_get_skipped_wall_time_option(): intlcal_get_skipped_wall_time_option: bad arguments in %s on line %d
+bool(false)
+
+Warning: intlcal_get_repeated_wall_time_option() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: intlcal_get_repeated_wall_time_option(): intlcal_get_repeated_wall_time_option: bad arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intlcal_get_skipped_wall_time_option() must be an instance of IntlCalendar, integer given in %s on line %d
diff --git a/ext/intl/tests/calendar_getTimeZone_basic.phpt b/ext/intl/tests/calendar_getTimeZone_basic.phpt
new file mode 100644
index 0000000000..fd9aff1f99
--- /dev/null
+++ b/ext/intl/tests/calendar_getTimeZone_basic.phpt
@@ -0,0 +1,34 @@
+--TEST--
+IntlCalendar::getTimeZone() basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '4.8') < 0)
+ die('skip for ICU 4.8+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$intlcal = IntlCalendar::createInstance('GMT+00:01');
+print_r($intlcal->getTimeZone());
+print_r(intlcal_get_time_zone($intlcal));
+?>
+==DONE==
+--EXPECT--
+IntlTimeZone Object
+(
+ [valid] => 1
+ [id] => GMT+00:01
+ [rawOffset] => 60000
+ [currentOffset] => 60000
+)
+IntlTimeZone Object
+(
+ [valid] => 1
+ [id] => GMT+00:01
+ [rawOffset] => 60000
+ [currentOffset] => 60000
+)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_getTimeZone_error.phpt b/ext/intl/tests/calendar_getTimeZone_error.phpt
new file mode 100644
index 0000000000..470701cd91
--- /dev/null
+++ b/ext/intl/tests/calendar_getTimeZone_error.phpt
@@ -0,0 +1,32 @@
+--TEST--
+IntlCalendar::getTimeZone(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+var_dump($c->getTimeZone(1));
+
+var_dump(intlcal_get_time_zone($c, 1));
+var_dump(intlcal_get_time_zone(1));
+
+--EXPECTF--
+
+Warning: IntlCalendar::getTimeZone() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlCalendar::getTimeZone(): intlcal_get_time_zone: bad arguments in %s on line %d
+bool(false)
+
+Warning: intlcal_get_time_zone() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: intlcal_get_time_zone(): intlcal_get_time_zone: bad arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intlcal_get_time_zone() must be an instance of IntlCalendar, integer given in %s on line %d
diff --git a/ext/intl/tests/calendar_getTime_basic.phpt b/ext/intl/tests/calendar_getTime_basic.phpt
new file mode 100644
index 0000000000..659c71c961
--- /dev/null
+++ b/ext/intl/tests/calendar_getTime_basic.phpt
@@ -0,0 +1,29 @@
+--TEST--
+IntlCalendar::getTime() basic test
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$intlcal = IntlCalendar::createInstance('UTC');
+$intlcal->clear();
+$intlcal->set(IntlCalendar::FIELD_YEAR, 2012);
+$intlcal->set(IntlCalendar::FIELD_MONTH, 1 /* Feb */);
+$intlcal->set(IntlCalendar::FIELD_DAY_OF_MONTH, 29);
+
+$time = strtotime('2012-02-29 00:00:00 +0000');
+
+var_dump((float)$time*1000, $intlcal->getTime());
+
+?>
+==DONE==
+--EXPECT--
+float(1330473600000)
+float(1330473600000)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_getTime_error.phpt b/ext/intl/tests/calendar_getTime_error.phpt
new file mode 100644
index 0000000000..5d27e21101
--- /dev/null
+++ b/ext/intl/tests/calendar_getTime_error.phpt
@@ -0,0 +1,31 @@
+--TEST--
+IntlCalendar::getTime(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+var_dump($c->getTime(1));
+
+var_dump(intlcal_get_time($c, 1));
+var_dump(intlcal_get_time(1));
+--EXPECTF--
+
+Warning: IntlCalendar::getTime() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlCalendar::getTime(): intlcal_get_time: bad arguments in %s on line %d
+bool(false)
+
+Warning: intlcal_get_time() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: intlcal_get_time(): intlcal_get_time: bad arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intlcal_get_time() must be an instance of IntlCalendar, integer given in %s on line %d
diff --git a/ext/intl/tests/calendar_getType_basic.phpt b/ext/intl/tests/calendar_getType_basic.phpt
new file mode 100644
index 0000000000..ba32dd0526
--- /dev/null
+++ b/ext/intl/tests/calendar_getType_basic.phpt
@@ -0,0 +1,23 @@
+--TEST--
+IntlCalendar::getType() basic test
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$intlcal = IntlCalendar::createInstance();
+VAR_DUMP($intlcal->getType());
+$intlcal = IntlCalendar::createInstance(null, "nl_NL@calendar=hebrew");
+VAR_DUMP(intlcal_get_type($intlcal));
+?>
+==DONE==
+--EXPECT--
+string(9) "gregorian"
+string(6) "hebrew"
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_getType_error.phpt b/ext/intl/tests/calendar_getType_error.phpt
new file mode 100644
index 0000000000..668ebeafb4
--- /dev/null
+++ b/ext/intl/tests/calendar_getType_error.phpt
@@ -0,0 +1,32 @@
+--TEST--
+IntlCalendar::getType(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+var_dump($c->getType(1));
+
+var_dump(intlcal_get_type($c, 1));
+var_dump(intlcal_get_type(1));
+
+--EXPECTF--
+
+Warning: IntlCalendar::getType() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlCalendar::getType(): intlcal_get_type: bad arguments in %s on line %d
+bool(false)
+
+Warning: intlcal_get_type() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: intlcal_get_type(): intlcal_get_type: bad arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intlcal_get_type() must be an instance of IntlCalendar, integer given in %s on line %d
diff --git a/ext/intl/tests/calendar_getWeekendTransition_basic.phpt b/ext/intl/tests/calendar_getWeekendTransition_basic.phpt
new file mode 100644
index 0000000000..e725743006
--- /dev/null
+++ b/ext/intl/tests/calendar_getWeekendTransition_basic.phpt
@@ -0,0 +1,24 @@
+--TEST--
+IntlCalendar::getWeekendTransition() basic test
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '4.4') < 0)
+ die('skip for ICU 4.4+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$intlcal = IntlCalendar::createInstance();
+var_dump($intlcal->getWeekendTransition(IntlCalendar::DOW_SUNDAY));
+var_dump(intlcal_get_weekend_transition($intlcal, IntlCalendar::DOW_SUNDAY));
+?>
+==DONE==
+--EXPECT--
+int(86400000)
+int(86400000)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_getWeekendTransition_error.phpt b/ext/intl/tests/calendar_getWeekendTransition_error.phpt
new file mode 100644
index 0000000000..f7c9cc7ed1
--- /dev/null
+++ b/ext/intl/tests/calendar_getWeekendTransition_error.phpt
@@ -0,0 +1,44 @@
+--TEST--
+IntlCalendar::getWeekendTransition(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '4.4') < 0)
+ die('skip for ICU 4.4+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+var_dump($c->getWeekendTransition());
+var_dump($c->getWeekendTransition(1, 2));
+var_dump($c->getWeekendTransition(0));
+
+var_dump(intlcal_get_weekend_transition($c));
+var_dump(intlcal_get_weekend_transition(1, 1));
+
+--EXPECTF--
+
+Warning: IntlCalendar::getWeekendTransition() expects exactly 1 parameter, 0 given in %s on line %d
+
+Warning: IntlCalendar::getWeekendTransition(): intlcal_get_weekend_transition: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::getWeekendTransition() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: IntlCalendar::getWeekendTransition(): intlcal_get_weekend_transition: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::getWeekendTransition(): intlcal_get_weekend_transition: invalid day of week in %s on line %d
+bool(false)
+
+Warning: intlcal_get_weekend_transition() expects exactly 2 parameters, 1 given in %s on line %d
+
+Warning: intlcal_get_weekend_transition(): intlcal_get_weekend_transition: bad arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intlcal_get_weekend_transition() must be an instance of IntlCalendar, integer given in %s on line %d
diff --git a/ext/intl/tests/calendar_getXMaximum_basic.phpt b/ext/intl/tests/calendar_getXMaximum_basic.phpt
new file mode 100644
index 0000000000..9b840212d9
--- /dev/null
+++ b/ext/intl/tests/calendar_getXMaximum_basic.phpt
@@ -0,0 +1,34 @@
+--TEST--
+IntlCalendar::getMaximum(), ::getActualMaximum(), ::getLeastMaximum() basic test
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$intlcal = IntlCalendar::createInstance('UTC');
+$intlcal->setTime(strtotime('2012-02-29 05:06:07 +0000') * 1000);
+var_dump(
+ $intlcal->getLeastMaximum(IntlCalendar::FIELD_DAY_OF_MONTH),
+ intlcal_get_least_maximum($intlcal, IntlCalendar::FIELD_DAY_OF_MONTH),
+ $intlcal->getActualMaximum(IntlCalendar::FIELD_DAY_OF_MONTH),
+ intlcal_get_actual_maximum($intlcal, IntlCalendar::FIELD_DAY_OF_MONTH),
+ $intlcal->getMaximum(IntlCalendar::FIELD_DAY_OF_MONTH),
+ intlcal_get_maximum($intlcal, IntlCalendar::FIELD_DAY_OF_MONTH)
+);
+
+?>
+==DONE==
+--EXPECT--
+int(28)
+int(28)
+int(29)
+int(29)
+int(31)
+int(31)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_getXMinimum_basic.phpt b/ext/intl/tests/calendar_getXMinimum_basic.phpt
new file mode 100644
index 0000000000..83fd163809
--- /dev/null
+++ b/ext/intl/tests/calendar_getXMinimum_basic.phpt
@@ -0,0 +1,34 @@
+--TEST--
+IntlCalendar::getMinimum(), ::getActualMinimum(), ::getGreatestMinimum() basic test
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$intlcal = IntlCalendar::createInstance('UTC');
+$intlcal->setTime(strtotime('2012-02-29 05:06:07 +0000') * 1000);
+var_dump(
+ $intlcal->getGreatestMinimum(IntlCalendar::FIELD_DAY_OF_MONTH),
+ intlcal_get_greatest_minimum($intlcal, IntlCalendar::FIELD_DAY_OF_MONTH),
+ $intlcal->getActualMinimum(IntlCalendar::FIELD_DAY_OF_MONTH),
+ intlcal_get_actual_minimum($intlcal, IntlCalendar::FIELD_DAY_OF_MONTH),
+ $intlcal->getMinimum(IntlCalendar::FIELD_DAY_OF_MONTH),
+ intlcal_get_minimum($intlcal, IntlCalendar::FIELD_DAY_OF_MONTH)
+);
+
+?>
+==DONE==
+--EXPECT--
+int(1)
+int(1)
+int(1)
+int(1)
+int(1)
+int(1)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_get_Least_Greatest_Minimum_Maximum_error.phpt b/ext/intl/tests/calendar_get_Least_Greatest_Minimum_Maximum_error.phpt
new file mode 100644
index 0000000000..acd9b58c1d
--- /dev/null
+++ b/ext/intl/tests/calendar_get_Least_Greatest_Minimum_Maximum_error.phpt
@@ -0,0 +1,100 @@
+--TEST--
+IntlCalendar::get/Least/Greatest/Minimum/Maximum(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+var_dump($c->getLeastMaximum());
+var_dump($c->getMaximum());
+var_dump($c->getGreatestMinimum());
+var_dump($c->getMinimum());
+
+var_dump($c->getLeastMaximum(-1));
+var_dump($c->getMaximum(-1));
+var_dump($c->getGreatestMinimum(-1));
+var_dump($c->getMinimum(-1));
+
+var_dump(intlcal_get_least_maximum($c, -1));
+var_dump(intlcal_get_maximum($c, -1));
+var_dump(intlcal_get_greatest_minimum($c, -1));
+var_dump(intlcal_get_minimum($c, -1));
+
+function eh($errno, $errstr) {
+echo "error: $errno, $errstr\n";
+}
+set_error_handler('eh');
+
+var_dump(intlcal_get_least_maximum(1, 1));
+var_dump(intlcal_get_maximum(1, 1));
+var_dump(intlcal_get_greatest_minimum(1, -1));
+var_dump(intlcal_get_minimum(1, -1));
+
+--EXPECTF--
+
+Warning: IntlCalendar::getLeastMaximum() expects exactly 1 parameter, 0 given in %s on line %d
+
+Warning: IntlCalendar::getLeastMaximum(): intlcal_get_least_maximum: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::getMaximum() expects exactly 1 parameter, 0 given in %s on line %d
+
+Warning: IntlCalendar::getMaximum(): intlcal_get_maximum: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::getGreatestMinimum() expects exactly 1 parameter, 0 given in %s on line %d
+
+Warning: IntlCalendar::getGreatestMinimum(): intlcal_get_greatest_minimum: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::getMinimum() expects exactly 1 parameter, 0 given in %s on line %d
+
+Warning: IntlCalendar::getMinimum(): intlcal_get_minimum: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::getLeastMaximum(): intlcal_get_least_maximum: invalid field in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::getMaximum(): intlcal_get_maximum: invalid field in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::getGreatestMinimum(): intlcal_get_greatest_minimum: invalid field in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::getMinimum(): intlcal_get_minimum: invalid field in %s on line %d
+bool(false)
+
+Warning: intlcal_get_least_maximum(): intlcal_get_least_maximum: invalid field in %s on line %d
+bool(false)
+
+Warning: intlcal_get_maximum(): intlcal_get_maximum: invalid field in %s on line %d
+bool(false)
+
+Warning: intlcal_get_greatest_minimum(): intlcal_get_greatest_minimum: invalid field in %s on line %d
+bool(false)
+
+Warning: intlcal_get_minimum(): intlcal_get_minimum: invalid field in %s on line %d
+bool(false)
+error: 4096, Argument 1 passed to intlcal_get_least_maximum() must be an instance of IntlCalendar, integer given
+error: 2, intlcal_get_least_maximum() expects parameter 1 to be IntlCalendar, integer given
+error: 2, intlcal_get_least_maximum(): intlcal_get_least_maximum: bad arguments
+bool(false)
+error: 4096, Argument 1 passed to intlcal_get_maximum() must be an instance of IntlCalendar, integer given
+error: 2, intlcal_get_maximum() expects parameter 1 to be IntlCalendar, integer given
+error: 2, intlcal_get_maximum(): intlcal_get_maximum: bad arguments
+bool(false)
+error: 4096, Argument 1 passed to intlcal_get_greatest_minimum() must be an instance of IntlCalendar, integer given
+error: 2, intlcal_get_greatest_minimum() expects parameter 1 to be IntlCalendar, integer given
+error: 2, intlcal_get_greatest_minimum(): intlcal_get_greatest_minimum: bad arguments
+bool(false)
+error: 4096, Argument 1 passed to intlcal_get_minimum() must be an instance of IntlCalendar, integer given
+error: 2, intlcal_get_minimum() expects parameter 1 to be IntlCalendar, integer given
+error: 2, intlcal_get_minimum(): intlcal_get_minimum: bad arguments
+bool(false)
diff --git a/ext/intl/tests/calendar_get_basic.phpt b/ext/intl/tests/calendar_get_basic.phpt
new file mode 100644
index 0000000000..c617639610
--- /dev/null
+++ b/ext/intl/tests/calendar_get_basic.phpt
@@ -0,0 +1,23 @@
+--TEST--
+IntlCalendar::get() basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$intlcal = IntlCalendar::createInstance('UTC');
+$intlcal->set(IntlCalendar::FIELD_DAY_OF_MONTH, 4);
+
+var_dump($intlcal->get(IntlCalendar::FIELD_DAY_OF_MONTH));
+var_dump(intlcal_get($intlcal, IntlCalendar::FIELD_DAY_OF_MONTH));
+
+?>
+==DONE==
+--EXPECT--
+int(4)
+int(4)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_get_getActualMaximum_Minumum_error.phpt b/ext/intl/tests/calendar_get_getActualMaximum_Minumum_error.phpt
new file mode 100644
index 0000000000..f6ccb128ee
--- /dev/null
+++ b/ext/intl/tests/calendar_get_getActualMaximum_Minumum_error.phpt
@@ -0,0 +1,84 @@
+--TEST--
+IntlCalendar::get/getActualMaximum/getActualMinimum(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+var_dump($c->get());
+var_dump($c->getActualMaximum());
+var_dump($c->getActualMinimum());
+
+var_dump($c->get(-1));
+var_dump($c->getActualMaximum(-1));
+var_dump($c->getActualMinimum(-1));
+
+var_dump($c->get("s"));
+var_dump($c->getActualMaximum("s"));
+var_dump($c->getActualMinimum("s"));
+
+var_dump($c->get(1, 2));
+var_dump($c->getActualMaximum(1, 2));
+var_dump($c->getActualMinimum(1, 2));
+--EXPECTF--
+
+Warning: IntlCalendar::get() expects exactly 1 parameter, 0 given in %s on line %d
+
+Warning: IntlCalendar::get(): intlcal_get: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::getActualMaximum() expects exactly 1 parameter, 0 given in %s on line %d
+
+Warning: IntlCalendar::getActualMaximum(): intlcal_get_actual_maximum: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::getActualMinimum() expects exactly 1 parameter, 0 given in %s on line %d
+
+Warning: IntlCalendar::getActualMinimum(): intlcal_get_actual_minimum: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::get(): intlcal_get: invalid field in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::getActualMaximum(): intlcal_get_actual_maximum: invalid field in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::getActualMinimum(): intlcal_get_actual_minimum: invalid field in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::get() expects parameter 1 to be long, string given in %s on line %d
+
+Warning: IntlCalendar::get(): intlcal_get: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::getActualMaximum() expects parameter 1 to be long, string given in %s on line %d
+
+Warning: IntlCalendar::getActualMaximum(): intlcal_get_actual_maximum: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::getActualMinimum() expects parameter 1 to be long, string given in %s on line %d
+
+Warning: IntlCalendar::getActualMinimum(): intlcal_get_actual_minimum: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::get() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: IntlCalendar::get(): intlcal_get: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::getActualMaximum() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: IntlCalendar::getActualMaximum(): intlcal_get_actual_maximum: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::getActualMinimum() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: IntlCalendar::getActualMinimum(): intlcal_get_actual_minimum: bad arguments in %s on line %d
+bool(false)
diff --git a/ext/intl/tests/calendar_get_getActualMaximum_Minumum_error2.phpt b/ext/intl/tests/calendar_get_getActualMaximum_Minumum_error2.phpt
new file mode 100644
index 0000000000..a8d1a4aa2f
--- /dev/null
+++ b/ext/intl/tests/calendar_get_getActualMaximum_Minumum_error2.phpt
@@ -0,0 +1,71 @@
+--TEST--
+IntlCalendar::get/getActualMaximum/getActualMinimum(): bad arguments (procedural)
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+function eh($errno, $errstr) {
+echo "error: $errno, $errstr\n";
+}
+set_error_handler('eh');
+
+var_dump(intlcal_get($c));
+var_dump(intlcal_get_actual_maximum($c));
+var_dump(intlcal_get_actual_minimum($c));
+
+var_dump(intlcal_get($c, -1));
+var_dump(intlcal_get_actual_maximum($c, -1));
+var_dump(intlcal_get_actual_minimum($c, -1));
+
+var_dump(intlcal_get($c, "s"));
+var_dump(intlcal_get_actual_maximum($c, "s"));
+var_dump(intlcal_get_actual_minimum($c, "s"));
+
+var_dump(intlcal_get(1));
+var_dump(intlcal_get_actual_maximum(1));
+var_dump(intlcal_get_actual_minimum(1));
+--EXPECT--
+error: 2, intlcal_get() expects exactly 2 parameters, 1 given
+error: 2, intlcal_get(): intlcal_get: bad arguments
+bool(false)
+error: 2, intlcal_get_actual_maximum() expects exactly 2 parameters, 1 given
+error: 2, intlcal_get_actual_maximum(): intlcal_get_actual_maximum: bad arguments
+bool(false)
+error: 2, intlcal_get_actual_minimum() expects exactly 2 parameters, 1 given
+error: 2, intlcal_get_actual_minimum(): intlcal_get_actual_minimum: bad arguments
+bool(false)
+error: 2, intlcal_get(): intlcal_get: invalid field
+bool(false)
+error: 2, intlcal_get_actual_maximum(): intlcal_get_actual_maximum: invalid field
+bool(false)
+error: 2, intlcal_get_actual_minimum(): intlcal_get_actual_minimum: invalid field
+bool(false)
+error: 2, intlcal_get() expects parameter 2 to be long, string given
+error: 2, intlcal_get(): intlcal_get: bad arguments
+bool(false)
+error: 2, intlcal_get_actual_maximum() expects parameter 2 to be long, string given
+error: 2, intlcal_get_actual_maximum(): intlcal_get_actual_maximum: bad arguments
+bool(false)
+error: 2, intlcal_get_actual_minimum() expects parameter 2 to be long, string given
+error: 2, intlcal_get_actual_minimum(): intlcal_get_actual_minimum: bad arguments
+bool(false)
+error: 4096, Argument 1 passed to intlcal_get() must be an instance of IntlCalendar, integer given
+error: 2, intlcal_get() expects exactly 2 parameters, 1 given
+error: 2, intlcal_get(): intlcal_get: bad arguments
+bool(false)
+error: 4096, Argument 1 passed to intlcal_get_actual_maximum() must be an instance of IntlCalendar, integer given
+error: 2, intlcal_get_actual_maximum() expects exactly 2 parameters, 1 given
+error: 2, intlcal_get_actual_maximum(): intlcal_get_actual_maximum: bad arguments
+bool(false)
+error: 4096, Argument 1 passed to intlcal_get_actual_minimum() must be an instance of IntlCalendar, integer given
+error: 2, intlcal_get_actual_minimum() expects exactly 2 parameters, 1 given
+error: 2, intlcal_get_actual_minimum(): intlcal_get_actual_minimum: bad arguments
+bool(false)
diff --git a/ext/intl/tests/calendar_get_setRepeatedWallTimeOption_basic.phpt b/ext/intl/tests/calendar_get_setRepeatedWallTimeOption_basic.phpt
new file mode 100644
index 0000000000..52765433fe
--- /dev/null
+++ b/ext/intl/tests/calendar_get_setRepeatedWallTimeOption_basic.phpt
@@ -0,0 +1,49 @@
+--TEST--
+IntlCalendar::get/setRepeatedWallTimeOption(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '49') < 0)
+ die('skip for ICU 49+');
+--FILE--
+
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+date_default_timezone_set('Europe/Amsterdam');
+
+//28 October 2012, transition from DST
+$intlcal = new IntlGregorianCalendar(2012, 9, 28, 0, 0, 0);
+var_dump($intlcal->setRepeatedWallTimeOption(IntlCalendar::WALLTIME_LAST));
+var_dump($intlcal->getRepeatedWallTimeOption());
+$intlcal->set(IntlCalendar::FIELD_HOUR_OF_DAY, 2);
+$intlcal->set(IntlCalendar::FIELD_MINUTE, 30);
+var_dump(
+ strtotime('2012-10-28 02:30:00 +0100'),
+ (int)($intlcal->getTime() /1000)
+);
+
+var_dump(intlcal_set_repeated_wall_time_option($intlcal, IntlCalendar::WALLTIME_FIRST));
+var_dump(intlcal_get_repeated_wall_time_option($intlcal));
+$intlcal->set(IntlCalendar::FIELD_HOUR_OF_DAY, 2);
+$intlcal->set(IntlCalendar::FIELD_MINUTE, 30);
+var_dump(
+ strtotime('2012-10-28 02:30:00 +0200'),
+ (int)($intlcal->getTime() /1000)
+);
+
+?>
+==DONE==
+--EXPECT--
+
+bool(true)
+int(0)
+int(1351387800)
+int(1351387800)
+bool(true)
+int(1)
+int(1351384200)
+int(1351384200)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_get_setSkippedWallTimeOption_basic.phpt b/ext/intl/tests/calendar_get_setSkippedWallTimeOption_basic.phpt
new file mode 100644
index 0000000000..bbbf031c88
--- /dev/null
+++ b/ext/intl/tests/calendar_get_setSkippedWallTimeOption_basic.phpt
@@ -0,0 +1,67 @@
+--TEST--
+IntlCalendar::get/setSkippedWallTimeOption(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '49') < 0)
+ die('skip for ICU 49+');
+--FILE--
+
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+date_default_timezone_set('Europe/Amsterdam');
+
+//25 March 2012, transition to DST
+$intlcal = new IntlGregorianCalendar(2012, 2, 25, 0, 0, 0);
+var_dump($intlcal->getSkippedWallTimeOption());
+$intlcal->set(IntlCalendar::FIELD_HOUR_OF_DAY, 2);
+$intlcal->set(IntlCalendar::FIELD_MINUTE, 30);
+echo "Should be 3h30\n";
+var_dump(
+ $intlcal->get(IntlCalendar::FIELD_HOUR_OF_DAY),
+ $intlcal->get(IntlCalendar::FIELD_MINUTE)
+);
+
+var_dump($intlcal->setSkippedWallTimeOption(IntlCalendar::WALLTIME_FIRST));
+var_dump(intlcal_get_skipped_wall_time_option($intlcal));
+$intlcal->set(IntlCalendar::FIELD_HOUR_OF_DAY, 2);
+$intlcal->set(IntlCalendar::FIELD_MINUTE, 30);
+echo "Should be 1h30\n";
+var_dump(
+ $intlcal->get(IntlCalendar::FIELD_HOUR_OF_DAY),
+ $intlcal->get(IntlCalendar::FIELD_MINUTE)
+);
+
+var_dump(intlcal_set_skipped_wall_time_option($intlcal, IntlCalendar::WALLTIME_NEXT_VALID));
+var_dump($intlcal->getSkippedWallTimeOption());
+$intlcal->set(IntlCalendar::FIELD_HOUR_OF_DAY, 2);
+$intlcal->set(IntlCalendar::FIELD_MINUTE, 30);
+echo "Should be 3h00\n";
+var_dump(
+ $intlcal->get(IntlCalendar::FIELD_HOUR_OF_DAY),
+ $intlcal->get(IntlCalendar::FIELD_MINUTE)
+);
+
+
+?>
+==DONE==
+--EXPECT--
+
+int(0)
+Should be 3h30
+int(3)
+int(30)
+bool(true)
+int(1)
+Should be 1h30
+int(1)
+int(30)
+bool(true)
+int(2)
+Should be 3h00
+int(3)
+int(0)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_inDaylightTime_basic.phpt b/ext/intl/tests/calendar_inDaylightTime_basic.phpt
new file mode 100644
index 0000000000..dff8ef50d3
--- /dev/null
+++ b/ext/intl/tests/calendar_inDaylightTime_basic.phpt
@@ -0,0 +1,24 @@
+--TEST--
+IntlCalendar::inDaylightTime() basic test
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$intlcal = IntlCalendar::createInstance('Europe/Amsterdam');
+$intlcal->setTime(strtotime('2012-01-01') * 1000);
+var_dump($intlcal->inDaylightTime());
+$intlcal->setTime(strtotime('2012-04-01') * 1000);
+var_dump(intlcal_in_daylight_time($intlcal));
+?>
+==DONE==
+--EXPECT--
+bool(false)
+bool(true)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_inDaylightTime_error.phpt b/ext/intl/tests/calendar_inDaylightTime_error.phpt
new file mode 100644
index 0000000000..9af9aa5048
--- /dev/null
+++ b/ext/intl/tests/calendar_inDaylightTime_error.phpt
@@ -0,0 +1,32 @@
+--TEST--
+IntlCalendar::inDaylightTime(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+var_dump($c->inDaylightTime(1));
+
+var_dump(intlcal_in_daylight_time($c, 1));
+var_dump(intlcal_in_daylight_time(1));
+
+--EXPECTF--
+
+Warning: IntlCalendar::inDaylightTime() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlCalendar::inDaylightTime(): intlcal_in_daylight_time: bad arguments in %s on line %d
+bool(false)
+
+Warning: intlcal_in_daylight_time() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: intlcal_in_daylight_time(): intlcal_in_daylight_time: bad arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intlcal_in_daylight_time() must be an instance of IntlCalendar, integer given in %s on line %d
diff --git a/ext/intl/tests/calendar_isEquivalentTo_basic.phpt b/ext/intl/tests/calendar_isEquivalentTo_basic.phpt
new file mode 100644
index 0000000000..f71fd8ad5b
--- /dev/null
+++ b/ext/intl/tests/calendar_isEquivalentTo_basic.phpt
@@ -0,0 +1,40 @@
+--TEST--
+IntlCalendar::isEquivalentTo() basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$intlcal1 = IntlCalendar::createInstance('Europe/Amsterdam');
+$intlcal2 = IntlCalendar::createInstance('Europe/Lisbon');
+$intlcal3 = IntlCalendar::createInstance('Europe/Amsterdam', "nl_NL@calendar=islamic");
+$intlcal4 = IntlCalendar::createInstance('Europe/Amsterdam');
+$intlcal4->roll(IntlCalendar::FIELD_MONTH, true);
+
+var_dump(
+ "1 - 1",
+ $intlcal1->isEquivalentTo($intlcal1),
+ "1 - 2",
+ $intlcal1->isEquivalentTo($intlcal2),
+ "1 - 3",
+ $intlcal1->isEquivalentTo($intlcal3),
+ "1 - 4",
+ $intlcal1->isEquivalentTo($intlcal4)
+);
+
+?>
+==DONE==
+--EXPECT--
+string(5) "1 - 1"
+bool(true)
+string(5) "1 - 2"
+bool(false)
+string(5) "1 - 3"
+bool(false)
+string(5) "1 - 4"
+bool(true)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_isEquivalentTo_error.phpt b/ext/intl/tests/calendar_isEquivalentTo_error.phpt
new file mode 100644
index 0000000000..4fa7da5eb6
--- /dev/null
+++ b/ext/intl/tests/calendar_isEquivalentTo_error.phpt
@@ -0,0 +1,50 @@
+--TEST--
+IntlCalendar::isEquivalentTo(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+function eh($errno, $errstr) {
+echo "error: $errno, $errstr\n";
+}
+set_error_handler('eh');
+
+var_dump($c->isEquivalentTo(0));
+var_dump($c->isEquivalentTo($c, 1));
+var_dump($c->isEquivalentTo(1));
+
+var_dump(intlcal_is_equivalent_to($c));
+var_dump(intlcal_is_equivalent_to($c, 1));
+var_dump(intlcal_is_equivalent_to(1, $c));
+
+--EXPECT--
+error: 4096, Argument 1 passed to IntlCalendar::isEquivalentTo() must be an instance of IntlCalendar, integer given
+error: 2, IntlCalendar::isEquivalentTo() expects parameter 1 to be IntlCalendar, integer given
+error: 2, IntlCalendar::isEquivalentTo(): intlcal_is_equivalent_to: bad arguments
+bool(false)
+error: 2, IntlCalendar::isEquivalentTo() expects exactly 1 parameter, 2 given
+error: 2, IntlCalendar::isEquivalentTo(): intlcal_is_equivalent_to: bad arguments
+bool(false)
+error: 4096, Argument 1 passed to IntlCalendar::isEquivalentTo() must be an instance of IntlCalendar, integer given
+error: 2, IntlCalendar::isEquivalentTo() expects parameter 1 to be IntlCalendar, integer given
+error: 2, IntlCalendar::isEquivalentTo(): intlcal_is_equivalent_to: bad arguments
+bool(false)
+error: 2, intlcal_is_equivalent_to() expects exactly 2 parameters, 1 given
+error: 2, intlcal_is_equivalent_to(): intlcal_is_equivalent_to: bad arguments
+bool(false)
+error: 4096, Argument 2 passed to intlcal_is_equivalent_to() must be an instance of IntlCalendar, integer given
+error: 2, intlcal_is_equivalent_to() expects parameter 2 to be IntlCalendar, integer given
+error: 2, intlcal_is_equivalent_to(): intlcal_is_equivalent_to: bad arguments
+bool(false)
+error: 4096, Argument 1 passed to intlcal_is_equivalent_to() must be an instance of IntlCalendar, integer given
+error: 2, intlcal_is_equivalent_to() expects parameter 1 to be IntlCalendar, integer given
+error: 2, intlcal_is_equivalent_to(): intlcal_is_equivalent_to: bad arguments
+bool(false)
diff --git a/ext/intl/tests/calendar_isLenient_error.phpt b/ext/intl/tests/calendar_isLenient_error.phpt
new file mode 100644
index 0000000000..7ddde1ae02
--- /dev/null
+++ b/ext/intl/tests/calendar_isLenient_error.phpt
@@ -0,0 +1,32 @@
+--TEST--
+IntlCalendar::isLenient(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+var_dump($c->isLenient(1));
+
+var_dump(intlcal_is_lenient($c, 1));
+var_dump(intlcal_is_lenient(1));
+
+--EXPECTF--
+
+Warning: IntlCalendar::isLenient() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlCalendar::isLenient(): intlcal_is_lenient: bad arguments in %s on line %d
+bool(false)
+
+Warning: intlcal_is_lenient() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: intlcal_is_lenient(): intlcal_is_lenient: bad arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intlcal_is_lenient() must be an instance of IntlCalendar, integer given in %s on line %d
diff --git a/ext/intl/tests/calendar_isSet_basic.phpt b/ext/intl/tests/calendar_isSet_basic.phpt
new file mode 100644
index 0000000000..8ef01448d5
--- /dev/null
+++ b/ext/intl/tests/calendar_isSet_basic.phpt
@@ -0,0 +1,24 @@
+--TEST--
+IntlCalendar::isSet() basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$intlcal = IntlCalendar::createInstance('UTC');
+var_dump($intlcal->isSet(IntlCalendar::FIELD_MINUTE));
+$intlcal->clear(IntlCalendar::FIELD_MINUTE);
+var_dump($intlcal->isSet(IntlCalendar::FIELD_MINUTE));
+$intlcal->set(IntlCalendar::FIELD_MINUTE, 0);
+var_dump(intlcal_is_set($intlcal, IntlCalendar::FIELD_MINUTE));
+?>
+==DONE==
+--EXPECT--
+bool(true)
+bool(false)
+bool(true)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_isSet_error.phpt b/ext/intl/tests/calendar_isSet_error.phpt
new file mode 100644
index 0000000000..f238d776b2
--- /dev/null
+++ b/ext/intl/tests/calendar_isSet_error.phpt
@@ -0,0 +1,42 @@
+--TEST--
+IntlCalendar::isSet(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+var_dump($c->isSet());
+var_dump($c->isSet(1, 2));
+var_dump($c->isSet(-1));
+
+var_dump(intlcal_is_set($c));
+var_dump(intlcal_is_set(1, 2));
+
+--EXPECTF--
+
+Warning: IntlCalendar::isSet() expects exactly 1 parameter, 0 given in %s on line %d
+
+Warning: IntlCalendar::isSet(): intlcal_is_set: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::isSet() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: IntlCalendar::isSet(): intlcal_is_set: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::isSet(): intlcal_is_set: invalid field in %s on line %d
+bool(false)
+
+Warning: intlcal_is_set() expects exactly 2 parameters, 1 given in %s on line %d
+
+Warning: intlcal_is_set(): intlcal_is_set: bad arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intlcal_is_set() must be an instance of IntlCalendar, integer given in %s on line %d
diff --git a/ext/intl/tests/calendar_isWeekend_basic.phpt b/ext/intl/tests/calendar_isWeekend_basic.phpt
new file mode 100644
index 0000000000..d6452c71f7
--- /dev/null
+++ b/ext/intl/tests/calendar_isWeekend_basic.phpt
@@ -0,0 +1,26 @@
+--TEST--
+IntlCalendar::isWeekend basic test
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '4.4') < 0)
+ die('skip for ICU 4.4+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$intlcal = IntlCalendar::createInstance('UTC');
+var_dump($intlcal->isWeekend(strtotime('2012-02-29 12:00:00 +0000') * 1000));
+var_dump(intlcal_is_weekend($intlcal, strtotime('2012-02-29 12:00:00 +0000') * 1000));
+var_dump($intlcal->isWeekend(strtotime('2012-03-11 12:00:00 +0000') * 1000));
+?>
+==DONE==
+--EXPECT--
+bool(false)
+bool(false)
+bool(true)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_isWeekend_error.phpt b/ext/intl/tests/calendar_isWeekend_error.phpt
new file mode 100644
index 0000000000..7939a66a14
--- /dev/null
+++ b/ext/intl/tests/calendar_isWeekend_error.phpt
@@ -0,0 +1,38 @@
+--TEST--
+IntlCalendar::isWeekend(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '4.4') < 0)
+ die('skip for ICU 4.4+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+var_dump($c->isWeekend(1, 2));
+var_dump($c->isWeekend("jhhk"));
+
+var_dump(intlcal_is_weekend($c, "jj"));
+var_dump(intlcal_is_weekend(1));
+
+--EXPECTF--
+
+Warning: IntlCalendar::isWeekend(): intlcal_is_weekend: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::isWeekend() expects parameter 1 to be double, string given in %s on line %d
+
+Warning: IntlCalendar::isWeekend(): intlcal_is_weekend: bad arguments in %s on line %d
+bool(false)
+
+Warning: intlcal_is_weekend() expects parameter 2 to be double, string given in %s on line %d
+
+Warning: intlcal_is_weekend(): intlcal_is_weekend: bad arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intlcal_is_weekend() must be an instance of IntlCalendar, integer given in %s on line %d
diff --git a/ext/intl/tests/calendar_is_set_lenient_basic.phpt b/ext/intl/tests/calendar_is_set_lenient_basic.phpt
new file mode 100644
index 0000000000..64f537f9bc
--- /dev/null
+++ b/ext/intl/tests/calendar_is_set_lenient_basic.phpt
@@ -0,0 +1,28 @@
+--TEST--
+IntlCalendar::isLenient(), ::setLenient() basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$intlcal1 = IntlCalendar::createInstance('UTC');
+var_dump($intlcal1->isLenient());
+var_dump(intlcal_is_lenient($intlcal1));
+var_dump($intlcal1->setLenient(false));
+var_dump($intlcal1->isLenient());
+var_dump(intlcal_set_lenient($intlcal1, true));
+var_dump($intlcal1->isLenient());
+?>
+==DONE==
+--EXPECT--
+bool(true)
+bool(true)
+bool(true)
+bool(false)
+bool(true)
+bool(true)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_roll_basic.phpt b/ext/intl/tests/calendar_roll_basic.phpt
new file mode 100644
index 0000000000..971c36217b
--- /dev/null
+++ b/ext/intl/tests/calendar_roll_basic.phpt
@@ -0,0 +1,34 @@
+--TEST--
+IntlCalendar::roll() basic test
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$intlcal = new IntlGregorianCalendar(2012, 1, 28);
+var_dump($intlcal->roll(IntlCalendar::FIELD_DAY_OF_MONTH, 2));
+var_dump($intlcal->get(IntlCalendar::FIELD_MONTH)); //1 (Feb)
+var_dump($intlcal->get(IntlCalendar::FIELD_DAY_OF_MONTH)); //1
+
+$intlcal = new IntlGregorianCalendar(2012, 1, 28);
+var_dump(intlcal_roll($intlcal, IntlCalendar::FIELD_DAY_OF_MONTH, 2));
+var_dump($intlcal->get(IntlCalendar::FIELD_MONTH)); //1 (Feb)
+var_dump($intlcal->get(IntlCalendar::FIELD_DAY_OF_MONTH)); //1
+
+
+?>
+==DONE==
+--EXPECT--
+bool(true)
+int(1)
+int(1)
+bool(true)
+int(1)
+int(1)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_roll_error.phpt b/ext/intl/tests/calendar_roll_error.phpt
new file mode 100644
index 0000000000..a567394699
--- /dev/null
+++ b/ext/intl/tests/calendar_roll_error.phpt
@@ -0,0 +1,37 @@
+--TEST--
+IntlCalendar::roll(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+var_dump($c->roll(1, 2, 3));
+var_dump($c->roll(-1, 2));
+var_dump($c->roll(1));
+
+var_dump(intlcal_roll($c, 1, 2, 3));
+var_dump(intlcal_roll(1, 2, 3));
+--EXPECTF--
+
+Warning: IntlCalendar::roll(): intlcal_set: too many arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::roll(): intlcal_roll: invalid field in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::roll() expects exactly 2 parameters, 1 given in %s on line %d
+
+Warning: IntlCalendar::roll(): intlcal_roll: bad arguments in %s on line %d
+bool(false)
+
+Warning: intlcal_roll(): intlcal_set: too many arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intlcal_roll() must be an instance of IntlCalendar, integer given in %s on line %d
diff --git a/ext/intl/tests/calendar_roll_variation1.phpt b/ext/intl/tests/calendar_roll_variation1.phpt
new file mode 100644
index 0000000000..9fb8d75e5a
--- /dev/null
+++ b/ext/intl/tests/calendar_roll_variation1.phpt
@@ -0,0 +1,32 @@
+--TEST--
+IntlCalendar::roll() bool argument variation
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$intlcal = new IntlGregorianCalendar(2012, 1, 28);
+var_dump($intlcal->roll(IntlCalendar::FIELD_DAY_OF_MONTH, true));
+var_dump($intlcal->get(IntlCalendar::FIELD_MONTH)); //1 (Feb)
+var_dump($intlcal->get(IntlCalendar::FIELD_DAY_OF_MONTH)); //29
+
+var_dump(intlcal_roll($intlcal, IntlCalendar::FIELD_DAY_OF_MONTH, false));
+var_dump($intlcal->get(IntlCalendar::FIELD_MONTH)); //1 (Feb)
+var_dump($intlcal->get(IntlCalendar::FIELD_DAY_OF_MONTH)); //28
+
+?>
+==DONE==
+--EXPECT--
+bool(true)
+int(1)
+int(29)
+bool(true)
+int(1)
+int(28)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_setFirstDayOfWeek_basic.phpt b/ext/intl/tests/calendar_setFirstDayOfWeek_basic.phpt
new file mode 100644
index 0000000000..79b38104e4
--- /dev/null
+++ b/ext/intl/tests/calendar_setFirstDayOfWeek_basic.phpt
@@ -0,0 +1,28 @@
+--TEST--
+IntlCalendar::setFirstDayOfWeek() basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$intlcal = IntlCalendar::createInstance('UTC');
+var_dump(
+ IntlCalendar::DOW_TUESDAY,
+ $intlcal->setFirstDayOfWeek(IntlCalendar::DOW_TUESDAY),
+ $intlcal->getFirstDayOfWeek(),
+ intlcal_set_first_day_of_week($intlcal, IntlCalendar::DOW_WEDNESDAY),
+ $intlcal->getFirstDayOfWeek()
+);
+?>
+==DONE==
+--EXPECT--
+int(3)
+bool(true)
+int(3)
+bool(true)
+int(4)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_setFirstDayOfWeek_error.phpt b/ext/intl/tests/calendar_setFirstDayOfWeek_error.phpt
new file mode 100644
index 0000000000..98237e56fa
--- /dev/null
+++ b/ext/intl/tests/calendar_setFirstDayOfWeek_error.phpt
@@ -0,0 +1,40 @@
+--TEST--
+IntlCalendar::setFirstDayOfWeek(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+var_dump($c->setFirstDayOfWeek());
+var_dump($c->setFirstDayOfWeek(1, 2));
+var_dump($c->setFirstDayOfWeek(0));
+
+var_dump(intlcal_set_first_day_of_week($c, 0));
+var_dump(intlcal_set_first_day_of_week(1, 2));
+
+--EXPECTF--
+
+Warning: IntlCalendar::setFirstDayOfWeek() expects exactly 1 parameter, 0 given in %s on line %d
+
+Warning: IntlCalendar::setFirstDayOfWeek(): intlcal_set_first_day_of_week: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::setFirstDayOfWeek() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: IntlCalendar::setFirstDayOfWeek(): intlcal_set_first_day_of_week: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::setFirstDayOfWeek(): intlcal_set_first_day_of_week: invalid day of week in %s on line %d
+bool(false)
+
+Warning: intlcal_set_first_day_of_week(): intlcal_set_first_day_of_week: invalid day of week in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intlcal_set_first_day_of_week() must be an instance of IntlCalendar, integer given in %s on line %d
diff --git a/ext/intl/tests/calendar_setLenient_error.phpt b/ext/intl/tests/calendar_setLenient_error.phpt
new file mode 100644
index 0000000000..2b1d7b016d
--- /dev/null
+++ b/ext/intl/tests/calendar_setLenient_error.phpt
@@ -0,0 +1,44 @@
+--TEST--
+IntlCalendar::setLenient(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+var_dump($c->setLenient());
+var_dump($c->setLenient(array()));
+var_dump($c->setLenient(1, 2));
+
+var_dump(intlcal_set_lenient($c, array()));
+var_dump(intlcal_set_lenient(1, false));
+
+--EXPECTF--
+
+Warning: IntlCalendar::setLenient() expects exactly 1 parameter, 0 given in %s on line %d
+
+Warning: IntlCalendar::setLenient(): intlcal_set_lenient: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::setLenient() expects parameter 1 to be boolean, array given in %s on line %d
+
+Warning: IntlCalendar::setLenient(): intlcal_set_lenient: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::setLenient() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: IntlCalendar::setLenient(): intlcal_set_lenient: bad arguments in %s on line %d
+bool(false)
+
+Warning: intlcal_set_lenient() expects parameter 2 to be boolean, array given in %s on line %d
+
+Warning: intlcal_set_lenient(): intlcal_set_lenient: bad arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intlcal_set_lenient() must be an instance of IntlCalendar, integer given in %s on line %d
diff --git a/ext/intl/tests/calendar_setMinimalDaysInFirstWeek_basic.phpt b/ext/intl/tests/calendar_setMinimalDaysInFirstWeek_basic.phpt
new file mode 100644
index 0000000000..998e74bc01
--- /dev/null
+++ b/ext/intl/tests/calendar_setMinimalDaysInFirstWeek_basic.phpt
@@ -0,0 +1,26 @@
+--TEST--
+IntlCalendar::setMinimalDaysInFirstWeek() basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$intlcal = IntlCalendar::createInstance('UTC');
+var_dump(
+ $intlcal->setMinimalDaysInFirstWeek(6),
+ $intlcal->getMinimalDaysInFirstWeek(),
+ intlcal_set_minimal_days_in_first_week($intlcal, 5),
+ $intlcal->getMinimalDaysInFirstWeek()
+);
+?>
+==DONE==
+--EXPECT--
+bool(true)
+int(6)
+bool(true)
+int(5)
+==DONE==
diff --git a/ext/intl/tests/calendar_setMinimalDaysInFirstWeek_error.phpt b/ext/intl/tests/calendar_setMinimalDaysInFirstWeek_error.phpt
new file mode 100644
index 0000000000..c133558ddc
--- /dev/null
+++ b/ext/intl/tests/calendar_setMinimalDaysInFirstWeek_error.phpt
@@ -0,0 +1,40 @@
+--TEST--
+IntlCalendar::setMinimalDaysInFirstWeek(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+var_dump($c->setMinimalDaysInFirstWeek());
+var_dump($c->setMinimalDaysInFirstWeek(1, 2));
+var_dump($c->setMinimalDaysInFirstWeek(0));
+
+var_dump(intlcal_set_minimal_days_in_first_week($c, 0));
+var_dump(intlcal_set_minimal_days_in_first_week(1, 2));
+
+--EXPECTF--
+Warning: IntlCalendar::setMinimalDaysInFirstWeek() expects exactly 1 parameter, 0 given in %s on line %d
+
+Warning: IntlCalendar::setMinimalDaysInFirstWeek(): intlcal_set_minimal_days_in_first_week: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::setMinimalDaysInFirstWeek() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: IntlCalendar::setMinimalDaysInFirstWeek(): intlcal_set_minimal_days_in_first_week: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::setMinimalDaysInFirstWeek(): intlcal_set_minimal_days_in_first_week: invalid number of days; must be between 1 and 7 in %s on line %d
+bool(false)
+
+Warning: intlcal_set_minimal_days_in_first_week(): intlcal_set_minimal_days_in_first_week: invalid number of days; must be between 1 and 7 in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intlcal_set_minimal_days_in_first_week() must be an instance of IntlCalendar, integer given in %s on line %d
+
diff --git a/ext/intl/tests/calendar_setSkipped_RepeatedWallTimeOption_error.phpt b/ext/intl/tests/calendar_setSkipped_RepeatedWallTimeOption_error.phpt
new file mode 100644
index 0000000000..dab55d2b29
--- /dev/null
+++ b/ext/intl/tests/calendar_setSkipped_RepeatedWallTimeOption_error.phpt
@@ -0,0 +1,82 @@
+--TEST--
+IntlCalendar::setSkipped/RepeatedWallTimeOption(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '49') < 0)
+ die('skip for ICU 49+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+var_dump($c->setSkippedWallTimeOption());
+var_dump($c->setRepeatedWallTimeOption());
+
+var_dump($c->setSkippedWallTimeOption(1, 2));
+var_dump($c->setRepeatedWallTimeOption(1, 2));
+
+var_dump($c->setSkippedWallTimeOption(array()));
+var_dump($c->setRepeatedWallTimeOption(array()));
+
+var_dump($c->setSkippedWallTimeOption(3));
+var_dump($c->setRepeatedWallTimeOption(2));
+
+var_dump(intlcal_set_skipped_wall_time_option($c));
+var_dump(intlcal_set_repeated_wall_time_option($c));
+
+var_dump(intlcal_set_repeated_wall_time_option(1, 1));
+
+--EXPECTF--
+
+Warning: IntlCalendar::setSkippedWallTimeOption() expects exactly 1 parameter, 0 given in %s on line %d
+
+Warning: IntlCalendar::setSkippedWallTimeOption(): intlcal_set_skipped_wall_time_option: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::setRepeatedWallTimeOption() expects exactly 1 parameter, 0 given in %s on line %d
+
+Warning: IntlCalendar::setRepeatedWallTimeOption(): intlcal_set_repeated_wall_time_option: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::setSkippedWallTimeOption() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: IntlCalendar::setSkippedWallTimeOption(): intlcal_set_skipped_wall_time_option: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::setRepeatedWallTimeOption() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: IntlCalendar::setRepeatedWallTimeOption(): intlcal_set_repeated_wall_time_option: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::setSkippedWallTimeOption() expects parameter 1 to be long, array given in %s on line %d
+
+Warning: IntlCalendar::setSkippedWallTimeOption(): intlcal_set_skipped_wall_time_option: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::setRepeatedWallTimeOption() expects parameter 1 to be long, array given in %s on line %d
+
+Warning: IntlCalendar::setRepeatedWallTimeOption(): intlcal_set_repeated_wall_time_option: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::setSkippedWallTimeOption(): intlcal_set_skipped_wall_time_option: invalid option in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::setRepeatedWallTimeOption(): intlcal_set_repeated_wall_time_option: invalid option in %s on line %d
+bool(false)
+
+Warning: intlcal_set_skipped_wall_time_option() expects exactly 2 parameters, 1 given in %s on line %d
+
+Warning: intlcal_set_skipped_wall_time_option(): intlcal_set_skipped_wall_time_option: bad arguments in %s on line %d
+bool(false)
+
+Warning: intlcal_set_repeated_wall_time_option() expects exactly 2 parameters, 1 given in %s on line %d
+
+Warning: intlcal_set_repeated_wall_time_option(): intlcal_set_repeated_wall_time_option: bad arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intlcal_set_repeated_wall_time_option() must be an instance of IntlCalendar, integer given in %s on line %d
diff --git a/ext/intl/tests/calendar_setTimeZone_basic.phpt b/ext/intl/tests/calendar_setTimeZone_basic.phpt
new file mode 100644
index 0000000000..525840ddd6
--- /dev/null
+++ b/ext/intl/tests/calendar_setTimeZone_basic.phpt
@@ -0,0 +1,39 @@
+--TEST--
+IntlCalendar::setTimeZone() basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '4.8') < 0)
+ die('skip for ICU 4.8+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$intlcal = IntlCalendar::createInstance('Europe/Amsterdam');
+print_r($intlcal->getTimeZone()->getID());
+echo "\n";
+var_dump($intlcal->get(IntlCalendar::FIELD_ZONE_OFFSET));
+
+$intlcal->setTimeZone(IntlTimeZone::getGMT());
+print_r($intlcal->getTimeZone()->getID());
+echo "\n";
+var_dump($intlcal->get(IntlCalendar::FIELD_ZONE_OFFSET));
+
+intlcal_set_time_zone($intlcal,
+ IntlTimeZone::createTimeZone('GMT+05:30'));
+print_r($intlcal->getTimeZone()->getID());
+echo "\n";
+var_dump($intlcal->get(IntlCalendar::FIELD_ZONE_OFFSET));
+
+?>
+==DONE==
+--EXPECT--
+Europe/Amsterdam
+int(3600000)
+GMT
+int(0)
+GMT+05:30
+int(19800000)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_setTimeZone_error.phpt b/ext/intl/tests/calendar_setTimeZone_error.phpt
new file mode 100644
index 0000000000..ebe4d119ea
--- /dev/null
+++ b/ext/intl/tests/calendar_setTimeZone_error.phpt
@@ -0,0 +1,41 @@
+--TEST--
+IntlCalendar::setTimeZone(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+$gmt = IntlTimeZone::getGMT();
+
+function eh($errno, $errstr) {
+echo "error: $errno, $errstr\n";
+}
+set_error_handler('eh');
+
+var_dump($c->setTimeZone($gmt, 2));
+var_dump($c->setTimeZone());
+
+var_dump(intlcal_set_time_zone($c, 1, 2));
+var_dump(intlcal_set_time_zone(1, $gmt));
+
+--EXPECT--
+error: 2, IntlCalendar::setTimeZone() expects exactly 1 parameter, 2 given
+error: 2, IntlCalendar::setTimeZone(): intlcal_set_time_zone: bad arguments
+bool(false)
+error: 2, IntlCalendar::setTimeZone() expects exactly 1 parameter, 0 given
+error: 2, IntlCalendar::setTimeZone(): intlcal_set_time_zone: bad arguments
+bool(false)
+error: 2, intlcal_set_time_zone() expects exactly 2 parameters, 3 given
+error: 2, intlcal_set_time_zone(): intlcal_set_time_zone: bad arguments
+bool(false)
+error: 4096, Argument 1 passed to intlcal_set_time_zone() must be an instance of IntlCalendar, integer given
+error: 2, intlcal_set_time_zone() expects parameter 1 to be IntlCalendar, integer given
+error: 2, intlcal_set_time_zone(): intlcal_set_time_zone: bad arguments
+bool(false)
diff --git a/ext/intl/tests/calendar_setTimeZone_error2.phpt b/ext/intl/tests/calendar_setTimeZone_error2.phpt
new file mode 100644
index 0000000000..aa1eaba209
--- /dev/null
+++ b/ext/intl/tests/calendar_setTimeZone_error2.phpt
@@ -0,0 +1,29 @@
+--TEST--
+IntlCalendar::setTimeZone(): valid time zones for DateTime but not ICU
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+date_default_timezone_set('Europe/Amsterdam');
+
+$intlcal = new IntlGregorianCalendar();
+
+$pstdate = new DateTime('2012-01-01 00:00:00 WEST');
+$intlcal->setTimeZone($pstdate->getTimeZone());
+var_dump($intlcal->getTimeZone()->getID());
+
+$pstdate = new DateTime('2012-01-01 00:00:00 +24:00');
+$intlcal->setTimeZone($pstdate->getTimeZone());
+var_dump($intlcal->getTimeZone()->getID());
+
+--EXPECTF--
+
+Warning: IntlCalendar::setTimeZone(): intlcal_set_time_zone: time zone id 'WEST' extracted from ext/date DateTimeZone not recognized in %s on line %d
+string(16) "Europe/Amsterdam"
+
+Warning: IntlCalendar::setTimeZone(): intlcal_set_time_zone: object has an time zone offset that's too large in %s on line %d
+string(16) "Europe/Amsterdam"
diff --git a/ext/intl/tests/calendar_setTimeZone_variation1.phpt b/ext/intl/tests/calendar_setTimeZone_variation1.phpt
new file mode 100644
index 0000000000..b1cbb74edf
--- /dev/null
+++ b/ext/intl/tests/calendar_setTimeZone_variation1.phpt
@@ -0,0 +1,30 @@
+--TEST--
+IntlCalendar::setTimeZone() variation with NULL arg
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$intlcal = IntlCalendar::createInstance('Europe/Amsterdam');
+print_r($intlcal->getTimeZone()->getID());
+echo "\n";
+var_dump($intlcal->get(IntlCalendar::FIELD_ZONE_OFFSET));
+
+/* passing NULL has no effect */
+$intlcal->setTimeZone(null);
+print_r($intlcal->getTimeZone()->getID());
+echo "\n";
+var_dump($intlcal->get(IntlCalendar::FIELD_ZONE_OFFSET));
+
+?>
+==DONE==
+--EXPECT--
+Europe/Amsterdam
+int(3600000)
+Europe/Amsterdam
+int(3600000)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_setTimeZone_variation2.phpt b/ext/intl/tests/calendar_setTimeZone_variation2.phpt
new file mode 100644
index 0000000000..7f4a7ffa37
--- /dev/null
+++ b/ext/intl/tests/calendar_setTimeZone_variation2.phpt
@@ -0,0 +1,30 @@
+--TEST--
+IntlCalendar::setTimeZone(): different ways to specify time zone
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+date_default_timezone_set('Europe/Amsterdam');
+
+$intlcal = new IntlGregorianCalendar();
+$intlcal->setTimeZone('Europe/Paris');
+var_dump($intlcal->getTimeZone()->getID());
+$intlcal->setTimeZone(new DateTimeZone('Europe/Madrid'));
+var_dump($intlcal->getTimeZone()->getID());
+
+$pstdate = new DateTime('2012-01-01 00:00:00 PST');
+$intlcal->setTimeZone($pstdate->getTimeZone());
+var_dump($intlcal->getTimeZone()->getID());
+
+$offsetdate = new DateTime('2012-01-01 00:00:00 -02:30');
+$intlcal->setTimeZone($offsetdate->getTimeZone());
+var_dump($intlcal->getTimeZone()->getID());
+--EXPECTF--
+string(12) "Europe/Paris"
+string(13) "Europe/Madrid"
+string(3) "PST"
+string(%d) "GMT-02%S30"
diff --git a/ext/intl/tests/calendar_setTime_basic.phpt b/ext/intl/tests/calendar_setTime_basic.phpt
new file mode 100644
index 0000000000..f7f213c0d8
--- /dev/null
+++ b/ext/intl/tests/calendar_setTime_basic.phpt
@@ -0,0 +1,33 @@
+--TEST--
+IntlCalendar::setTime() basic test
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$time = strtotime('2012-02-29 00:00:00 +0000');
+
+$intlcal = IntlCalendar::createInstance('UTC');
+$intlcal->setTime($time * 1000);
+
+var_dump(
+ (float)$time*1000,
+ $intlcal->getTime());
+
+$intlcal = IntlCalendar::createInstance('UTC');
+intlcal_set_time($intlcal,$time * 1000);
+var_dump(intlcal_get_time($intlcal));
+
+?>
+==DONE==
+--EXPECT--
+float(1330473600000)
+float(1330473600000)
+float(1330473600000)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_setTime_error.phpt b/ext/intl/tests/calendar_setTime_error.phpt
new file mode 100644
index 0000000000..71c5b0a1bd
--- /dev/null
+++ b/ext/intl/tests/calendar_setTime_error.phpt
@@ -0,0 +1,37 @@
+--TEST--
+IntlCalendar::setTime(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+var_dump($c->setTime(1, 2));
+var_dump($c->setTime("jjj"));
+
+var_dump(intlcal_set_time($c, 1, 2));
+var_dump(intlcal_set_time(1));
+--EXPECTF--
+
+Warning: IntlCalendar::setTime() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: IntlCalendar::setTime(): intlcal_set_time: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::setTime() expects parameter 1 to be double, string given in %s on line %d
+
+Warning: IntlCalendar::setTime(): intlcal_set_time: bad arguments in %s on line %d
+bool(false)
+
+Warning: intlcal_set_time() expects exactly 2 parameters, 3 given in %s on line %d
+
+Warning: intlcal_set_time(): intlcal_set_time: bad arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intlcal_set_time() must be an instance of IntlCalendar, integer given in %s on line %d
diff --git a/ext/intl/tests/calendar_set_basic.phpt b/ext/intl/tests/calendar_set_basic.phpt
new file mode 100644
index 0000000000..8eccb32da6
--- /dev/null
+++ b/ext/intl/tests/calendar_set_basic.phpt
@@ -0,0 +1,27 @@
+--TEST--
+IntlCalendar::set() basic test
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$intlcal = IntlCalendar::createInstance();
+var_dump($intlcal->set(IntlCalendar::FIELD_DAY_OF_MONTH, 2));
+var_dump($intlcal->get(IntlCalendar::FIELD_DAY_OF_MONTH));
+var_dump(intlcal_set($intlcal, IntlCalendar::FIELD_DAY_OF_MONTH, 3));
+var_dump($intlcal->get(IntlCalendar::FIELD_DAY_OF_MONTH));
+
+?>
+==DONE==
+--EXPECT--
+bool(true)
+int(2)
+bool(true)
+int(3)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_set_error.phpt b/ext/intl/tests/calendar_set_error.phpt
new file mode 100644
index 0000000000..669b1888e0
--- /dev/null
+++ b/ext/intl/tests/calendar_set_error.phpt
@@ -0,0 +1,41 @@
+--TEST--
+IntlCalendar::set(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+var_dump($c->set(1));
+var_dump($c->set(1, 2, 3, 4));
+var_dump($c->set(1, 2, 3, 4, 5, 6, 7));
+var_dump($c->set(-1, 2));
+
+var_dump(intlcal_set($c, -1, 2));
+var_dump(intlcal_set(1, 2, 3));
+--EXPECTF--
+
+Warning: IntlCalendar::set() expects at least 2 parameters, 1 given in %s on line %d
+
+Warning: IntlCalendar::set(): intlcal_set: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::set(): intlcal_set: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::set(): intlcal_set: too many arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::set(): intlcal_set: invalid field in %s on line %d
+bool(false)
+
+Warning: intlcal_set(): intlcal_set: invalid field in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intlcal_set() must be an instance of IntlCalendar, integer given in %s on line %d
diff --git a/ext/intl/tests/calendar_set_variation1.phpt b/ext/intl/tests/calendar_set_variation1.phpt
new file mode 100644
index 0000000000..8ea016ed61
--- /dev/null
+++ b/ext/intl/tests/calendar_set_variation1.phpt
@@ -0,0 +1,41 @@
+--TEST--
+IntlCalendar::set() argument variations
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$intlcal = IntlCalendar::createInstance('UTC');
+$intlcal->clear();
+var_dump($intlcal->set(2012, 1, 29));
+var_dump($intlcal->getTime(),
+ strtotime('2012-02-29 00:00:00 +0000') * 1000.);
+
+//two minutes to midnight!
+var_dump($intlcal->set(2012, 1, 29, 23, 58));
+var_dump($intlcal->getTime(),
+ strtotime('2012-02-29 23:58:00 +0000') * 1000.);
+
+var_dump($intlcal->set(2012, 1, 29, 23, 58, 31));
+var_dump($intlcal->getTime(),
+ strtotime('2012-02-29 23:58:31 +0000') * 1000.);
+
+?>
+==DONE==
+--EXPECT--
+bool(true)
+float(1330473600000)
+float(1330473600000)
+bool(true)
+float(1330559880000)
+float(1330559880000)
+bool(true)
+float(1330559911000)
+float(1330559911000)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_toDateTime_basic.phpt b/ext/intl/tests/calendar_toDateTime_basic.phpt
new file mode 100644
index 0000000000..d38487dabf
--- /dev/null
+++ b/ext/intl/tests/calendar_toDateTime_basic.phpt
@@ -0,0 +1,23 @@
+--TEST--
+IntlCalendar::toDateTime(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+//ini_set("intl.default_locale", "nl");
+ini_set('date.timezone', 'Europe/Lisbon');
+
+$cal = new IntlGregorianCalendar(2012,04,17,17,35,36);
+
+$dt = $cal->toDateTime();
+
+var_dump($dt->format("c"), $dt->getTimeZone()->getName());
+?>
+==DONE==
+--EXPECT--
+string(25) "2012-05-17T17:35:36+01:00"
+string(13) "Europe/Lisbon"
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/calendar_toDateTime_error.phpt b/ext/intl/tests/calendar_toDateTime_error.phpt
new file mode 100644
index 0000000000..961a9c86a6
--- /dev/null
+++ b/ext/intl/tests/calendar_toDateTime_error.phpt
@@ -0,0 +1,41 @@
+--TEST--
+IntlCalendar::toDateTime(): bad arguments
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set('date.timezone', 'Europe/Lisbon');
+
+$cal = new IntlGregorianCalendar();
+var_dump($cal->toDateTime(3));
+
+var_dump(intlcal_to_date_time($cal, 3));
+
+$cal = new IntlGregorianCalendar("Etc/Unknown");
+try {
+var_dump($cal->toDateTime());
+} catch (Exception $e) {
+var_dump("exception: {$e->getMessage()}");
+}
+
+var_dump(intlcal_to_date_time(3));
+
+--EXPECTF--
+
+Warning: IntlCalendar::toDateTime() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlCalendar::toDateTime(): intlcal_to_date_time: bad arguments in %s on line %d
+bool(false)
+
+Warning: intlcal_to_date_time() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: intlcal_to_date_time(): intlcal_to_date_time: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlCalendar::toDateTime(): intlcal_to_date_time: DateTimeZone constructor threw exception in %s on line %d
+string(77) "exception: DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown)"
+
+Catchable fatal error: Argument 1 passed to intlcal_to_date_time() must be an instance of IntlCalendar, integer given in %s on line %d
diff --git a/ext/intl/tests/collator_asort.phpt b/ext/intl/tests/collator_asort.phpt
index a614ddc3f8..308f3a3ca3 100644
--- a/ext/intl/tests/collator_asort.phpt
+++ b/ext/intl/tests/collator_asort.phpt
@@ -2,6 +2,7 @@
asort()
--SKIPIF--
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') >= 0) die('skip for ICU < 51.2'); ?>
--FILE--
<?php
diff --git a/ext/intl/tests/collator_asort_variant2.phpt b/ext/intl/tests/collator_asort_variant2.phpt
new file mode 100644
index 0000000000..f9dff13608
--- /dev/null
+++ b/ext/intl/tests/collator_asort_variant2.phpt
@@ -0,0 +1,243 @@
+--TEST--
+asort()
+--SKIPIF--
+<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') < 0) die('skip for ICU >= 51.2'); ?>
+--FILE--
+<?php
+
+/*
+ * Sort associative arrays using various locales.
+ */
+
+
+$test_num = 1;
+
+/*
+ * Sort various arrays in specified locale.
+ */
+function sort_arrays( $locale, $test_arrays, $sort_flag = Collator::SORT_REGULAR )
+{
+ $res_str = '';
+
+ $coll = ut_coll_create( $locale );
+
+ foreach( $test_arrays as $test_array )
+ {
+ // Try to sort test data.
+ $res_val = ut_coll_asort( $coll, $test_array, $sort_flag );
+
+ // Return output data.
+ $res_dump = "\n" . dump( $test_array ) .
+ "\n Result: " . dump( $res_val );
+
+ // Preppend test signature to output string
+ $md5 = md5( $res_dump );
+
+ global $test_num;
+
+ $res_str .= "\n\n".
+ "Test $test_num.$md5:" .
+ $res_dump;
+ ++$test_num;
+ }
+
+ return $res_str;
+}
+
+/*
+ * Test main function.
+ */
+function ut_main()
+{
+ global $test_num;
+ $test_num = 1;
+ $res_str = '';
+
+ // Sort an array in SORT_REGULAR mode using en_US locale.
+ $test_params = array(
+ array( 'd' => 'y' ,
+ 'c' => 'i' ,
+ 'a' => 'k' ),
+
+ array( 'a' => 'a' ,
+ 'b' => 'aaa',
+ 'c' => 'aa' ),
+
+ array( 'a' => 'a' ,
+ 'aaa'=> 'a' ,
+ 'aa' => 'a' ),
+
+ array( '1' => 'abc',
+ '5' => '!' ,
+ '2' => null ,
+ '7' => '' ),
+
+ array( '1' => '100',
+ '2' => '25' ,
+ '3' => '36' ),
+
+ array( '1' => 5 ,
+ '2' => '30' ,
+ '3' => 2 )
+ );
+
+ $res_str .= sort_arrays( 'en_US', $test_params );
+
+ // Sort an array in SORT_STRING mode using en_US locale.
+ $test_params = array(
+ array( '1' => '100',
+ '2' => '25' ,
+ '3' => '36' ),
+
+ array( '1' => 5 ,
+ '2' => '30' ,
+ '3' => 2 ),
+
+ array( '1' => 'd' ,
+ '2' => '' ,
+ '3' => ' a' ),
+
+ array( '1' => 'y' ,
+ '2' => 'k' ,
+ '3' => 'i' )
+ );
+
+ $res_str .= sort_arrays( 'en_US', $test_params, Collator::SORT_STRING );
+
+ // Sort a non-ASCII array using ru_RU locale.
+ $test_params = array(
+ array( 'п' => 'у',
+ 'б' => 'в',
+ 'е' => 'а' ),
+
+ array( '1' => 'п',
+ '4' => '',
+ '7' => 'd',
+ '2' => 'пп' )
+ );
+
+ $res_str .= sort_arrays( 'ru_RU', $test_params );
+
+
+ // Sort an array using Lithuanian locale.
+ $test_params = array(
+ array( 'd' => 'y',
+ 'c' => 'i',
+ 'a' => 'k' )
+ );
+
+ $res_str .= sort_arrays( 'lt_LT', $test_params );
+
+ return $res_str . "\n";
+}
+
+include_once( 'ut_common.inc' );
+ut_run();
+?>
+--EXPECT--
+Test 1.162b81ac12878b817fc39063097e45b5:
+array (
+ 'c' => 'i',
+ 'a' => 'k',
+ 'd' => 'y',
+)
+ Result: true
+
+Test 2.93d96e22f692d8a281b0a389f01f8d1e:
+array (
+ 'a' => 'a',
+ 'c' => 'aa',
+ 'b' => 'aaa',
+)
+ Result: true
+
+Test 3.9f25de4482bc7b58de508e278113317c:
+array (
+ 'aa' => 'a',
+ 'aaa' => 'a',
+ 'a' => 'a',
+)
+ Result: true
+
+Test 4.a85a41ea78e45b651080cfd98c0b431d:
+array (
+ 7 => '',
+ 2 => NULL,
+ 5 => '!',
+ 1 => 'abc',
+)
+ Result: true
+
+Test 5.99dc71f405b286e03d489061b36e6900:
+array (
+ 2 => '25',
+ 3 => '36',
+ 1 => '100',
+)
+ Result: true
+
+Test 6.bf5bba243307c9d12934e756ad4be190:
+array (
+ 3 => 2,
+ 1 => 5,
+ 2 => '30',
+)
+ Result: true
+
+Test 7.e4ee7024c61476e9e7a6c28b5e47df6f:
+array (
+ 1 => '100',
+ 2 => '25',
+ 3 => '36',
+)
+ Result: true
+
+Test 8.5fa7033dd43784be0db1474eb48b83c8:
+array (
+ 3 => 2,
+ 2 => '30',
+ 1 => 5,
+)
+ Result: true
+
+Test 9.588cdf4692bc09aa92ffe7e48f9e4579:
+array (
+ 2 => '',
+ 3 => ' a',
+ 1 => 'd',
+)
+ Result: true
+
+Test 10.be02641a47ebcccd23e4183ca3a415f7:
+array (
+ 3 => 'i',
+ 2 => 'k',
+ 1 => 'y',
+)
+ Result: true
+
+Test 11.153d9b11d1e5936afc917a94a4e11f34:
+array (
+ 'е' => 'а',
+ 'б' => 'в',
+ 'п' => 'у',
+)
+ Result: true
+
+Test 12.e1f5cb037b564dce39ffbd0a61562d59:
+array (
+ 4 => '',
+ 1 => 'п',
+ 2 => 'пп',
+ 7 => 'd',
+)
+ Result: true
+
+Test 13.8800d48abb960a59002eef77f1d73ae0:
+array (
+ 'c' => 'i',
+ 'd' => 'y',
+ 'a' => 'k',
+)
+ Result: true
diff --git a/ext/intl/tests/collator_compare.phpt b/ext/intl/tests/collator_compare.phpt
index f10b5708f4..7c07204b70 100644
--- a/ext/intl/tests/collator_compare.phpt
+++ b/ext/intl/tests/collator_compare.phpt
@@ -2,6 +2,7 @@
compare()
--SKIPIF--
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') >= 0) die('skip for ICU < 51.2'); ?>
--FILE--
<?php
diff --git a/ext/intl/tests/collator_compare_variant2.phpt b/ext/intl/tests/collator_compare_variant2.phpt
new file mode 100644
index 0000000000..15c725bc4f
--- /dev/null
+++ b/ext/intl/tests/collator_compare_variant2.phpt
@@ -0,0 +1,135 @@
+--TEST--
+compare()
+--SKIPIF--
+<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') < 0) die('skip for ICU >= 51.2'); ?>
+--FILE--
+<?php
+
+/*
+ * Compare various string pairs using various locales.
+ */
+
+
+/*
+ * Converts comparison result to a character.
+ */
+function cmp_to_char( $comp_res )
+{
+ switch( $comp_res )
+ {
+ case 0: // UCOL_EQUAL
+ return '=';
+ case 1: // UCOL_GREATER
+ return '>';
+ case -1: // UCOL_LESS
+ return '<';
+ default:
+ return '?';
+ }
+}
+
+/*
+ * Compare string pairs in the given array
+ * using specified locale.
+ */
+function compare_pairs( $locale, $test_array )
+{
+ $res_str = '';
+
+ $coll = ut_coll_create( $locale );
+
+ foreach( $test_array as $test_strings )
+ {
+ list( $str1, $str2 ) = $test_strings;
+
+ // Compare strings.
+ $res_val = cmp_to_char( ut_coll_compare( $coll, $str1, $str2 ) );
+
+ // Concatenate result strings.
+ $res_str .= dump( $str1 ) .
+ ' ' . $res_val . ' ' .
+ dump( $str2 ) . "\n";
+ }
+
+ return $res_str;
+
+}
+
+function ut_main()
+{
+ $res_str = '';
+
+ // Compare strings using en_US locale.
+ $test_params = array(
+ array( 'abc', 'abc' ),
+ array( 'Abc', 'abc' ),
+ array( 'a' , 'abc' ),
+ array( 'a' , '' ),
+ array( '' , '' ),
+ array( 'a' , 'b' ),
+ array( 'ab' , 'b' ),
+ array( 'ab' , 'a' ),
+ array( 123 , 'abc' ),
+ array( 'ac' , null ),
+ array( '.' , '.' ),
+ // Try to compare long strings.
+ array( 'abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcde',
+ 'abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdea'),
+ array( null , null )
+ );
+
+ $res_str .= compare_pairs( 'en_US', $test_params );
+
+
+ // Compare strings using ru_RU locale.
+ $test_params = array(
+ array( 'а', 'б' ),
+ array( 'а', 'аа' ),
+ array( 'аб', 'ба' ),
+ array( 'а', ',' ),
+ array( 'а', 'b' ),
+ array( 'а', 'bb' ),
+ array( 'а', 'ab' ),
+ array( 'а', null )
+ );
+
+ $res_str .= compare_pairs( 'ru_RU', $test_params );
+
+
+ // Compare strings using lt_LT locale.
+ $test_params = array(
+ array( 'y', 'k' )
+ );
+
+ $res_str .= compare_pairs( 'lt_LT', $test_params );
+
+ return $res_str;
+}
+
+include_once( 'ut_common.inc' );
+ut_run();
+?>
+--EXPECT--
+'abc' = 'abc'
+'Abc' > 'abc'
+'a' < 'abc'
+'a' > ''
+'' = ''
+'a' < 'b'
+'ab' < 'b'
+'ab' > 'a'
+123 < 'abc'
+'ac' > NULL
+'.' = '.'
+'abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcde' < 'abcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdea'
+NULL = NULL
+'а' < 'б'
+'а' < 'аа'
+'аб' < 'ба'
+'а' > ','
+'а' < 'b'
+'а' < 'bb'
+'а' < 'ab'
+'а' > NULL
+'y' < 'k'
diff --git a/ext/intl/tests/collator_get_sort_key.phpt b/ext/intl/tests/collator_get_sort_key.phpt
index a9c4d71348..58240d426c 100644
--- a/ext/intl/tests/collator_get_sort_key.phpt
+++ b/ext/intl/tests/collator_get_sort_key.phpt
@@ -3,6 +3,8 @@ collator_get_sort_key()
--SKIPIF--
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
<?php if(version_compare(INTL_ICU_VERSION, '4.8') < 0) print 'skip ICU >= 4.8 only'; ?>
+<?php /* XXX Obviously it fails somewhere between >= 4.8 and < 51.2 */
+if (version_compare(INTL_ICU_VERSION, '51.2') >= 0) die('skip for ICU < 51.2'); ?>
--FILE--
<?php
@@ -95,4 +97,4 @@ key: 5c0a161801070107
source: жжж
key: 5c3a3a3a01070107
source: эюя
-key: 5d3b3f4501070107 \ No newline at end of file
+key: 5d3b3f4501070107
diff --git a/ext/intl/tests/collator_get_sort_key_variant2.phpt b/ext/intl/tests/collator_get_sort_key_variant2.phpt
new file mode 100644
index 0000000000..bb09256d6b
--- /dev/null
+++ b/ext/intl/tests/collator_get_sort_key_variant2.phpt
@@ -0,0 +1,98 @@
+--TEST--
+collator_get_sort_key()
+--SKIPIF--
+<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') < 0) die('skip for ICU >= 51.2'); ?>
+--FILE--
+<?php
+
+/*
+ * Get sort keys using various locales
+ */
+function sort_arrays( $locale, $data )
+{
+ $res_str = '';
+
+ $coll = ut_coll_create( $locale );
+
+ foreach($data as $value) {
+ $res_val = ut_coll_get_sort_key( $coll, $value );
+ $res_str .= "source: ".$value."\n".
+ "key: ".bin2hex($res_val)."\n";
+ }
+
+ return $res_str;
+}
+
+
+function ut_main()
+{
+ $res_str = '';
+
+ // Regular strings keys
+ $test_params = array(
+ 'abc', 'abd', 'aaa',
+ 'аа', 'а', 'z',
+ '', null , '3',
+ 'y' , 'i' , 'k'
+ );
+
+ $res_str .= sort_arrays( 'en_US', $test_params );
+
+ // Sort a non-ASCII array using ru_RU locale.
+ $test_params = array(
+ 'абг', 'абв', 'жжж', 'эюя'
+ );
+
+ $res_str .= sort_arrays( 'ru_RU', $test_params );
+
+ // Sort an array using Lithuanian locale.
+ $res_str .= sort_arrays( 'lt_LT', $test_params );
+
+ return $res_str . "\n";
+}
+
+include_once( 'ut_common.inc' );
+ut_run();
+?>
+--EXPECT--
+source: abc
+key: 27292b01070107
+source: abd
+key: 27292d01070107
+source: aaa
+key: 27272701070107
+source: аа
+key: 5c0a0a01060106
+source: а
+key: 5c0a01050105
+source: z
+key: 5901050105
+source:
+key: 0101
+source:
+key: 0101
+source: 3
+key: 1801050105
+source: y
+key: 5701050105
+source: i
+key: 3701050105
+source: k
+key: 3b01050105
+source: абг
+key: 260a161a01070107
+source: абв
+key: 260a161801070107
+source: жжж
+key: 263a3a3a01070107
+source: эюя
+key: 273b3f4501070107
+source: абг
+key: 5c0a161a01070107
+source: абв
+key: 5c0a161801070107
+source: жжж
+key: 5c3a3a3a01070107
+source: эюя
+key: 5d3b3f4501070107
diff --git a/ext/intl/tests/collator_sort.phpt b/ext/intl/tests/collator_sort.phpt
index 5cefe2fd7c..e16eeea1e8 100644
--- a/ext/intl/tests/collator_sort.phpt
+++ b/ext/intl/tests/collator_sort.phpt
@@ -2,6 +2,7 @@
sort()
--SKIPIF--
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') >= 0) die('skip for ICU < 51.2'); ?>
--FILE--
<?php
diff --git a/ext/intl/tests/collator_sort_variant2.phpt b/ext/intl/tests/collator_sort_variant2.phpt
new file mode 100644
index 0000000000..29a5082fda
--- /dev/null
+++ b/ext/intl/tests/collator_sort_variant2.phpt
@@ -0,0 +1,248 @@
+--TEST--
+sort()
+--SKIPIF--
+<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') < 0) die('skip for ICU >= 51.2'); ?>
+--FILE--
+<?php
+
+/*
+ * Sort arrays using various locales.
+ */
+
+
+$test_num = 1;
+
+/*
+ * Sort arrays in the given list using specified locale.
+ */
+function sort_arrays( $locale, $arrays, $sort_flag = Collator::SORT_REGULAR )
+{
+ $res_str = '';
+
+ $coll = ut_coll_create( $locale );
+
+ foreach( $arrays as $array )
+ {
+ // Sort array values
+ $res_val = ut_coll_sort( $coll, $array, $sort_flag );
+
+ // Concatenate the sorted array and function result
+ // with output string.
+ $res_dump = "\n" . dump( $array ) .
+ "\n Result: " . dump( $res_val );
+
+ // Preppend test signature to output string
+ $md5 = md5( $res_dump );
+
+ global $test_num;
+
+ $res_str .= "\n\n".
+ "Test $test_num.$md5:" .
+ $res_dump;
+ ++$test_num;
+ }
+
+ return $res_str;
+}
+
+function ut_main()
+{
+ global $test_num;
+ $test_num = 1;
+ $res_str = '';
+
+ // Sort an array in SORT_REGULAR mode using en_US locale.
+ $test_params = array(
+ array( 'abc', 'abd', 'aaa' ),
+ array( 'm' , '1' , '_' ),
+ array( 'a' , 'aaa', 'aa' ),
+ array( 'ba' , 'b' , 'ab' ),
+ array( 'e' , 'c' , 'a' ),
+ array( '100', '25' , '36' ),
+ array( 5 , '30' , 2 ),
+ array( 'd' , '' , ' a' ),
+ array( 'd ' , 'f ' , ' a' ),
+ array( 'a' , null , '3' ),
+ array( 'y' , 'k' , 'i' )
+ );
+
+ $res_str .= sort_arrays( 'en_US', $test_params );
+
+ $test_params = array(
+ array( '100', '25' , '36' ),
+ array( 5 , '30' , 2 ),
+ array( 'd' , '' , ' a' ),
+ array( 'y' , 'k' , 'i' )
+ );
+
+ // Sort in en_US locale with SORT_STRING flag
+ $res_str .= sort_arrays( 'en_US', $test_params, Collator::SORT_STRING );
+
+
+ // Sort a non-ASCII array using ru_RU locale.
+ $test_params = array(
+ array( 'абг', 'абв', 'ааа', 'abc' ),
+ array( 'аа', 'ааа' , 'а' )
+ );
+
+ $res_str .= sort_arrays( 'ru_RU', $test_params );
+
+ // Sort an array using Lithuanian locale.
+ $test_params = array(
+ array( 'y' , 'k' , 'i' )
+ );
+
+ $res_str .= sort_arrays( 'lt_LT', $test_params );
+
+ return $res_str;
+}
+
+include_once( 'ut_common.inc' );
+ut_run();
+?>
+--EXPECT--
+Test 1.e8f1cd28133d79ecd660002f1c660d0e:
+array (
+ 0 => 'aaa',
+ 1 => 'abc',
+ 2 => 'abd',
+)
+ Result: true
+
+Test 2.c2ded12173dd2996927378cae37eb275:
+array (
+ 0 => '_',
+ 1 => '1',
+ 2 => 'm',
+)
+ Result: true
+
+Test 3.54071c968d71cb98c5d379145f8d7d38:
+array (
+ 0 => 'a',
+ 1 => 'aa',
+ 2 => 'aaa',
+)
+ Result: true
+
+Test 4.19abe63d6f6dfef65b0e3c9ab4826b07:
+array (
+ 0 => 'ab',
+ 1 => 'b',
+ 2 => 'ba',
+)
+ Result: true
+
+Test 5.9a8dc0a9bc771368c2f1fc3d02754610:
+array (
+ 0 => 'a',
+ 1 => 'c',
+ 2 => 'e',
+)
+ Result: true
+
+Test 6.ab530b060e5e54a65bfb8b9f8fc61870:
+array (
+ 0 => '25',
+ 1 => '36',
+ 2 => '100',
+)
+ Result: true
+
+Test 7.0718dd838509017bded2ed307a6e785f:
+array (
+ 0 => 2,
+ 1 => 5,
+ 2 => '30',
+)
+ Result: true
+
+Test 8.923d65739c5219c634616ffd100a50e4:
+array (
+ 0 => '',
+ 1 => ' a',
+ 2 => 'd',
+)
+ Result: true
+
+Test 9.289bc2f28e87d3201ec9d7e8477ae1b0:
+array (
+ 0 => ' a',
+ 1 => 'd ',
+ 2 => 'f ',
+)
+ Result: true
+
+Test 10.de0fd958484f2377a645835d7fbcf124:
+array (
+ 0 => NULL,
+ 1 => '3',
+ 2 => 'a',
+)
+ Result: true
+
+Test 11.dd2b8f0adb37c45d528cad1a0cc0f361:
+array (
+ 0 => 'i',
+ 1 => 'k',
+ 2 => 'y',
+)
+ Result: true
+
+Test 12.1e6b4d6f7df9d4580317634ea46d8208:
+array (
+ 0 => '100',
+ 1 => '25',
+ 2 => '36',
+)
+ Result: true
+
+Test 13.cec115dc9850b98dfbdf102efa09e61b:
+array (
+ 0 => 2,
+ 1 => '30',
+ 2 => 5,
+)
+ Result: true
+
+Test 14.923d65739c5219c634616ffd100a50e4:
+array (
+ 0 => '',
+ 1 => ' a',
+ 2 => 'd',
+)
+ Result: true
+
+Test 15.dd2b8f0adb37c45d528cad1a0cc0f361:
+array (
+ 0 => 'i',
+ 1 => 'k',
+ 2 => 'y',
+)
+ Result: true
+
+Test 16.49056308afb2b800363c5baa735ed247:
+array (
+ 0 => 'ааа',
+ 1 => 'абв',
+ 2 => 'абг',
+ 3 => 'abc',
+)
+ Result: true
+
+Test 17.91480b10473a0c96a4cd6d88c23c577a:
+array (
+ 0 => 'а',
+ 1 => 'аа',
+ 2 => 'ааа',
+)
+ Result: true
+
+Test 18.fdd3fe3981476039164aa000bf9177f2:
+array (
+ 0 => 'i',
+ 1 => 'y',
+ 2 => 'k',
+)
+ Result: true
diff --git a/ext/intl/tests/collator_sort_with_sort_keys.phpt b/ext/intl/tests/collator_sort_with_sort_keys.phpt
index 2f489d745c..8be9c97789 100644
--- a/ext/intl/tests/collator_sort_with_sort_keys.phpt
+++ b/ext/intl/tests/collator_sort_with_sort_keys.phpt
@@ -2,6 +2,7 @@
sort_with_sort_keys()
--SKIPIF--
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') >= 0) die('skip for ICU < 51.2'); ?>
--FILE--
<?php
diff --git a/ext/intl/tests/collator_sort_with_sort_keys_variant2.phpt b/ext/intl/tests/collator_sort_with_sort_keys_variant2.phpt
new file mode 100644
index 0000000000..5257f8a6ff
--- /dev/null
+++ b/ext/intl/tests/collator_sort_with_sort_keys_variant2.phpt
@@ -0,0 +1,190 @@
+--TEST--
+sort_with_sort_keys()
+--SKIPIF--
+<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') < 0) die('skip for ICU >= 51.2'); ?>
+--FILE--
+<?php
+
+/*
+ * Sort arrays using various locales.
+ */
+
+
+$test_num = 1;
+
+/*
+ * Sort arrays in the given list using specified locale.
+ */
+function sort_arrays( $locale, $arrays )
+{
+ $res_str = '';
+
+ $coll = ut_coll_create( $locale );
+
+ foreach( $arrays as $array )
+ {
+ // Sort array values
+ $res_val = ut_coll_sort_with_sort_keys( $coll, $array );
+
+ // Concatenate the sorted array and function result
+ // with output string.
+ $res_dump = "\n" . dump( $array ) .
+ "\n Result: " . dump( $res_val );
+
+
+ // Preppend test signature to output string
+ $md5 = md5( $res_dump );
+
+ global $test_num;
+
+ $res_str .= "\n\n".
+ "Test $test_num.$md5:" .
+ $res_dump;
+ ++$test_num;
+ }
+
+ return $res_str;
+}
+
+
+function ut_main()
+{
+ global $test_num;
+ $test_num = 1;
+ $res_str = '';
+
+ // Sort an array in SORT_REGULAR mode using en_US locale.
+ $test_params = array(
+ array( 'abc', 'abd', 'aaa' ),
+ array( 'm' , '1' , '_' ),
+ array( 'a' , 'aaa', 'aa' ),
+ array( 'ba' , 'b' , 'ab' ),
+ array( 'e' , 'c' , 'a' ),
+ array( 'd' , '' , ' a' ),
+ array( 'd ' , 'f ' , ' a' ),
+ array( 'a' , null , '3' ),
+ array( 'y' , 'i' , 'k' )
+ );
+
+ $res_str .= sort_arrays( 'en_US', $test_params );
+
+ // Sort a non-ASCII array using ru_RU locale.
+ $test_params = array(
+ array( 'абг', 'абв', 'ааа', 'abc' ),
+ array( 'аа', 'ааа', 'а' )
+ );
+
+ $res_str .= sort_arrays( 'ru_RU', $test_params );
+
+ // Array with data for sorting.
+ $test_params = array(
+ array( 'y' , 'i' , 'k' )
+ );
+
+ // Sort an array using Lithuanian locale.
+ $res_str .= sort_arrays( 'lt_LT', $test_params );
+
+ return $res_str . "\n";
+}
+
+include_once( 'ut_common.inc' );
+ut_run();
+?>
+--EXPECT--
+Test 1.e8f1cd28133d79ecd660002f1c660d0e:
+array (
+ 0 => 'aaa',
+ 1 => 'abc',
+ 2 => 'abd',
+)
+ Result: true
+
+Test 2.c2ded12173dd2996927378cae37eb275:
+array (
+ 0 => '_',
+ 1 => '1',
+ 2 => 'm',
+)
+ Result: true
+
+Test 3.54071c968d71cb98c5d379145f8d7d38:
+array (
+ 0 => 'a',
+ 1 => 'aa',
+ 2 => 'aaa',
+)
+ Result: true
+
+Test 4.19abe63d6f6dfef65b0e3c9ab4826b07:
+array (
+ 0 => 'ab',
+ 1 => 'b',
+ 2 => 'ba',
+)
+ Result: true
+
+Test 5.9a8dc0a9bc771368c2f1fc3d02754610:
+array (
+ 0 => 'a',
+ 1 => 'c',
+ 2 => 'e',
+)
+ Result: true
+
+Test 6.923d65739c5219c634616ffd100a50e4:
+array (
+ 0 => '',
+ 1 => ' a',
+ 2 => 'd',
+)
+ Result: true
+
+Test 7.289bc2f28e87d3201ec9d7e8477ae1b0:
+array (
+ 0 => ' a',
+ 1 => 'd ',
+ 2 => 'f ',
+)
+ Result: true
+
+Test 8.de0fd958484f2377a645835d7fbcf124:
+array (
+ 0 => NULL,
+ 1 => '3',
+ 2 => 'a',
+)
+ Result: true
+
+Test 9.dd2b8f0adb37c45d528cad1a0cc0f361:
+array (
+ 0 => 'i',
+ 1 => 'k',
+ 2 => 'y',
+)
+ Result: true
+
+Test 10.49056308afb2b800363c5baa735ed247:
+array (
+ 0 => 'ааа',
+ 1 => 'абв',
+ 2 => 'абг',
+ 3 => 'abc',
+)
+ Result: true
+
+Test 11.91480b10473a0c96a4cd6d88c23c577a:
+array (
+ 0 => 'а',
+ 1 => 'аа',
+ 2 => 'ааа',
+)
+ Result: true
+
+Test 12.fdd3fe3981476039164aa000bf9177f2:
+array (
+ 0 => 'i',
+ 1 => 'y',
+ 2 => 'k',
+)
+ Result: true
diff --git a/ext/intl/tests/cpbi_clone_equality.phpt b/ext/intl/tests/cpbi_clone_equality.phpt
new file mode 100644
index 0000000000..c62b452747
--- /dev/null
+++ b/ext/intl/tests/cpbi_clone_equality.phpt
@@ -0,0 +1,33 @@
+--TEST--
+IntlCodePointBreakIterator: clone and equality
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+
+$text = 'ตัวอย่างข้อความ';
+$text2 = 'foo';
+
+$it = IntlBreakIterator::createCodePointInstance();
+$it->setText($text);
+
+$it_clone = clone $it;
+var_dump($it == $it_clone);
+
+$it->setText($text2 );
+var_dump($it == $it_clone);
+
+$it_clone->setText($text2);
+var_dump($it == $it_clone);
+
+?>
+==DONE==
+--EXPECT--
+bool(true)
+bool(false)
+bool(true)
+==DONE==
diff --git a/ext/intl/tests/cpbi_getLastCodePoint_basic.phpt b/ext/intl/tests/cpbi_getLastCodePoint_basic.phpt
new file mode 100644
index 0000000000..74a07a6292
--- /dev/null
+++ b/ext/intl/tests/cpbi_getLastCodePoint_basic.phpt
@@ -0,0 +1,82 @@
+--TEST--
+IntlCodepointBreakIterator::getLastCodePoint(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+
+$text = 'ตัวอย่างข้อความ';
+
+$codepoint_it = IntlBreakIterator::createCodePointInstance();
+$codepoint_it->setText($text);
+
+var_dump($codepoint_it->getLastCodePoint());
+//first() and last() don't read codepoint and set the last code point var to -1
+//The pointer is after the last read codepoint if moving forward and
+//before the last read codepoint is moving backwards
+$p = $codepoint_it->first();
+while ($p != IntlBreakIterator::DONE) {
+ $c = $codepoint_it->getLastCodePoint();
+ if ($c > 0)
+ var_dump(sprintf('U+%04X', $codepoint_it->getLastCodePoint()));
+ else
+ var_dump($c);
+ //it's a post-increment operation as to the codepoint, i.e., it gives the codepoint
+ //starting at the initial position and only then moves the pointer forward
+ $p = $codepoint_it->next();
+}
+
+echo "Now backwards\n";
+$p = $codepoint_it->last();
+while ($p != IntlBreakIterator::DONE) {
+ $c = $codepoint_it->getLastCodePoint();
+ if ($c > 0)
+ var_dump(sprintf('U+%04X', $codepoint_it->getLastCodePoint()));
+ else
+ var_dump($c);
+ $p = $codepoint_it->previous();
+}
+
+
+?>
+==DONE==
+--EXPECT--
+int(-1)
+int(-1)
+string(6) "U+0E15"
+string(6) "U+0E31"
+string(6) "U+0E27"
+string(6) "U+0E2D"
+string(6) "U+0E22"
+string(6) "U+0E48"
+string(6) "U+0E32"
+string(6) "U+0E07"
+string(6) "U+0E02"
+string(6) "U+0E49"
+string(6) "U+0E2D"
+string(6) "U+0E04"
+string(6) "U+0E27"
+string(6) "U+0E32"
+string(6) "U+0E21"
+Now backwards
+int(-1)
+string(6) "U+0E21"
+string(6) "U+0E32"
+string(6) "U+0E27"
+string(6) "U+0E04"
+string(6) "U+0E2D"
+string(6) "U+0E49"
+string(6) "U+0E02"
+string(6) "U+0E07"
+string(6) "U+0E32"
+string(6) "U+0E48"
+string(6) "U+0E22"
+string(6) "U+0E2D"
+string(6) "U+0E27"
+string(6) "U+0E31"
+string(6) "U+0E15"
+==DONE==
diff --git a/ext/intl/tests/cpbi_getLastCodePoint_error.phpt b/ext/intl/tests/cpbi_getLastCodePoint_error.phpt
new file mode 100644
index 0000000000..78bd216629
--- /dev/null
+++ b/ext/intl/tests/cpbi_getLastCodePoint_error.phpt
@@ -0,0 +1,19 @@
+--TEST--
+IntlBreakIterator::getLastCodePoint(): bad args
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$it = IntlBreakIterator::createCodePointInstance();
+var_dump($it->getLastCodePoint(array()));
+--EXPECTF--
+
+Warning: IntlCodePointBreakIterator::getLastCodePoint() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlCodePointBreakIterator::getLastCodePoint(): cpbi_get_last_code_point: bad arguments in %s on line %d
+bool(false)
+
diff --git a/ext/intl/tests/cpbi_parts_iterator.phpt b/ext/intl/tests/cpbi_parts_iterator.phpt
new file mode 100644
index 0000000000..4754c12371
--- /dev/null
+++ b/ext/intl/tests/cpbi_parts_iterator.phpt
@@ -0,0 +1,40 @@
+--TEST--
+IntlCodepointBreakIterator's part iterator
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+
+$text = 'ตัวอย่างข้อความ';
+
+$it = IntlBreakIterator::createCodePointInstance()->getPartsIterator();
+$it->getBreakIterator()->setText($text);
+
+foreach ($it as $k => $v) {
+ echo "$k. $v (" . sprintf("U+%04X", $it->getBreakIterator()->getLastCodePoint()) .
+ ") at {$it->getBreakIterator()->current()}\r\n";
+}
+
+?>
+==DONE==
+--EXPECT--
+0. ต (U+0E15) at 3
+1. ั (U+0E31) at 6
+2. ว (U+0E27) at 9
+3. อ (U+0E2D) at 12
+4. ย (U+0E22) at 15
+5. ่ (U+0E48) at 18
+6. า (U+0E32) at 21
+7. ง (U+0E07) at 24
+8. ข (U+0E02) at 27
+9. ้ (U+0E49) at 30
+10. อ (U+0E2D) at 33
+11. ค (U+0E04) at 36
+12. ว (U+0E27) at 39
+13. า (U+0E32) at 42
+14. ม (U+0E21) at 45
+==DONE==
diff --git a/ext/intl/tests/dateformat___construct_bad_tz_cal.phpt b/ext/intl/tests/dateformat___construct_bad_tz_cal.phpt
new file mode 100644
index 0000000000..cfd9338717
--- /dev/null
+++ b/ext/intl/tests/dateformat___construct_bad_tz_cal.phpt
@@ -0,0 +1,32 @@
+--TEST--
+IntlDateFormatter::__construct(): bad timezone or calendar
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+ini_set("date.timezone", 'Atlantic/Azores');
+
+var_dump(new IntlDateFormatter(NULL, 0, 0, 'bad timezone'));
+
+var_dump(new IntlDateFormatter(NULL, 0, 0, NULL, 3));
+
+var_dump(new IntlDateFormatter(NULL, 0, 0, NULL, new stdclass));
+
+
+?>
+==DONE==
+--EXPECTF--
+
+Warning: IntlDateFormatter::__construct(): datefmt_create: no such time zone: 'bad timezone' in %s on line %d
+NULL
+
+Warning: IntlDateFormatter::__construct(): datefmt_create: invalid value for calendar type; it must be one of IntlDateFormatter::TRADITIONAL (locale's default calendar) or IntlDateFormatter::GREGORIAN. Alternatively, it can be an IntlCalendar object in %s on line %d
+NULL
+
+Warning: IntlDateFormatter::__construct(): datefmt_create: Invalid calendar argument; should be an integer or an IntlCalendar instance in %s on line %d
+NULL
+==DONE==
diff --git a/ext/intl/tests/dateformat_calendars.phpt b/ext/intl/tests/dateformat_calendars.phpt
index 27f380c718..2239af28df 100644
--- a/ext/intl/tests/dateformat_calendars.phpt
+++ b/ext/intl/tests/dateformat_calendars.phpt
@@ -4,8 +4,8 @@ IntlDateFormatter, calendars and time zone
date.timezone=Atlantic/Azores
--SKIPIF--
<?php
-if (!extension_loaded('intl'))
- die('skip intl extension not enabled');
+if (!extension_loaded('intl')) die('skip intl extension not enabled'); ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') >= 0) die('skip for ICU < 51.2'); ?>
--FILE--
<?php
ini_set("intl.error_level", E_WARNING);
@@ -41,5 +41,5 @@ string(44) "Sunday, January 1, 2012 5:12:00 AM GMT+05:12"
string(44) "Sunday, January 1, 2012 5:12:00 AM GMT+05:12"
string(42) "Sunday, Tevet 6, 5772 5:12:00 AM GMT+05:12"
-Warning: IntlDateFormatter::__construct(): datefmt_create: invalid value for calendar type; it must be one of IntlDateFormatter::TRADITIONAL (locale's default calendar) or IntlDateFormatter::GREGORIAN in %s on line %d
+Warning: IntlDateFormatter::__construct(): datefmt_create: invalid value for calendar type; it must be one of IntlDateFormatter::TRADITIONAL (locale's default calendar) or IntlDateFormatter::GREGORIAN. Alternatively, it can be an IntlCalendar object in %s on line %d
==DONE==
diff --git a/ext/intl/tests/dateformat_calendars_variant2.phpt b/ext/intl/tests/dateformat_calendars_variant2.phpt
new file mode 100644
index 0000000000..61cdea8408
--- /dev/null
+++ b/ext/intl/tests/dateformat_calendars_variant2.phpt
@@ -0,0 +1,45 @@
+--TEST--
+IntlDateFormatter, calendars and time zone
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl')) die('skip intl extension not enabled'); ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') < 0) die('skip for ICU >= 51.2'); ?>
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$fmt1 = new IntlDateFormatter('en_US',
+ IntlDateFormatter::FULL,
+ IntlDateFormatter::FULL,
+ 'GMT+05:12',
+ IntlDateFormatter::TRADITIONAL);
+$fmt2 = new IntlDateFormatter('en_US',
+ IntlDateFormatter::FULL,
+ IntlDateFormatter::FULL,
+ 'GMT+05:12',
+ IntlDateFormatter::GREGORIAN);
+$fmt3 = new IntlDateFormatter('en_US@calendar=hebrew',
+ IntlDateFormatter::FULL,
+ IntlDateFormatter::FULL,
+ 'GMT+05:12',
+ IntlDateFormatter::TRADITIONAL);
+var_dump($fmt1->format(strtotime('2012-01-01 00:00:00 +0000')));
+var_dump($fmt2->format(strtotime('2012-01-01 00:00:00 +0000')));
+var_dump($fmt3->format(strtotime('2012-01-01 00:00:00 +0000')));
+
+new IntlDateFormatter('en_US@calendar=hebrew',
+ IntlDateFormatter::FULL,
+ IntlDateFormatter::FULL,
+ 'GMT+05:12',
+ -1);
+?>
+==DONE==
+--EXPECTF--
+string(47) "Sunday, January 1, 2012 at 5:12:00 AM GMT+05:12"
+string(47) "Sunday, January 1, 2012 at 5:12:00 AM GMT+05:12"
+string(48) "Sunday, Tevet 6, 5772 AM at 5:12:00 AM GMT+05:12"
+
+Warning: IntlDateFormatter::__construct(): datefmt_create: invalid value for calendar type; it must be one of IntlDateFormatter::TRADITIONAL (locale's default calendar) or IntlDateFormatter::GREGORIAN. Alternatively, it can be an IntlCalendar object in %sdateformat_calendars_variant2.php on line %d
+==DONE==
diff --git a/ext/intl/tests/dateformat_create_cal_arg.phpt b/ext/intl/tests/dateformat_create_cal_arg.phpt
new file mode 100644
index 0000000000..a8f351247b
--- /dev/null
+++ b/ext/intl/tests/dateformat_create_cal_arg.phpt
@@ -0,0 +1,53 @@
+--TEST--
+IntlDateFormatter: several forms of the calendar arg
+--SKIPIF--
+<?php
+if (!extension_loaded('intl')) die('skip intl extension not enabled'); ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') >= 0) die('skip for ICU < 51.2'); ?>
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+ini_set("date.timezone", 'Atlantic/Azores');
+
+$ts = strtotime('2012-01-01 00:00:00 UTC');
+
+$cal = new IntlGregorianCalendar('UTC', NULL);
+$df = new IntlDateFormatter('es_ES', 0, 0, NULL, $cal);
+echo $df->format($ts), "\n";
+
+$cal = IntlCalendar::createInstance('UTC', 'en@calendar=islamic');
+$df = new IntlDateFormatter('es_ES', 0, 0, NULL, $cal);
+echo $df->format($ts), "\n";
+
+//override calendar's timezone
+$cal = new IntlGregorianCalendar('UTC', NULL);
+$df = new IntlDateFormatter('es_ES', 0, 0, 'Europe/Madrid', $cal);
+echo $df->format($ts), "\n";
+
+//default calendar is gregorian
+$df = new IntlDateFormatter('es_ES@calendar=islamic', 0, 0);
+echo $df->format($ts), "\n";
+
+//try now with traditional
+$df = new IntlDateFormatter('es_ES@calendar=islamic', 0, 0, NULL, IntlDateFormatter::TRADITIONAL);
+echo $df->format($ts), "\n";
+
+//the timezone can be overridden when not specifying a calendar
+$df = new IntlDateFormatter('es_ES@calendar=islamic', 0, 0, 'UTC', IntlDateFormatter::TRADITIONAL);
+echo $df->format($ts), "\n";
+
+$df = new IntlDateFormatter('es_ES', 0, 0, 'UTC', 0);
+echo $df->format($ts), "\n";
+
+?>
+==DONE==
+--EXPECTF--
+domingo%S 1 de enero de 2012 00:00:00 GMT
+domingo%S 8 de Safar de 1433 00:00:00 GMT
+domingo%S 1 de enero de 2012 01:00:00 Hora estándar de Europa Central
+sábado%S 31 de diciembre de 2011 d.C. 23:00:00 Hora %Sde las Azores
+sábado%S 7 de Safar de 1433 AH 23:00:00 Hora %Sde las Azores
+domingo%S 8 de Safar de 1433 AH 00:00:00 GMT
+domingo%S 1 de enero de 2012 00:00:00 GMT
+==DONE==
diff --git a/ext/intl/tests/dateformat_create_cal_arg_variant2.phpt b/ext/intl/tests/dateformat_create_cal_arg_variant2.phpt
new file mode 100644
index 0000000000..70b862017b
--- /dev/null
+++ b/ext/intl/tests/dateformat_create_cal_arg_variant2.phpt
@@ -0,0 +1,53 @@
+--TEST--
+IntlDateFormatter: several forms of the calendar arg
+--SKIPIF--
+<?php
+if (!extension_loaded('intl')) die('skip intl extension not enabled'); ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') < 0) die('skip for ICU >= 51.2'); ?>
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+ini_set("date.timezone", 'Atlantic/Azores');
+
+$ts = strtotime('2012-01-01 00:00:00 UTC');
+
+$cal = new IntlGregorianCalendar('UTC', NULL);
+$df = new IntlDateFormatter('es_ES', 0, 0, NULL, $cal);
+echo $df->format($ts), "\n";
+
+$cal = IntlCalendar::createInstance('UTC', 'en@calendar=islamic');
+$df = new IntlDateFormatter('es_ES', 0, 0, NULL, $cal);
+echo $df->format($ts), "\n";
+
+//override calendar's timezone
+$cal = new IntlGregorianCalendar('UTC', NULL);
+$df = new IntlDateFormatter('es_ES', 0, 0, 'Europe/Madrid', $cal);
+echo $df->format($ts), "\n";
+
+//default calendar is gregorian
+$df = new IntlDateFormatter('es_ES@calendar=islamic', 0, 0);
+echo $df->format($ts), "\n";
+
+//try now with traditional
+$df = new IntlDateFormatter('es_ES@calendar=islamic', 0, 0, NULL, IntlDateFormatter::TRADITIONAL);
+echo $df->format($ts), "\n";
+
+//the timezone can be overridden when not specifying a calendar
+$df = new IntlDateFormatter('es_ES@calendar=islamic', 0, 0, 'UTC', IntlDateFormatter::TRADITIONAL);
+echo $df->format($ts), "\n";
+
+$df = new IntlDateFormatter('es_ES', 0, 0, 'UTC', 0);
+echo $df->format($ts), "\n";
+
+?>
+==DONE==
+--EXPECTF--
+domingo%S 1 de enero de 2012 00:00:00 GMT
+domingo%S 8 de Safar de 1433 00:00:00 GMT
+domingo%S 1 de enero de 2012 01:00:00 Hora estándar de Europa central
+sábado%S 31 de diciembre de 2011 d.C. 23:00:00 Hora %Sde las Azores
+sábado%S 7 de Safar de 1433 AH 23:00:00 Hora %Sde las Azores
+domingo%S 8 de Safar de 1433 AH 00:00:00 GMT
+domingo%S 1 de enero de 2012 00:00:00 GMT
+==DONE==
diff --git a/ext/intl/tests/dateformat_format.phpt b/ext/intl/tests/dateformat_format.phpt
index e5548196d1..c3f6c297d9 100644
--- a/ext/intl/tests/dateformat_format.phpt
+++ b/ext/intl/tests/dateformat_format.phpt
@@ -2,9 +2,12 @@
datefmt_format_code()
--SKIPIF--
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') >= 0) die('skip for ICU < 51.2'); ?>
--FILE--
<?php
+//ini_set("intl.error_level", E_WARNING);
+
/*
* Test for the datefmt_format function
*/
@@ -12,7 +15,7 @@ datefmt_format_code()
function ut_main()
{
- $timezone = 'GMT-10';
+ $timezone = 'GMT-10:00';
$locale_arr = array (
'en_US'
@@ -397,24 +400,24 @@ Formatted DateTime is : 20001230 05:04 PM
Date is: stdClass::__set_state(array(
))
------------
-Error while formatting as: 'datefmt_format: object must be an instance of DateTime: U_ILLEGAL_ARGUMENT_ERROR'
+Error while formatting as: 'datefmt_format: invalid object type for date/time (only IntlCalendar and DateTime permitted): U_ILLEGAL_ARGUMENT_ERROR'
------------
Date is: stdClass::__set_state(array(
))
------------
-Error while formatting as: 'datefmt_format: object must be an instance of DateTime: U_ILLEGAL_ARGUMENT_ERROR'
+Error while formatting as: 'datefmt_format: invalid object type for date/time (only IntlCalendar and DateTime permitted): U_ILLEGAL_ARGUMENT_ERROR'
------------
Date is: stdClass::__set_state(array(
))
------------
-Error while formatting as: 'datefmt_format: object must be an instance of DateTime: U_ILLEGAL_ARGUMENT_ERROR'
+Error while formatting as: 'datefmt_format: invalid object type for date/time (only IntlCalendar and DateTime permitted): U_ILLEGAL_ARGUMENT_ERROR'
------------
Date is: stdClass::__set_state(array(
))
------------
-Error while formatting as: 'datefmt_format: object must be an instance of DateTime: U_ILLEGAL_ARGUMENT_ERROR'
+Error while formatting as: 'datefmt_format: invalid object type for date/time (only IntlCalendar and DateTime permitted): U_ILLEGAL_ARGUMENT_ERROR'
------------
Date is: stdClass::__set_state(array(
))
------------
-Error while formatting as: 'datefmt_format: object must be an instance of DateTime: U_ILLEGAL_ARGUMENT_ERROR'
+Error while formatting as: 'datefmt_format: invalid object type for date/time (only IntlCalendar and DateTime permitted): U_ILLEGAL_ARGUMENT_ERROR'
diff --git a/ext/intl/tests/dateformat_formatObject_calendar.phpt b/ext/intl/tests/dateformat_formatObject_calendar.phpt
new file mode 100644
index 0000000000..d3ab6260ff
--- /dev/null
+++ b/ext/intl/tests/dateformat_formatObject_calendar.phpt
@@ -0,0 +1,41 @@
+--TEST--
+IntlDateFormatter::formatObject(): IntlCalendar tests
+--SKIPIF--
+<?php
+if (!extension_loaded('intl')) die('skip intl extension not enabled'); ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') >= 0) die('skip for ICU < 51.2'); ?>
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+ini_set("date.timezone", "Europe/Lisbon");
+
+$cal = IntlCalendar::fromDateTime('2012-01-01 00:00:00'); //Europe/Lisbon
+echo IntlDateFormatter::formatObject($cal), "\n";
+echo IntlDateFormatter::formatObject($cal, IntlDateFormatter::FULL), "\n";
+echo IntlDateFormatter::formatObject($cal, null, "en-US"), "\n";
+echo IntlDateFormatter::formatObject($cal, array(IntlDateFormatter::SHORT, IntlDateFormatter::FULL), "en-US"), "\n";
+echo IntlDateFormatter::formatObject($cal, 'E y-MM-d HH,mm,ss.SSS v', "en-US"), "\n";
+
+$cal = IntlCalendar::fromDateTime('2012-01-01 05:00:00+03:00');
+echo datefmt_format_object($cal, IntlDateFormatter::FULL), "\n";
+
+$cal = IntlCalendar::createInstance(null,'en-US@calendar=islamic-civil');
+$cal->setTime(strtotime('2012-01-01 00:00:00')*1000.);
+echo IntlDateFormatter::formatObject($cal), "\n";
+echo IntlDateFormatter::formatObject($cal, IntlDateFormatter::FULL, "en-US"), "\n";
+
+?>
+==DONE==
+
+--EXPECTF--
+01/01/2012 00:00:00
+Domingo, 1 de Janeiro de 2012 0:00:00 Hora %Sda Europa Ocidental
+Jan 1, 2012 12:00:00 AM
+1/1/12 12:00:00 AM Western European %STime
+Sun 2012-01-1 00,00,00.000 Portugal Time (Lisbon)
+Domingo, 1 de Janeiro de 2012 5:00:00 GMT+03:00
+06/02/1433 00:00:00
+Sunday, Safar 6, 1433 12:00:00 AM Western European %STime
+==DONE==
+
diff --git a/ext/intl/tests/dateformat_formatObject_calendar_variant2.phpt b/ext/intl/tests/dateformat_formatObject_calendar_variant2.phpt
new file mode 100644
index 0000000000..1ec1fa669a
--- /dev/null
+++ b/ext/intl/tests/dateformat_formatObject_calendar_variant2.phpt
@@ -0,0 +1,40 @@
+--TEST--
+IntlDateFormatter::formatObject(): IntlCalendar tests
+--SKIPIF--
+<?php
+if (!extension_loaded('intl')) die('skip intl extension not enabled'); ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') < 0) die('skip for ICU >= 51.2'); ?>
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+ini_set("date.timezone", "Europe/Lisbon");
+
+$cal = IntlCalendar::fromDateTime('2012-01-01 00:00:00'); //Europe/Lisbon
+echo IntlDateFormatter::formatObject($cal), "\n";
+echo IntlDateFormatter::formatObject($cal, IntlDateFormatter::FULL), "\n";
+echo IntlDateFormatter::formatObject($cal, null, "en-US"), "\n";
+echo IntlDateFormatter::formatObject($cal, array(IntlDateFormatter::SHORT, IntlDateFormatter::FULL), "en-US"), "\n";
+echo IntlDateFormatter::formatObject($cal, 'E y-MM-d HH,mm,ss.SSS v', "en-US"), "\n";
+
+$cal = IntlCalendar::fromDateTime('2012-01-01 05:00:00+03:00');
+echo datefmt_format_object($cal, IntlDateFormatter::FULL), "\n";
+
+$cal = IntlCalendar::createInstance(null,'en-US@calendar=islamic-civil');
+$cal->setTime(strtotime('2012-01-01 00:00:00')*1000.);
+echo IntlDateFormatter::formatObject($cal), "\n";
+echo IntlDateFormatter::formatObject($cal, IntlDateFormatter::FULL, "en-US"), "\n";
+
+?>
+==DONE==
+
+--EXPECTF--
+01/01/2012, 00:00:00
+Domingo, 1 de Janeiro de 2012 às 00:00:00 Hora %Sda Europa Ocidental
+Jan 1, 2012, 12:00:00 AM
+1/1/12, 12:00:00 AM Western European Standard %STime
+Sun 2012-01-1 00,00,00.000 Portugal Time
+Domingo, 1 de Janeiro de 2012 às 05:00:00 GMT+03:00
+06/02/1433, 00:00:00
+Sunday, Safar 6, 1433 at 12:00:00 AM Western European Standard Time
+==DONE==
diff --git a/ext/intl/tests/dateformat_formatObject_datetime.phpt b/ext/intl/tests/dateformat_formatObject_datetime.phpt
new file mode 100644
index 0000000000..d9ddb0e644
--- /dev/null
+++ b/ext/intl/tests/dateformat_formatObject_datetime.phpt
@@ -0,0 +1,34 @@
+--TEST--
+IntlDateFormatter::formatObject(): DateTime tests
+--SKIPIF--
+<?php
+if (!extension_loaded('intl')) die('skip intl extension not enabled') ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') >= 0) die('skip for ICU < 51.2'); ?>
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+ini_set("date.timezone", "Europe/Lisbon");
+
+$dt = new DateTime('2012-01-01 00:00:00'); //Europe/Lisbon
+echo IntlDateFormatter::formatObject($dt), "\n";
+echo IntlDateFormatter::formatObject($dt, IntlDateFormatter::FULL), "\n";
+echo IntlDateFormatter::formatObject($dt, null, "en-US"), "\n";
+echo IntlDateFormatter::formatObject($dt, array(IntlDateFormatter::SHORT, IntlDateFormatter::FULL), "en-US"), "\n";
+echo IntlDateFormatter::formatObject($dt, 'E y-MM-d HH,mm,ss.SSS v', "en-US"), "\n";
+
+$dt = new DateTime('2012-01-01 05:00:00+03:00');
+echo IntlDateFormatter::formatObject($dt, IntlDateFormatter::FULL), "\n";
+
+?>
+==DONE==
+
+--EXPECTF--
+01/01/2012 00:00:00
+Domingo, 1 de Janeiro de 2012 0:00:00 Hora %Sda Europa Ocidental
+Jan 1, 2012 12:00:00 AM
+1/1/12 12:00:00 AM Western European %STime
+Sun 2012-01-1 00,00,00.000 Portugal Time (Lisbon)
+Domingo, 1 de Janeiro de 2012 5:00:00 GMT+03:00
+==DONE==
+
diff --git a/ext/intl/tests/dateformat_formatObject_datetime_variant2.phpt b/ext/intl/tests/dateformat_formatObject_datetime_variant2.phpt
new file mode 100644
index 0000000000..2ca9ffd7e8
--- /dev/null
+++ b/ext/intl/tests/dateformat_formatObject_datetime_variant2.phpt
@@ -0,0 +1,33 @@
+--TEST--
+IntlDateFormatter::formatObject(): DateTime tests
+--SKIPIF--
+<?php
+if (!extension_loaded('intl')) die('skip intl extension not enabled'); ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') < 0) die('skip for ICU >= 51.2'); ?>
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+ini_set("date.timezone", "Europe/Lisbon");
+
+$dt = new DateTime('2012-01-01 00:00:00'); //Europe/Lisbon
+echo IntlDateFormatter::formatObject($dt), "\n";
+echo IntlDateFormatter::formatObject($dt, IntlDateFormatter::FULL), "\n";
+echo IntlDateFormatter::formatObject($dt, null, "en-US"), "\n";
+echo IntlDateFormatter::formatObject($dt, array(IntlDateFormatter::SHORT, IntlDateFormatter::FULL), "en-US"), "\n";
+echo IntlDateFormatter::formatObject($dt, 'E y-MM-d HH,mm,ss.SSS v', "en-US"), "\n";
+
+$dt = new DateTime('2012-01-01 05:00:00+03:00');
+echo IntlDateFormatter::formatObject($dt, IntlDateFormatter::FULL), "\n";
+
+?>
+==DONE==
+
+--EXPECTF--
+01/01/2012, 00:00:00
+Domingo, 1 de Janeiro de 2012 às 00:00:00 Hora %Sda Europa Ocidental
+Jan 1, 2012, 12:00:00 AM
+1/1/12, 12:00:00 AM Western European Standard %STime
+Sun 2012-01-1 00,00,00.000 Portugal Time
+Domingo, 1 de Janeiro de 2012 às 05:00:00 GMT+03:00
+==DONE==
diff --git a/ext/intl/tests/dateformat_formatObject_error.phpt b/ext/intl/tests/dateformat_formatObject_error.phpt
new file mode 100644
index 0000000000..7aaf69e54e
--- /dev/null
+++ b/ext/intl/tests/dateformat_formatObject_error.phpt
@@ -0,0 +1,74 @@
+--TEST--
+IntlDateFormatter::formatObject(): error conditions
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+ini_set("date.timezone", "Europe/Lisbon");
+
+var_dump(IntlDateFormatter::formatObject());
+var_dump(IntlDateFormatter::formatObject(1));
+var_dump(IntlDateFormatter::formatObject(new stdclass));
+
+class A extends IntlCalendar {function __construct(){}}
+var_dump(IntlDateFormatter::formatObject(new A));
+class B extends DateTime {function __construct(){}}
+var_dump(IntlDateFormatter::formatObject(new B));
+
+$cal = IntlCalendar::createInstance();
+var_dump(IntlDateFormatter::formatObject($cal, -2));
+var_dump(IntlDateFormatter::formatObject($cal, array()));
+var_dump(IntlDateFormatter::formatObject($cal, array(1,2,3)));
+var_dump(IntlDateFormatter::formatObject($cal, array(array(), 1)));
+var_dump(IntlDateFormatter::formatObject($cal, array(1, -2)));
+var_dump(IntlDateFormatter::formatObject($cal, ""));
+var_dump(IntlDateFormatter::formatObject($cal, "YYYY", array()));
+
+?>
+==DONE==
+
+--EXPECTF--
+
+Warning: IntlDateFormatter::formatObject() expects at least 1 parameter, 0 given in %s on line %d
+bool(false)
+
+Warning: IntlDateFormatter::formatObject() expects parameter 1 to be object, integer given in %s on line %d
+bool(false)
+
+Warning: IntlDateFormatter::formatObject(): datefmt_format_object: the passed object must be an instance of either IntlCalendar or DateTime in %s on line %d
+bool(false)
+
+Warning: IntlDateFormatter::formatObject(): datefmt_format_object: bad IntlCalendar instance: not initialized properly in %s on line %d
+bool(false)
+
+Warning: DateTime::getTimestamp(): The DateTime object has not been correctly initialized by its constructor in %s on line %d
+
+Warning: IntlDateFormatter::formatObject(): datefmt_format_object: error calling ::getTimeStamp() on the object in %s on line %d
+bool(false)
+
+Warning: IntlDateFormatter::formatObject(): datefmt_format_object: the date/time format type is invalid in %s on line %d
+bool(false)
+
+Warning: IntlDateFormatter::formatObject(): datefmt_format_object: bad format; if array, it must have two elements in %s on line %d
+bool(false)
+
+Warning: IntlDateFormatter::formatObject(): datefmt_format_object: bad format; if array, it must have two elements in %s on line %d
+bool(false)
+
+Warning: IntlDateFormatter::formatObject(): datefmt_format_object: bad format; the date format (first element of the array) is not valid in %s on line %d
+bool(false)
+
+Warning: IntlDateFormatter::formatObject(): datefmt_format_object: bad format; the time format (second element of the array) is not valid in %s on line %d
+bool(false)
+
+Warning: IntlDateFormatter::formatObject(): datefmt_format_object: the format is empty in %s on line %d
+bool(false)
+
+Warning: IntlDateFormatter::formatObject() expects parameter 3 to be string, array given in %s on line %d
+bool(false)
+==DONE==
+
diff --git a/ext/intl/tests/dateformat_format_parse.phpt b/ext/intl/tests/dateformat_format_parse.phpt
index bd41d715b9..dfb479e937 100644
--- a/ext/intl/tests/dateformat_format_parse.phpt
+++ b/ext/intl/tests/dateformat_format_parse.phpt
@@ -2,6 +2,7 @@
datefmt_format_code() and datefmt_parse_code()
--SKIPIF--
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') >= 0) die('skip for ICU < 51.2'); ?>
--FILE--
<?php
@@ -12,7 +13,7 @@ datefmt_format_code() and datefmt_parse_code()
function ut_main()
{
- $timezone = 'GMT+5';
+ $timezone = 'GMT+05:00';
$locale_arr = array (
'en_US'
diff --git a/ext/intl/tests/dateformat_format_parse_version2.phpt b/ext/intl/tests/dateformat_format_parse_version2.phpt
new file mode 100644
index 0000000000..8c6f00ef54
--- /dev/null
+++ b/ext/intl/tests/dateformat_format_parse_version2.phpt
@@ -0,0 +1,295 @@
+--TEST--
+datefmt_format_code() and datefmt_parse_code()
+--SKIPIF--
+<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') < 0) die('skip for ICU >= 51.2'); ?>
+--FILE--
+<?php
+
+/*
+ * Test for the datefmt_format function
+ */
+
+
+function ut_main()
+{
+ $timezone = 'GMT+05:00';
+
+ $locale_arr = array (
+ 'en_US'
+ );
+
+ $datetype_arr = array (
+ IntlDateFormatter::FULL,
+ IntlDateFormatter::LONG,
+ IntlDateFormatter::MEDIUM
+ );
+
+ $res_str = '';
+
+
+ $time_arr = array (
+ 0,
+ -1200000,
+ 1200000,
+ 2200000000,
+ -2200000000,
+ 90099999,
+ 3600,
+ -3600
+ );
+
+ $localtime_arr1 = array (
+ 'tm_sec' => 24 ,
+ 'tm_min' => 3,
+ 'tm_hour' => 19,
+ 'tm_mday' => 3,
+ 'tm_mon' => 3,
+ 'tm_year' => 105,
+ );
+ $localtime_arr2 = array (
+ 'tm_sec' => 21,
+ 'tm_min' => 5,
+ 'tm_hour' => 7,
+ 'tm_mday' => 13,
+ 'tm_mon' => 7,
+ 'tm_year' => 205,
+ );
+ $localtime_arr3 = array (
+ 'tm_sec' => 11,
+ 'tm_min' => 13,
+ 'tm_hour' => 0,
+ 'tm_mday' => 17,
+ 'tm_mon' => 11,
+ 'tm_year' => -5
+ );
+
+ $localtime_arr = array (
+ $localtime_arr1,
+ $localtime_arr2,
+ $localtime_arr3
+ );
+
+ //Test format and parse with a timestamp : long
+ foreach( $time_arr as $timestamp_entry){
+ $res_str .= "\n------------\n";
+ $res_str .= "\nInput timestamp is : $timestamp_entry";
+ $res_str .= "\n------------\n";
+ foreach( $locale_arr as $locale_entry ){
+ foreach( $datetype_arr as $datetype_entry ) {
+ $res_str .= "\nIntlDateFormatter locale= $locale_entry ,datetype = $datetype_entry ,timetype =$datetype_entry ";
+ $fmt = ut_datefmt_create( $locale_entry , $datetype_entry ,$datetype_entry,$timezone);
+ $formatted = ut_datefmt_format( $fmt , $timestamp_entry);
+ $res_str .= "\nFormatted timestamp is : $formatted";
+ $parsed = ut_datefmt_parse( $fmt , $formatted);
+ if( intl_get_error_code() == U_ZERO_ERROR){
+ $res_str .= "\nParsed timestamp is : $parsed";
+ }else{
+ $res_str .= "\nError while parsing as: '".intl_get_error_message()."'";
+ }
+ }
+ }
+ }
+
+ //Test format and parse with a localtime :array
+ foreach( $localtime_arr as $localtime_entry){
+ $res_str .= "\n------------\n";
+ $res_str .= "\nInput localtime is : ";
+ foreach( $localtime_entry as $key => $value){
+ $res_str .= "$key : '$value' , ";
+ }
+
+ $res_str .= "\n------------\n";
+ foreach( $locale_arr as $locale_entry ){
+ foreach( $datetype_arr as $datetype_entry ) {
+ $res_str .= "\nIntlDateFormatter locale= $locale_entry ,datetype = $datetype_entry ,timetype =$datetype_entry ";
+ $fmt = ut_datefmt_create( $locale_entry , $datetype_entry ,$datetype_entry,$timezone);
+ $formatted1 = ut_datefmt_format( $fmt , $localtime_entry);
+ if( intl_get_error_code() == U_ZERO_ERROR){
+ $res_str .= "\nFormatted localtime_array is : $formatted1";
+ }else{
+ $res_str .= "\nError while formatting as: '".intl_get_error_message()."'";
+ }
+ //Parsing
+ $parsed_arr = ut_datefmt_localtime( $fmt, $formatted1 );
+
+ if( $parsed_arr){
+ $res_str .= "\nParsed array is: ";
+ foreach( $parsed_arr as $key => $value){
+ $res_str .= "$key : '$value' , ";
+ }
+ }
+/*
+ else{
+ //$res_str .= "No values found from LocaleTime parsing.";
+ $res_str .= "\tError : '".intl_get_error_message()."'";
+ }
+*/
+ }
+ }
+ }
+
+ return $res_str;
+
+}
+
+include_once( 'ut_common.inc' );
+
+// Run the test
+ut_run();
+?>
+--EXPECT--
+------------
+
+Input timestamp is : 0
+------------
+
+IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0
+Formatted timestamp is : Thursday, January 1, 1970 at 5:00:00 AM GMT+05:00
+Parsed timestamp is : 0
+IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1
+Formatted timestamp is : January 1, 1970 at 5:00:00 AM GMT+5
+Parsed timestamp is : 0
+IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2
+Formatted timestamp is : Jan 1, 1970, 5:00:00 AM
+Parsed timestamp is : 0
+------------
+
+Input timestamp is : -1200000
+------------
+
+IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0
+Formatted timestamp is : Thursday, December 18, 1969 at 7:40:00 AM GMT+05:00
+Parsed timestamp is : -1200000
+IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1
+Formatted timestamp is : December 18, 1969 at 7:40:00 AM GMT+5
+Parsed timestamp is : -1200000
+IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2
+Formatted timestamp is : Dec 18, 1969, 7:40:00 AM
+Parsed timestamp is : -1200000
+------------
+
+Input timestamp is : 1200000
+------------
+
+IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0
+Formatted timestamp is : Thursday, January 15, 1970 at 2:20:00 AM GMT+05:00
+Parsed timestamp is : 1200000
+IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1
+Formatted timestamp is : January 15, 1970 at 2:20:00 AM GMT+5
+Parsed timestamp is : 1200000
+IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2
+Formatted timestamp is : Jan 15, 1970, 2:20:00 AM
+Parsed timestamp is : 1200000
+------------
+
+Input timestamp is : 2200000000
+------------
+
+IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0
+Formatted timestamp is : Monday, September 19, 2039 at 4:06:40 AM GMT+05:00
+Parsed timestamp is : 2200000000
+IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1
+Formatted timestamp is : September 19, 2039 at 4:06:40 AM GMT+5
+Parsed timestamp is : 2200000000
+IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2
+Formatted timestamp is : Sep 19, 2039, 4:06:40 AM
+Parsed timestamp is : 2200000000
+------------
+
+Input timestamp is : -2200000000
+------------
+
+IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0
+Formatted timestamp is : Sunday, April 15, 1900 at 5:53:20 AM GMT+05:00
+Parsed timestamp is : -2200000000
+IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1
+Formatted timestamp is : April 15, 1900 at 5:53:20 AM GMT+5
+Parsed timestamp is : -2200000000
+IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2
+Formatted timestamp is : Apr 15, 1900, 5:53:20 AM
+Parsed timestamp is : -2200000000
+------------
+
+Input timestamp is : 90099999
+------------
+
+IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0
+Formatted timestamp is : Thursday, November 9, 1972 at 12:46:39 AM GMT+05:00
+Parsed timestamp is : 90099999
+IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1
+Formatted timestamp is : November 9, 1972 at 12:46:39 AM GMT+5
+Parsed timestamp is : 90099999
+IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2
+Formatted timestamp is : Nov 9, 1972, 12:46:39 AM
+Parsed timestamp is : 90099999
+------------
+
+Input timestamp is : 3600
+------------
+
+IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0
+Formatted timestamp is : Thursday, January 1, 1970 at 6:00:00 AM GMT+05:00
+Parsed timestamp is : 3600
+IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1
+Formatted timestamp is : January 1, 1970 at 6:00:00 AM GMT+5
+Parsed timestamp is : 3600
+IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2
+Formatted timestamp is : Jan 1, 1970, 6:00:00 AM
+Parsed timestamp is : 3600
+------------
+
+Input timestamp is : -3600
+------------
+
+IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0
+Formatted timestamp is : Thursday, January 1, 1970 at 4:00:00 AM GMT+05:00
+Parsed timestamp is : -3600
+IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1
+Formatted timestamp is : January 1, 1970 at 4:00:00 AM GMT+5
+Parsed timestamp is : -3600
+IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2
+Formatted timestamp is : Jan 1, 1970, 4:00:00 AM
+Parsed timestamp is : -3600
+------------
+
+Input localtime is : tm_sec : '24' , tm_min : '3' , tm_hour : '19' , tm_mday : '3' , tm_mon : '3' , tm_year : '105' ,
+------------
+
+IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0
+Formatted localtime_array is : Sunday, April 3, 2005 at 7:03:24 PM GMT+05:00
+Parsed array is: tm_sec : '24' , tm_min : '3' , tm_hour : '19' , tm_year : '105' , tm_mday : '3' , tm_wday : '0' , tm_yday : '93' , tm_mon : '3' , tm_isdst : '0' ,
+IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1
+Formatted localtime_array is : April 3, 2005 at 7:03:24 PM GMT+5
+Parsed array is: tm_sec : '24' , tm_min : '3' , tm_hour : '19' , tm_year : '105' , tm_mday : '3' , tm_wday : '0' , tm_yday : '93' , tm_mon : '3' , tm_isdst : '0' ,
+IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2
+Formatted localtime_array is : Apr 3, 2005, 7:03:24 PM
+Parsed array is: tm_sec : '24' , tm_min : '3' , tm_hour : '19' , tm_year : '105' , tm_mday : '3' , tm_wday : '0' , tm_yday : '93' , tm_mon : '3' , tm_isdst : '0' ,
+------------
+
+Input localtime is : tm_sec : '21' , tm_min : '5' , tm_hour : '7' , tm_mday : '13' , tm_mon : '7' , tm_year : '205' ,
+------------
+
+IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0
+Formatted localtime_array is : Thursday, August 13, 2105 at 7:05:21 AM GMT+05:00
+Parsed array is: tm_sec : '21' , tm_min : '5' , tm_hour : '7' , tm_year : '205' , tm_mday : '13' , tm_wday : '4' , tm_yday : '225' , tm_mon : '7' , tm_isdst : '0' ,
+IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1
+Formatted localtime_array is : August 13, 2105 at 7:05:21 AM GMT+5
+Parsed array is: tm_sec : '21' , tm_min : '5' , tm_hour : '7' , tm_year : '205' , tm_mday : '13' , tm_wday : '4' , tm_yday : '225' , tm_mon : '7' , tm_isdst : '0' ,
+IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2
+Formatted localtime_array is : Aug 13, 2105, 7:05:21 AM
+Parsed array is: tm_sec : '21' , tm_min : '5' , tm_hour : '7' , tm_year : '205' , tm_mday : '13' , tm_wday : '4' , tm_yday : '225' , tm_mon : '7' , tm_isdst : '0' ,
+------------
+
+Input localtime is : tm_sec : '11' , tm_min : '13' , tm_hour : '0' , tm_mday : '17' , tm_mon : '11' , tm_year : '-5' ,
+------------
+
+IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0
+Formatted localtime_array is : Tuesday, December 17, 1895 at 12:13:11 AM GMT+05:00
+Parsed array is: tm_sec : '11' , tm_min : '13' , tm_hour : '0' , tm_year : '-5' , tm_mday : '17' , tm_wday : '2' , tm_yday : '351' , tm_mon : '11' , tm_isdst : '0' ,
+IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1
+Formatted localtime_array is : December 17, 1895 at 12:13:11 AM GMT+5
+Parsed array is: tm_sec : '11' , tm_min : '13' , tm_hour : '0' , tm_year : '-5' , tm_mday : '17' , tm_wday : '2' , tm_yday : '351' , tm_mon : '11' , tm_isdst : '0' ,
+IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2
+Formatted localtime_array is : Dec 17, 1895, 12:13:11 AM
+Parsed array is: tm_sec : '11' , tm_min : '13' , tm_hour : '0' , tm_year : '-5' , tm_mday : '17' , tm_wday : '2' , tm_yday : '351' , tm_mon : '11' , tm_isdst : '0' ,
diff --git a/ext/intl/tests/dateformat_format_variant2.phpt b/ext/intl/tests/dateformat_format_variant2.phpt
new file mode 100644
index 0000000000..7c5bcfcfd4
--- /dev/null
+++ b/ext/intl/tests/dateformat_format_variant2.phpt
@@ -0,0 +1,423 @@
+--TEST--
+datefmt_format_code()
+--SKIPIF--
+<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') < 0) die('skip for ICU >= 51.2'); ?>
+--FILE--
+<?php
+
+//ini_set("intl.error_level", E_WARNING);
+
+/*
+ * Test for the datefmt_format function
+ */
+
+
+function ut_main()
+{
+ $timezone = 'GMT-10:00';
+
+ $locale_arr = array (
+ 'en_US'
+ );
+
+ $datetype_arr = array (
+ IntlDateFormatter::FULL,
+ IntlDateFormatter::LONG,
+ IntlDateFormatter::MEDIUM,
+ IntlDateFormatter::SHORT,
+ IntlDateFormatter::NONE
+ );
+
+ $res_str = '';
+
+
+ $time_arr = array (
+ 0,
+ -1200000,
+ 1200000,
+ 2200000000.0,
+ -2200000000.0,
+ 90099999,
+ 3600,
+ -3600
+ );
+
+ $localtime_arr1 = array (
+ 'tm_sec' => 24 ,
+ 'tm_min' => 3,
+ 'tm_hour' => 19,
+ 'tm_mday' => 3,
+ 'tm_mon' => 3,
+ 'tm_year' => 105,
+ );
+ $localtime_arr2 = array (
+ 'tm_sec' => 21,
+ 'tm_min' => 5,
+ 'tm_hour' => 7,
+ 'tm_mday' => 13,
+ 'tm_mon' => 4,
+ 'tm_year' => 205,
+ );
+ $localtime_arr3 = array (
+ 'tm_sec' => 11,
+ 'tm_min' => 13,
+ 'tm_hour' => 0,
+ 'tm_mday' => 17,
+ 'tm_mon' => 11,
+ 'tm_year' => -5
+ );
+
+ $localtime_arr = array (
+ $localtime_arr1,
+ $localtime_arr2,
+ $localtime_arr3
+ );
+
+ $d1 = new DateTime("2010-01-01 01:02:03", new DateTimeZone("UTC"));
+ $d2 = new DateTime("2000-12-31 03:04:05", new DateTimeZone("UTC"));
+ $d2->setTimezone(new DateTimeZone("PDT"));
+ $dates = array(
+ $d1,
+ $d2,
+ new StdClass(),
+ );
+
+ //Test format with input as a timestamp : integer
+ foreach( $time_arr as $timestamp_entry){
+ $res_str .= "\n------------\n";
+ $res_str .= "\nInput timestamp is : $timestamp_entry";
+ $res_str .= "\n------------\n";
+ foreach( $locale_arr as $locale_entry ){
+ foreach( $datetype_arr as $datetype_entry )
+ {
+ $res_str .= "\nIntlDateFormatter locale= $locale_entry ,datetype = $datetype_entry ,timetype =$datetype_entry ";
+ $fmt = ut_datefmt_create( $locale_entry , $datetype_entry ,$datetype_entry, $timezone, IntlDateFormatter::GREGORIAN);
+ $formatted = ut_datefmt_format( $fmt , $timestamp_entry);
+ $res_str .= "\nFormatted timestamp is : $formatted";
+ }
+ }
+ }
+
+ //Test format with input as a localtime :array
+ foreach( $localtime_arr as $localtime_entry){
+ $res_str .= "\n------------\n";
+ $res_str .= "\nInput localtime is : ";
+ foreach( $localtime_entry as $key => $value){
+ $res_str .= "$key : '$value' , ";
+ }
+
+ $res_str .= "\n------------\n";
+ foreach( $locale_arr as $locale_entry ){
+ foreach( $datetype_arr as $datetype_entry )
+ {
+ $res_str .= "\nIntlDateFormatter locale= $locale_entry ,datetype = $datetype_entry ,timetype =$datetype_entry ";
+ $fmt = ut_datefmt_create( $locale_entry , $datetype_entry ,$datetype_entry, $timezone, IntlDateFormatter::GREGORIAN );
+ $formatted1 = ut_datefmt_format( $fmt , $localtime_entry);
+ if( intl_get_error_code() == U_ZERO_ERROR){
+ $res_str .= "\nFormatted localtime_array is : $formatted1";
+ }else{
+ $res_str .= "\nError while formatting as: '".intl_get_error_message()."'";
+ }
+ }
+ }
+ }
+
+ foreach($dates as $date_entry) {
+ foreach( $locale_arr as $locale_entry ){
+ foreach( $datetype_arr as $datetype_entry ) {
+ $res_str .= "\n------------";
+ $res_str .= "\nDate is: ".var_export($date_entry, true);
+ $res_str .= "\n------------";
+
+ $fmt = ut_datefmt_create( $locale_entry , $datetype_entry ,$datetype_entry, $timezone, IntlDateFormatter::GREGORIAN );
+ $formatted1 = ut_datefmt_format( $fmt , $date_entry);
+ if( intl_get_error_code() == U_ZERO_ERROR){
+ $res_str .= "\nFormatted DateTime is : $formatted1";
+ }else{
+ $res_str .= "\nError while formatting as: '".intl_get_error_message()."'";
+ }
+ }
+ }
+ }
+
+ return $res_str;
+
+}
+
+include_once( 'ut_common.inc' );
+
+// Run the test
+ut_run();
+?>
+--EXPECT--
+------------
+
+Input timestamp is : 0
+------------
+
+IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0
+Formatted timestamp is : Wednesday, December 31, 1969 at 2:00:00 PM GMT-10:00
+IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1
+Formatted timestamp is : December 31, 1969 at 2:00:00 PM GMT-10
+IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2
+Formatted timestamp is : Dec 31, 1969, 2:00:00 PM
+IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3
+Formatted timestamp is : 12/31/69, 2:00 PM
+IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1
+Formatted timestamp is : 19691231 02:00 PM
+------------
+
+Input timestamp is : -1200000
+------------
+
+IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0
+Formatted timestamp is : Wednesday, December 17, 1969 at 4:40:00 PM GMT-10:00
+IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1
+Formatted timestamp is : December 17, 1969 at 4:40:00 PM GMT-10
+IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2
+Formatted timestamp is : Dec 17, 1969, 4:40:00 PM
+IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3
+Formatted timestamp is : 12/17/69, 4:40 PM
+IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1
+Formatted timestamp is : 19691217 04:40 PM
+------------
+
+Input timestamp is : 1200000
+------------
+
+IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0
+Formatted timestamp is : Wednesday, January 14, 1970 at 11:20:00 AM GMT-10:00
+IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1
+Formatted timestamp is : January 14, 1970 at 11:20:00 AM GMT-10
+IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2
+Formatted timestamp is : Jan 14, 1970, 11:20:00 AM
+IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3
+Formatted timestamp is : 1/14/70, 11:20 AM
+IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1
+Formatted timestamp is : 19700114 11:20 AM
+------------
+
+Input timestamp is : 2200000000
+------------
+
+IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0
+Formatted timestamp is : Sunday, September 18, 2039 at 1:06:40 PM GMT-10:00
+IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1
+Formatted timestamp is : September 18, 2039 at 1:06:40 PM GMT-10
+IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2
+Formatted timestamp is : Sep 18, 2039, 1:06:40 PM
+IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3
+Formatted timestamp is : 9/18/39, 1:06 PM
+IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1
+Formatted timestamp is : 20390918 01:06 PM
+------------
+
+Input timestamp is : -2200000000
+------------
+
+IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0
+Formatted timestamp is : Saturday, April 14, 1900 at 2:53:20 PM GMT-10:00
+IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1
+Formatted timestamp is : April 14, 1900 at 2:53:20 PM GMT-10
+IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2
+Formatted timestamp is : Apr 14, 1900, 2:53:20 PM
+IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3
+Formatted timestamp is : 4/14/00, 2:53 PM
+IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1
+Formatted timestamp is : 19000414 02:53 PM
+------------
+
+Input timestamp is : 90099999
+------------
+
+IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0
+Formatted timestamp is : Wednesday, November 8, 1972 at 9:46:39 AM GMT-10:00
+IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1
+Formatted timestamp is : November 8, 1972 at 9:46:39 AM GMT-10
+IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2
+Formatted timestamp is : Nov 8, 1972, 9:46:39 AM
+IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3
+Formatted timestamp is : 11/8/72, 9:46 AM
+IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1
+Formatted timestamp is : 19721108 09:46 AM
+------------
+
+Input timestamp is : 3600
+------------
+
+IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0
+Formatted timestamp is : Wednesday, December 31, 1969 at 3:00:00 PM GMT-10:00
+IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1
+Formatted timestamp is : December 31, 1969 at 3:00:00 PM GMT-10
+IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2
+Formatted timestamp is : Dec 31, 1969, 3:00:00 PM
+IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3
+Formatted timestamp is : 12/31/69, 3:00 PM
+IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1
+Formatted timestamp is : 19691231 03:00 PM
+------------
+
+Input timestamp is : -3600
+------------
+
+IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0
+Formatted timestamp is : Wednesday, December 31, 1969 at 1:00:00 PM GMT-10:00
+IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1
+Formatted timestamp is : December 31, 1969 at 1:00:00 PM GMT-10
+IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2
+Formatted timestamp is : Dec 31, 1969, 1:00:00 PM
+IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3
+Formatted timestamp is : 12/31/69, 1:00 PM
+IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1
+Formatted timestamp is : 19691231 01:00 PM
+------------
+
+Input localtime is : tm_sec : '24' , tm_min : '3' , tm_hour : '19' , tm_mday : '3' , tm_mon : '3' , tm_year : '105' ,
+------------
+
+IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0
+Formatted localtime_array is : Sunday, April 3, 2005 at 7:03:24 PM GMT-10:00
+IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1
+Formatted localtime_array is : April 3, 2005 at 7:03:24 PM GMT-10
+IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2
+Formatted localtime_array is : Apr 3, 2005, 7:03:24 PM
+IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3
+Formatted localtime_array is : 4/3/05, 7:03 PM
+IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1
+Formatted localtime_array is : 20050403 07:03 PM
+------------
+
+Input localtime is : tm_sec : '21' , tm_min : '5' , tm_hour : '7' , tm_mday : '13' , tm_mon : '4' , tm_year : '205' ,
+------------
+
+IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0
+Formatted localtime_array is : Wednesday, May 13, 2105 at 7:05:21 AM GMT-10:00
+IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1
+Formatted localtime_array is : May 13, 2105 at 7:05:21 AM GMT-10
+IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2
+Formatted localtime_array is : May 13, 2105, 7:05:21 AM
+IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3
+Formatted localtime_array is : 5/13/05, 7:05 AM
+IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1
+Formatted localtime_array is : 21050513 07:05 AM
+------------
+
+Input localtime is : tm_sec : '11' , tm_min : '13' , tm_hour : '0' , tm_mday : '17' , tm_mon : '11' , tm_year : '-5' ,
+------------
+
+IntlDateFormatter locale= en_US ,datetype = 0 ,timetype =0
+Formatted localtime_array is : Tuesday, December 17, 1895 at 12:13:11 AM GMT-10:00
+IntlDateFormatter locale= en_US ,datetype = 1 ,timetype =1
+Formatted localtime_array is : December 17, 1895 at 12:13:11 AM GMT-10
+IntlDateFormatter locale= en_US ,datetype = 2 ,timetype =2
+Formatted localtime_array is : Dec 17, 1895, 12:13:11 AM
+IntlDateFormatter locale= en_US ,datetype = 3 ,timetype =3
+Formatted localtime_array is : 12/17/95, 12:13 AM
+IntlDateFormatter locale= en_US ,datetype = -1 ,timetype =-1
+Formatted localtime_array is : 18951217 12:13 AM
+------------
+Date is: DateTime::__set_state(array(
+ 'date' => '2010-01-01 01:02:03',
+ 'timezone_type' => 3,
+ 'timezone' => 'UTC',
+))
+------------
+Formatted DateTime is : Thursday, December 31, 2009 at 3:02:03 PM GMT-10:00
+------------
+Date is: DateTime::__set_state(array(
+ 'date' => '2010-01-01 01:02:03',
+ 'timezone_type' => 3,
+ 'timezone' => 'UTC',
+))
+------------
+Formatted DateTime is : December 31, 2009 at 3:02:03 PM GMT-10
+------------
+Date is: DateTime::__set_state(array(
+ 'date' => '2010-01-01 01:02:03',
+ 'timezone_type' => 3,
+ 'timezone' => 'UTC',
+))
+------------
+Formatted DateTime is : Dec 31, 2009, 3:02:03 PM
+------------
+Date is: DateTime::__set_state(array(
+ 'date' => '2010-01-01 01:02:03',
+ 'timezone_type' => 3,
+ 'timezone' => 'UTC',
+))
+------------
+Formatted DateTime is : 12/31/09, 3:02 PM
+------------
+Date is: DateTime::__set_state(array(
+ 'date' => '2010-01-01 01:02:03',
+ 'timezone_type' => 3,
+ 'timezone' => 'UTC',
+))
+------------
+Formatted DateTime is : 20091231 03:02 PM
+------------
+Date is: DateTime::__set_state(array(
+ 'date' => '2000-12-30 19:04:05',
+ 'timezone_type' => 3,
+ 'timezone' => 'America/Los_Angeles',
+))
+------------
+Formatted DateTime is : Saturday, December 30, 2000 at 5:04:05 PM GMT-10:00
+------------
+Date is: DateTime::__set_state(array(
+ 'date' => '2000-12-30 19:04:05',
+ 'timezone_type' => 3,
+ 'timezone' => 'America/Los_Angeles',
+))
+------------
+Formatted DateTime is : December 30, 2000 at 5:04:05 PM GMT-10
+------------
+Date is: DateTime::__set_state(array(
+ 'date' => '2000-12-30 19:04:05',
+ 'timezone_type' => 3,
+ 'timezone' => 'America/Los_Angeles',
+))
+------------
+Formatted DateTime is : Dec 30, 2000, 5:04:05 PM
+------------
+Date is: DateTime::__set_state(array(
+ 'date' => '2000-12-30 19:04:05',
+ 'timezone_type' => 3,
+ 'timezone' => 'America/Los_Angeles',
+))
+------------
+Formatted DateTime is : 12/30/00, 5:04 PM
+------------
+Date is: DateTime::__set_state(array(
+ 'date' => '2000-12-30 19:04:05',
+ 'timezone_type' => 3,
+ 'timezone' => 'America/Los_Angeles',
+))
+------------
+Formatted DateTime is : 20001230 05:04 PM
+------------
+Date is: stdClass::__set_state(array(
+))
+------------
+Error while formatting as: 'datefmt_format: invalid object type for date/time (only IntlCalendar and DateTime permitted): U_ILLEGAL_ARGUMENT_ERROR'
+------------
+Date is: stdClass::__set_state(array(
+))
+------------
+Error while formatting as: 'datefmt_format: invalid object type for date/time (only IntlCalendar and DateTime permitted): U_ILLEGAL_ARGUMENT_ERROR'
+------------
+Date is: stdClass::__set_state(array(
+))
+------------
+Error while formatting as: 'datefmt_format: invalid object type for date/time (only IntlCalendar and DateTime permitted): U_ILLEGAL_ARGUMENT_ERROR'
+------------
+Date is: stdClass::__set_state(array(
+))
+------------
+Error while formatting as: 'datefmt_format: invalid object type for date/time (only IntlCalendar and DateTime permitted): U_ILLEGAL_ARGUMENT_ERROR'
+------------
+Date is: stdClass::__set_state(array(
+))
+------------
+Error while formatting as: 'datefmt_format: invalid object type for date/time (only IntlCalendar and DateTime permitted): U_ILLEGAL_ARGUMENT_ERROR'
diff --git a/ext/intl/tests/dateformat_getCalendarObject_error.phpt b/ext/intl/tests/dateformat_getCalendarObject_error.phpt
new file mode 100644
index 0000000000..d2ad66c829
--- /dev/null
+++ b/ext/intl/tests/dateformat_getCalendarObject_error.phpt
@@ -0,0 +1,43 @@
+--TEST--
+IntlDateFormatter::getCalendarObject(): bad args
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+ini_set("date.timezone", 'Atlantic/Azores');
+
+$df = new IntlDateFormatter(NULL, 0, 0);
+
+var_dump($df->getCalendarObject(9));
+var_dump(datefmt_get_calendar_object($df, 9));
+var_dump(datefmt_get_calendar_object($df, 9));
+var_dump(datefmt_get_calendar_object(new stdclass));
+
+?>
+==DONE==
+--EXPECTF--
+
+Warning: IntlDateFormatter::getCalendarObject() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlDateFormatter::getCalendarObject(): datefmt_get_calendar_object: unable to parse input params in %s on line %d
+bool(false)
+
+Warning: datefmt_get_calendar_object() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: datefmt_get_calendar_object(): datefmt_get_calendar_object: unable to parse input params in %s on line %d
+bool(false)
+
+Warning: datefmt_get_calendar_object() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: datefmt_get_calendar_object(): datefmt_get_calendar_object: unable to parse input params in %s on line %d
+bool(false)
+
+Warning: datefmt_get_calendar_object() expects parameter 1 to be IntlDateFormatter, object given in %s on line %d
+
+Warning: datefmt_get_calendar_object(): datefmt_get_calendar_object: unable to parse input params in %s on line %d
+bool(false)
+==DONE==
diff --git a/ext/intl/tests/dateformat_getTimeZone_error.phpt b/ext/intl/tests/dateformat_getTimeZone_error.phpt
new file mode 100644
index 0000000000..4ac5555d88
--- /dev/null
+++ b/ext/intl/tests/dateformat_getTimeZone_error.phpt
@@ -0,0 +1,43 @@
+--TEST--
+IntlDateFormatter::getTimeZone(): bad args
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+ini_set("date.timezone", 'Atlantic/Azores');
+
+$df = new IntlDateFormatter(NULL, 0, 0);
+
+var_dump($df->getTimeZone(9));
+var_dump(datefmt_get_timezone($df, 9));
+var_dump(datefmt_get_timezone($df, 9));
+var_dump(datefmt_get_timezone(new stdclass));
+
+?>
+==DONE==
+--EXPECTF--
+
+Warning: IntlDateFormatter::getTimeZone() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlDateFormatter::getTimeZone(): datefmt_get_timezone: unable to parse input params in %s on line %d
+bool(false)
+
+Warning: datefmt_get_timezone() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: datefmt_get_timezone(): datefmt_get_timezone: unable to parse input params in %s on line %d
+bool(false)
+
+Warning: datefmt_get_timezone() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: datefmt_get_timezone(): datefmt_get_timezone: unable to parse input params in %s on line %d
+bool(false)
+
+Warning: datefmt_get_timezone() expects parameter 1 to be IntlDateFormatter, object given in %s on line %d
+
+Warning: datefmt_get_timezone(): datefmt_get_timezone: unable to parse input params in %s on line %d
+bool(false)
+==DONE==
diff --git a/ext/intl/tests/dateformat_get_set_calendar.phpt b/ext/intl/tests/dateformat_get_set_calendar.phpt
index bfd4e578e1..f91fe5c775 100644
--- a/ext/intl/tests/dateformat_get_set_calendar.phpt
+++ b/ext/intl/tests/dateformat_get_set_calendar.phpt
@@ -1,60 +1,55 @@
--TEST--
-datefmt_get_calendar_code() datefmt_set_calendar_code()
+IntlDateFormatter: setCalendar()/getCalendar()/getCalendarObject()
--SKIPIF--
-<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+<?php
+if (!extension_loaded('intl')) die('skip intl extension not enabled'); ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') >= 0) die('skip for ICU < 51.2'); ?>
--FILE--
<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+ini_set("date.timezone", 'Atlantic/Azores');
+
+$ts = strtotime('2012-01-01 00:00:00 UTC');
+
+function d(IntlDateFormatter $df) {
+global $ts;
+echo $df->format($ts), "\n";
+var_dump($df->getCalendar(),
+$df->getCalendarObject()->getType(),
+$df->getCalendarObject()->getTimeZone()->getId());
+echo "\n";
+}
-/*
- * Test for the datefmt_get_calendar and datefmt_set_calendar functions
- */
-
-
-function ut_main()
-{
- $calendar_arr = array (
- IntlDateFormatter::GREGORIAN,
- IntlDateFormatter::TRADITIONAL,
- 3
- );
-
- $res_str = '';
-
- $start_calendar = IntlDateFormatter::GREGORIAN;
- $res_str .= "\nCreating IntlDateFormatter with calendar = $start_calendar";
- $fmt = ut_datefmt_create( "de-DE", IntlDateFormatter::SHORT, IntlDateFormatter::SHORT ,'America/Los_Angeles', IntlDateFormatter::GREGORIAN);
- $calendar = ut_datefmt_get_calendar( $fmt);
- $res_str .= "\nAfter call to get_calendar : calendar= $calendar";
- $res_str .= "\n-------------------";
-
- foreach( $calendar_arr as $calendar_entry )
- {
- $res_str .= "\nSetting IntlDateFormatter with calendar = $calendar_entry";
- ut_datefmt_set_calendar( $fmt, $calendar_entry);
- $calendar = ut_datefmt_get_calendar( $fmt);
- $res_str .= "\nAfter call to get_calendar : calendar= $calendar";
- $res_str .= "\n-------------------";
- }
-
- return $res_str;
+$df = new IntlDateFormatter('fr@calendar=islamic', 0, 0, 'Europe/Minsk');
+d($df);
-}
-include_once( 'ut_common.inc' );
+//changing the calendar with a cal type should not change tz
+$df->setCalendar(IntlDateFormatter::TRADITIONAL);
+d($df);
+
+//but changing with an actual calendar should
+$cal = IntlCalendar::createInstance("UTC");
+$df->setCalendar($cal);
+d($df);
-// Run the test
-ut_run();
?>
+==DONE==
--EXPECT--
-Creating IntlDateFormatter with calendar = 1
-After call to get_calendar : calendar= 1
--------------------
-Setting IntlDateFormatter with calendar = 1
-After call to get_calendar : calendar= 1
--------------------
-Setting IntlDateFormatter with calendar = 0
-After call to get_calendar : calendar= 0
--------------------
-Setting IntlDateFormatter with calendar = 3
-After call to get_calendar : calendar= 0
-------------------- \ No newline at end of file
+dimanche 1 janvier 2012 ap. J.-C. 03:00:00 UTC+03:00
+int(1)
+string(9) "gregorian"
+string(12) "Europe/Minsk"
+
+dimanche 8 Safar 1433 AH 03:00:00 UTC+03:00
+int(0)
+string(7) "islamic"
+string(12) "Europe/Minsk"
+
+dimanche 1 janvier 2012 ap. J.-C. 00:00:00 UTC
+bool(false)
+string(9) "gregorian"
+string(3) "UTC"
+
+==DONE==
diff --git a/ext/intl/tests/dateformat_get_set_calendar_variant2.phpt b/ext/intl/tests/dateformat_get_set_calendar_variant2.phpt
new file mode 100644
index 0000000000..1c5169e65d
--- /dev/null
+++ b/ext/intl/tests/dateformat_get_set_calendar_variant2.phpt
@@ -0,0 +1,55 @@
+--TEST--
+IntlDateFormatter: setCalendar()/getCalendar()/getCalendarObject()
+--SKIPIF--
+<?php
+if (!extension_loaded('intl')) die('skip intl extension not enabled'); ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') < 0) die('skip for ICU >= 51.2'); ?>
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+ini_set("date.timezone", 'Atlantic/Azores');
+
+$ts = strtotime('2012-01-01 00:00:00 UTC');
+
+function d(IntlDateFormatter $df) {
+global $ts;
+echo $df->format($ts), "\n";
+var_dump($df->getCalendar(),
+$df->getCalendarObject()->getType(),
+$df->getCalendarObject()->getTimeZone()->getId());
+echo "\n";
+}
+
+$df = new IntlDateFormatter('fr@calendar=islamic', 0, 0, 'Europe/Minsk');
+d($df);
+
+
+//changing the calendar with a cal type should not change tz
+$df->setCalendar(IntlDateFormatter::TRADITIONAL);
+d($df);
+
+//but changing with an actual calendar should
+$cal = IntlCalendar::createInstance("UTC");
+$df->setCalendar($cal);
+d($df);
+
+?>
+==DONE==
+--EXPECT--
+dimanche 1 janvier 2012 ap. J.-C. 03:00:00 UTC+03:00
+int(1)
+string(9) "gregorian"
+string(12) "Europe/Minsk"
+
+dimanche 8 safar 1433 AH 03:00:00 UTC+03:00
+int(0)
+string(7) "islamic"
+string(12) "Europe/Minsk"
+
+dimanche 1 janvier 2012 ap. J.-C. 00:00:00 UTC
+bool(false)
+string(9) "gregorian"
+string(3) "UTC"
+
+==DONE==
diff --git a/ext/intl/tests/dateformat_get_set_timezone.phpt b/ext/intl/tests/dateformat_get_set_timezone.phpt
new file mode 100644
index 0000000000..2a7ffa6c73
--- /dev/null
+++ b/ext/intl/tests/dateformat_get_set_timezone.phpt
@@ -0,0 +1,62 @@
+--TEST--
+IntlDateFormatter: get/setTimeZone()
+--SKIPIF--
+<?php
+if (!extension_loaded('intl')) die('skip intl extension not enabled'); ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') >= 0) die('skip for ICU < 51.2'); ?>
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+ini_set("date.timezone", 'Atlantic/Azores');
+
+$ts = strtotime('2012-01-01 00:00:00 UTC');
+
+function d(IntlDateFormatter $df) {
+global $ts;
+echo $df->format($ts), "\n";
+var_dump(
+$df->getTimeZoneID(),
+$df->getTimeZone()->getID());
+echo "\n";
+}
+
+$df = new IntlDateFormatter('pt_PT', 0, 0, 'Europe/Minsk');
+d($df);
+
+$df->setTimeZone(NULL);
+d($df);
+
+$df->setTimeZone('Europe/Madrid');
+d($df);
+
+$df->setTimeZone(IntlTimeZone::createTimeZone('Europe/Paris'));
+d($df);
+
+$df->setTimeZone(new DateTimeZone('Europe/Amsterdam'));
+d($df);
+
+?>
+==DONE==
+--EXPECTF--
+Domingo, 1 de Janeiro de 2012 3:00:00 GMT+03:00
+string(12) "Europe/Minsk"
+string(12) "Europe/Minsk"
+
+Sábado, 31 de Dezembro de 2011 23:00:00 Hor%s %Sdos Açores
+string(15) "Atlantic/Azores"
+string(15) "Atlantic/Azores"
+
+Domingo, 1 de Janeiro de 2012 1:00:00 Hor%s %Sda Europa Central
+string(13) "Europe/Madrid"
+string(13) "Europe/Madrid"
+
+Domingo, 1 de Janeiro de 2012 1:00:00 Hor%s %Sda Europa Central
+string(12) "Europe/Paris"
+string(12) "Europe/Paris"
+
+Domingo, 1 de Janeiro de 2012 1:00:00 Hor%s %Sda Europa Central
+string(16) "Europe/Amsterdam"
+string(16) "Europe/Amsterdam"
+
+==DONE==
diff --git a/ext/intl/tests/dateformat_get_set_timezone_variant2.phpt b/ext/intl/tests/dateformat_get_set_timezone_variant2.phpt
new file mode 100644
index 0000000000..af9ddf29a4
--- /dev/null
+++ b/ext/intl/tests/dateformat_get_set_timezone_variant2.phpt
@@ -0,0 +1,62 @@
+--TEST--
+IntlDateFormatter: get/setTimeZone()
+--SKIPIF--
+<?php
+if (!extension_loaded('intl')) die('skip intl extension not enabled'); ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') < 0) die('skip for ICU >= 51.2'); ?>
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+ini_set("date.timezone", 'Atlantic/Azores');
+
+$ts = strtotime('2012-01-01 00:00:00 UTC');
+
+function d(IntlDateFormatter $df) {
+global $ts;
+echo $df->format($ts), "\n";
+var_dump(
+$df->getTimeZoneID(),
+$df->getTimeZone()->getID());
+echo "\n";
+}
+
+$df = new IntlDateFormatter('pt_PT', 0, 0, 'Europe/Minsk');
+d($df);
+
+$df->setTimeZone(NULL);
+d($df);
+
+$df->setTimeZone('Europe/Madrid');
+d($df);
+
+$df->setTimeZone(IntlTimeZone::createTimeZone('Europe/Paris'));
+d($df);
+
+$df->setTimeZone(new DateTimeZone('Europe/Amsterdam'));
+d($df);
+
+?>
+==DONE==
+--EXPECTF--
+Domingo, 1 de Janeiro de 2012 às 03:00:00 GMT+03:00
+string(12) "Europe/Minsk"
+string(12) "Europe/Minsk"
+
+Sábado, 31 de Dezembro de 2011 às 23:00:00 Hor%s %Sdos Açores
+string(15) "Atlantic/Azores"
+string(15) "Atlantic/Azores"
+
+Domingo, 1 de Janeiro de 2012 às 01:00:00 Hor%s %Sda Europa Central
+string(13) "Europe/Madrid"
+string(13) "Europe/Madrid"
+
+Domingo, 1 de Janeiro de 2012 às 01:00:00 Hor%s %Sda Europa Central
+string(12) "Europe/Paris"
+string(12) "Europe/Paris"
+
+Domingo, 1 de Janeiro de 2012 às 01:00:00 Hor%s %Sda Europa Central
+string(16) "Europe/Amsterdam"
+string(16) "Europe/Amsterdam"
+
+==DONE==
diff --git a/ext/intl/tests/dateformat_get_timezone_id.phpt b/ext/intl/tests/dateformat_get_timezone_id.phpt
index 80cbdbbf0f..a9701c3868 100644
--- a/ext/intl/tests/dateformat_get_timezone_id.phpt
+++ b/ext/intl/tests/dateformat_get_timezone_id.phpt
@@ -1,5 +1,8 @@
--TEST--
datefmt_get_timezone_id_code()
+--INI--
+date.timezone=Atlantic/Azores
+intl.error_level=E_WARNING
--SKIPIF--
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
--FILE--
@@ -14,8 +17,8 @@ function ut_main()
{
$timezone_id_arr = array (
'America/New_York',
- 'America/Los_Angeles',
- 'America/Dallas'
+ 'US/Pacific',
+ 'US/Central'
);
$res_str = '';
@@ -42,8 +45,8 @@ ut_run();
Creating IntlDateFormatter with timezone_id = America/New_York
After call to get_timezone_id : timezone_id= America/New_York
-Creating IntlDateFormatter with timezone_id = America/Los_Angeles
-After call to get_timezone_id : timezone_id= America/Los_Angeles
+Creating IntlDateFormatter with timezone_id = US/Pacific
+After call to get_timezone_id : timezone_id= US/Pacific
-Creating IntlDateFormatter with timezone_id = America/Dallas
-After call to get_timezone_id : timezone_id= America/Dallas
+Creating IntlDateFormatter with timezone_id = US/Central
+After call to get_timezone_id : timezone_id= US/Central
diff --git a/ext/intl/tests/dateformat_setTimeZoneID_deprecation.phpt b/ext/intl/tests/dateformat_setTimeZoneID_deprecation.phpt
new file mode 100644
index 0000000000..5ee5b94d24
--- /dev/null
+++ b/ext/intl/tests/dateformat_setTimeZoneID_deprecation.phpt
@@ -0,0 +1,22 @@
+--TEST--
+IntlDateFormatter: setTimeZoneID() deprecation
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+ini_set("date.timezone", 'Atlantic/Azores');
+
+$df = new IntlDateFormatter('pt_PT', 0, 0, 'Europe/Minsk');
+
+$df->setTimeZoneId('Europe/Madrid');
+
+?>
+==DONE==
+--EXPECTF--
+
+Deprecated: IntlDateFormatter::setTimeZoneId(): Use datefmt_set_timezone() instead, which also accepts a plain time zone identifier and for which this function is now an alias in %s on line %d
+==DONE==
diff --git a/ext/intl/tests/dateformat_setTimeZone_error.phpt b/ext/intl/tests/dateformat_setTimeZone_error.phpt
new file mode 100644
index 0000000000..bd37031325
--- /dev/null
+++ b/ext/intl/tests/dateformat_setTimeZone_error.phpt
@@ -0,0 +1,53 @@
+--TEST--
+IntlDateFormatter::setTimeZone() bad args
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+ini_set("date.timezone", 'Atlantic/Azores');
+
+$df = new IntlDateFormatter(NULL, 0, 0);
+
+var_dump($df->setTimeZone());
+var_dump(datefmt_set_timezone());
+var_dump($df->setTimeZone(array()));
+var_dump($df->setTimeZone(1, 2));
+var_dump($df->setTimeZone('non existing timezone'));
+var_dump(datefmt_set_timezone(new stdclass, 'UTC'));
+
+?>
+==DONE==
+--EXPECTF--
+
+Warning: IntlDateFormatter::setTimeZone() expects exactly 1 parameter, 0 given in %s on line %d
+
+Warning: IntlDateFormatter::setTimeZone(): datefmt_set_timezone: unable to parse input params in %s on line %d
+bool(false)
+
+Warning: datefmt_set_timezone() expects exactly 2 parameters, 0 given in %s on line %d
+
+Warning: datefmt_set_timezone(): datefmt_set_timezone: unable to parse input params in %s on line %d
+bool(false)
+
+Notice: Array to string conversion in %s on line %d
+
+Warning: IntlDateFormatter::setTimeZone(): datefmt_set_timezone: no such time zone: 'Array' in %s on line %d
+bool(false)
+
+Warning: IntlDateFormatter::setTimeZone() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: IntlDateFormatter::setTimeZone(): datefmt_set_timezone: unable to parse input params in %s on line %d
+bool(false)
+
+Warning: IntlDateFormatter::setTimeZone(): datefmt_set_timezone: no such time zone: 'non existing timezone' in %s on line %d
+bool(false)
+
+Warning: datefmt_set_timezone() expects parameter 1 to be IntlDateFormatter, object given in %s on line %d
+
+Warning: datefmt_set_timezone(): datefmt_set_timezone: unable to parse input params in %s on line %d
+bool(false)
+==DONE==
diff --git a/ext/intl/tests/dateformat_set_timezone_id2.phpt b/ext/intl/tests/dateformat_set_timezone_id2.phpt
index 23aacda90a..a1ee440e71 100644
--- a/ext/intl/tests/dateformat_set_timezone_id2.phpt
+++ b/ext/intl/tests/dateformat_set_timezone_id2.phpt
@@ -1,11 +1,17 @@
--TEST--
datefmt_set_timezone_id_code() icu >= 4.8
+--INI--
+date.timezone=Atlantic/Azores
--SKIPIF--
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
<?php if(version_compare(INTL_ICU_VERSION, '4.8') < 0) print 'skip'; ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') >= 0) die('skip for ICU < 51.2'); ?>
--FILE--
<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("error_reporting", ~E_DEPRECATED);
+
/*
* Test for the datefmt_set_timezone_id function
*/
@@ -23,7 +29,7 @@ function ut_main()
$res_str = '';
- $fmt = ut_datefmt_create( "en_US", IntlDateFormatter::FULL, IntlDateFormatter::FULL, 'America/San_Francisco' , IntlDateFormatter::GREGORIAN );
+ $fmt = ut_datefmt_create( "en_US", IntlDateFormatter::FULL, IntlDateFormatter::FULL, 'US/Pacific' , IntlDateFormatter::GREGORIAN );
$timezone_id = ut_datefmt_get_timezone_id( $fmt );
$res_str .= "\nAfter creation of the dateformatter : timezone_id= $timezone_id\n";
@@ -52,8 +58,13 @@ include_once( 'ut_common.inc' );
// Run the test
ut_run();
?>
---EXPECT--
-After creation of the dateformatter : timezone_id= America/San_Francisco
+--EXPECTF--
+
+Warning: IntlDateFormatter::setTimeZoneId(): datefmt_set_timezone: no such time zone: 'CN' in %s on line %d
+
+Warning: datefmt_set_timezone_id(): datefmt_set_timezone: no such time zone: 'CN' in %s on line %d
+
+After creation of the dateformatter : timezone_id= US/Pacific
-----------
Trying to set timezone_id= America/New_York
After call to set_timezone_id : timezone_id= America/New_York
@@ -71,6 +82,6 @@ Formatting timestamp=0 resulted in Wednesday, December 31, 1969 6:00:00 PM Cent
Formatting timestamp=3600 resulted in Wednesday, December 31, 1969 7:00:00 PM Central Standard Time
-----------
Trying to set timezone_id= CN
-After call to set_timezone_id : timezone_id= CN
-Formatting timestamp=0 resulted in Thursday, January 1, 1970 12:00:00 AM GMT
-Formatting timestamp=3600 resulted in Thursday, January 1, 1970 1:00:00 AM GMT
+After call to set_timezone_id : timezone_id= America/Chicago
+Formatting timestamp=0 resulted in Wednesday, December 31, 1969 6:00:00 PM Central Standard Time
+Formatting timestamp=3600 resulted in Wednesday, December 31, 1969 7:00:00 PM Central Standard Time
diff --git a/ext/intl/tests/dateformat_set_timezone_id3.phpt b/ext/intl/tests/dateformat_set_timezone_id3.phpt
new file mode 100644
index 0000000000..b3968f9ac0
--- /dev/null
+++ b/ext/intl/tests/dateformat_set_timezone_id3.phpt
@@ -0,0 +1,85 @@
+--TEST--
+datefmt_set_timezone_id_code() icu >= 4.8
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') < 0) die('skip for ICU >= 51.2'); ?>
+--FILE--
+<?php
+
+ini_set("intl.error_level", E_WARNING);
+ini_set("error_reporting", ~E_DEPRECATED);
+
+/*
+ * Test for the datefmt_set_timezone_id function
+ */
+
+
+function ut_main()
+{
+ $timezone_id_arr = array (
+ 'America/New_York',
+ 'America/Los_Angeles',
+ 'America/Chicago',
+ 'CN'
+ );
+ $timestamp_entry = 0;
+
+ $res_str = '';
+
+ $fmt = ut_datefmt_create( "en_US", IntlDateFormatter::FULL, IntlDateFormatter::FULL, 'US/Pacific' , IntlDateFormatter::GREGORIAN );
+ $timezone_id = ut_datefmt_get_timezone_id( $fmt );
+ $res_str .= "\nAfter creation of the dateformatter : timezone_id= $timezone_id\n";
+
+ foreach( $timezone_id_arr as $timezone_id_entry )
+ {
+
+ $res_str .= "-----------";
+ $res_str .= "\nTrying to set timezone_id= $timezone_id_entry";
+ ut_datefmt_set_timezone_id( $fmt , $timezone_id_entry );
+ $timezone_id = ut_datefmt_get_timezone_id( $fmt );
+ $res_str .= "\nAfter call to set_timezone_id : timezone_id= $timezone_id";
+ $formatted = ut_datefmt_format( $fmt, 0);
+ $res_str .= "\nFormatting timestamp=0 resulted in $formatted";
+ $formatted = ut_datefmt_format( $fmt, 3600);
+ $res_str .= "\nFormatting timestamp=3600 resulted in $formatted";
+ $res_str .= "\n";
+
+ }
+
+ return $res_str;
+
+}
+
+include_once( 'ut_common.inc' );
+
+// Run the test
+ut_run();
+?>
+--EXPECTF--
+Warning: IntlDateFormatter::setTimeZoneId(): datefmt_set_timezone: no such time zone: 'CN' in %sut_common.inc on line %d
+
+Warning: datefmt_set_timezone_id(): datefmt_set_timezone: no such time zone: 'CN' in %sut_common.inc on line %d
+
+After creation of the dateformatter : timezone_id= US/Pacific
+-----------
+Trying to set timezone_id= America/New_York
+After call to set_timezone_id : timezone_id= America/New_York
+Formatting timestamp=0 resulted in Wednesday, December 31, 1969 at 7:00:00 PM Eastern Standard Time
+Formatting timestamp=3600 resulted in Wednesday, December 31, 1969 at 8:00:00 PM Eastern Standard Time
+-----------
+Trying to set timezone_id= America/Los_Angeles
+After call to set_timezone_id : timezone_id= America/Los_Angeles
+Formatting timestamp=0 resulted in Wednesday, December 31, 1969 at 4:00:00 PM Pacific Standard Time
+Formatting timestamp=3600 resulted in Wednesday, December 31, 1969 at 5:00:00 PM Pacific Standard Time
+-----------
+Trying to set timezone_id= America/Chicago
+After call to set_timezone_id : timezone_id= America/Chicago
+Formatting timestamp=0 resulted in Wednesday, December 31, 1969 at 6:00:00 PM Central Standard Time
+Formatting timestamp=3600 resulted in Wednesday, December 31, 1969 at 7:00:00 PM Central Standard Time
+-----------
+Trying to set timezone_id= CN
+After call to set_timezone_id : timezone_id= America/Chicago
+Formatting timestamp=0 resulted in Wednesday, December 31, 1969 at 6:00:00 PM Central Standard Time
+Formatting timestamp=3600 resulted in Wednesday, December 31, 1969 at 7:00:00 PM Central Standard Time
diff --git a/ext/intl/tests/dateformat_timezone_arg_variations.phpt b/ext/intl/tests/dateformat_timezone_arg_variations.phpt
new file mode 100644
index 0000000000..9fbb145c72
--- /dev/null
+++ b/ext/intl/tests/dateformat_timezone_arg_variations.phpt
@@ -0,0 +1,45 @@
+--TEST--
+IntlDateFormatter: several forms of the timezone arg
+--SKIPIF--
+<?php
+if (!extension_loaded('intl')) die('skip intl extension not enabled'); ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') >= 0) die('skip for ICU < 51.2'); ?>
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("date.timezone", 'Atlantic/Azores');
+
+$ts = strtotime('2012-01-01 00:00:00 UTC');
+
+//should use Atlantic/Azores
+$df = new IntlDateFormatter('es_ES', 0, 0, NULL);
+echo $df->format($ts), "\n";
+
+$df = new IntlDateFormatter('es_ES', 0, 0, 'Europe/Amsterdam');
+echo $df->format($ts), "\n";
+
+$df = new IntlDateFormatter('es_ES', 0, 0, new DateTimeZone('Europe/Lisbon'));
+echo $df->format($ts), "\n";
+
+$df = new IntlDateFormatter('es_ES', 0, 0, IntlTimeZone::createTimeZone('America/New_York'));
+echo $df->format($ts), "\n";
+
+//time zone has priority
+$df = new IntlDateFormatter('es_ES', 0, 0, 'Europe/Amsterdam', new IntlGregorianCalendar('Europe/Lisbon'));
+echo $df->format($ts), "\n";
+
+//calendar has priority
+$df = new IntlDateFormatter('es_ES', 0, 0, NULL, new IntlGregorianCalendar('Europe/Lisbon'));
+echo $df->format($ts), "\n";
+
+$df = new IntlDateFormatter('es_ES', 0, 0, 'Europe/Amsterdam', 0);
+echo $df->format($ts), "\n";
+
+--EXPECTF--
+sábado%S 31 de diciembre de 2011 23:00:00 Hora%S de las Azores
+domingo%S 1 de enero de 2012 01:00:00 Hora estándar de Europa Central
+domingo%S 1 de enero de 2012 00:00:00 Hora%S de Europa Occidental
+sábado%S 31 de diciembre de 2011 19:00:00 Hora estándar oriental
+domingo%S 1 de enero de 2012 01:00:00 Hora estándar de Europa Central
+domingo%S 1 de enero de 2012 00:00:00 Hora%S de Europa Occidental
+domingo%S 1 de enero de 2012 01:00:00 Hora estándar de Europa Central
diff --git a/ext/intl/tests/dateformat_timezone_arg_variations2.phpt b/ext/intl/tests/dateformat_timezone_arg_variations2.phpt
new file mode 100644
index 0000000000..a957963a44
--- /dev/null
+++ b/ext/intl/tests/dateformat_timezone_arg_variations2.phpt
@@ -0,0 +1,45 @@
+--TEST--
+IntlDateFormatter: several forms of the timezone arg
+--SKIPIF--
+<?php
+if (!extension_loaded('intl')) die('skip intl extension not enabled'); ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') < 0) die('skip for ICU >= 51.2'); ?>
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("date.timezone", 'Atlantic/Azores');
+
+$ts = strtotime('2012-01-01 00:00:00 UTC');
+
+//should use Atlantic/Azores
+$df = new IntlDateFormatter('es_ES', 0, 0, NULL);
+echo $df->format($ts), "\n";
+
+$df = new IntlDateFormatter('es_ES', 0, 0, 'Europe/Amsterdam');
+echo $df->format($ts), "\n";
+
+$df = new IntlDateFormatter('es_ES', 0, 0, new DateTimeZone('Europe/Lisbon'));
+echo $df->format($ts), "\n";
+
+$df = new IntlDateFormatter('es_ES', 0, 0, IntlTimeZone::createTimeZone('America/New_York'));
+echo $df->format($ts), "\n";
+
+//time zone has priority
+$df = new IntlDateFormatter('es_ES', 0, 0, 'Europe/Amsterdam', new IntlGregorianCalendar('Europe/Lisbon'));
+echo $df->format($ts), "\n";
+
+//calendar has priority
+$df = new IntlDateFormatter('es_ES', 0, 0, NULL, new IntlGregorianCalendar('Europe/Lisbon'));
+echo $df->format($ts), "\n";
+
+$df = new IntlDateFormatter('es_ES', 0, 0, 'Europe/Amsterdam', 0);
+echo $df->format($ts), "\n";
+
+--EXPECTF--
+sábado%S, 31 de diciembre de 2011 23:00:00 Hora estándar de las Azores
+domingo%S, 1 de enero de 2012 01:00:00 Hora estándar de Europa central
+domingo%S, 1 de enero de 2012 00:00:00 Hora%S de Europa occidental
+sábado%S, 31 de diciembre de 2011 19:00:00 Hora estándar oriental
+domingo%S, 1 de enero de 2012 01:00:00 Hora estándar de Europa central
+domingo%S, 1 de enero de 2012 00:00:00 Hora%S de Europa occidental
+domingo%S, 1 de enero de 2012 01:00:00 Hora estándar de Europa central
diff --git a/ext/intl/tests/formatter_get_locale.phpt b/ext/intl/tests/formatter_get_locale.phpt
index 3d4fb2ae4e..7474eabbba 100644
--- a/ext/intl/tests/formatter_get_locale.phpt
+++ b/ext/intl/tests/formatter_get_locale.phpt
@@ -2,6 +2,7 @@
numfmt_get_locale()
--SKIPIF--
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') >= 0) die('skip for ICU < 51.2'); ?>
--FILE--
<?php
diff --git a/ext/intl/tests/formatter_get_locale_variant2.phpt b/ext/intl/tests/formatter_get_locale_variant2.phpt
new file mode 100644
index 0000000000..9d25d1cf90
--- /dev/null
+++ b/ext/intl/tests/formatter_get_locale_variant2.phpt
@@ -0,0 +1,50 @@
+--TEST--
+numfmt_get_locale()
+--SKIPIF--
+<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') < 0) die('skip for ICU >= 51.2'); ?>
+--FILE--
+<?php
+
+/*
+ * Get locale.
+ */
+
+function ut_main()
+{
+ $locales = array(
+ 'en_UK',
+ 'en_US@California',
+ 'fr_CA',
+ );
+
+ $loc_types = array(
+ Locale::ACTUAL_LOCALE => 'actual',
+ Locale::VALID_LOCALE => 'valid',
+ );
+
+ $res_str = '';
+
+ foreach( $locales as $locale )
+ {
+ $fmt = ut_nfmt_create( $locale, NumberFormatter::DECIMAL );
+ $res_str .= "$locale: ";
+ foreach( $loc_types as $loc_type => $loc_type_name )
+ $res_str .= sprintf( " %s=%s",
+ $loc_type_name,
+ dump( ut_nfmt_get_locale( $fmt, $loc_type ) ) );
+ $res_str .= "\n";
+ }
+
+ return $res_str;
+}
+
+include_once( 'ut_common.inc' );
+
+// Run the test
+ut_run();
+?>
+--EXPECT--
+en_UK: actual='en' valid='en'
+en_US@California: actual='en' valid='en'
+fr_CA: actual='fr' valid='fr_CA'
diff --git a/ext/intl/tests/gregoriancalendar___construct_basic.phpt b/ext/intl/tests/gregoriancalendar___construct_basic.phpt
new file mode 100644
index 0000000000..bdbef6725b
--- /dev/null
+++ b/ext/intl/tests/gregoriancalendar___construct_basic.phpt
@@ -0,0 +1,51 @@
+--TEST--
+IntlGregorianCalendar::__construct(): basic
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '4.8') < 0)
+ die('skip for ICU 4.8+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+date_default_timezone_set('Europe/Amsterdam');
+
+$intlcal = intlgregcal_create_instance();
+var_dump($intlcal->getTimeZone()->getId());
+var_dump($intlcal->getLocale(1));
+
+$intlcal = new IntlGregorianCalendar('Europe/Lisbon', NULL);
+var_dump($intlcal->getTimeZone()->getId());
+var_dump($intlcal->getLocale(1));
+
+$intlcal = new IntlGregorianCalendar(NULL, 'pt_PT');
+var_dump($intlcal->getTimeZone()->getId());
+var_dump($intlcal->getLocale(1));
+
+$intlcal = new IntlGregorianCalendar('Europe/Lisbon', 'pt_PT');
+var_dump($intlcal->getTimeZone()->getId());
+var_dump($intlcal->getLocale(1));
+
+$intlcal = new IntlGregorianCalendar('Europe/Paris', 'fr_CA', NULL, NULL, NULL, NULL);
+var_dump($intlcal->getTimeZone()->getId());
+var_dump($intlcal->getLocale(1));
+
+var_dump($intlcal->getType());
+?>
+==DONE==
+--EXPECT--
+string(16) "Europe/Amsterdam"
+string(5) "nl_NL"
+string(13) "Europe/Lisbon"
+string(5) "nl_NL"
+string(16) "Europe/Amsterdam"
+string(5) "pt_PT"
+string(13) "Europe/Lisbon"
+string(5) "pt_PT"
+string(12) "Europe/Paris"
+string(5) "fr_CA"
+string(9) "gregorian"
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/gregoriancalendar___construct_error.phpt b/ext/intl/tests/gregoriancalendar___construct_error.phpt
new file mode 100644
index 0000000000..0e85394a48
--- /dev/null
+++ b/ext/intl/tests/gregoriancalendar___construct_error.phpt
@@ -0,0 +1,35 @@
+--TEST--
+IntlGregorianCalendar::__construct(): bad arguments
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+var_dump(intlgregcal_create_instance(1,2,3,4,5,6,7));
+var_dump(intlgregcal_create_instance(1,2,3,4,5,6,7,8));
+var_dump(intlgregcal_create_instance(1,2,3,4));
+var_dump(new IntlGregorianCalendar(1,2,NULL,4));
+var_dump(new IntlGregorianCalendar(1,2,3,4,NULL,array()));
+
+
+--EXPECTF--
+
+Warning: intlgregcal_create_instance(): intlgregcal_create_instance: too many arguments in %s on line %d
+NULL
+
+Warning: intlgregcal_create_instance(): intlgregcal_create_instance: too many arguments in %s on line %d
+NULL
+
+Warning: intlgregcal_create_instance(): intlgregcal_create_instance: no variant with 4 arguments (excluding trailing NULLs) in %s on line %d
+NULL
+
+Warning: IntlGregorianCalendar::__construct(): intlgregcal_create_instance: no variant with 4 arguments (excluding trailing NULLs) in %s on line %d
+NULL
+
+Warning: IntlGregorianCalendar::__construct() expects parameter 6 to be long, array given in %s on line %d
+
+Warning: IntlGregorianCalendar::__construct(): intlgregcal_create_instance: bad arguments in %s on line %d
+NULL
diff --git a/ext/intl/tests/gregoriancalendar___construct_variant1.phpt b/ext/intl/tests/gregoriancalendar___construct_variant1.phpt
new file mode 100644
index 0000000000..63266b792e
--- /dev/null
+++ b/ext/intl/tests/gregoriancalendar___construct_variant1.phpt
@@ -0,0 +1,30 @@
+--TEST--
+IntlGregorianCalendar::__construct(): argument variants
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+date_default_timezone_set('Europe/Amsterdam');
+
+$intlcal = intlgregcal_create_instance(2012, 1, 29, 16, 0, NULL);
+var_dump($intlcal->getTimeZone()->getId());
+var_dump($intlcal->getTime(), (float)strtotime('2012-02-29 16:00:00') * 1000);
+
+$intlcal = new IntlGregorianCalendar(2012, 1, 29, 16, 7, 8);
+var_dump($intlcal->getTime(), (float)strtotime('2012-02-29 16:07:08') * 1000);
+
+var_dump($intlcal->getType());
+?>
+==DONE==
+--EXPECT--
+string(16) "Europe/Amsterdam"
+float(1330527600000)
+float(1330527600000)
+float(1330528028000)
+float(1330528028000)
+string(9) "gregorian"
+==DONE==
diff --git a/ext/intl/tests/gregoriancalendar_getGregorianChange_error.phpt b/ext/intl/tests/gregoriancalendar_getGregorianChange_error.phpt
new file mode 100644
index 0000000000..58d566223b
--- /dev/null
+++ b/ext/intl/tests/gregoriancalendar_getGregorianChange_error.phpt
@@ -0,0 +1,30 @@
+--TEST--
+IntlGregorianCalendar::getGregorianChange(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+var_dump($c->getGregorianChange(1));
+
+var_dump(intlgregcal_get_gregorian_change($c, 1));
+var_dump(intlgregcal_get_gregorian_change(1));
+--EXPECTF--
+
+Warning: IntlGregorianCalendar::getGregorianChange() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlGregorianCalendar::getGregorianChange(): intlgregcal_get_gregorian_change: bad arguments in %s on line %d
+bool(false)
+
+Warning: intlgregcal_get_gregorian_change() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: intlgregcal_get_gregorian_change(): intlgregcal_get_gregorian_change: bad arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intlgregcal_get_gregorian_change() must be an instance of IntlGregorianCalendar, integer given in %s on line %d
diff --git a/ext/intl/tests/gregoriancalendar_get_setGregorianChange_basic.phpt b/ext/intl/tests/gregoriancalendar_get_setGregorianChange_basic.phpt
new file mode 100644
index 0000000000..b08ad7981f
--- /dev/null
+++ b/ext/intl/tests/gregoriancalendar_get_setGregorianChange_basic.phpt
@@ -0,0 +1,32 @@
+--TEST--
+IntlGregorianCalendar::get/setGregorianChange(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+date_default_timezone_set('Europe/Amsterdam');
+
+$intlcal = new IntlGregorianCalendar();
+
+var_dump($intlcal->getGregorianChange());
+
+var_dump($intlcal->setGregorianChange(0));
+var_dump(intlgregcal_get_gregorian_change($intlcal));
+
+var_dump(intlgregcal_set_gregorian_change($intlcal, 1));
+var_dump($intlcal->getGregorianChange());
+
+?>
+==DONE==
+--EXPECT--
+float(-12219292800000)
+bool(true)
+float(0)
+bool(true)
+float(1)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/gregoriancalendar_isLeapYear_basic.phpt b/ext/intl/tests/gregoriancalendar_isLeapYear_basic.phpt
new file mode 100644
index 0000000000..b37452fcba
--- /dev/null
+++ b/ext/intl/tests/gregoriancalendar_isLeapYear_basic.phpt
@@ -0,0 +1,28 @@
+--TEST--
+IntlGregorianCalendar::isLeapYear(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+date_default_timezone_set('Europe/Amsterdam');
+
+$intlcal = new IntlGregorianCalendar();
+
+var_dump($intlcal->isLeapYear(2012));
+var_dump($intlcal->isLeapYear(1900));
+
+var_dump(intlgregcal_is_leap_year($intlcal, 2012));
+var_dump(intlgregcal_is_leap_year($intlcal, 1900));
+?>
+==DONE==
+--EXPECT--
+bool(true)
+bool(false)
+bool(true)
+bool(false)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/gregoriancalendar_isLeapYear_error.phpt b/ext/intl/tests/gregoriancalendar_isLeapYear_error.phpt
new file mode 100644
index 0000000000..40a6c85396
--- /dev/null
+++ b/ext/intl/tests/gregoriancalendar_isLeapYear_error.phpt
@@ -0,0 +1,48 @@
+--TEST--
+IntlGregorianCalendar::isLeapYear(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+var_dump($c->isLeapYear(2000, 2011));
+var_dump($c->isLeapYear());
+var_dump($c->isLeapYear("fgdf"));
+
+var_dump(intlgregcal_is_leap_year($c, 1, 2));
+var_dump(intlgregcal_is_leap_year($c));
+var_dump(intlgregcal_is_leap_year(1, 2));
+--EXPECTF--
+
+Warning: IntlGregorianCalendar::isLeapYear() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: IntlGregorianCalendar::isLeapYear(): intlgregcal_is_leap_year: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlGregorianCalendar::isLeapYear() expects exactly 1 parameter, 0 given in %s on line %d
+
+Warning: IntlGregorianCalendar::isLeapYear(): intlgregcal_is_leap_year: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlGregorianCalendar::isLeapYear() expects parameter 1 to be long, string given in %s on line %d
+
+Warning: IntlGregorianCalendar::isLeapYear(): intlgregcal_is_leap_year: bad arguments in %s on line %d
+bool(false)
+
+Warning: intlgregcal_is_leap_year() expects exactly 2 parameters, 3 given in %s on line %d
+
+Warning: intlgregcal_is_leap_year(): intlgregcal_is_leap_year: bad arguments in %s on line %d
+bool(false)
+
+Warning: intlgregcal_is_leap_year() expects exactly 2 parameters, 1 given in %s on line %d
+
+Warning: intlgregcal_is_leap_year(): intlgregcal_is_leap_year: bad arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intlgregcal_is_leap_year() must be an instance of IntlGregorianCalendar, integer given in %s on line %d
diff --git a/ext/intl/tests/gregoriancalendar_setGregorianChange_error.phpt b/ext/intl/tests/gregoriancalendar_setGregorianChange_error.phpt
new file mode 100644
index 0000000000..eac8deb61b
--- /dev/null
+++ b/ext/intl/tests/gregoriancalendar_setGregorianChange_error.phpt
@@ -0,0 +1,42 @@
+--TEST--
+IntlGregorianCalendar::setGregorianChange(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar();
+var_dump($c->setGregorianChange());
+var_dump($c->setGregorianChange(1, 2));
+var_dump($c->setGregorianChange("sdfds"));
+
+var_dump(intlgregcal_set_gregorian_change($c));
+var_dump(intlgregcal_set_gregorian_change(1, 4.));
+--EXPECTF--
+
+Warning: IntlGregorianCalendar::setGregorianChange() expects exactly 1 parameter, 0 given in %s on line %d
+
+Warning: IntlGregorianCalendar::setGregorianChange(): intlgregcal_set_gregorian_change: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlGregorianCalendar::setGregorianChange() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: IntlGregorianCalendar::setGregorianChange(): intlgregcal_set_gregorian_change: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlGregorianCalendar::setGregorianChange() expects parameter 1 to be double, string given in %s on line %d
+
+Warning: IntlGregorianCalendar::setGregorianChange(): intlgregcal_set_gregorian_change: bad arguments in %s on line %d
+bool(false)
+
+Warning: intlgregcal_set_gregorian_change() expects exactly 2 parameters, 1 given in %s on line %d
+
+Warning: intlgregcal_set_gregorian_change(): intlgregcal_set_gregorian_change: bad arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intlgregcal_set_gregorian_change() must be an instance of IntlGregorianCalendar, integer given in %s on line %d
diff --git a/ext/intl/tests/ini_use_exceptions_basic.phpt b/ext/intl/tests/ini_use_exceptions_basic.phpt
new file mode 100644
index 0000000000..36ccbcb8a0
--- /dev/null
+++ b/ext/intl/tests/ini_use_exceptions_basic.phpt
@@ -0,0 +1,21 @@
+--TEST--
+intl.use_exceptions INI setting
+--SKIPIF--
+<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+--FILE--
+<?php
+ini_set("intl.use_exceptions", true);
+$t = transliterator_create('any-hex');
+try {
+ var_dump($t->transliterate('a', 3));
+} catch (IntlException $intlE) {
+ var_dump($intlE->getMessage());
+}
+ini_set("intl.use_exceptions", false);
+ini_set("intl.error_level", E_NOTICE);
+var_dump($t->transliterate('a', 3));
+--EXPECTF--
+string(130) "transliterator_transliterate: Neither "start" nor the "end" arguments can exceed the number of UTF-16 code units (in this case, 1)"
+
+Notice: Transliterator::transliterate(): transliterator_transliterate: Neither "start" nor the "end" arguments can exceed the number of UTF-16 code units (in this case, 1) in %s on line %d
+bool(false)
diff --git a/ext/intl/tests/locale_filter_matches2.phpt b/ext/intl/tests/locale_filter_matches2.phpt
index 37f9e5a377..12d247dc6b 100644
--- a/ext/intl/tests/locale_filter_matches2.phpt
+++ b/ext/intl/tests/locale_filter_matches2.phpt
@@ -1,8 +1,9 @@
--TEST--
-locale_filter_matches.phpt() icu >= 4.8
+locale_filter_matches.phpt() icu >= 4.8 && icu < 51.2
--SKIPIF--
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
<?php if(version_compare(INTL_ICU_VERSION, '4.8') < 0) print 'skip'; ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') >= 0) die('skip for ICU < 51.2'); ?>
--FILE--
<?php
diff --git a/ext/intl/tests/locale_filter_matches3.phpt b/ext/intl/tests/locale_filter_matches3.phpt
new file mode 100644
index 0000000000..4c1d4d3898
--- /dev/null
+++ b/ext/intl/tests/locale_filter_matches3.phpt
@@ -0,0 +1,366 @@
+--TEST--
+locale_filter_matches.phpt() ICU >= 51.2
+--SKIPIF--
+<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') < 0) die('skip for ICU >= 51.2'); ?>
+--FILE--
+<?php
+
+/*
+ * Try parsing different Locales
+ * with Procedural and Object methods.
+ */
+
+function ut_main()
+{
+ $loc_ranges = array(
+ 'de-de',
+ 'sl_IT',
+ 'sl_IT_Nedis',
+ 'jbo',
+ 'art-lojban',
+ 'sl_IT'
+ );
+
+ $lang_tags = array(
+ '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'
+ );
+
+ $res_str = '';
+ $isCanonical = false;
+ foreach($loc_ranges as $loc_range){
+ foreach($lang_tags as $lang_tag){
+ $res_str .="--------------\n";
+ $result= ut_loc_locale_filter_matches( $lang_tag , $loc_range , $isCanonical);
+ $res_str .= "loc_range:$loc_range matches lang_tag $lang_tag ? ";
+ if( $result){
+ $res_str .= "YES\n";
+ }else{
+ $res_str .= "NO\n";
+ }
+//canonicalized version
+ $result= ut_loc_locale_filter_matches( $lang_tag , $loc_range , !($isCanonical));
+ $can_loc_range = ut_loc_canonicalize($loc_range);
+ $can_lang_tag = ut_loc_canonicalize($lang_tag);
+ $res_str .= "loc_range:$can_loc_range canonically matches lang_tag $can_lang_tag ? ";
+ if( $result){
+ $res_str .= "YES\n";
+ }else{
+ $res_str .= "NO\n";
+ }
+ }
+ }
+
+ $res_str .= "\n";
+ return $res_str;
+
+}
+
+include_once( 'ut_common.inc' );
+ut_run();
+
+?>
+--EXPECT--
+--------------
+loc_range:de-de matches lang_tag de-DEVA ? NO
+loc_range:de_DE canonically matches lang_tag de_Deva ? NO
+--------------
+loc_range:de-de matches lang_tag de-DE-1996 ? YES
+loc_range:de_DE canonically matches lang_tag de_DE_1996 ? YES
+--------------
+loc_range:de-de matches lang_tag de-DE ? YES
+loc_range:de_DE canonically matches lang_tag de_DE ? YES
+--------------
+loc_range:de-de matches lang_tag zh_Hans ? NO
+loc_range:de_DE canonically matches lang_tag zh_Hans ? NO
+--------------
+loc_range:de-de matches lang_tag de-CH-1996 ? NO
+loc_range:de_DE canonically matches lang_tag de_CH_1996 ? NO
+--------------
+loc_range:de-de matches lang_tag sl_IT ? NO
+loc_range:de_DE canonically matches lang_tag sl_IT ? NO
+--------------
+loc_range:de-de matches lang_tag sl_IT_nedis-a-kirti-x-xyz ? NO
+loc_range:de_DE canonically matches lang_tag sl_IT_NEDIS_A_KIRTI_X_XYZ ? NO
+--------------
+loc_range:de-de matches lang_tag sl_IT_rozaj ? NO
+loc_range:de_DE canonically matches lang_tag sl_IT_ROZAJ ? NO
+--------------
+loc_range:de-de matches lang_tag sl_IT_NEDIS_ROJAZ_1901 ? NO
+loc_range:de_DE canonically matches lang_tag sl_IT_NEDIS_ROJAZ_1901 ? NO
+--------------
+loc_range:de-de matches lang_tag i-enochian ? NO
+loc_range:de_DE canonically matches lang_tag @x=i-enochian ? NO
+--------------
+loc_range:de-de matches lang_tag sgn-CH-de ? NO
+loc_range:de_DE canonically matches lang_tag sgn_CH_DE ? NO
+--------------
+loc_range:de-de matches lang_tag art-lojban ? NO
+loc_range:de_DE canonically matches lang_tag art__LOJBAN ? NO
+--------------
+loc_range:de-de matches lang_tag i-lux ? NO
+loc_range:de_DE canonically matches lang_tag lb ? NO
+--------------
+loc_range:de-de matches lang_tag art-lojban ? NO
+loc_range:de_DE canonically matches lang_tag art__LOJBAN ? NO
+--------------
+loc_range:de-de matches lang_tag jbo ? NO
+loc_range:de_DE canonically matches lang_tag jbo ? NO
+--------------
+loc_range:de-de matches lang_tag en_sl_IT ? NO
+loc_range:de_DE canonically matches lang_tag en_SL_IT ? NO
+--------------
+loc_range:sl_IT matches lang_tag de-DEVA ? NO
+loc_range:sl_IT canonically matches lang_tag de_Deva ? NO
+--------------
+loc_range:sl_IT matches lang_tag de-DE-1996 ? NO
+loc_range:sl_IT canonically matches lang_tag de_DE_1996 ? NO
+--------------
+loc_range:sl_IT matches lang_tag de-DE ? NO
+loc_range:sl_IT canonically matches lang_tag de_DE ? NO
+--------------
+loc_range:sl_IT matches lang_tag zh_Hans ? NO
+loc_range:sl_IT canonically matches lang_tag zh_Hans ? NO
+--------------
+loc_range:sl_IT matches lang_tag de-CH-1996 ? NO
+loc_range:sl_IT canonically matches lang_tag de_CH_1996 ? NO
+--------------
+loc_range:sl_IT matches lang_tag sl_IT ? YES
+loc_range:sl_IT canonically matches lang_tag sl_IT ? YES
+--------------
+loc_range:sl_IT matches lang_tag sl_IT_nedis-a-kirti-x-xyz ? YES
+loc_range:sl_IT canonically matches lang_tag sl_IT_NEDIS_A_KIRTI_X_XYZ ? YES
+--------------
+loc_range:sl_IT matches lang_tag sl_IT_rozaj ? YES
+loc_range:sl_IT canonically matches lang_tag sl_IT_ROZAJ ? YES
+--------------
+loc_range:sl_IT matches lang_tag sl_IT_NEDIS_ROJAZ_1901 ? YES
+loc_range:sl_IT canonically matches lang_tag sl_IT_NEDIS_ROJAZ_1901 ? YES
+--------------
+loc_range:sl_IT matches lang_tag i-enochian ? NO
+loc_range:sl_IT canonically matches lang_tag @x=i-enochian ? NO
+--------------
+loc_range:sl_IT matches lang_tag sgn-CH-de ? NO
+loc_range:sl_IT canonically matches lang_tag sgn_CH_DE ? NO
+--------------
+loc_range:sl_IT matches lang_tag art-lojban ? NO
+loc_range:sl_IT canonically matches lang_tag art__LOJBAN ? NO
+--------------
+loc_range:sl_IT matches lang_tag i-lux ? NO
+loc_range:sl_IT canonically matches lang_tag lb ? NO
+--------------
+loc_range:sl_IT matches lang_tag art-lojban ? NO
+loc_range:sl_IT canonically matches lang_tag art__LOJBAN ? NO
+--------------
+loc_range:sl_IT matches lang_tag jbo ? NO
+loc_range:sl_IT canonically matches lang_tag jbo ? NO
+--------------
+loc_range:sl_IT matches lang_tag en_sl_IT ? NO
+loc_range:sl_IT canonically matches lang_tag en_SL_IT ? NO
+--------------
+loc_range:sl_IT_Nedis matches lang_tag de-DEVA ? NO
+loc_range:sl_IT_NEDIS canonically matches lang_tag de_Deva ? NO
+--------------
+loc_range:sl_IT_Nedis matches lang_tag de-DE-1996 ? NO
+loc_range:sl_IT_NEDIS canonically matches lang_tag de_DE_1996 ? NO
+--------------
+loc_range:sl_IT_Nedis matches lang_tag de-DE ? NO
+loc_range:sl_IT_NEDIS canonically matches lang_tag de_DE ? NO
+--------------
+loc_range:sl_IT_Nedis matches lang_tag zh_Hans ? NO
+loc_range:sl_IT_NEDIS canonically matches lang_tag zh_Hans ? NO
+--------------
+loc_range:sl_IT_Nedis matches lang_tag de-CH-1996 ? NO
+loc_range:sl_IT_NEDIS canonically matches lang_tag de_CH_1996 ? NO
+--------------
+loc_range:sl_IT_Nedis matches lang_tag sl_IT ? NO
+loc_range:sl_IT_NEDIS canonically matches lang_tag sl_IT ? NO
+--------------
+loc_range:sl_IT_Nedis matches lang_tag sl_IT_nedis-a-kirti-x-xyz ? YES
+loc_range:sl_IT_NEDIS canonically matches lang_tag sl_IT_NEDIS_A_KIRTI_X_XYZ ? YES
+--------------
+loc_range:sl_IT_Nedis matches lang_tag sl_IT_rozaj ? NO
+loc_range:sl_IT_NEDIS canonically matches lang_tag sl_IT_ROZAJ ? NO
+--------------
+loc_range:sl_IT_Nedis matches lang_tag sl_IT_NEDIS_ROJAZ_1901 ? YES
+loc_range:sl_IT_NEDIS canonically matches lang_tag sl_IT_NEDIS_ROJAZ_1901 ? YES
+--------------
+loc_range:sl_IT_Nedis matches lang_tag i-enochian ? NO
+loc_range:sl_IT_NEDIS canonically matches lang_tag @x=i-enochian ? NO
+--------------
+loc_range:sl_IT_Nedis matches lang_tag sgn-CH-de ? NO
+loc_range:sl_IT_NEDIS canonically matches lang_tag sgn_CH_DE ? NO
+--------------
+loc_range:sl_IT_Nedis matches lang_tag art-lojban ? NO
+loc_range:sl_IT_NEDIS canonically matches lang_tag art__LOJBAN ? NO
+--------------
+loc_range:sl_IT_Nedis matches lang_tag i-lux ? NO
+loc_range:sl_IT_NEDIS canonically matches lang_tag lb ? NO
+--------------
+loc_range:sl_IT_Nedis matches lang_tag art-lojban ? NO
+loc_range:sl_IT_NEDIS canonically matches lang_tag art__LOJBAN ? NO
+--------------
+loc_range:sl_IT_Nedis matches lang_tag jbo ? NO
+loc_range:sl_IT_NEDIS canonically matches lang_tag jbo ? NO
+--------------
+loc_range:sl_IT_Nedis matches lang_tag en_sl_IT ? NO
+loc_range:sl_IT_NEDIS canonically matches lang_tag en_SL_IT ? NO
+--------------
+loc_range:jbo matches lang_tag de-DEVA ? NO
+loc_range:jbo canonically matches lang_tag de_Deva ? NO
+--------------
+loc_range:jbo matches lang_tag de-DE-1996 ? NO
+loc_range:jbo canonically matches lang_tag de_DE_1996 ? NO
+--------------
+loc_range:jbo matches lang_tag de-DE ? NO
+loc_range:jbo canonically matches lang_tag de_DE ? NO
+--------------
+loc_range:jbo matches lang_tag zh_Hans ? NO
+loc_range:jbo canonically matches lang_tag zh_Hans ? NO
+--------------
+loc_range:jbo matches lang_tag de-CH-1996 ? NO
+loc_range:jbo canonically matches lang_tag de_CH_1996 ? NO
+--------------
+loc_range:jbo matches lang_tag sl_IT ? NO
+loc_range:jbo canonically matches lang_tag sl_IT ? NO
+--------------
+loc_range:jbo matches lang_tag sl_IT_nedis-a-kirti-x-xyz ? NO
+loc_range:jbo canonically matches lang_tag sl_IT_NEDIS_A_KIRTI_X_XYZ ? NO
+--------------
+loc_range:jbo matches lang_tag sl_IT_rozaj ? NO
+loc_range:jbo canonically matches lang_tag sl_IT_ROZAJ ? NO
+--------------
+loc_range:jbo matches lang_tag sl_IT_NEDIS_ROJAZ_1901 ? NO
+loc_range:jbo canonically matches lang_tag sl_IT_NEDIS_ROJAZ_1901 ? NO
+--------------
+loc_range:jbo matches lang_tag i-enochian ? NO
+loc_range:jbo canonically matches lang_tag @x=i-enochian ? NO
+--------------
+loc_range:jbo matches lang_tag sgn-CH-de ? NO
+loc_range:jbo canonically matches lang_tag sgn_CH_DE ? NO
+--------------
+loc_range:jbo matches lang_tag art-lojban ? NO
+loc_range:jbo canonically matches lang_tag art__LOJBAN ? NO
+--------------
+loc_range:jbo matches lang_tag i-lux ? NO
+loc_range:jbo canonically matches lang_tag lb ? NO
+--------------
+loc_range:jbo matches lang_tag art-lojban ? NO
+loc_range:jbo canonically matches lang_tag art__LOJBAN ? NO
+--------------
+loc_range:jbo matches lang_tag jbo ? YES
+loc_range:jbo canonically matches lang_tag jbo ? YES
+--------------
+loc_range:jbo matches lang_tag en_sl_IT ? NO
+loc_range:jbo canonically matches lang_tag en_SL_IT ? NO
+--------------
+loc_range:art-lojban matches lang_tag de-DEVA ? NO
+loc_range:art__LOJBAN canonically matches lang_tag de_Deva ? NO
+--------------
+loc_range:art-lojban matches lang_tag de-DE-1996 ? NO
+loc_range:art__LOJBAN canonically matches lang_tag de_DE_1996 ? NO
+--------------
+loc_range:art-lojban matches lang_tag de-DE ? NO
+loc_range:art__LOJBAN canonically matches lang_tag de_DE ? NO
+--------------
+loc_range:art-lojban matches lang_tag zh_Hans ? NO
+loc_range:art__LOJBAN canonically matches lang_tag zh_Hans ? NO
+--------------
+loc_range:art-lojban matches lang_tag de-CH-1996 ? NO
+loc_range:art__LOJBAN canonically matches lang_tag de_CH_1996 ? NO
+--------------
+loc_range:art-lojban matches lang_tag sl_IT ? NO
+loc_range:art__LOJBAN canonically matches lang_tag sl_IT ? NO
+--------------
+loc_range:art-lojban matches lang_tag sl_IT_nedis-a-kirti-x-xyz ? NO
+loc_range:art__LOJBAN canonically matches lang_tag sl_IT_NEDIS_A_KIRTI_X_XYZ ? NO
+--------------
+loc_range:art-lojban matches lang_tag sl_IT_rozaj ? NO
+loc_range:art__LOJBAN canonically matches lang_tag sl_IT_ROZAJ ? NO
+--------------
+loc_range:art-lojban matches lang_tag sl_IT_NEDIS_ROJAZ_1901 ? NO
+loc_range:art__LOJBAN canonically matches lang_tag sl_IT_NEDIS_ROJAZ_1901 ? NO
+--------------
+loc_range:art-lojban matches lang_tag i-enochian ? NO
+loc_range:art__LOJBAN canonically matches lang_tag @x=i-enochian ? NO
+--------------
+loc_range:art-lojban matches lang_tag sgn-CH-de ? NO
+loc_range:art__LOJBAN canonically matches lang_tag sgn_CH_DE ? NO
+--------------
+loc_range:art-lojban matches lang_tag art-lojban ? YES
+loc_range:art__LOJBAN canonically matches lang_tag art__LOJBAN ? YES
+--------------
+loc_range:art-lojban matches lang_tag i-lux ? NO
+loc_range:art__LOJBAN canonically matches lang_tag lb ? NO
+--------------
+loc_range:art-lojban matches lang_tag art-lojban ? YES
+loc_range:art__LOJBAN canonically matches lang_tag art__LOJBAN ? YES
+--------------
+loc_range:art-lojban matches lang_tag jbo ? NO
+loc_range:art__LOJBAN canonically matches lang_tag jbo ? NO
+--------------
+loc_range:art-lojban matches lang_tag en_sl_IT ? NO
+loc_range:art__LOJBAN canonically matches lang_tag en_SL_IT ? NO
+--------------
+loc_range:sl_IT matches lang_tag de-DEVA ? NO
+loc_range:sl_IT canonically matches lang_tag de_Deva ? NO
+--------------
+loc_range:sl_IT matches lang_tag de-DE-1996 ? NO
+loc_range:sl_IT canonically matches lang_tag de_DE_1996 ? NO
+--------------
+loc_range:sl_IT matches lang_tag de-DE ? NO
+loc_range:sl_IT canonically matches lang_tag de_DE ? NO
+--------------
+loc_range:sl_IT matches lang_tag zh_Hans ? NO
+loc_range:sl_IT canonically matches lang_tag zh_Hans ? NO
+--------------
+loc_range:sl_IT matches lang_tag de-CH-1996 ? NO
+loc_range:sl_IT canonically matches lang_tag de_CH_1996 ? NO
+--------------
+loc_range:sl_IT matches lang_tag sl_IT ? YES
+loc_range:sl_IT canonically matches lang_tag sl_IT ? YES
+--------------
+loc_range:sl_IT matches lang_tag sl_IT_nedis-a-kirti-x-xyz ? YES
+loc_range:sl_IT canonically matches lang_tag sl_IT_NEDIS_A_KIRTI_X_XYZ ? YES
+--------------
+loc_range:sl_IT matches lang_tag sl_IT_rozaj ? YES
+loc_range:sl_IT canonically matches lang_tag sl_IT_ROZAJ ? YES
+--------------
+loc_range:sl_IT matches lang_tag sl_IT_NEDIS_ROJAZ_1901 ? YES
+loc_range:sl_IT canonically matches lang_tag sl_IT_NEDIS_ROJAZ_1901 ? YES
+--------------
+loc_range:sl_IT matches lang_tag i-enochian ? NO
+loc_range:sl_IT canonically matches lang_tag @x=i-enochian ? NO
+--------------
+loc_range:sl_IT matches lang_tag sgn-CH-de ? NO
+loc_range:sl_IT canonically matches lang_tag sgn_CH_DE ? NO
+--------------
+loc_range:sl_IT matches lang_tag art-lojban ? NO
+loc_range:sl_IT canonically matches lang_tag art__LOJBAN ? NO
+--------------
+loc_range:sl_IT matches lang_tag i-lux ? NO
+loc_range:sl_IT canonically matches lang_tag lb ? NO
+--------------
+loc_range:sl_IT matches lang_tag art-lojban ? NO
+loc_range:sl_IT canonically matches lang_tag art__LOJBAN ? NO
+--------------
+loc_range:sl_IT matches lang_tag jbo ? NO
+loc_range:sl_IT canonically matches lang_tag jbo ? NO
+--------------
+loc_range:sl_IT matches lang_tag en_sl_IT ? NO
+loc_range:sl_IT canonically matches lang_tag en_SL_IT ? NO
diff --git a/ext/intl/tests/locale_get_display_name2.phpt b/ext/intl/tests/locale_get_display_name2.phpt
index 40ccc0c2c5..bd8cb50cd5 100644
--- a/ext/intl/tests/locale_get_display_name2.phpt
+++ b/ext/intl/tests/locale_get_display_name2.phpt
@@ -1,8 +1,9 @@
--TEST--
-locale_get_display_name() icu >= 4.8
+locale_get_display_name() icu >= 4.8 && icu < 51.2
--SKIPIF--
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
<?php if(version_compare(INTL_ICU_VERSION, '4.8') < 0) print 'skip'; ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') >= 0) die('skip for ICU < 51.2'); ?>
--FILE--
<?php
diff --git a/ext/intl/tests/locale_get_display_name3.phpt b/ext/intl/tests/locale_get_display_name3.phpt
new file mode 100644
index 0000000000..3f3d26fcfa
--- /dev/null
+++ b/ext/intl/tests/locale_get_display_name3.phpt
@@ -0,0 +1,342 @@
+--TEST--
+locale_get_display_name() icu >= 51.2
+--SKIPIF--
+<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') < 0) die('skip for ICU >= 51.2'); ?>
+--FILE--
+<?php
+
+/*
+ * Try getting the display_name for different locales
+ * with Procedural and Object methods.
+ */
+
+function ut_main()
+{
+ $res_str='';
+
+ $disp_locales=array('en','fr','de');
+
+ $locales = array(
+ 'sl_IT_nedis_KIRTI',
+ 'sl_IT_nedis-a-kirti-x-xyz',
+ 'sl_IT_rozaj',
+ 'sl_IT_NEDIS_ROJAZ_1901',
+ 'i-enochian',
+ 'zh-hakka',
+ 'zh-wuu',
+ 'i-tay',
+ 'sgn-BE-nl',
+ 'sgn-CH-de',
+ 'sl_IT_rozaj@currency=EUR',
+ 'uk-ua_CALIFORNIA@currency=;currency=GRN',
+ 'root',
+ 'uk@currency=EURO',
+ 'Hindi',
+//Simple language subtag
+ 'de',
+ 'fr',
+ 'ja',
+ 'i-enochian', //(example of a grandfathered tag)
+//Language subtag plus Script subtag:
+ 'zh-Hant',
+ 'zh-Hans',
+ 'sr-Cyrl',
+ 'sr-Latn',
+//Language-Script-Region
+ 'zh-Hans-CN',
+ 'sr-Latn-CS',
+//Language-Variant
+ 'sl-rozaj',
+ 'sl-nedis',
+//Language-Region-Variant
+ 'de-CH-1901',
+ 'sl-IT-nedis',
+//Language-Script-Region-Variant
+ 'sl-Latn-IT-nedis',
+//Language-Region:
+ 'de-DE',
+ 'en-US',
+ 'es-419',
+//Private use subtags:
+ 'de-CH-x-phonebk',
+ 'az-Arab-x-AZE-derbend',
+//Extended language subtags
+ 'zh-min',
+ 'zh-min-nan-Hant-CN',
+//Private use registry values
+ 'x-whatever',
+ 'qaa-Qaaa-QM-x-southern',
+ 'sr-Latn-QM',
+ 'sr-Qaaa-CS',
+/*Tags that use extensions (examples ONLY: extensions MUST be defined
+ by revision or update to this document or by RFC): */
+ 'en-US-u-islamCal',
+ 'zh-CN-a-myExt-x-private',
+ 'en-a-myExt-b-another',
+//Some Invalid Tags:
+ 'de-419-DE',
+ 'a-DE',
+ 'ar-a-aaa-b-bbb-a-ccc'
+ );
+
+
+ $res_str = '';
+
+ foreach( $locales as $locale )
+ {
+ $res_str .= "locale='$locale'\n";
+ foreach( $disp_locales as $disp_locale )
+ {
+ $scr = ut_loc_get_display_name( $locale ,$disp_locale );
+ $scr = str_replace(array('(', ')'), '#', $scr);
+ $res_str .= "disp_locale=$disp_locale : display_name=$scr";
+ $res_str .= "\n";
+ }
+ $res_str .= "-----------------\n";
+ }
+
+ return $res_str;
+
+}
+
+include_once( 'ut_common.inc' );
+ut_run();
+
+?>
+--EXPECTREGEX--
+locale='sl_IT_nedis_KIRTI'
+disp_locale=en : display_name=Slovenian #Italy, NEDIS_KIRTI#
+disp_locale=fr : display_name=slovène #Italie, NEDIS_KIRTI#
+disp_locale=de : display_name=Slowenisch #Italien, NEDIS_KIRTI#
+-----------------
+locale='sl_IT_nedis-a-kirti-x-xyz'
+disp_locale=en : display_name=Slovenian #Italy, NEDIS_A_KIRTI_X_XYZ#
+disp_locale=fr : display_name=slovène #Italie, NEDIS_A_KIRTI_X_XYZ#
+disp_locale=de : display_name=Slowenisch #Italien, NEDIS_A_KIRTI_X_XYZ#
+-----------------
+locale='sl_IT_rozaj'
+disp_locale=en : display_name=Slovenian #Italy, Resian#
+disp_locale=fr : display_name=slovène #Italie, dialecte de Resia#
+disp_locale=de : display_name=Slowenisch #Italien, (ROZAJ|Resianisch)#
+-----------------
+locale='sl_IT_NEDIS_ROJAZ_1901'
+disp_locale=en : display_name=Slovenian #Italy, NEDIS_ROJAZ_1901#
+disp_locale=fr : display_name=slovène #Italie, NEDIS_ROJAZ_1901#
+disp_locale=de : display_name=Slowenisch #Italien, NEDIS_ROJAZ_1901#
+-----------------
+locale='i-enochian'
+disp_locale=en : display_name=i-enochian #Private-Use=i-enochian#
+disp_locale=fr : display_name=i-enochian #Usage privé=i-enochian#
+disp_locale=de : display_name=i-enochian #Privatnutzung=i-enochian#
+-----------------
+locale='zh-hakka'
+disp_locale=en : display_name=Chinese( #HAKKA#)?
+disp_locale=fr : display_name=chinois( #HAKKA#)?
+disp_locale=de : display_name=Chinesisch( #HAKKA#)?
+-----------------
+locale='zh-wuu'
+disp_locale=en : display_name=Chinese #WUU#
+disp_locale=fr : display_name=chinois #WUU#
+disp_locale=de : display_name=Chinesisch #WUU#
+-----------------
+locale='i-tay'
+disp_locale=en : display_name=i-tay
+disp_locale=fr : display_name=i-tay
+disp_locale=de : display_name=i-tay
+-----------------
+locale='sgn-BE-nl'
+disp_locale=en : display_name=Sign Languages? #Belgium, NL#
+disp_locale=fr : display_name=langues? des signes #Belgique, NL#
+disp_locale=de : display_name=Gebärdensprache #Belgien, NL#
+-----------------
+locale='sgn-CH-de'
+disp_locale=en : display_name=Sign Languages? #Switzerland, DE#
+disp_locale=fr : display_name=langues? des signes #Suisse, DE#
+disp_locale=de : display_name=Gebärdensprache #Schweiz, DE#
+-----------------
+locale='sl_IT_rozaj@currency=EUR'
+disp_locale=en : display_name=Slovenian #Italy, Resian, [Cc]urrency=Euro#
+disp_locale=fr : display_name=slovène #Italie, dialecte de Resia, [Dd]evise=euro#
+disp_locale=de : display_name=Slowenisch #Italien, (ROZAJ|Resianisch), Währung=Euro#
+-----------------
+locale='uk-ua_CALIFORNIA@currency=;currency=GRN'
+disp_locale=en : display_name=Ukrainian #Ukraine, CALIFORNIA, [Cc]urrency#
+disp_locale=fr : display_name=ukrainien #Ukraine, CALIFORNIA, [Dd]evise#
+disp_locale=de : display_name=Ukrainisch #Ukraine, CALIFORNIA, Währung#
+-----------------
+locale='root'
+disp_locale=en : display_name=Root
+disp_locale=fr : display_name=racine
+disp_locale=de : display_name=[Rr]oot
+-----------------
+locale='uk@currency=EURO'
+disp_locale=en : display_name=Ukrainian #[Cc]urrency=EURO#
+disp_locale=fr : display_name=ukrainien #[Dd]evise=EURO#
+disp_locale=de : display_name=Ukrainisch #Währung=EURO#
+-----------------
+locale='Hindi'
+disp_locale=en : display_name=hindi
+disp_locale=fr : display_name=hindi
+disp_locale=de : display_name=hindi
+-----------------
+locale='de'
+disp_locale=en : display_name=German
+disp_locale=fr : display_name=allemand
+disp_locale=de : display_name=Deutsch
+-----------------
+locale='fr'
+disp_locale=en : display_name=French
+disp_locale=fr : display_name=français
+disp_locale=de : display_name=Französisch
+-----------------
+locale='ja'
+disp_locale=en : display_name=Japanese
+disp_locale=fr : display_name=japonais
+disp_locale=de : display_name=Japanisch
+-----------------
+locale='i-enochian'
+disp_locale=en : display_name=i-enochian #Private-Use=i-enochian#
+disp_locale=fr : display_name=i-enochian #Usage privé=i-enochian#
+disp_locale=de : display_name=i-enochian #Privatnutzung=i-enochian#
+-----------------
+locale='zh-Hant'
+disp_locale=en : display_name=Chinese #Traditional#
+disp_locale=fr : display_name=chinois #traditionnel#
+disp_locale=de : display_name=Chinesisch #Traditionell#
+-----------------
+locale='zh-Hans'
+disp_locale=en : display_name=Chinese #Simplified#
+disp_locale=fr : display_name=chinois #simplifié#
+disp_locale=de : display_name=Chinesisch #Vereinfacht#
+-----------------
+locale='sr-Cyrl'
+disp_locale=en : display_name=Serbian #Cyrillic#
+disp_locale=fr : display_name=serbe #cyrillique#
+disp_locale=de : display_name=Serbisch #Kyrillisch#
+-----------------
+locale='sr-Latn'
+disp_locale=en : display_name=Serbian #Latin#
+disp_locale=fr : display_name=serbe #latin#
+disp_locale=de : display_name=Serbisch #Lateinisch#
+-----------------
+locale='zh-Hans-CN'
+disp_locale=en : display_name=Chinese #Simplified, China#
+disp_locale=fr : display_name=chinois #simplifié, Chine#
+disp_locale=de : display_name=Chinesisch #Vereinfacht, China#
+-----------------
+locale='sr-Latn-CS'
+disp_locale=en : display_name=Serbian #Latin, Serbia#
+disp_locale=fr : display_name=serbe #latin, Serbie#
+disp_locale=de : display_name=Serbisch #Lateinisch, Serbien#
+-----------------
+locale='sl-rozaj'
+disp_locale=en : display_name=Slovenian #Resian#
+disp_locale=fr : display_name=slovène #dialecte de Resia#
+disp_locale=de : display_name=Slowenisch( #(ROZAJ|Resianisch)#)?
+-----------------
+locale='sl-nedis'
+disp_locale=en : display_name=Slovenian #Natisone dialect#
+disp_locale=fr : display_name=slovène #dialecte de Natisone#
+disp_locale=de : display_name=Slowenisch #Natisone-Dialekt#
+-----------------
+locale='de-CH-1901'
+disp_locale=en : display_name=German #Switzerland, Traditional German orthography#
+disp_locale=fr : display_name=allemand #Suisse, orthographe allemande traditionnelle#
+disp_locale=de : display_name=Deutsch #Schweiz, (1901|[aA]lte deutsche Rechtschreibung)#
+-----------------
+locale='sl-IT-nedis'
+disp_locale=en : display_name=Slovenian #Italy, Natisone dialect#
+disp_locale=fr : display_name=slovène #Italie, dialecte de Natisone#
+disp_locale=de : display_name=Slowenisch #Italien, (NEDIS|Natisone-Dialekt)#
+-----------------
+locale='sl-Latn-IT-nedis'
+disp_locale=en : display_name=Slovenian #Latin, Italy, Natisone dialect#
+disp_locale=fr : display_name=slovène #latin, Italie, dialecte de Natisone#
+disp_locale=de : display_name=Slowenisch #Lateinisch, Italien, (NEDIS|Natisone-Dialekt)#
+-----------------
+locale='de-DE'
+disp_locale=en : display_name=German #Germany#
+disp_locale=fr : display_name=allemand #Allemagne#
+disp_locale=de : display_name=Deutsch #Deutschland#
+-----------------
+locale='en-US'
+disp_locale=en : display_name=English #United States#
+disp_locale=fr : display_name=anglais #États-Unis#
+disp_locale=de : display_name=Englisch #Vereinigte Staaten#
+-----------------
+locale='es-419'
+disp_locale=en : display_name=Spanish #Latin America#
+disp_locale=fr : display_name=espagnol #Amérique latine#
+disp_locale=de : display_name=Spanisch #Lateinamerika#
+-----------------
+locale='de-CH-x-phonebk'
+disp_locale=en : display_name=German #Switzerland, Private-Use=phonebk#
+disp_locale=fr : display_name=allemand #Suisse, Usage privé=phonebk#
+disp_locale=de : display_name=Deutsch #Schweiz, Privatnutzung=phonebk#
+-----------------
+locale='az-Arab-x-AZE-derbend'
+disp_locale=en : display_name=Azerbaijani #Arabic, Private-Use=aze-derbend#
+disp_locale=fr : display_name=azéri #arabe, Usage privé=aze-derbend#
+disp_locale=de : display_name=Aserbaidschanisch #Arabisch, Privatnutzung=aze-derbend#
+-----------------
+locale='zh-min'
+disp_locale=en : display_name=Chinese #MIN#
+disp_locale=fr : display_name=chinois #MIN#
+disp_locale=de : display_name=Chinesisch #MIN#
+-----------------
+locale='zh-min-nan-Hant-CN'
+disp_locale=en : display_name=Chinese #MIN, NAN_HANT_CN#
+disp_locale=fr : display_name=chinois #MIN, NAN_HANT_CN#
+disp_locale=de : display_name=Chinesisch #MIN, NAN_HANT_CN#
+-----------------
+locale='x-whatever'
+disp_locale=en : display_name=x-whatever #Private-Use=whatever#
+disp_locale=fr : display_name=x-whatever #Usage privé=whatever#
+disp_locale=de : display_name=x-whatever #Privatnutzung=whatever#
+-----------------
+locale='qaa-Qaaa-QM-x-southern'
+disp_locale=en : display_name=qaa #Qaaa, QM, Private-Use=southern#
+disp_locale=fr : display_name=qaa #Qaaa, QM, Usage privé=southern#
+disp_locale=de : display_name=qaa #Qaaa, QM, Privatnutzung=southern#
+-----------------
+locale='sr-Latn-QM'
+disp_locale=en : display_name=Serbian #Latin, QM#
+disp_locale=fr : display_name=serbe #latin, QM#
+disp_locale=de : display_name=Serbisch #Lateinisch, QM#
+-----------------
+locale='sr-Qaaa-CS'
+disp_locale=en : display_name=Serbian #Qaaa, Serbia#
+disp_locale=fr : display_name=serbe #Qaaa, Serbie#
+disp_locale=de : display_name=Serbisch #Qaaa, Serbien#
+-----------------
+locale='en-US-u-islamCal'
+disp_locale=en : display_name=English #United States, attribute=islamcal#
+disp_locale=fr : display_name=anglais #États-Unis, attribute=islamcal#
+disp_locale=de : display_name=Englisch #Vereinigte Staaten, attribute=islamcal#
+-----------------
+locale='zh-CN-a-myExt-x-private'
+disp_locale=en : display_name=Chinese #China, a=myext, Private-Use=private#
+disp_locale=fr : display_name=chinois #Chine, a=myext, Usage privé=private#
+disp_locale=de : display_name=Chinesisch #China, a=myext, Privatnutzung=private#
+-----------------
+locale='en-a-myExt-b-another'
+disp_locale=en : display_name=English #a=myext, b=another#
+disp_locale=fr : display_name=anglais #a=myext, b=another#
+disp_locale=de : display_name=Englisch #a=myext, b=another#
+-----------------
+locale='de-419-DE'
+disp_locale=en : display_name=German #Latin America, DE#
+disp_locale=fr : display_name=allemand #Amérique latine, DE#
+disp_locale=de : display_name=Deutsch #Lateinamerika, DE#
+-----------------
+locale='a-DE'
+disp_locale=en : display_name=a #Germany#
+disp_locale=fr : display_name=a #Allemagne#
+disp_locale=de : display_name=a #Deutschland#
+-----------------
+locale='ar-a-aaa-b-bbb-a-ccc'
+disp_locale=en : display_name=Arabic #a=aaa, b=bbb#
+disp_locale=fr : display_name=arabe #a=aaa, b=bbb#
+disp_locale=de : display_name=Arabisch #a=aaa, b=bbb#
+-----------------
diff --git a/ext/intl/tests/locale_get_display_region2.phpt b/ext/intl/tests/locale_get_display_region2.phpt
index f1b584188a..1d7354bd1b 100644
--- a/ext/intl/tests/locale_get_display_region2.phpt
+++ b/ext/intl/tests/locale_get_display_region2.phpt
@@ -1,8 +1,9 @@
--TEST--
-locale_get_display_region() icu >= 4.8
+locale_get_display_region() icu >= 4.8 && icu < 51.2
--SKIPIF--
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
<?php if(version_compare(INTL_ICU_VERSION, '4.8') < 0) print 'skip'; ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') >= 0) die('skip for ICU < 51.2'); ?>
--FILE--
<?php
diff --git a/ext/intl/tests/locale_get_display_region3.phpt b/ext/intl/tests/locale_get_display_region3.phpt
new file mode 100644
index 0000000000..ec287a6446
--- /dev/null
+++ b/ext/intl/tests/locale_get_display_region3.phpt
@@ -0,0 +1,275 @@
+--TEST--
+locale_get_display_region() icu >= 51.2
+--SKIPIF--
+<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') < 0) die('skip for ICU >= 51.2'); ?>
+--FILE--
+<?php
+
+/*
+ * Try getting the display_region for different locales
+ * with Procedural and Object methods.
+ */
+
+function ut_main()
+{
+ $res_str = '';
+
+ $disp_locales=array('en','fr','de');
+
+ $locales = array(
+ 'uk-ua_CALIFORNIA@currency=;currency=GRN',
+ 'root',
+ 'uk@currency=EURO',
+ 'Hindi',
+//Simple language subtag
+ 'de',
+ 'fr',
+ 'ja',
+ 'i-enochian', //(example of a grandfathered tag)
+//Language subtag plus Script subtag:
+ 'zh-Hant',
+ 'zh-Hans',
+ 'sr-Cyrl',
+ 'sr-Latn',
+//Language-Script-Region
+ 'zh-Hans-CN',
+ 'sr-Latn-CS',
+//Language-Variant
+ 'sl-rozaj',
+ 'sl-nedis',
+//Language-Region-Variant
+ 'de-CH-1901',
+ 'sl-IT-nedis',
+//Language-Script-Region-Variant
+ 'sl-Latn-IT-nedis',
+//Language-Region:
+ 'de-DE',
+ 'en-US',
+ 'es-419',
+//Private use subtags:
+ 'de-CH-x-phonebk',
+ 'az-Arab-x-AZE-derbend',
+//Extended language subtags
+ 'zh-min',
+ 'zh-min-nan-Hant-CN',
+//Private use registry values
+ 'x-whatever',
+ 'qaa-Qaaa-QM-x-southern',
+ 'sr-Latn-QM',
+ 'sr-Qaaa-CS',
+/*Tags that use extensions (examples ONLY: extensions MUST be defined
+ by revision or update to this document or by RFC): */
+ 'en-US-u-islamCal',
+ 'zh-CN-a-myExt-x-private',
+ 'en-a-myExt-b-another',
+//Some Invalid Tags:
+ 'de-419-DE',
+ 'a-DE',
+ 'ar-a-aaa-b-bbb-a-ccc'
+ );
+
+
+ $res_str = '';
+
+ foreach( $locales as $locale )
+ {
+ $res_str .= "locale='$locale'\n";
+ foreach( $disp_locales as $disp_locale )
+ {
+ $scr = ut_loc_get_display_region( $locale ,$disp_locale );
+ $res_str .= "disp_locale=$disp_locale : display_region=$scr";
+ $res_str .= "\n";
+ }
+ $res_str .= "-----------------\n";
+ }
+
+ return $res_str;
+
+}
+
+include_once( 'ut_common.inc' );
+ut_run();
+
+?>
+--EXPECTREGEX--
+locale='uk-ua_CALIFORNIA@currency=;currency=GRN'
+disp_locale=en : display_region=Ukraine
+disp_locale=fr : display_region=Ukraine
+disp_locale=de : display_region=Ukraine
+-----------------
+locale='root'
+disp_locale=en : display_region=
+disp_locale=fr : display_region=
+disp_locale=de : display_region=
+-----------------
+locale='uk@currency=EURO'
+disp_locale=en : display_region=
+disp_locale=fr : display_region=
+disp_locale=de : display_region=
+-----------------
+locale='Hindi'
+disp_locale=en : display_region=
+disp_locale=fr : display_region=
+disp_locale=de : display_region=
+-----------------
+locale='de'
+disp_locale=en : display_region=
+disp_locale=fr : display_region=
+disp_locale=de : display_region=
+-----------------
+locale='fr'
+disp_locale=en : display_region=
+disp_locale=fr : display_region=
+disp_locale=de : display_region=
+-----------------
+locale='ja'
+disp_locale=en : display_region=
+disp_locale=fr : display_region=
+disp_locale=de : display_region=
+-----------------
+locale='i-enochian'
+disp_locale=en : display_region=
+disp_locale=fr : display_region=
+disp_locale=de : display_region=
+-----------------
+locale='zh-Hant'
+disp_locale=en : display_region=
+disp_locale=fr : display_region=
+disp_locale=de : display_region=
+-----------------
+locale='zh-Hans'
+disp_locale=en : display_region=
+disp_locale=fr : display_region=
+disp_locale=de : display_region=
+-----------------
+locale='sr-Cyrl'
+disp_locale=en : display_region=
+disp_locale=fr : display_region=
+disp_locale=de : display_region=
+-----------------
+locale='sr-Latn'
+disp_locale=en : display_region=
+disp_locale=fr : display_region=
+disp_locale=de : display_region=
+-----------------
+locale='zh-Hans-CN'
+disp_locale=en : display_region=China
+disp_locale=fr : display_region=Chine
+disp_locale=de : display_region=China
+-----------------
+locale='sr-Latn-CS'
+disp_locale=en : display_region=Serbia
+disp_locale=fr : display_region=Serbie
+disp_locale=de : display_region=Serbien
+-----------------
+locale='sl-rozaj'
+disp_locale=en : display_region=(ROZAJ)?
+disp_locale=fr : display_region=(ROZAJ)?
+disp_locale=de : display_region=(ROZAJ)?
+-----------------
+locale='sl-nedis'
+disp_locale=en : display_region=(NEDIS)?
+disp_locale=fr : display_region=(NEDIS)?
+disp_locale=de : display_region=(NEDIS)?
+-----------------
+locale='de-CH-1901'
+disp_locale=en : display_region=Switzerland
+disp_locale=fr : display_region=Suisse
+disp_locale=de : display_region=Schweiz
+-----------------
+locale='sl-IT-nedis'
+disp_locale=en : display_region=Italy
+disp_locale=fr : display_region=Italie
+disp_locale=de : display_region=Italien
+-----------------
+locale='sl-Latn-IT-nedis'
+disp_locale=en : display_region=Italy
+disp_locale=fr : display_region=Italie
+disp_locale=de : display_region=Italien
+-----------------
+locale='de-DE'
+disp_locale=en : display_region=Germany
+disp_locale=fr : display_region=Allemagne
+disp_locale=de : display_region=Deutschland
+-----------------
+locale='en-US'
+disp_locale=en : display_region=United States
+disp_locale=fr : display_region=États-Unis
+disp_locale=de : display_region=Vereinigte Staaten
+-----------------
+locale='es-419'
+disp_locale=en : display_region=Latin America
+disp_locale=fr : display_region=Amérique latine
+disp_locale=de : display_region=Lateinamerika
+-----------------
+locale='de-CH-x-phonebk'
+disp_locale=en : display_region=Switzerland
+disp_locale=fr : display_region=Suisse
+disp_locale=de : display_region=Schweiz
+-----------------
+locale='az-Arab-x-AZE-derbend'
+disp_locale=en : display_region=X?
+disp_locale=fr : display_region=X?
+disp_locale=de : display_region=X?
+-----------------
+locale='zh-min'
+disp_locale=en : display_region=
+disp_locale=fr : display_region=
+disp_locale=de : display_region=
+-----------------
+locale='zh-min-nan-Hant-CN'
+disp_locale=en : display_region=MIN
+disp_locale=fr : display_region=MIN
+disp_locale=de : display_region=MIN
+-----------------
+locale='x-whatever'
+disp_locale=en : display_region=
+disp_locale=fr : display_region=
+disp_locale=de : display_region=
+-----------------
+locale='qaa-Qaaa-QM-x-southern'
+disp_locale=en : display_region=QM
+disp_locale=fr : display_region=QM
+disp_locale=de : display_region=QM
+-----------------
+locale='sr-Latn-QM'
+disp_locale=en : display_region=QM
+disp_locale=fr : display_region=QM
+disp_locale=de : display_region=QM
+-----------------
+locale='sr-Qaaa-CS'
+disp_locale=en : display_region=Serbia
+disp_locale=fr : display_region=Serbie
+disp_locale=de : display_region=Serbien
+-----------------
+locale='en-US-u-islamCal'
+disp_locale=en : display_region=United States
+disp_locale=fr : display_region=États-Unis
+disp_locale=de : display_region=Vereinigte Staaten
+-----------------
+locale='zh-CN-a-myExt-x-private'
+disp_locale=en : display_region=China
+disp_locale=fr : display_region=Chine
+disp_locale=de : display_region=China
+-----------------
+locale='en-a-myExt-b-another'
+disp_locale=en : display_region=A?
+disp_locale=fr : display_region=A?
+disp_locale=de : display_region=A?
+-----------------
+locale='de-419-DE'
+disp_locale=en : display_region=Latin America
+disp_locale=fr : display_region=Amérique latine
+disp_locale=de : display_region=Lateinamerika
+-----------------
+locale='a-DE'
+disp_locale=en : display_region=Germany
+disp_locale=fr : display_region=Allemagne
+disp_locale=de : display_region=Deutschland
+-----------------
+locale='ar-a-aaa-b-bbb-a-ccc'
+disp_locale=en : display_region=A?
+disp_locale=fr : display_region=A?
+disp_locale=de : display_region=A?
+-----------------
diff --git a/ext/intl/tests/locale_lookup.phpt b/ext/intl/tests/locale_lookup.phpt
index f0affafa6f..df5204f07d 100644
--- a/ext/intl/tests/locale_lookup.phpt
+++ b/ext/intl/tests/locale_lookup.phpt
@@ -2,6 +2,7 @@
locale_lookup.phpt()
--SKIPIF--
<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') >= 0) die('skip for ICU < 51.2'); ?>
--FILE--
<?php
diff --git a/ext/intl/tests/locale_lookup_variant2.phpt b/ext/intl/tests/locale_lookup_variant2.phpt
new file mode 100644
index 0000000000..4715951e9a
--- /dev/null
+++ b/ext/intl/tests/locale_lookup_variant2.phpt
@@ -0,0 +1,100 @@
+--TEST--
+locale_lookup.phpt()
+--SKIPIF--
+<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') < 0) die('skip for ICU >= 51.2'); ?>
+--FILE--
+<?php
+
+/*
+ * Try parsing different Locales
+ * with Procedural and Object methods.
+ */
+
+function ut_main()
+{
+ $loc_ranges = array(
+ 'de-de',
+ 'sl_IT',
+ 'sl_IT_Nedis',
+ 'jbo',
+ 'art-lojban'
+ );
+
+ $lang_tags = array(
+ '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'
+ );
+
+
+ $res_str = '';
+ $isCanonical = false;
+
+ foreach($loc_ranges as $loc_range){
+ $res_str .="--------------\n";
+ $result= ut_loc_locale_lookup( $lang_tags , $loc_range,$isCanonical,"en_US");
+ $comma_arr =implode(",",$lang_tags);
+ $res_str .= "loc_range:$loc_range \nlang_tags: $comma_arr\n";
+ $res_str .= "\nlookup result:$result\n";
+//canonicalized version
+ $result= ut_loc_locale_lookup( $lang_tags , $loc_range,!($isCanonical),"en_US");
+ $can_loc_range = ut_loc_canonicalize($loc_range);
+ $res_str .= "Canonical lookup result:$result\n";
+
+ }
+
+ $res_str .= "\n";
+ return $res_str;
+
+}
+
+include_once( 'ut_common.inc' );
+ut_run();
+
+?>
+--EXPECT--
+--------------
+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
+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
+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
+Canonical lookup result:sl_it
+--------------
+loc_range:jbo
+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:jbo
+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:art__lojban
diff --git a/ext/intl/tests/msgfmt_format_datetime.phpt b/ext/intl/tests/msgfmt_format_datetime.phpt
new file mode 100644
index 0000000000..07e7d68f14
--- /dev/null
+++ b/ext/intl/tests/msgfmt_format_datetime.phpt
@@ -0,0 +1,28 @@
+--TEST--
+MessageFormatter::format(): DateTime accepted to format dates and times
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+//ini_set("intl.default_locale", "nl");
+
+$fmt = <<<EOD
+{0,date} {0,time}
+EOD;
+
+$dt = new DateTime("2012-05-06 18:00:42", new DateTimeZone("Europe/Lisbon"));
+
+$mf = new MessageFormatter('en_US', $fmt);
+
+var_dump($mf->format(array($dt)));
+
+?>
+==DONE==
+--EXPECTF--
+string(%s) "May %d, 2012 %d:%d:42 %s"
+==DONE==
diff --git a/ext/intl/tests/msgfmt_format_error1.phpt b/ext/intl/tests/msgfmt_format_error1.phpt
new file mode 100644
index 0000000000..684b05970a
--- /dev/null
+++ b/ext/intl/tests/msgfmt_format_error1.phpt
@@ -0,0 +1,19 @@
+--TEST--
+MessageFormatter::format() insufficient numeric arguments
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$fmt = <<<EOD
+{0} {1}
+EOD;
+
+$mf = new MessageFormatter('en_US', $fmt);
+var_dump($mf->format(array(7)));
+
+--EXPECTF--
+string(5) "7 {1}"
diff --git a/ext/intl/tests/msgfmt_format_error2.phpt b/ext/intl/tests/msgfmt_format_error2.phpt
new file mode 100644
index 0000000000..85d1b1c83d
--- /dev/null
+++ b/ext/intl/tests/msgfmt_format_error2.phpt
@@ -0,0 +1,23 @@
+--TEST--
+MessageFormatter::format() inconsistent types in named argument
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '4.8') < 0)
+ die('skip for ICU 4.8+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$fmt = <<<EOD
+{foo,number} {foo}
+EOD;
+
+$mf = new MessageFormatter('en_US', $fmt);
+var_dump($mf->format(array(7)));
+
+--EXPECTF--
+
+Warning: MessageFormatter::format(): Inconsistent types declared for an argument in %s on line %d
+bool(false)
diff --git a/ext/intl/tests/msgfmt_format_error3.phpt b/ext/intl/tests/msgfmt_format_error3.phpt
new file mode 100644
index 0000000000..6dfbee3c90
--- /dev/null
+++ b/ext/intl/tests/msgfmt_format_error3.phpt
@@ -0,0 +1,23 @@
+--TEST--
+MessageFormatter::format() given negative arg key
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '4.8') < 0)
+ die('skip for ICU 4.8+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$fmt = <<<EOD
+{foo,number,percent}
+EOD;
+
+$mf = new MessageFormatter('en_US', $fmt);
+var_dump($mf->format(array("foo" => 7, -1 => "bar")));
+
+--EXPECTF--
+
+Warning: MessageFormatter::format(): Found negative or too large array key in %s on line %d
+bool(false)
diff --git a/ext/intl/tests/msgfmt_format_error4.phpt b/ext/intl/tests/msgfmt_format_error4.phpt
new file mode 100644
index 0000000000..3b92b48b8b
--- /dev/null
+++ b/ext/intl/tests/msgfmt_format_error4.phpt
@@ -0,0 +1,28 @@
+--TEST--
+MessageFormatter::format() invalid UTF-8 for arg key or value
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '4.8') < 0)
+ die('skip for ICU 4.8+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$fmt = <<<EOD
+{foo}
+EOD;
+
+$mf = new MessageFormatter('en_US', $fmt);
+var_dump($mf->format(array("foo" => 7, "\x80" => "bar")));
+
+var_dump($mf->format(array("foo" => "\x80")));
+
+--EXPECTF--
+
+Warning: MessageFormatter::format(): Invalid UTF-8 data in argument key: '' in %s on line %d
+bool(false)
+
+Warning: MessageFormatter::format(): Invalid UTF-8 data in string argument: '' in %s on line %d
+bool(false)
diff --git a/ext/intl/tests/msgfmt_format_error5.phpt b/ext/intl/tests/msgfmt_format_error5.phpt
new file mode 100644
index 0000000000..ebbd4550e8
--- /dev/null
+++ b/ext/intl/tests/msgfmt_format_error5.phpt
@@ -0,0 +1,26 @@
+--TEST--
+MessageFormatter::format() invalid date/time argument
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '4.8') < 0)
+ die('skip for ICU 4.8+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$fmt = <<<EOD
+{foo,date}
+EOD;
+
+$mf = new MessageFormatter('en_US', $fmt);
+var_dump($mf->format(array("foo" => new stdclass())));
+
+--EXPECTF--
+Warning: MessageFormatter::format(): msgfmt_format: invalid object type for date/time (only IntlCalendar and DateTime permitted) in %s on line %d
+
+Warning: MessageFormatter::format(): The argument for key 'foo' cannot be used as a date or time in %s on line %d
+bool(false)
diff --git a/ext/intl/tests/msgfmt_format_error6.phpt b/ext/intl/tests/msgfmt_format_error6.phpt
new file mode 100644
index 0000000000..b07d2ab774
--- /dev/null
+++ b/ext/intl/tests/msgfmt_format_error6.phpt
@@ -0,0 +1,23 @@
+--TEST--
+MessageFormatter::format() invalid type for key not in pattern
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '4.8') < 0)
+ die('skip for ICU 4.8+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$fmt = <<<EOD
+{foo}
+EOD;
+
+$mf = new MessageFormatter('en_US', $fmt);
+var_dump($mf->format(array("foo" => 'bar', 7 => fopen('php://memory', 'r+'))));
+
+--EXPECTF--
+
+Warning: MessageFormatter::format(): No strategy to convert the value given for the argument with key '7' is available in %s on line %d
+bool(false)
diff --git a/ext/intl/tests/msgfmt_format_intlcalendar.phpt b/ext/intl/tests/msgfmt_format_intlcalendar.phpt
new file mode 100644
index 0000000000..a6bff2ecdd
--- /dev/null
+++ b/ext/intl/tests/msgfmt_format_intlcalendar.phpt
@@ -0,0 +1,30 @@
+--TEST--
+MessageFormat accepts IntlCalendar args
+--SKIPIF--
+<?php
+if (!extension_loaded('intl')) die('skip intl extension not enabled'); ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') >= 0) die('skip for ICU < 51.2'); ?>
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+//ini_set("intl.default_locale", "nl");
+ini_set('date.timezone', 'Europe/Lisbon');
+
+$cal = new IntlGregorianCalendar(2012,04,17,17,35,36);
+
+$msgf = new MessageFormatter('pt_PT', '{0,date,full} {0,time,h:m:s a V}');
+echo $msgf->format(array($cal)), "\n";
+
+//NOT FIXED:
+/*$msgf = new MessageFormatter('en_US',
+'{1, select, date {{0,date,full}} other {{0,time,h:m:s a V}}}');
+
+echo "msgf2: ", $msgf->format(array($time, 'date')), " ",
+ $msgf->format(array($time, 'time')), "\n";
+*/
+
+?>
+==DONE==
+--EXPECT--
+Quinta-feira, 17 de Maio de 2012 5:35:36 p.m. WEST
+==DONE==
diff --git a/ext/intl/tests/msgfmt_format_intlcalendar_variant2.phpt b/ext/intl/tests/msgfmt_format_intlcalendar_variant2.phpt
new file mode 100644
index 0000000000..f2d16b899d
--- /dev/null
+++ b/ext/intl/tests/msgfmt_format_intlcalendar_variant2.phpt
@@ -0,0 +1,30 @@
+--TEST--
+MessageFormat accepts IntlCalendar args
+--SKIPIF--
+<?php
+if (!extension_loaded('intl')) die('skip intl extension not enabled'); ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') < 0) die('skip for ICU >= 51.2'); ?>
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+//ini_set("intl.default_locale", "nl");
+ini_set('date.timezone', 'Europe/Lisbon');
+
+$cal = new IntlGregorianCalendar(2012,04,17,17,35,36);
+
+$msgf = new MessageFormatter('pt_PT', '{0,date,full} {0,time,h:m:s a V}');
+echo $msgf->format(array($cal)), "\n";
+
+//NOT FIXED:
+/*$msgf = new MessageFormatter('en_US',
+'{1, select, date {{0,date,full}} other {{0,time,h:m:s a V}}}');
+
+echo "msgf2: ", $msgf->format(array($time, 'date')), " ",
+ $msgf->format(array($time, 'time')), "\n";
+*/
+
+?>
+==DONE==
+--EXPECT--
+Quinta-feira, 17 de Maio de 2012 5:35:36 PM ptlis
+==DONE==
diff --git a/ext/intl/tests/msgfmt_format_mixed_params.phpt b/ext/intl/tests/msgfmt_format_mixed_params.phpt
new file mode 100644
index 0000000000..93412f49e2
--- /dev/null
+++ b/ext/intl/tests/msgfmt_format_mixed_params.phpt
@@ -0,0 +1,25 @@
+--TEST--
+MessageFormatter::format(): mixed named and numeric parameters
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '4.8') < 0)
+ die('skip for ICU 4.8+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+//ini_set("intl.default_locale", "nl");
+
+$mf = new MessageFormatter('en_US',
+ "{0,number} -- {foo,ordinal}");
+
+var_dump($mf->format(array(2.3, "foo" => 1.3)));
+var_dump($mf->format(array("foo" => 1.3, 0 => 2.3)));
+
+?>
+==DONE==
+--EXPECT--
+string(10) "2.3 -- 1st"
+string(10) "2.3 -- 1st"
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/msgfmt_format_simple_types_numeric_strings.phpt b/ext/intl/tests/msgfmt_format_simple_types_numeric_strings.phpt
new file mode 100644
index 0000000000..299ae483a4
--- /dev/null
+++ b/ext/intl/tests/msgfmt_format_simple_types_numeric_strings.phpt
@@ -0,0 +1,58 @@
+--TEST--
+MessageFormatter::format(): simple types handling with numeric strings
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '4.8') < 0)
+ die('skip for ICU 4.8+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+//ini_set("intl.default_locale", "nl");
+
+$mf = new MessageFormatter('en_US',"
+ none {a}
+ number {b,number}
+ number integer {c,number,integer}
+ number currency {d,number,currency}
+ number percent {e,number,percent}
+ date {f,date}
+ time {g,time}
+ spellout {h,spellout}
+ ordinal {i,ordinal}
+ duration {j,duration}
+ ");
+
+$ex = "1336317965.5 str";
+var_dump($mf->format(array(
+'a' => $ex,
+'b' => $ex,
+'c' => $ex,
+'d' => $ex,
+'e' => $ex,
+'f' => " 1336317965.5",
+'g' => " 1336317965.5",
+'h' => $ex,
+'i' => $ex,
+'j' => $ex,
+)));
+
+?>
+==DONE==
+--EXPECTF--
+string(%d) "
+ none 1336317965.5 str
+ number 1,336,317,965.5
+ number integer 1,336,317,965
+ number currency $1,336,317,965.50
+ number percent 133,631,796,550%
+ date May %d, 2012
+ time %d:%d:05 PM
+ spellout one billion three hundred thirty-six million three hundred seventeen thousand nine hundred sixty-five point five
+ ordinal 1,336,317,966th
+ duration 371,199:26:06
+ "
+==DONE==
diff --git a/ext/intl/tests/msgfmt_format_subpatterns.phpt b/ext/intl/tests/msgfmt_format_subpatterns.phpt
new file mode 100644
index 0000000000..9f11e3e255
--- /dev/null
+++ b/ext/intl/tests/msgfmt_format_subpatterns.phpt
@@ -0,0 +1,75 @@
+--TEST--
+msgfmt_format() with subpatterns
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '4.8') < 0)
+ die('skip for ICU 4.8+');
+--FILE--
+<?php
+
+/*
+ * Format a number using misc locales/patterns.
+ */
+
+
+function ut_main()
+{
+
+$pattern=<<<_MSG_
+{0, select,
+ female {{1, plural, offset:1
+ =0 {{2} does not give a party.}
+ =1 {{2} invites {3} to her party.}
+ =2 {{2} invites {3} and one other person to her party.}
+ other {{2} invites {3} as one of the # people invited to her party.}}}
+ male {{1, plural, offset:1
+ =0 {{2} does not give a party.}
+ =1 {{2} invites {3} to his party.}
+ =2 {{2} invites {3} and one other person to his party.}
+ other {{2} invites {3} as one of the # other people invited to his party.}}}
+ other {{1, plural, offset:1
+ =0 {{2} does not give a party.}
+ =1 {{2} invites {3} to their party.}
+ =2 {{2} invites {3} and one other person to their party.}
+ other {{2} invites {3} as one of the # other people invited to their party.}}}}
+_MSG_;
+
+
+$args = array(
+ array('female', 0, 'Alice', 'Bob'),
+ array('male', 1, 'Alice', 'Bob'),
+ array('none', 2, 'Alice', 'Bob'),
+ array('female', 27, 'Alice', 'Bob'),
+);
+
+$str_res = '';
+
+ $fmt = ut_msgfmt_create( 'en_US', $pattern );
+ if(!$fmt) {
+ $str_res .= dump(intl_get_error_message())."\n";
+ return $str_res;
+ }
+ foreach ($args as $arg) {
+ $str_res .= dump( ut_msgfmt_format($fmt, $arg) ). "\n";
+ $str_res .= dump( ut_msgfmt_format_message('en_US', $pattern, $arg) ) . "\n";
+ }
+ return $str_res;
+}
+
+include_once( 'ut_common.inc' );
+
+// Run the test
+ut_run();
+
+?>
+--EXPECT--
+'Alice does not give a party.'
+'Alice does not give a party.'
+'Alice invites Bob to his party.'
+'Alice invites Bob to his party.'
+'Alice invites Bob and one other person to their party.'
+'Alice invites Bob and one other person to their party.'
+'Alice invites Bob as one of the 26 people invited to her party.'
+'Alice invites Bob as one of the 26 people invited to her party.'
diff --git a/ext/intl/tests/msgfmt_format_subpatterns_named.phpt b/ext/intl/tests/msgfmt_format_subpatterns_named.phpt
new file mode 100644
index 0000000000..f6af02561b
--- /dev/null
+++ b/ext/intl/tests/msgfmt_format_subpatterns_named.phpt
@@ -0,0 +1,75 @@
+--TEST--
+msgfmt_format() with named subpatterns
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '4.8') < 0)
+ die('skip for ICU 4.8+');
+--FILE--
+<?php
+
+/*
+ * Format a number using misc locales/patterns.
+ */
+
+
+function ut_main()
+{
+
+$pattern=<<<_MSG_
+{gender_of_host, select,
+ female {{num_guests, plural, offset:1
+ =0 {{host} does not give a party.}
+ =1 {{host} invites {guest} to her party.}
+ =2 {{host} invites {guest} and one other person to her party.}
+ other {{host} invites {guest} as one of the # people invited to her party.}}}
+ male {{num_guests, plural, offset:1
+ =0 {{host} does not give a party.}
+ =1 {{host} invites {guest} to his party.}
+ =2 {{host} invites {guest} and one other person to his party.}
+ other {{host} invites {guest} as one of the # people invited to his party.}}}
+ other {{num_guests, plural, offset:1
+ =0 {{host} does not give a party.}
+ =1 {{host} invites {guest} to their party.}
+ =2 {{host} invites {guest} and one other person to their party.}
+ other {{host} invites {guest} as one of the # people invited to their party.}}}}
+_MSG_;
+
+
+$args = array(
+ array('gender_of_host' => 'female', 'num_guests' => 0, 'host' => 'Alice', 'guest' => 'Bob'),
+ array('gender_of_host' => 'male', 'num_guests' => 1, 'host' => 'Alice', 'guest' => 'Bob'),
+ array('gender_of_host' => 'none', 'num_guests' => 2, 'host' => 'Alice', 'guest' => 'Bob'),
+ array('gender_of_host' => 'female', 'num_guests' => 27, 'host' => 'Alice', 'guest' => 'Bob'),
+);
+
+$str_res = '';
+
+ $fmt = ut_msgfmt_create( 'en_US', $pattern );
+ if(!$fmt) {
+ $str_res .= dump(intl_get_error_message())."\n";
+ return $str_res;
+ }
+ foreach ($args as $arg) {
+ $str_res .= dump( ut_msgfmt_format($fmt, $arg) ). "\n";
+ $str_res .= dump( ut_msgfmt_format_message('en_US', $pattern, $arg) ) . "\n";
+ }
+ return $str_res;
+}
+
+include_once( 'ut_common.inc' );
+
+// Run the test
+ut_run();
+
+?>
+--EXPECT--
+'Alice does not give a party.'
+'Alice does not give a party.'
+'Alice invites Bob to his party.'
+'Alice invites Bob to his party.'
+'Alice invites Bob and one other person to their party.'
+'Alice invites Bob and one other person to their party.'
+'Alice invites Bob as one of the 26 people invited to her party.'
+'Alice invites Bob as one of the 26 people invited to her party.'
diff --git a/ext/intl/tests/msgfmt_get_error.phpt b/ext/intl/tests/msgfmt_get_error.phpt
deleted file mode 100644
index 015c50d465..0000000000
--- a/ext/intl/tests/msgfmt_get_error.phpt
+++ /dev/null
@@ -1,29 +0,0 @@
---TEST--
-msgmfmt_get_error_message/code()
---SKIPIF--
-<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
---FILE--
-<?php
-
-/*
- * Error handling.
- */
-
-
-function ut_main()
-{
- $fmt = ut_msgfmt_create( "en_US", "{0, number} monkeys on {1, number} trees" );
- $num = ut_msgfmt_format( $fmt, array());
- if( $num === false )
- return $fmt->getErrorMessage() . " (" . $fmt->getErrorCode() . ")\n";
- else
- return "Ooops, an error should have occured.";
-}
-
-include_once( 'ut_common.inc' );
-
-// Run the test
-ut_run();
-?>
---EXPECT--
-msgfmt_format: not enough parameters: U_ILLEGAL_ARGUMENT_ERROR (1)
diff --git a/ext/intl/tests/msgfmt_millisecond_dates.phpt b/ext/intl/tests/msgfmt_millisecond_dates.phpt
new file mode 100644
index 0000000000..7dd051426b
--- /dev/null
+++ b/ext/intl/tests/msgfmt_millisecond_dates.phpt
@@ -0,0 +1,29 @@
+--TEST--
+MessageFrormatter parses and formats dates with millisecond precision
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+date_default_timezone_set('Europe/Lisbon'); //ignored for now, see bug #58756
+
+$d = 1336308097.123;
+$mf = new MessageFormatter('en_US',
+ "On {0,time,yyyy-MM-dd G 'at' HH:mm:ss.SSS zzz} something odd happened");
+
+var_dump($mf->format(array(1336310569.123)));
+
+$p = 'On 2012-05-06 AD at 15:22:49.123 GMT+02:00 something odd happened';
+var_dump($mf->parse($p));
+
+?>
+==DONE==
+--EXPECTF--
+string(%d) "On 2012-05-0%d AD at %d:%d:49.123 %s something odd happened"
+array(1) {
+ [0]=>
+ float(1336310569.123)
+}
+==DONE==
diff --git a/ext/intl/tests/msgfmt_setPattern_cache.phpt b/ext/intl/tests/msgfmt_setPattern_cache.phpt
new file mode 100644
index 0000000000..35ec463c2a
--- /dev/null
+++ b/ext/intl/tests/msgfmt_setPattern_cache.phpt
@@ -0,0 +1,26 @@
+--TEST--
+MessageFormatter::setPattern() invalidates arg types cache
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+//ini_set("intl.default_locale", "nl");
+
+$mf = new MessageFormatter('en_US',
+ "{0,number} -- {1,ordinal}");
+
+var_dump($mf->format(array(1.3, 1.3)));
+var_dump($mf->format(array(1.3, 1.3)));
+$mf->setPattern("{0,ordinal} -- {1,number}");
+var_dump($mf->format(array(1.3, 1.3)));
+
+?>
+==DONE==
+--EXPECT--
+string(10) "1.3 -- 1st"
+string(10) "1.3 -- 1st"
+string(10) "1st -- 1.3"
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/rbbiter___construct_basic.phpt b/ext/intl/tests/rbbiter___construct_basic.phpt
new file mode 100644
index 0000000000..6fb584fdee
--- /dev/null
+++ b/ext/intl/tests/rbbiter___construct_basic.phpt
@@ -0,0 +1,31 @@
+--TEST--
+IntlRuleBasedBreakIterator::__construct: basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+
+$rules = <<<RULES
+\$LN = [[:letter:] [:number:]];
+\$S = [.;,:];
+
+!!forward;
+\$LN+ {1};
+\$S+ {42};
+!!reverse;
+\$LN+ {1};
+\$S+ {42};
+!!safe_forward;
+!!safe_reverse;
+RULES;
+$rbbi = new IntlRuleBasedBreakIterator($rules);
+var_dump(get_class($rbbi));
+?>
+==DONE==
+--EXPECT--
+string(26) "IntlRuleBasedBreakIterator"
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/rbbiter_getBinaryRules_basic.phpt b/ext/intl/tests/rbbiter_getBinaryRules_basic.phpt
new file mode 100644
index 0000000000..dce0714d4d
--- /dev/null
+++ b/ext/intl/tests/rbbiter_getBinaryRules_basic.phpt
@@ -0,0 +1,39 @@
+--TEST--
+IntlRuleBasedBreakIterator::getBinaryRules(): basic test
+--SKIPIF--
+<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+<?php if(version_compare(INTL_ICU_VERSION, '4.8') < 0) print 'skip ICU >= 4.8 only'; ?>
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+
+$rules = <<<RULES
+\$LN = [[:letter:] [:number:]];
+\$S = [.;,:];
+
+!!forward;
+\$LN+ {1};
+\$S+ {42};
+!!reverse;
+\$LN+ {1};
+\$S+ {42};
+!!safe_forward;
+!!safe_reverse;
+RULES;
+$rbbi = new IntlRuleBasedBreakIterator($rules);
+$rbbi->setText('sdfkjsdf88á.... ,;');;
+
+$br = $rbbi->getBinaryRules();
+
+$rbbi2 = new IntlRuleBasedBreakIterator($br, true);
+
+var_dump($rbbi->getRules(), $rbbi2->getRules());
+var_dump($rbbi->getRules() == $rbbi2->getRules());
+?>
+==DONE==
+--EXPECT--
+string(128) "$LN = [[:letter:] [:number:]];$S = [.;,:];!!forward;$LN+ {1};$S+ {42};!!reverse;$LN+ {1};$S+ {42};!!safe_forward;!!safe_reverse;"
+string(128) "$LN = [[:letter:] [:number:]];$S = [.;,:];!!forward;$LN+ {1};$S+ {42};!!reverse;$LN+ {1};$S+ {42};!!safe_forward;!!safe_reverse;"
+bool(true)
+==DONE==
diff --git a/ext/intl/tests/rbbiter_getRuleStatusVec_basic.phpt b/ext/intl/tests/rbbiter_getRuleStatusVec_basic.phpt
new file mode 100644
index 0000000000..a56f6bc488
--- /dev/null
+++ b/ext/intl/tests/rbbiter_getRuleStatusVec_basic.phpt
@@ -0,0 +1,59 @@
+--TEST--
+IntlRuleBasedBreakIterator::getRuleStatusVec(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+
+$rules = <<<RULES
+\$LN = [[:letter:] [:number:]];
+\$S = [.;,:];
+
+!!forward;
+\$LN+ {1};
+[^.]+ {4};
+\$S+ {42};
+!!reverse;
+\$LN+ {1};
+[^.]+ {4};
+\$S+ {42};
+!!safe_forward;
+!!safe_reverse;
+RULES;
+$rbbi = new IntlRuleBasedBreakIterator($rules);
+$rbbi->setText('sdfkjsdf88á.... ,;');;
+
+do {
+ var_dump($rbbi->current(), $rbbi->getRuleStatusVec());
+} while ($rbbi->next() != IntlBreakIterator::DONE);
+
+?>
+==DONE==
+--EXPECT--
+int(0)
+array(1) {
+ [0]=>
+ int(0)
+}
+int(12)
+array(2) {
+ [0]=>
+ int(1)
+ [1]=>
+ int(4)
+}
+int(16)
+array(1) {
+ [0]=>
+ int(42)
+}
+int(19)
+array(1) {
+ [0]=>
+ int(4)
+}
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/rbbiter_getRuleStatus_basic.phpt b/ext/intl/tests/rbbiter_getRuleStatus_basic.phpt
new file mode 100644
index 0000000000..80eedbfba5
--- /dev/null
+++ b/ext/intl/tests/rbbiter_getRuleStatus_basic.phpt
@@ -0,0 +1,46 @@
+--TEST--
+IntlRuleBasedBreakIterator::getRuleStatus(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+
+$rules = <<<RULES
+\$LN = [[:letter:] [:number:]];
+\$S = [.;,:];
+
+!!forward;
+\$LN+ {1};
+\$S+ {42};
+!!reverse;
+\$LN+ {1};
+\$S+ {42};
+!!safe_forward;
+!!safe_reverse;
+RULES;
+$rbbi = new IntlRuleBasedBreakIterator($rules);
+$rbbi->setText('sdfkjsdf88á.... ,;');
+
+do {
+ echo "pos : {$rbbi->current()}\n",
+ "rule status: {$rbbi->getRuleStatus()}\n";
+} while ($rbbi->next() != IntlBreakIterator::DONE);
+
+?>
+==DONE==
+--EXPECT--
+pos : 0
+rule status: 0
+pos : 12
+rule status: 1
+pos : 16
+rule status: 42
+pos : 17
+rule status: 0
+pos : 19
+rule status: 42
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/rbbiter_getRules_basic.phpt b/ext/intl/tests/rbbiter_getRules_basic.phpt
new file mode 100644
index 0000000000..2f7a40eb71
--- /dev/null
+++ b/ext/intl/tests/rbbiter_getRules_basic.phpt
@@ -0,0 +1,32 @@
+--TEST--
+IntlRuleBasedBreakIterator::getRules(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "pt_PT");
+
+$rules = <<<RULES
+\$LN = [[:letter:] [:number:]];
+\$S = [.;,:];
+
+!!forward;
+\$LN+ {1};
+\$S+ {42};
+!!reverse;
+\$LN+ {1};
+\$S+ {42};
+!!safe_forward;
+!!safe_reverse;
+RULES;
+$rbbi = new IntlRuleBasedBreakIterator($rules);
+var_dump($rbbi->getRules());
+
+?>
+==DONE==
+--EXPECT--
+string(128) "$LN = [[:letter:] [:number:]];$S = [.;,:];!!forward;$LN+ {1};$S+ {42};!!reverse;$LN+ {1};$S+ {42};!!safe_forward;!!safe_reverse;"
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/resourcebundle_null_mandatory_args.phpt b/ext/intl/tests/resourcebundle_null_mandatory_args.phpt
index 17fab6d630..bbbc1b1e91 100644
--- a/ext/intl/tests/resourcebundle_null_mandatory_args.phpt
+++ b/ext/intl/tests/resourcebundle_null_mandatory_args.phpt
@@ -3,11 +3,9 @@ ResourceBundle constructor bundle accepts NULL for first two arguments
--INI--
date.timezone=Atlantic/Azores
--SKIPIF--
-<?php
-if (!extension_loaded('intl'))
- die('skip intl extension not enabled');
-if (version_compare(INTL_ICU_VERSION, '4.8') < 0)
- die('skip ICU >= 4.8 only');
+<?php if (!extension_loaded('intl')) die('skip intl extension not enabled'); ?>
+<?php if (version_compare(INTL_ICU_VERSION, '4.8') < 0) die('skip ICU >= 4.8 only'); ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') >= 0) die('skip for ICU < 51.2'); ?>
--FILE--
<?php
ini_set("intl.error_level", E_WARNING);
diff --git a/ext/intl/tests/resourcebundle_null_mandatory_args_variant2.phpt b/ext/intl/tests/resourcebundle_null_mandatory_args_variant2.phpt
new file mode 100644
index 0000000000..cf721c8ef2
--- /dev/null
+++ b/ext/intl/tests/resourcebundle_null_mandatory_args_variant2.phpt
@@ -0,0 +1,26 @@
+--TEST--
+ResourceBundle constructor bundle accepts NULL for first two arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl')) die('skip intl extension not enabled'); ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') < 0) die('skip for ICU >= 51.2'); ?>
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$r = new ResourceBundle('en_US', NULL);
+$c = $r->get('calendar')->get('gregorian')->get('DateTimePatterns')->get(0);
+var_dump($c);
+
+ini_set('intl.default_locale', 'pt_PT');
+$r = new ResourceBundle(NULL, NULL);
+$c = $r->get('calendar')->get('gregorian')->get('DateTimePatterns')->get(0);
+var_dump($c);
+?>
+==DONE==
+--EXPECT--
+string(14) "h:mm:ss a zzzz"
+string(13) "HH:mm:ss zzzz"
+==DONE==
diff --git a/ext/intl/tests/timezone_clone_basic.phpt b/ext/intl/tests/timezone_clone_basic.phpt
new file mode 100644
index 0000000000..a8ef83f864
--- /dev/null
+++ b/ext/intl/tests/timezone_clone_basic.phpt
@@ -0,0 +1,51 @@
+--TEST--
+IntlTimeZone clone handler: basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$tz1 = IntlTimeZone::createTimeZone('Europe/Amsterdam');
+print_r($tz1);
+print_r(clone $tz1);
+
+//clone non-owned object
+$gmt = IntlTimeZone::getGMT();
+print_r($gmt);
+print_r(clone $gmt);
+
+?>
+==DONE==
+--EXPECTF--
+IntlTimeZone Object
+(
+ [valid] => 1
+ [id] => Europe/Amsterdam
+ [rawOffset] => 3600000
+ [currentOffset] => %d
+)
+IntlTimeZone Object
+(
+ [valid] => 1
+ [id] => Europe/Amsterdam
+ [rawOffset] => 3600000
+ [currentOffset] => %d
+)
+IntlTimeZone Object
+(
+ [valid] => 1
+ [id] => GMT
+ [rawOffset] => 0
+ [currentOffset] => 0
+)
+IntlTimeZone Object
+(
+ [valid] => 1
+ [id] => GMT
+ [rawOffset] => 0
+ [currentOffset] => 0
+)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/timezone_clone_error.phpt b/ext/intl/tests/timezone_clone_error.phpt
new file mode 100644
index 0000000000..df501be3b4
--- /dev/null
+++ b/ext/intl/tests/timezone_clone_error.phpt
@@ -0,0 +1,32 @@
+--TEST--
+IntlTimeZone clone handler: error test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+class A extends IntlTimeZone {
+function __construct() {}
+}
+
+$tz = new A();
+var_dump($tz);
+try {
+var_dump(clone $tz);
+} catch (Exception $e) {
+ var_dump(get_class($e), $e->getMessage());
+}
+
+?>
+==DONE==
+--EXPECT--
+object(A)#1 (1) {
+ ["valid"]=>
+ bool(false)
+}
+string(9) "Exception"
+string(39) "Cannot clone unconstructed IntlTimeZone"
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/timezone_countEquivalentIDs_basic.phpt b/ext/intl/tests/timezone_countEquivalentIDs_basic.phpt
new file mode 100644
index 0000000000..ec3e4050ab
--- /dev/null
+++ b/ext/intl/tests/timezone_countEquivalentIDs_basic.phpt
@@ -0,0 +1,20 @@
+--TEST--
+IntlTimeZone::countEquivalentIDs(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+$count = IntlTimeZone::countEquivalentIDs('Europe/Lisbon');
+var_dump($count >= 2);
+
+$count2 = intltz_count_equivalent_ids('Europe/Lisbon');
+var_dump($count2 == $count);
+?>
+==DONE==
+--EXPECT--
+bool(true)
+bool(true)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/timezone_countEquivalentIDs_error.phpt b/ext/intl/tests/timezone_countEquivalentIDs_error.phpt
new file mode 100644
index 0000000000..4d8f4bc3e3
--- /dev/null
+++ b/ext/intl/tests/timezone_countEquivalentIDs_error.phpt
@@ -0,0 +1,35 @@
+--TEST--
+IntlTimeZone::countEquivalentIDs(): errors
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+var_dump(IntlTimeZone::countEquivalentIDs());
+var_dump(IntlTimeZone::countEquivalentIDs(array()));
+var_dump(IntlTimeZone::countEquivalentIDs("foo\x80"));
+var_dump(IntlTimeZone::countEquivalentIDs("foo bar", 7));
+
+
+--EXPECTF--
+
+Warning: IntlTimeZone::countEquivalentIDs() expects exactly 1 parameter, 0 given in %s on line %d
+
+Warning: IntlTimeZone::countEquivalentIDs(): intltz_count_equivalent_ids: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlTimeZone::countEquivalentIDs() expects parameter 1 to be string, array given in %s on line %d
+
+Warning: IntlTimeZone::countEquivalentIDs(): intltz_count_equivalent_ids: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlTimeZone::countEquivalentIDs(): intltz_count_equivalent_ids: could not convert time zone id to UTF-16 in %s on line %d
+bool(false)
+
+Warning: IntlTimeZone::countEquivalentIDs() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: IntlTimeZone::countEquivalentIDs(): intltz_count_equivalent_ids: bad arguments in %s on line %d
+bool(false)
diff --git a/ext/intl/tests/timezone_createDefault_basic.phpt b/ext/intl/tests/timezone_createDefault_basic.phpt
new file mode 100644
index 0000000000..1988d3b9e5
--- /dev/null
+++ b/ext/intl/tests/timezone_createDefault_basic.phpt
@@ -0,0 +1,31 @@
+--TEST--
+IntlTimeZone::createDefault(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+$tz = IntlTimeZone::createDefault();
+print_r($tz);
+$tz = intltz_create_default();
+print_r($tz);
+?>
+==DONE==
+--EXPECTF--
+IntlTimeZone Object
+(
+ [valid] => 1
+ [id] => %s
+ [rawOffset] => %i
+ [currentOffset] => %i
+)
+IntlTimeZone Object
+(
+ [valid] => 1
+ [id] => %s
+ [rawOffset] => %i
+ [currentOffset] => %i
+)
+==DONE==
diff --git a/ext/intl/tests/timezone_createDefault_error.phpt b/ext/intl/tests/timezone_createDefault_error.phpt
new file mode 100644
index 0000000000..0724898219
--- /dev/null
+++ b/ext/intl/tests/timezone_createDefault_error.phpt
@@ -0,0 +1,19 @@
+--TEST--
+IntlTimeZone::createDefault(): errors
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+var_dump(IntlTimeZone::createDefault(4));
+
+
+--EXPECTF--
+
+Warning: IntlTimeZone::createDefault() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlTimeZone::createDefault(): intltz_create_default: bad arguments in %s on line %d
+NULL
diff --git a/ext/intl/tests/timezone_createEnumeration_basic.phpt b/ext/intl/tests/timezone_createEnumeration_basic.phpt
new file mode 100644
index 0000000000..2df32562b1
--- /dev/null
+++ b/ext/intl/tests/timezone_createEnumeration_basic.phpt
@@ -0,0 +1,26 @@
+--TEST--
+IntlTimeZone::createEnumeration(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+$tz = IntlTimeZone::createEnumeration();
+var_dump(get_class($tz));
+$count = count(iterator_to_array($tz));
+var_dump($count > 300);
+
+$tz = intltz_create_enumeration();
+var_dump(get_class($tz));
+$count2 = count(iterator_to_array($tz));
+var_dump($count == $count2);
+?>
+==DONE==
+--EXPECT--
+string(12) "IntlIterator"
+bool(true)
+string(12) "IntlIterator"
+bool(true)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/timezone_createEnumeration_error.phpt b/ext/intl/tests/timezone_createEnumeration_error.phpt
new file mode 100644
index 0000000000..e1e7cb9333
--- /dev/null
+++ b/ext/intl/tests/timezone_createEnumeration_error.phpt
@@ -0,0 +1,23 @@
+--TEST--
+IntlTimeZone::createEnumeration(): errors
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+var_dump(IntlTimeZone::createEnumeration(array()));
+var_dump(IntlTimeZone::createEnumeration(1, 2));
+
+
+--EXPECTF--
+
+Warning: IntlTimeZone::createEnumeration(): intltz_create_enumeration: invalid argument type in %s on line %d
+bool(false)
+
+Warning: IntlTimeZone::createEnumeration() expects at most 1 parameter, 2 given in %s on line %d
+
+Warning: IntlTimeZone::createEnumeration(): intltz_create_enumeration: bad arguments in %s on line %d
+bool(false)
diff --git a/ext/intl/tests/timezone_createEnumeration_variation1.phpt b/ext/intl/tests/timezone_createEnumeration_variation1.phpt
new file mode 100644
index 0000000000..30fc43660e
--- /dev/null
+++ b/ext/intl/tests/timezone_createEnumeration_variation1.phpt
@@ -0,0 +1,24 @@
+--TEST--
+IntlTimeZone::createEnumeration(): variant with offset
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+$tz = IntlTimeZone::createEnumeration(3600000);
+var_dump(get_class($tz));
+$count = count(iterator_to_array($tz));
+var_dump($count > 20);
+
+$tz->rewind();
+var_dump(in_array('Europe/Amsterdam', iterator_to_array($tz)));
+
+?>
+==DONE==
+--EXPECT--
+string(12) "IntlIterator"
+bool(true)
+bool(true)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/timezone_createEnumeration_variation2.phpt b/ext/intl/tests/timezone_createEnumeration_variation2.phpt
new file mode 100644
index 0000000000..ddf1a6ece1
--- /dev/null
+++ b/ext/intl/tests/timezone_createEnumeration_variation2.phpt
@@ -0,0 +1,24 @@
+--TEST--
+IntlTimeZone::createEnumeration(): variant with country
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+$tz = IntlTimeZone::createEnumeration('NL');
+var_dump(get_class($tz));
+$count = count(iterator_to_array($tz));
+var_dump($count >= 1);
+
+$tz->rewind();
+var_dump(in_array('Europe/Amsterdam', iterator_to_array($tz)));
+
+?>
+==DONE==
+--EXPECT--
+string(12) "IntlIterator"
+bool(true)
+bool(true)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/timezone_createTimeZoneIDEnumeration_basic.phpt b/ext/intl/tests/timezone_createTimeZoneIDEnumeration_basic.phpt
new file mode 100644
index 0000000000..9ceffc5289
--- /dev/null
+++ b/ext/intl/tests/timezone_createTimeZoneIDEnumeration_basic.phpt
@@ -0,0 +1,34 @@
+--TEST--
+IntlTimeZone::createTimeZoneIDEnumeration(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '4.8') < 0)
+ die('skip for ICU 4.8+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+$enum = IntlTimeZone::createTimeZoneIDEnumeration(
+ IntlTimeZone::TYPE_ANY,
+ 'PT',
+ -3600000);
+print_r(iterator_to_array($enum));
+
+$enum = intltz_create_time_zone_id_enumeration(
+ IntlTimeZone::TYPE_ANY,
+ 'PT',
+ -3600000);
+print_r(iterator_to_array($enum));
+?>
+==DONE==
+--EXPECT--
+Array
+(
+ [0] => Atlantic/Azores
+)
+Array
+(
+ [0] => Atlantic/Azores
+)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/timezone_createTimeZoneIDEnumeration_error.phpt b/ext/intl/tests/timezone_createTimeZoneIDEnumeration_error.phpt
new file mode 100644
index 0000000000..2cc2ac48e7
--- /dev/null
+++ b/ext/intl/tests/timezone_createTimeZoneIDEnumeration_error.phpt
@@ -0,0 +1,42 @@
+--TEST--
+IntlTimeZone::createTimeZoneIDEnumeration(): errors
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '4.8') < 0)
+ die('skip for ICU 4.8+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+var_dump(IntlTimeZone::createTimeZoneIDEnumeration());
+var_dump(IntlTimeZone::createTimeZoneIDEnumeration(array()));
+var_dump(IntlTimeZone::createTimeZoneIDEnumeration(-1));
+var_dump(IntlTimeZone::createTimeZoneIDEnumeration(IntlTimeZone::TYPE_ANY, array()));
+var_dump(IntlTimeZone::createTimeZoneIDEnumeration(IntlTimeZone::TYPE_ANY, "PT", "a80"));
+
+--EXPECTF--
+
+Warning: IntlTimeZone::createTimeZoneIDEnumeration() expects at least 1 parameter, 0 given in %s on line %d
+
+Warning: IntlTimeZone::createTimeZoneIDEnumeration(): intltz_create_time_zone_id_enumeration: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlTimeZone::createTimeZoneIDEnumeration() expects parameter 1 to be long, array given in %s on line %d
+
+Warning: IntlTimeZone::createTimeZoneIDEnumeration(): intltz_create_time_zone_id_enumeration: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlTimeZone::createTimeZoneIDEnumeration(): intltz_create_time_zone_id_enumeration: bad zone type in %s on line %d
+bool(false)
+
+Warning: IntlTimeZone::createTimeZoneIDEnumeration() expects parameter 2 to be string, array given in %s on line %d
+
+Warning: IntlTimeZone::createTimeZoneIDEnumeration(): intltz_create_time_zone_id_enumeration: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlTimeZone::createTimeZoneIDEnumeration() expects parameter 3 to be long, string given in %s on line %d
+
+Warning: IntlTimeZone::createTimeZoneIDEnumeration(): intltz_create_time_zone_id_enumeration: bad arguments in %s on line %d
+bool(false)
diff --git a/ext/intl/tests/timezone_createTimeZoneIDEnumeration_variant1.phpt b/ext/intl/tests/timezone_createTimeZoneIDEnumeration_variant1.phpt
new file mode 100644
index 0000000000..d57dfbf42f
--- /dev/null
+++ b/ext/intl/tests/timezone_createTimeZoneIDEnumeration_variant1.phpt
@@ -0,0 +1,32 @@
+--TEST--
+IntlTimeZone::createTimeZoneIDEnumeration(): variant without offset
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '4.8') < 0)
+ die('skip for ICU 4.8+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+$enum = IntlTimeZone::createTimeZoneIDEnumeration(
+ IntlTimeZone::TYPE_ANY,
+ 'PT');
+$values = iterator_to_array($enum);
+var_dump(in_array('Europe/Lisbon', $values));
+var_dump(in_array('Atlantic/Azores', $values));
+
+$enum = IntlTimeZone::createTimeZoneIDEnumeration(
+ IntlTimeZone::TYPE_ANY,
+ 'PT',
+ null);
+$values2 = iterator_to_array($enum);
+var_dump($values2 == $values);
+
+?>
+==DONE==
+--EXPECT--
+bool(true)
+bool(true)
+bool(true)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/timezone_createTimeZoneIDEnumeration_variant2.phpt b/ext/intl/tests/timezone_createTimeZoneIDEnumeration_variant2.phpt
new file mode 100644
index 0000000000..2afe171c58
--- /dev/null
+++ b/ext/intl/tests/timezone_createTimeZoneIDEnumeration_variant2.phpt
@@ -0,0 +1,52 @@
+--TEST--
+IntlTimeZone::createTimeZoneIDEnumeration(): variant without region
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '4.8') < 0)
+ die('skip for ICU 4.8+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+$enum = IntlTimeZone::createTimeZoneIDEnumeration(
+ IntlTimeZone::TYPE_ANY);
+$countAny = count(iterator_to_array($enum));
+$enum = IntlTimeZone::createTimeZoneIDEnumeration(
+ IntlTimeZone::TYPE_CANONICAL);
+$countCanonical = count(iterator_to_array($enum));
+$enum = IntlTimeZone::createTimeZoneIDEnumeration(
+ IntlTimeZone::TYPE_CANONICAL_LOCATION);
+$countCanonicalLocation = count(iterator_to_array($enum));
+
+var_dump($countAny > $countCanonical);
+var_dump($countCanonical > $countCanonicalLocation);
+
+$enum = IntlTimeZone::createTimeZoneIDEnumeration(
+ IntlTimeZone::TYPE_ANY, null, null);
+$countAny2 = count(iterator_to_array($enum));
+var_dump($countAny == $countAny2);
+
+$enum = IntlTimeZone::createTimeZoneIDEnumeration(
+ IntlTimeZone::TYPE_ANY, null, -3600000);
+$values = iterator_to_array($enum);
+
+print_r(
+array_values(
+array_intersect($values,
+array('Etc/GMT+1', 'Atlantic/Azores'))
+));
+
+
+?>
+==DONE==
+--EXPECT--
+bool(true)
+bool(true)
+bool(true)
+Array
+(
+ [0] => Atlantic/Azores
+ [1] => Etc/GMT+1
+)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/timezone_createTimeZone_basic.phpt b/ext/intl/tests/timezone_createTimeZone_basic.phpt
new file mode 100644
index 0000000000..e79f5b58ee
--- /dev/null
+++ b/ext/intl/tests/timezone_createTimeZone_basic.phpt
@@ -0,0 +1,33 @@
+--TEST--
+IntlTimeZone::createTimeZone(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '4.8') < 0)
+ die('skip for ICU 4.8+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+$tz = IntlTimeZone::createTimeZone('GMT+01:00');
+print_r($tz);
+$tz = intltz_create_time_zone('GMT+01:00');
+print_r($tz);
+?>
+==DONE==
+--EXPECT--
+IntlTimeZone Object
+(
+ [valid] => 1
+ [id] => GMT+01:00
+ [rawOffset] => 3600000
+ [currentOffset] => 3600000
+)
+IntlTimeZone Object
+(
+ [valid] => 1
+ [id] => GMT+01:00
+ [rawOffset] => 3600000
+ [currentOffset] => 3600000
+)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/timezone_createTimeZone_error.phpt b/ext/intl/tests/timezone_createTimeZone_error.phpt
new file mode 100644
index 0000000000..2be821a67e
--- /dev/null
+++ b/ext/intl/tests/timezone_createTimeZone_error.phpt
@@ -0,0 +1,34 @@
+--TEST--
+IntlTimeZone::createTimeZone(): errors
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+var_dump(IntlTimeZone::createTimeZone());
+var_dump(IntlTimeZone::createTimeZone(new stdClass));
+var_dump(IntlTimeZone::createTimeZone("foo bar", 4));
+var_dump(IntlTimeZone::createTimeZone("foo\x80"));
+
+--EXPECTF--
+
+Warning: IntlTimeZone::createTimeZone() expects exactly 1 parameter, 0 given in %s on line %d
+
+Warning: IntlTimeZone::createTimeZone(): intltz_create_time_zone: bad arguments in %s on line %d
+NULL
+
+Warning: IntlTimeZone::createTimeZone() expects parameter 1 to be string, object given in %s on line %d
+
+Warning: IntlTimeZone::createTimeZone(): intltz_create_time_zone: bad arguments in %s on line %d
+NULL
+
+Warning: IntlTimeZone::createTimeZone() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: IntlTimeZone::createTimeZone(): intltz_create_time_zone: bad arguments in %s on line %d
+NULL
+
+Warning: IntlTimeZone::createTimeZone(): intltz_create_time_zone: could not convert time zone id to UTF-16 in %s on line %d
+NULL
diff --git a/ext/intl/tests/timezone_equals_basic.phpt b/ext/intl/tests/timezone_equals_basic.phpt
new file mode 100644
index 0000000000..105ae8582f
--- /dev/null
+++ b/ext/intl/tests/timezone_equals_basic.phpt
@@ -0,0 +1,33 @@
+--TEST--
+IntlTimeZone equals handler: basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$tz1 = intltz_create_time_zone('Europe/Lisbon');
+$tz2 = intltz_create_time_zone('Europe/Lisbon');
+echo "Comparison to self:\n";
+var_dump($tz1 == $tz1);
+echo "Comparison to equal instance:\n";
+var_dump($tz1 == $tz2);
+echo "Comparison to equivalent instance:\n";
+var_dump($tz1 == intltz_create_time_zone('Portugal'));
+echo "Comparison to GMT:\n";
+var_dump($tz1 == intltz_get_gmt());
+
+?>
+==DONE==
+--EXPECT--
+Comparison to self:
+bool(true)
+Comparison to equal instance:
+bool(true)
+Comparison to equivalent instance:
+bool(false)
+Comparison to GMT:
+bool(false)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/timezone_equals_error.phpt b/ext/intl/tests/timezone_equals_error.phpt
new file mode 100644
index 0000000000..d8d027a761
--- /dev/null
+++ b/ext/intl/tests/timezone_equals_error.phpt
@@ -0,0 +1,43 @@
+--TEST--
+IntlTimeZone equals handler: error test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+class A extends IntlTimeZone {
+function __construct() {}
+}
+
+$tz = new A();
+$tz2 = intltz_get_gmt();
+var_dump($tz, $tz2);
+try {
+var_dump($tz == $tz2);
+} catch (Exception $e) {
+ var_dump(get_class($e), $e->getMessage());
+}
+
+?>
+==DONE==
+--EXPECT--
+object(A)#1 (1) {
+ ["valid"]=>
+ bool(false)
+}
+object(IntlTimeZone)#2 (4) {
+ ["valid"]=>
+ bool(true)
+ ["id"]=>
+ string(3) "GMT"
+ ["rawOffset"]=>
+ int(0)
+ ["currentOffset"]=>
+ int(0)
+}
+string(9) "Exception"
+string(63) "Comparison with at least one unconstructed IntlTimeZone operand"
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/timezone_fromDateTimeZone_basic.phpt b/ext/intl/tests/timezone_fromDateTimeZone_basic.phpt
new file mode 100644
index 0000000000..10e2621ae4
--- /dev/null
+++ b/ext/intl/tests/timezone_fromDateTimeZone_basic.phpt
@@ -0,0 +1,41 @@
+--TEST--
+IntlTimeZone::fromDateTimeZone(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+date_default_timezone_set('Europe/Lisbon');
+
+$tz = IntlTimeZone::fromDateTimeZone(new DateTimeZone('Europe/Amsterdam'));
+var_dump($tz->getID(), $tz->getRawOffset());
+
+
+$dt = new DateTime('2012-01-01 00:00:00 CET');
+$dtz = $dt->getTimeZone();
+/* this is different from new DateTimeZone('CET'),
+ * which gives a Europe/Berlin timezone */
+var_dump($dtz->getName());
+$tz = IntlTimeZone::fromDateTimeZone($dtz);
+var_dump($tz->getID(), $tz->getRawOffset());
+
+
+$dt = new DateTime('2012-01-01 00:00:00 +0340');
+$dtz = $dt->getTimeZone();
+/* I don't think this timezone can be generated without a DateTime object */
+var_dump($dtz->getName());
+$tz = IntlTimeZone::fromDateTimeZone($dtz);
+var_dump($tz->getID(), $tz->getRawOffset() /* (3*60+40)*60000 */);
+
+--EXPECTF--
+string(16) "Europe/Amsterdam"
+int(3600000)
+string(3) "CET"
+string(3) "CET"
+int(3600000)
+string(6) "+03:40"
+string(%d) "GMT+03%s0"
+int(13200000)
diff --git a/ext/intl/tests/timezone_fromDateTimeZone_error.phpt b/ext/intl/tests/timezone_fromDateTimeZone_error.phpt
new file mode 100644
index 0000000000..031882277e
--- /dev/null
+++ b/ext/intl/tests/timezone_fromDateTimeZone_error.phpt
@@ -0,0 +1,50 @@
+--TEST--
+IntlTimeZone::fromDateTimeZone(): argument errors
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+var_dump(IntlTimeZone::fromDateTimeZone());
+var_dump(IntlTimeZone::fromDateTimeZone(1,2));
+var_dump(IntlTimeZone::fromDateTimeZone('sdfds'));
+var_dump(IntlTimeZone::fromDateTimeZone(new stdclass));
+$dt = new DateTime('2012-08-01 00:00:00 WEST');
+var_dump(IntlTimeZone::fromDateTimeZone($dt->getTimeZone()));
+
+var_dump(intltz_from_date_time_zone());
+
+--EXPECTF--
+
+Warning: IntlTimeZone::fromDateTimeZone() expects exactly 1 parameter, 0 given in %s on line %d
+
+Warning: IntlTimeZone::fromDateTimeZone(): intltz_from_date_time_zone: bad arguments in %s on line %d
+NULL
+
+Warning: IntlTimeZone::fromDateTimeZone() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: IntlTimeZone::fromDateTimeZone(): intltz_from_date_time_zone: bad arguments in %s on line %d
+NULL
+
+Warning: IntlTimeZone::fromDateTimeZone() expects parameter 1 to be DateTimeZone, string given in %s on line %d
+
+Warning: IntlTimeZone::fromDateTimeZone(): intltz_from_date_time_zone: bad arguments in %s on line %d
+NULL
+
+Warning: IntlTimeZone::fromDateTimeZone() expects parameter 1 to be DateTimeZone, object given in %s on line %d
+
+Warning: IntlTimeZone::fromDateTimeZone(): intltz_from_date_time_zone: bad arguments in %s on line %d
+NULL
+
+Warning: IntlTimeZone::fromDateTimeZone(): intltz_from_date_time_zone: time zone id 'WEST' extracted from ext/date DateTimeZone not recognized in %s on line %d
+NULL
+
+Warning: intltz_from_date_time_zone() expects exactly 1 parameter, 0 given in %s on line %d
+
+Warning: intltz_from_date_time_zone(): intltz_from_date_time_zone: bad arguments in %s on line %d
+NULL
diff --git a/ext/intl/tests/timezone_getCanonicalID_basic.phpt b/ext/intl/tests/timezone_getCanonicalID_basic.phpt
new file mode 100644
index 0000000000..897e9a9edc
--- /dev/null
+++ b/ext/intl/tests/timezone_getCanonicalID_basic.phpt
@@ -0,0 +1,19 @@
+--TEST--
+IntlTimeZone::getCanonicalID: basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+print_R(IntlTimeZone::getCanonicalID('Portugal'));
+echo "\n";
+print_R(intltz_get_canonical_id('Portugal'));
+echo "\n";
+?>
+==DONE==
+--EXPECT--
+Europe/Lisbon
+Europe/Lisbon
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/timezone_getCanonicalID_error.phpt b/ext/intl/tests/timezone_getCanonicalID_error.phpt
new file mode 100644
index 0000000000..c7ffb45b77
--- /dev/null
+++ b/ext/intl/tests/timezone_getCanonicalID_error.phpt
@@ -0,0 +1,32 @@
+--TEST--
+IntlTimeZone::getCanonicalID(): errors
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+var_dump(IntlTimeZone::getCanonicalID());
+var_dump(IntlTimeZone::getCanonicalID(array()));
+var_dump(IntlTimeZone::getCanonicalID("foo\x81"));
+var_dump(IntlTimeZone::getCanonicalID('foobar', null));
+
+
+--EXPECTF--
+
+Warning: IntlTimeZone::getCanonicalID() expects at least 1 parameter, 0 given in %s on line %d
+
+Warning: IntlTimeZone::getCanonicalID(): intltz_get_canonical_id: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlTimeZone::getCanonicalID() expects parameter 1 to be string, array given in %s on line %d
+
+Warning: IntlTimeZone::getCanonicalID(): intltz_get_canonical_id: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlTimeZone::getCanonicalID(): intltz_get_canonical_id: could not convert time zone id to UTF-16 in %s on line %d
+bool(false)
+
+Fatal error: Cannot pass parameter 2 by reference in %s on line %d
diff --git a/ext/intl/tests/timezone_getCanonicalID_variant1.phpt b/ext/intl/tests/timezone_getCanonicalID_variant1.phpt
new file mode 100644
index 0000000000..92a7f07378
--- /dev/null
+++ b/ext/intl/tests/timezone_getCanonicalID_variant1.phpt
@@ -0,0 +1,24 @@
+--TEST--
+IntlTimeZone::getCanonicalID(): second argument
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+var_dump(IntlTimeZone::getCanonicalID('Portugal', $isSystemId));
+var_dump($isSystemId);
+
+var_dump(IntlTimeZone::getCanonicalID('GMT +01:25', $isSystemId));
+var_dump($isSystemId);
+
+?>
+==DONE==
+--EXPECT--
+string(13) "Europe/Lisbon"
+bool(true)
+string(0) ""
+bool(false)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/timezone_getDSTSavings_basic.phpt b/ext/intl/tests/timezone_getDSTSavings_basic.phpt
new file mode 100644
index 0000000000..8dee5b8e94
--- /dev/null
+++ b/ext/intl/tests/timezone_getDSTSavings_basic.phpt
@@ -0,0 +1,21 @@
+--TEST--
+IntlTimeZone::getDSTSavings(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$lsb = IntlTimeZone::createTimeZone('Europe/Lisbon');
+var_dump($lsb->getDSTSavings());
+
+var_dump(intltz_get_dst_savings($lsb));
+
+?>
+==DONE==
+--EXPECT--
+int(3600000)
+int(3600000)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/timezone_getDSTSavings_error.phpt b/ext/intl/tests/timezone_getDSTSavings_error.phpt
new file mode 100644
index 0000000000..e1469f4ac6
--- /dev/null
+++ b/ext/intl/tests/timezone_getDSTSavings_error.phpt
@@ -0,0 +1,23 @@
+--TEST--
+IntlTimeZone::getDSTSavings(): errors
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$tz = IntlTimeZone::createTimeZone('Europe/Lisbon');
+var_dump($tz->getDSTSavings(array()));
+
+var_dump(intltz_get_dst_savings(null));
+
+--EXPECTF--
+
+Warning: IntlTimeZone::getDSTSavings() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlTimeZone::getDSTSavings(): intltz_get_dst_savings: bad arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intltz_get_dst_savings() must be an instance of IntlTimeZone, null given in %s on line %d
diff --git a/ext/intl/tests/timezone_getDisplayName_basic.phpt b/ext/intl/tests/timezone_getDisplayName_basic.phpt
new file mode 100644
index 0000000000..e4fc2f37ce
--- /dev/null
+++ b/ext/intl/tests/timezone_getDisplayName_basic.phpt
@@ -0,0 +1,24 @@
+--TEST--
+IntlTimeZone::getDisplayName(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$lsb = IntlTimeZone::createTimeZone('Europe/Lisbon');
+
+ini_set('intl.default_locale', 'en_US');
+var_dump($lsb->getDisplayName());
+
+ini_set('intl.default_locale', 'pt_PT');
+var_dump($lsb->getDisplayName());
+
+?>
+==DONE==
+--EXPECTF--
+string(%d) "Western European%sTime"
+string(%d) "Hora%sda Europa Ocidental"
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/timezone_getDisplayName_error.phpt b/ext/intl/tests/timezone_getDisplayName_error.phpt
new file mode 100644
index 0000000000..a12f85c855
--- /dev/null
+++ b/ext/intl/tests/timezone_getDisplayName_error.phpt
@@ -0,0 +1,45 @@
+--TEST--
+IntlTimeZone::getDisplayName(): errors
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$tz = IntlTimeZone::createTimeZone('Europe/Lisbon');
+var_dump($tz->getDisplayName(array()));
+var_dump($tz->getDisplayName(false, array()));
+var_dump($tz->getDisplayName(false, -1));
+var_dump($tz->getDisplayName(false, IntlTimeZone::DISPLAY_SHORT, array()));
+var_dump($tz->getDisplayName(false, IntlTimeZone::DISPLAY_SHORT, NULL, NULL));
+
+var_dump(intltz_get_display_name(null, IntlTimeZone::DISPLAY_SHORT, false, 'pt_PT'));
+
+--EXPECTF--
+
+Warning: IntlTimeZone::getDisplayName() expects parameter 1 to be boolean, array given in %s on line %d
+
+Warning: IntlTimeZone::getDisplayName(): intltz_get_display_name: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlTimeZone::getDisplayName() expects parameter 2 to be long, array given in %s on line %d
+
+Warning: IntlTimeZone::getDisplayName(): intltz_get_display_name: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlTimeZone::getDisplayName(): intltz_get_display_name: wrong display type in %s on line %d
+bool(false)
+
+Warning: IntlTimeZone::getDisplayName() expects parameter 3 to be string, array given in %s on line %d
+
+Warning: IntlTimeZone::getDisplayName(): intltz_get_display_name: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlTimeZone::getDisplayName() expects at most 3 parameters, 4 given in %s on line %d
+
+Warning: IntlTimeZone::getDisplayName(): intltz_get_display_name: bad arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intltz_get_display_name() must be an instance of IntlTimeZone, null given in %s on line %d
diff --git a/ext/intl/tests/timezone_getDisplayName_variant1.phpt b/ext/intl/tests/timezone_getDisplayName_variant1.phpt
new file mode 100644
index 0000000000..83922dd170
--- /dev/null
+++ b/ext/intl/tests/timezone_getDisplayName_variant1.phpt
@@ -0,0 +1,26 @@
+--TEST--
+IntlTimeZone::getDisplayName(): daylight parameter effect
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("error_reporting", -1);
+ini_set("display_errors", 1);
+
+$lsb = IntlTimeZone::createTimeZone('Europe/Lisbon');
+
+ini_set('intl.default_locale', 'en_US');
+var_dump($lsb->getDisplayName());
+var_dump($lsb->getDisplayName(false));
+var_dump($lsb->getDisplayName(true));
+
+?>
+==DONE==
+--EXPECTF--
+string(%d) "Western European%sTime"
+string(%d) "Western European%sTime"
+string(28) "Western European Summer Time"
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/timezone_getDisplayName_variant2-49+.phpt b/ext/intl/tests/timezone_getDisplayName_variant2-49+.phpt
new file mode 100644
index 0000000000..8f60f29040
--- /dev/null
+++ b/ext/intl/tests/timezone_getDisplayName_variant2-49+.phpt
@@ -0,0 +1,36 @@
+--TEST--
+IntlTimeZone::getDisplayName(): type parameter (ICU >= 49 && ICU < 51.2)
+--SKIPIF--
+<?php if (!extension_loaded('intl')) die('skip intl extension not enabled'); ?>
+<?php if (version_compare(INTL_ICU_VERSION, '49') < 0) die('skip for ICU 49+'); ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') >= 0) die('skip for ICU < 51.2'); ?>
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("error_reporting", -1);
+ini_set("display_errors", 1);
+
+$lsb = IntlTimeZone::createTimeZone('Europe/Lisbon');
+
+ini_set('intl.default_locale', 'en_US');
+var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_SHORT));
+var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_LONG));
+var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_SHORT_GENERIC));
+var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_LONG_GENERIC));
+var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_SHORT_GMT));
+var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_LONG_GMT));
+var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_SHORT_COMMONLY_USED));
+var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_GENERIC_LOCATION));
+
+?>
+==DONE==
+--EXPECT--
+string(3) "GMT"
+string(30) "Western European Standard Time"
+string(22) "Portugal Time (Lisbon)"
+string(21) "Western European Time"
+string(5) "+0000"
+string(3) "GMT"
+string(3) "GMT"
+string(22) "Portugal Time (Lisbon)"
+==DONE==
diff --git a/ext/intl/tests/timezone_getDisplayName_variant2.phpt b/ext/intl/tests/timezone_getDisplayName_variant2.phpt
new file mode 100644
index 0000000000..1ccf68767f
--- /dev/null
+++ b/ext/intl/tests/timezone_getDisplayName_variant2.phpt
@@ -0,0 +1,40 @@
+--TEST--
+IntlTimeZone::getDisplayName(): type parameter (ICU < 49)
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '49') >= 0)
+ die('skip for ICU < 49');
+if (version_compare(INTL_ICU_VERSION, '4.8') < 0)
+ die('skip for ICU 4.8+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("error_reporting", -1);
+ini_set("display_errors", 1);
+
+$lsb = IntlTimeZone::createTimeZone('Europe/Lisbon');
+
+ini_set('intl.default_locale', 'en_US');
+var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_SHORT));
+var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_LONG));
+var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_SHORT_GENERIC));
+var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_LONG_GENERIC));
+var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_SHORT_GMT));
+var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_LONG_GMT));
+var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_SHORT_COMMONLY_USED));
+var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_GENERIC_LOCATION));
+
+?>
+==DONE==
+--EXPECT--
+string(3) "WET"
+string(21) "Western European Time"
+string(22) "Portugal Time (Lisbon)"
+string(22) "Portugal Time (Lisbon)"
+string(5) "+0000"
+string(3) "GMT"
+string(3) "GMT"
+string(22) "Portugal Time (Lisbon)"
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/timezone_getDisplayName_variant3-49+.phpt b/ext/intl/tests/timezone_getDisplayName_variant3-49+.phpt
new file mode 100644
index 0000000000..e90cc4748c
--- /dev/null
+++ b/ext/intl/tests/timezone_getDisplayName_variant3-49+.phpt
@@ -0,0 +1,28 @@
+--TEST--
+IntlTimeZone::getDisplayName(): locale parameter
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '49') < 0)
+ die('skip for ICU 49+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("error_reporting", -1);
+ini_set("display_errors", 1);
+
+$lsb = IntlTimeZone::createTimeZone('Europe/Lisbon');
+
+ini_set('intl.default_locale', 'en_US');
+var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_LONG));
+var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_LONG, NULL));
+var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_LONG, 'pt_PT'));
+
+?>
+==DONE==
+--EXPECT--
+string(30) "Western European Standard Time"
+string(30) "Western European Standard Time"
+string(32) "Hora Padrão da Europa Ocidental"
+==DONE==
diff --git a/ext/intl/tests/timezone_getDisplayName_variant3.phpt b/ext/intl/tests/timezone_getDisplayName_variant3.phpt
new file mode 100644
index 0000000000..c160777583
--- /dev/null
+++ b/ext/intl/tests/timezone_getDisplayName_variant3.phpt
@@ -0,0 +1,28 @@
+--TEST--
+IntlTimeZone::getDisplayName(): locale parameter
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '49') >= 0)
+ die('skip for ICU <= 4.8');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("error_reporting", -1);
+ini_set("display_errors", 1);
+
+$lsb = IntlTimeZone::createTimeZone('Europe/Lisbon');
+
+ini_set('intl.default_locale', 'en_US');
+var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_LONG));
+var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_LONG, NULL));
+var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_LONG, 'pt_PT'));
+
+?>
+==DONE==
+--EXPECT--
+string(21) "Western European Time"
+string(21) "Western European Time"
+string(24) "Hora da Europa Ocidental"
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/timezone_getDisplayName_variant4.phpt b/ext/intl/tests/timezone_getDisplayName_variant4.phpt
new file mode 100644
index 0000000000..39e28892a4
--- /dev/null
+++ b/ext/intl/tests/timezone_getDisplayName_variant4.phpt
@@ -0,0 +1,35 @@
+--TEST--
+IntlTimeZone::getDisplayName(): type parameter (ICU >= 51.2)
+--SKIPIF--
+<?php if (!extension_loaded('intl')) die('skip intl extension not enabled'); ?>
+<?php if (version_compare(INTL_ICU_VERSION, '51.2') < 0) die('skip for ICU >= 51.2'); ?>
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("error_reporting", -1);
+ini_set("display_errors", 1);
+
+$lsb = IntlTimeZone::createTimeZone('Europe/Lisbon');
+
+ini_set('intl.default_locale', 'en_US');
+var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_SHORT));
+var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_LONG));
+var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_SHORT_GENERIC));
+var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_LONG_GENERIC));
+var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_SHORT_GMT));
+var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_LONG_GMT));
+var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_SHORT_COMMONLY_USED));
+var_dump($lsb->getDisplayName(false, IntlTimeZone::DISPLAY_GENERIC_LOCATION));
+
+?>
+==DONE==
+--EXPECT--
+string(3) "GMT"
+string(30) "Western European Standard Time"
+string(13) "Portugal Time"
+string(21) "Western European Time"
+string(5) "+0000"
+string(3) "GMT"
+string(3) "GMT"
+string(13) "Portugal Time"
+==DONE==
diff --git a/ext/intl/tests/timezone_getEquivalentID_basic.phpt b/ext/intl/tests/timezone_getEquivalentID_basic.phpt
new file mode 100644
index 0000000000..8af1e20897
--- /dev/null
+++ b/ext/intl/tests/timezone_getEquivalentID_basic.phpt
@@ -0,0 +1,19 @@
+--TEST--
+IntlTimeZone::getEquivalentID(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+print_R(IntlTimeZone::getEquivalentID('Europe/Lisbon', "1"));
+echo "\n";
+print_R(intltz_get_equivalent_id('Europe/Lisbon', 1));
+echo "\n";
+?>
+==DONE==
+--EXPECT--
+Portugal
+Portugal
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/timezone_getEquivalentID_error.phpt b/ext/intl/tests/timezone_getEquivalentID_error.phpt
new file mode 100644
index 0000000000..b3f344b54d
--- /dev/null
+++ b/ext/intl/tests/timezone_getEquivalentID_error.phpt
@@ -0,0 +1,34 @@
+--TEST--
+IntlTimeZone::getEquivalentID(): errors
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+var_dump(IntlTimeZone::getEquivalentID('foo'));
+var_dump(IntlTimeZone::getEquivalentID('foo', 'bar'));
+var_dump(IntlTimeZone::getEquivalentID('Europe/Lisbon', 0, 1));
+var_dump(IntlTimeZone::getEquivalentID("foo\x80", 0));
+
+--EXPECTF--
+
+Warning: IntlTimeZone::getEquivalentID() expects exactly 2 parameters, 1 given in %s on line %d
+
+Warning: IntlTimeZone::getEquivalentID(): intltz_get_equivalent_id: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlTimeZone::getEquivalentID() expects parameter 2 to be long, string given in %s on line %d
+
+Warning: IntlTimeZone::getEquivalentID(): intltz_get_equivalent_id: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlTimeZone::getEquivalentID() expects exactly 2 parameters, 3 given in %s on line %d
+
+Warning: IntlTimeZone::getEquivalentID(): intltz_get_equivalent_id: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlTimeZone::getEquivalentID(): intltz_get_equivalent_id: could not convert time zone id to UTF-16 in %s on line %d
+bool(false)
diff --git a/ext/intl/tests/timezone_getErrorCodeMessage_basic.phpt b/ext/intl/tests/timezone_getErrorCodeMessage_basic.phpt
new file mode 100644
index 0000000000..d3a3dee47d
--- /dev/null
+++ b/ext/intl/tests/timezone_getErrorCodeMessage_basic.phpt
@@ -0,0 +1,31 @@
+--TEST--
+IntlTimeZone::getErrorCode/Message(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$lsb = IntlTimeZone::createTimeZone('Europe/Lisbon');
+
+var_dump($lsb->getErrorCode());
+var_dump($lsb->getErrorMessage());
+
+var_dump($lsb->getOffset(INF, 1, $a, $b));
+
+var_dump($lsb->getErrorCode());
+var_dump($lsb->getErrorMessage());
+
+?>
+==DONE==
+--EXPECTF--
+int(0)
+string(12) "U_ZERO_ERROR"
+
+Warning: IntlTimeZone::getOffset(): intltz_get_offset: error obtaining offset in %s on line %d
+bool(false)
+int(1)
+string(67) "intltz_get_offset: error obtaining offset: U_ILLEGAL_ARGUMENT_ERROR"
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/timezone_getErrorCode_error.phpt b/ext/intl/tests/timezone_getErrorCode_error.phpt
new file mode 100644
index 0000000000..b56d3b0a48
--- /dev/null
+++ b/ext/intl/tests/timezone_getErrorCode_error.phpt
@@ -0,0 +1,23 @@
+--TEST--
+IntlTimeZone::getErrorCode(): errors
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$tz = IntlTimeZone::createTimeZone('Europe/Lisbon');
+var_dump($tz->getErrorCode(array()));
+
+var_dump(intltz_get_error_code(null));
+
+--EXPECTF--
+
+Warning: IntlTimeZone::getErrorCode() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlTimeZone::getErrorCode(): intltz_get_error_code: bad arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intltz_get_error_code() must be an instance of IntlTimeZone, null given in %s on line %d
diff --git a/ext/intl/tests/timezone_getErrorMessage_error.phpt b/ext/intl/tests/timezone_getErrorMessage_error.phpt
new file mode 100644
index 0000000000..067dcdc13b
--- /dev/null
+++ b/ext/intl/tests/timezone_getErrorMessage_error.phpt
@@ -0,0 +1,23 @@
+--TEST--
+IntlTimeZone::getErrorMessage(): errors
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$tz = IntlTimeZone::createTimeZone('Europe/Lisbon');
+var_dump($tz->getErrorMessage(array()));
+
+var_dump(intltz_get_error_message(null));
+
+--EXPECTF--
+
+Warning: IntlTimeZone::getErrorMessage() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlTimeZone::getErrorMessage(): intltz_get_error_message: bad arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intltz_get_error_message() must be an instance of IntlTimeZone, null given in %s on line %d
diff --git a/ext/intl/tests/timezone_getGMT_basic.phpt b/ext/intl/tests/timezone_getGMT_basic.phpt
new file mode 100644
index 0000000000..99b3fa22ca
--- /dev/null
+++ b/ext/intl/tests/timezone_getGMT_basic.phpt
@@ -0,0 +1,31 @@
+--TEST--
+IntlTimeZone::getGMT(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+$tz = IntlTimeZone::getGMT();
+print_r($tz);
+$tz = intltz_get_gmt();
+print_r($tz);
+?>
+==DONE==
+--EXPECT--
+IntlTimeZone Object
+(
+ [valid] => 1
+ [id] => GMT
+ [rawOffset] => 0
+ [currentOffset] => 0
+)
+IntlTimeZone Object
+(
+ [valid] => 1
+ [id] => GMT
+ [rawOffset] => 0
+ [currentOffset] => 0
+)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/timezone_getGMT_error.phpt b/ext/intl/tests/timezone_getGMT_error.phpt
new file mode 100644
index 0000000000..15afb765e4
--- /dev/null
+++ b/ext/intl/tests/timezone_getGMT_error.phpt
@@ -0,0 +1,19 @@
+--TEST--
+IntlTimeZone::getGMT(): errors
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+var_dump(IntlTimeZone::getGMT(4));
+
+
+--EXPECTF--
+
+Warning: IntlTimeZone::getGMT() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlTimeZone::getGMT(): intltz_get_gmt: bad arguments in %s on line %d
+NULL
diff --git a/ext/intl/tests/timezone_getID_error.phpt b/ext/intl/tests/timezone_getID_error.phpt
new file mode 100644
index 0000000000..b239b3facf
--- /dev/null
+++ b/ext/intl/tests/timezone_getID_error.phpt
@@ -0,0 +1,23 @@
+--TEST--
+IntlTimeZone::getID(): errors
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$tz = IntlTimeZone::createTimeZone('Europe/Lisbon');
+var_dump($tz->getID('foo'));
+intltz_get_id(null);
+
+
+--EXPECTF--
+
+Warning: IntlTimeZone::getID() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlTimeZone::getID(): intltz_get_id: bad arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intltz_get_id() must be an instance of IntlTimeZone, null given in %s on line %d
diff --git a/ext/intl/tests/timezone_getOffset_basic.phpt b/ext/intl/tests/timezone_getOffset_basic.phpt
new file mode 100644
index 0000000000..582d45cad9
--- /dev/null
+++ b/ext/intl/tests/timezone_getOffset_basic.phpt
@@ -0,0 +1,33 @@
+--TEST--
+IntlTimeZone::getOffset(): basic test
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+$ams = IntlTimeZone::createTimeZone('Europe/Amsterdam');
+
+$date = strtotime("1 July 2012 +0000");
+
+var_dump($ams->getOffset($date *1000., true, $rawOffset, $dstOffset),
+ $rawOffset, $dstOffset);
+
+$lsb = IntlTimeZone::createTimeZone('Europe/Lisbon');
+
+var_dump(intltz_get_offset($lsb, $date *1000., true, $rawOffset, $dstOffset),
+ $rawOffset, $dstOffset);
+
+?>
+==DONE==
+--EXPECT--
+bool(true)
+int(3600000)
+int(3600000)
+bool(true)
+int(0)
+int(3600000)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/timezone_getOffset_error.phpt b/ext/intl/tests/timezone_getOffset_error.phpt
new file mode 100644
index 0000000000..73555002c0
--- /dev/null
+++ b/ext/intl/tests/timezone_getOffset_error.phpt
@@ -0,0 +1,33 @@
+--TEST--
+IntlTimeZone::getOffset(): errors
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$tz = IntlTimeZone::createTimeZone('Europe/Lisbon');
+var_dump($tz->getOffset(INF, true, $a, $a));
+var_dump($tz->getOffset(time()*1000, true, $a));
+var_dump($tz->getOffset(time()*1000, true, $a, $a, $a));
+
+intltz_get_offset(null, time()*1000, false, $a, $a);
+
+--EXPECTF--
+
+Warning: IntlTimeZone::getOffset(): intltz_get_offset: error obtaining offset in %s on line %d
+bool(false)
+
+Warning: IntlTimeZone::getOffset() expects exactly 4 parameters, 3 given in %s on line %d
+
+Warning: IntlTimeZone::getOffset(): intltz_get_offset: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlTimeZone::getOffset() expects exactly 4 parameters, 5 given in %s on line %d
+
+Warning: IntlTimeZone::getOffset(): intltz_get_offset: bad arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intltz_get_offset() must be an instance of IntlTimeZone, null given in %s on line %d
diff --git a/ext/intl/tests/timezone_getRawOffset_basic.phpt b/ext/intl/tests/timezone_getRawOffset_basic.phpt
new file mode 100644
index 0000000000..a2b4debf2b
--- /dev/null
+++ b/ext/intl/tests/timezone_getRawOffset_basic.phpt
@@ -0,0 +1,21 @@
+--TEST--
+IntlTimeZone::getRawOffset(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+$ams = IntlTimeZone::createTimeZone('Europe/Amsterdam');
+var_dump($ams->getRawOffset());
+
+$lsb = IntlTimeZone::createTimeZone('Europe/Lisbon');
+var_dump(intltz_get_raw_offset($lsb));
+
+?>
+==DONE==
+--EXPECT--
+int(3600000)
+int(0)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/timezone_getRawOffset_error.phpt b/ext/intl/tests/timezone_getRawOffset_error.phpt
new file mode 100644
index 0000000000..eb6aac02cd
--- /dev/null
+++ b/ext/intl/tests/timezone_getRawOffset_error.phpt
@@ -0,0 +1,23 @@
+--TEST--
+IntlTimeZone::getRawOffset(): errors
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$tz = IntlTimeZone::createTimeZone('Europe/Lisbon');
+var_dump($tz->getRawOffset('foo'));
+
+intltz_get_raw_offset(null);
+
+--EXPECTF--
+
+Warning: IntlTimeZone::getRawOffset() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlTimeZone::getRawOffset(): intltz_get_raw_offset: bad arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intltz_get_raw_offset() must be an instance of IntlTimeZone, null given in %s on line %d
diff --git a/ext/intl/tests/timezone_getRegion_basic.phpt b/ext/intl/tests/timezone_getRegion_basic.phpt
new file mode 100644
index 0000000000..1a41ae8d58
--- /dev/null
+++ b/ext/intl/tests/timezone_getRegion_basic.phpt
@@ -0,0 +1,21 @@
+--TEST--
+IntlTimeZone::getRegion(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '4.8') < 0)
+ die('skip for ICU 4.8+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+print_R(IntlTimeZone::getRegion('Europe/Amsterdam'));
+echo "\n";
+print_R(intltz_get_region('Europe/Amsterdam'));
+echo "\n";
+?>
+==DONE==
+--EXPECT--
+NL
+NL
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/timezone_getRegion_error.phpt b/ext/intl/tests/timezone_getRegion_error.phpt
new file mode 100644
index 0000000000..34911d9abc
--- /dev/null
+++ b/ext/intl/tests/timezone_getRegion_error.phpt
@@ -0,0 +1,42 @@
+--TEST--
+IntlTimeZone::getRegion(): errors
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '4.8') < 0)
+ die('skip for ICU 4.8+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+var_dump(IntlTimeZone::getRegion());
+var_dump(IntlTimeZone::getRegion(array()));
+var_dump(IntlTimeZone::getRegion('Europe/Lisbon', 4));
+var_dump(IntlTimeZone::getRegion("foo\x81"));
+var_dump(IntlTimeZone::getRegion("foo"));
+
+
+
+--EXPECTF--
+
+Warning: IntlTimeZone::getRegion() expects exactly 1 parameter, 0 given in %s on line %d
+
+Warning: IntlTimeZone::getRegion(): intltz_get_region: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlTimeZone::getRegion() expects parameter 1 to be string, array given in %s on line %d
+
+Warning: IntlTimeZone::getRegion(): intltz_get_region: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlTimeZone::getRegion() expects exactly 1 parameter, 2 given in %s on line %d
+
+Warning: IntlTimeZone::getRegion(): intltz_get_region: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlTimeZone::getRegion(): intltz_get_region: could not convert time zone id to UTF-16 in %s on line %d
+bool(false)
+
+Warning: IntlTimeZone::getRegion(): intltz_get_region: Error obtaining region in %s on line %d
+bool(false)
diff --git a/ext/intl/tests/timezone_getTZDataVersion_error.phpt b/ext/intl/tests/timezone_getTZDataVersion_error.phpt
new file mode 100644
index 0000000000..258b8807b7
--- /dev/null
+++ b/ext/intl/tests/timezone_getTZDataVersion_error.phpt
@@ -0,0 +1,18 @@
+--TEST--
+IntlTimeZone::getTZDataVersion(): errors
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+var_dump(IntlTimeZone::getTZDataVersion('foo'));
+
+--EXPECTF--
+
+Warning: IntlTimeZone::getTZDataVersion() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlTimeZone::getTZDataVersion(): intltz_get_tz_data_version: bad arguments in %s on line %d
+bool(false)
diff --git a/ext/intl/tests/timezone_getTZData_basic.phpt b/ext/intl/tests/timezone_getTZData_basic.phpt
new file mode 100644
index 0000000000..dea5b7c4b3
--- /dev/null
+++ b/ext/intl/tests/timezone_getTZData_basic.phpt
@@ -0,0 +1,19 @@
+--TEST--
+IntlTimeZone::getTZDataVersion: basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+print_R(IntlTimeZone::getTZDataVersion());
+echo "\n";
+print_R(intltz_get_tz_data_version());
+echo "\n";
+?>
+==DONE==
+--EXPECTF--
+20%d%s
+20%d%s
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/timezone_getUnknown_basic.phpt b/ext/intl/tests/timezone_getUnknown_basic.phpt
new file mode 100644
index 0000000000..aef1a54561
--- /dev/null
+++ b/ext/intl/tests/timezone_getUnknown_basic.phpt
@@ -0,0 +1,35 @@
+--TEST--
+IntlCalendar::getUnknown(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '49') < 0)
+ die('skip for ICU 49+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+
+$tz = IntlTimeZone::getUnknown();
+print_r($tz);
+$tz = intltz_get_unknown();
+print_r($tz);
+?>
+==DONE==
+--EXPECT--
+IntlTimeZone Object
+(
+ [valid] => 1
+ [id] => Etc/Unknown
+ [rawOffset] => 0
+ [currentOffset] => 0
+)
+IntlTimeZone Object
+(
+ [valid] => 1
+ [id] => Etc/Unknown
+ [rawOffset] => 0
+ [currentOffset] => 0
+)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/timezone_getUnknown_error.phpt b/ext/intl/tests/timezone_getUnknown_error.phpt
new file mode 100644
index 0000000000..704b1b096f
--- /dev/null
+++ b/ext/intl/tests/timezone_getUnknown_error.phpt
@@ -0,0 +1,29 @@
+--TEST--
+IntlCalendar::getUnknown(): bad arguments
+--INI--
+date.timezone=Atlantic/Azores
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+if (version_compare(INTL_ICU_VERSION, '49') < 0)
+ die('skip for ICU 49+');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$c = new IntlGregorianCalendar(NULL, 'pt_PT');
+
+IntlTimeZone::getUnknown(1);
+
+intltz_get_unknown(1);
+
+--EXPECTF--
+
+Warning: IntlTimeZone::getUnknown() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlTimeZone::getUnknown(): intltz_get_unknown: bad arguments in %s on line %d
+
+Warning: intltz_get_unknown() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: intltz_get_unknown(): intltz_get_unknown: bad arguments in %s on line %d
diff --git a/ext/intl/tests/timezone_hasSameRules_basic.phpt b/ext/intl/tests/timezone_hasSameRules_basic.phpt
new file mode 100644
index 0000000000..55faaf760b
--- /dev/null
+++ b/ext/intl/tests/timezone_hasSameRules_basic.phpt
@@ -0,0 +1,35 @@
+--TEST--
+IntlTimeZone::hasSameRules(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$lsb = IntlTimeZone::createTimeZone('Europe/Lisbon');
+$prt = IntlTimeZone::createTimeZone('Portugal');
+$azo = IntlTimeZone::createTimeZone('Atlantic/Azores');
+
+echo "Europe/Lisbon has same rules as itself:\n";
+var_dump($lsb->hasSameRules($lsb));
+
+echo "\nEurope/Lisbon has same rules as Portugal:\n";
+var_dump($lsb->hasSameRules($prt));
+
+echo "\nEurope/Lisbon has same rules as Atlantic/Azores:\n";
+var_dump(intltz_has_same_rules($lsb, $azo));
+
+?>
+==DONE==
+--EXPECT--
+Europe/Lisbon has same rules as itself:
+bool(true)
+
+Europe/Lisbon has same rules as Portugal:
+bool(true)
+
+Europe/Lisbon has same rules as Atlantic/Azores:
+bool(false)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/timezone_hasSameRules_error.phpt b/ext/intl/tests/timezone_hasSameRules_error.phpt
new file mode 100644
index 0000000000..35a29be5db
--- /dev/null
+++ b/ext/intl/tests/timezone_hasSameRules_error.phpt
@@ -0,0 +1,37 @@
+--TEST--
+IntlTimeZone::hasSameRules(): errors
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+function error_handler($errno, $errstr, $errfile, $errline)
+{
+ var_dump($errno, $errstr);
+ return true;
+}
+set_error_handler("error_handler");
+
+$tz = IntlTimeZone::createTimeZone('Europe/Lisbon');
+var_dump($tz->hasSameRules('foo'));
+
+var_dump(intltz_has_same_rules(null, $tz));
+
+--EXPECT--
+int(4096)
+string(99) "Argument 1 passed to IntlTimeZone::hasSameRules() must be an instance of IntlTimeZone, string given"
+int(2)
+string(81) "IntlTimeZone::hasSameRules() expects parameter 1 to be IntlTimeZone, string given"
+int(2)
+string(66) "IntlTimeZone::hasSameRules(): intltz_has_same_rules: bad arguments"
+bool(false)
+int(4096)
+string(92) "Argument 1 passed to intltz_has_same_rules() must be an instance of IntlTimeZone, null given"
+int(2)
+string(74) "intltz_has_same_rules() expects parameter 1 to be IntlTimeZone, null given"
+int(2)
+string(61) "intltz_has_same_rules(): intltz_has_same_rules: bad arguments"
+bool(false)
diff --git a/ext/intl/tests/timezone_toDateTimeZone_basic.phpt b/ext/intl/tests/timezone_toDateTimeZone_basic.phpt
new file mode 100644
index 0000000000..d22aa689dc
--- /dev/null
+++ b/ext/intl/tests/timezone_toDateTimeZone_basic.phpt
@@ -0,0 +1,38 @@
+--TEST--
+IntlTimeZone::toDateTimeZone(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+ini_set("intl.default_locale", "nl");
+date_default_timezone_set('Europe/Lisbon');
+
+function do_test(IntlTimeZone $tz, $proc = false) {
+ var_dump($tz->getID(), $tz->getRawOffset());
+ if (!$proc)
+ $dtz = $tz->toDateTimeZone();
+ else
+ $dtz = intltz_to_date_time_zone($tz);
+ var_dump($dtz->getName(), $dtz->getOffset(new DateTime('2012-01-01 00:00:00')));
+}
+
+do_test(IntlTimeZone::createTimeZone('CET'));
+do_test(IntlTimeZone::createTimeZone('Europe/Amsterdam'));
+do_test(IntlTimeZone::createTimeZone('GMT+0405'), true);
+
+--EXPECTF--
+string(3) "CET"
+int(3600000)
+string(13) "Europe/Berlin"
+int(3600)
+string(16) "Europe/Amsterdam"
+int(3600000)
+string(16) "Europe/Amsterdam"
+int(3600)
+string(%s) "GMT+04%s5"
+int(14700000)
+string(6) "+04:05"
+int(14700)
diff --git a/ext/intl/tests/timezone_toDateTimeZone_error.phpt b/ext/intl/tests/timezone_toDateTimeZone_error.phpt
new file mode 100644
index 0000000000..e48d7aca92
--- /dev/null
+++ b/ext/intl/tests/timezone_toDateTimeZone_error.phpt
@@ -0,0 +1,38 @@
+--TEST--
+IntlTimeZone::toDateTimeZone(): errors
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$tz = IntlTimeZone::createTimeZone('Etc/Unknown');
+
+var_dump($tz->toDateTimeZone(''));
+try {
+ var_dump($tz->toDateTimeZone());
+} catch (Exception $e) {
+ var_dump($e->getMessage());
+}
+
+var_dump(intltz_to_date_time_zone());
+var_dump(intltz_to_date_time_zone(1));
+
+--EXPECTF--
+
+Warning: IntlTimeZone::toDateTimeZone() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlTimeZone::toDateTimeZone(): intltz_to_date_time_zone: bad arguments in %s on line %d
+bool(false)
+
+Warning: IntlTimeZone::toDateTimeZone(): intltz_to_date_time_zone: DateTimeZone constructor threw exception in %s on line %d
+string(66) "DateTimeZone::__construct(): Unknown or bad timezone (Etc/Unknown)"
+
+Warning: intltz_to_date_time_zone() expects exactly 1 parameter, 0 given in %s on line %d
+
+Warning: intltz_to_date_time_zone(): intltz_to_date_time_zone: bad arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intltz_to_date_time_zone() must be an instance of IntlTimeZone, integer given in %s on line %d
diff --git a/ext/intl/tests/timezone_useDaylightTime_basic.phpt b/ext/intl/tests/timezone_useDaylightTime_basic.phpt
new file mode 100644
index 0000000000..15baf108b3
--- /dev/null
+++ b/ext/intl/tests/timezone_useDaylightTime_basic.phpt
@@ -0,0 +1,25 @@
+--TEST--
+IntlTimeZone::useDaylightTime: basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+$lsb = IntlTimeZone::createTimeZone('Europe/Lisbon');
+$gmt = IntlTimeZone::getGMT();
+
+var_dump($lsb->useDaylightTime());
+var_dump($gmt->useDaylightTime());
+
+var_dump(intltz_use_daylight_time($lsb));
+var_dump(intltz_use_daylight_time($gmt));
+?>
+==DONE==
+--EXPECT--
+bool(true)
+bool(false)
+bool(true)
+bool(false)
+==DONE== \ No newline at end of file
diff --git a/ext/intl/tests/timezone_useDaylightTime_error.phpt b/ext/intl/tests/timezone_useDaylightTime_error.phpt
new file mode 100644
index 0000000000..aa5ca6cfca
--- /dev/null
+++ b/ext/intl/tests/timezone_useDaylightTime_error.phpt
@@ -0,0 +1,22 @@
+--TEST--
+IntlTimeZone::useDaylightTime(): errors
+--SKIPIF--
+<?php
+if (!extension_loaded('intl'))
+ die('skip intl extension not enabled');
+--FILE--
+<?php
+ini_set("intl.error_level", E_WARNING);
+
+$tz = IntlTimeZone::createTimeZone('Europe/Lisbon');
+var_dump($tz->useDaylightTime('foo'));
+intltz_use_daylight_time(null);
+
+--EXPECTF--
+
+Warning: IntlTimeZone::useDaylightTime() expects exactly 0 parameters, 1 given in %s on line %d
+
+Warning: IntlTimeZone::useDaylightTime(): intltz_use_daylight_time: bad arguments in %s on line %d
+bool(false)
+
+Catchable fatal error: Argument 1 passed to intltz_use_daylight_time() must be an instance of IntlTimeZone, null given in %s on line %d
diff --git a/ext/intl/tests/uconverter___construct_error.phpt b/ext/intl/tests/uconverter___construct_error.phpt
new file mode 100644
index 0000000000..1b2480818b
--- /dev/null
+++ b/ext/intl/tests/uconverter___construct_error.phpt
@@ -0,0 +1,14 @@
+--TEST--
+Basic UConverter::convert() usage
+--INI--
+intl.error_level = E_WARNING
+--SKIPIF--
+<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+--FILE--
+<?php
+$c = new UConverter('utf-8', "\x80");
+var_dump($c);
+--EXPECTF--
+Warning: UConverter::__construct(): ucnv_open() returned error 4: U_FILE_ACCESS_ERROR in %s on line %d
+object(UConverter)#%d (0) {
+}
diff --git a/ext/intl/tests/uconverter_enum.phpt b/ext/intl/tests/uconverter_enum.phpt
new file mode 100644
index 0000000000..67e02c9d75
--- /dev/null
+++ b/ext/intl/tests/uconverter_enum.phpt
@@ -0,0 +1,21 @@
+--TEST--
+UConverter Enumerations
+--SKIPIF--
+<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+--FILE--
+<?php
+$avail = UConverter::getAvailable();
+var_dump(count($avail) > 100);
+var_dump(in_array('UTF-7', $avail));
+var_dump(in_array('CESU-8', $avail));
+var_dump(in_array('ISO-8859-1', $avail));
+
+$latin1 = UConverter::getAliases('latin1');
+var_dump(in_array('ISO-8859-1', $latin1));
+
+--EXPECT--
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
diff --git a/ext/intl/tests/uconverter_func_basic.phpt b/ext/intl/tests/uconverter_func_basic.phpt
new file mode 100644
index 0000000000..da8956beae
--- /dev/null
+++ b/ext/intl/tests/uconverter_func_basic.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Basic UConverter::transcode() usage
+--SKIPIF--
+<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+--FILE--
+<?php
+var_dump(UConverter::transcode("This is an ascii string", 'utf-8', 'latin1'));
+// urlencode so that non-ascii shows up parsable in phpt file
+var_dump(urlencode(UConverter::transcode("Espa\xF1ol", 'utf-8', 'latin1')));
+var_dump(urlencode(UConverter::transcode("Stra\xDFa", 'utf-8', 'latin1')));
+
+var_dump(bin2hex(UConverter::transcode("\xE4", 'utf-8', 'koi8-r')));
+--EXPECT--
+string(23) "This is an ascii string"
+string(12) "Espa%C3%B1ol"
+string(11) "Stra%C3%9Fa"
+string(4) "d094"
diff --git a/ext/intl/tests/uconverter_func_subst.phpt b/ext/intl/tests/uconverter_func_subst.phpt
new file mode 100644
index 0000000000..5cac5ce59c
--- /dev/null
+++ b/ext/intl/tests/uconverter_func_subst.phpt
@@ -0,0 +1,31 @@
+--TEST--
+Basic UConverter::convert() w/ Subsitution
+--SKIPIF--
+<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+--INI--
+intl.use_exceptions=false
+--FILE--
+<?php
+foreach(array('?','','??') as $subst) {
+ $opts = array('to_subst' => $subst);
+ $ret = UConverter::transcode("This is an ascii string", 'ascii', 'utf-8', $opts);
+ if ($ret === FALSE) {
+ echo "Error: ", intl_get_error_message(), "\n";
+ } else {
+ var_dump($ret);
+ }
+ $ret = UConverter::transcode("Snowman: (\xE2\x98\x83)", 'ascii', 'utf-8', $opts);
+ if ($ret === FALSE) {
+ echo "Error: ", intl_get_error_message(), "\n";
+ } else {
+ var_dump($ret);
+ }
+}
+
+--EXPECTF--
+string(23) "This is an ascii string"
+string(12) "Snowman: (?)"
+Error: transcode() returned error 1: U_ILLEGAL_ARGUMENT_ERROR: U_ILLEGAL_ARGUMENT_ERROR
+Error: transcode() returned error 1: U_ILLEGAL_ARGUMENT_ERROR: U_ILLEGAL_ARGUMENT_ERROR
+Error: transcode() returned error 1: U_ILLEGAL_ARGUMENT_ERROR: U_ILLEGAL_ARGUMENT_ERROR
+Error: transcode() returned error 1: U_ILLEGAL_ARGUMENT_ERROR: U_ILLEGAL_ARGUMENT_ERROR
diff --git a/ext/intl/tests/uconverter_oop_algo.phpt b/ext/intl/tests/uconverter_oop_algo.phpt
new file mode 100644
index 0000000000..349182ce32
--- /dev/null
+++ b/ext/intl/tests/uconverter_oop_algo.phpt
@@ -0,0 +1,18 @@
+--TEST--
+UConverter Algorithmic converters
+--SKIPIF--
+<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+--FILE--
+<?php
+$c = new UConverter('utf-8', 'latin1');
+var_dump(UConverter::LATIN_1 === $c->getSourceType());
+var_dump(UConverter::UTF8 === $c->getDestinationType());
+
+$c = new UConverter('koi8-r', 'utf-32be');
+var_dump(UConverter::UTF32_BigEndian === $c->getSourceType());
+var_dump(UConverter::SBCS === $c->getDestinationType());
+--EXPECT--
+bool(true)
+bool(true)
+bool(true)
+bool(true)
diff --git a/ext/intl/tests/uconverter_oop_basic.phpt b/ext/intl/tests/uconverter_oop_basic.phpt
new file mode 100644
index 0000000000..2b8909ff31
--- /dev/null
+++ b/ext/intl/tests/uconverter_oop_basic.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Basic UConverter::convert() usage
+--SKIPIF--
+<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+--FILE--
+<?php
+$c = new UConverter('utf-8', 'latin1');
+var_dump($c->convert("This is an ascii string"));
+// urlencode so that non-ascii shows up parsable in phpt file
+var_dump(urlencode($c->convert("Espa\xF1ol"))); // U+00F1 LATIN SMALL LETTER N WITH TILDE
+var_dump(urlencode($c->convert("Stra\xDFa"))); // U+00DF LATIN SMALL LETTER SHARP S
+var_dump(urlencode($c->convert("Stra\xC3\x9Fa", true))); // Reverse prior op
+
+$k = new UConverter('utf-8', 'koi8-r');
+var_dump(bin2hex($k->convert("\xE4"))); // U+0414 CYRILLIC CAPITAL LETTER DE
+--EXPECT--
+string(23) "This is an ascii string"
+string(12) "Espa%C3%B1ol"
+string(11) "Stra%C3%9Fa"
+string(8) "Stra%DFa"
+string(4) "d094"
diff --git a/ext/intl/tests/uconverter_oop_callback.phpt b/ext/intl/tests/uconverter_oop_callback.phpt
new file mode 100644
index 0000000000..47daf43305
--- /dev/null
+++ b/ext/intl/tests/uconverter_oop_callback.phpt
@@ -0,0 +1,52 @@
+--TEST--
+UConverter::convert() w/ Callback Reasons
+--SKIPIF--
+<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+--FILE--
+<?php
+class MyConverter extends UConverter {
+ /**
+ * Called during conversion from source encoding to internal UChar representation
+ */
+ public function toUCallback($reason, $source, $codeUnits, &$error) {
+ echo "toUCallback(", UConverter::reasonText($reason), ", ...)\n";
+ return parent::toUCallback($reason, $source, $codeUnits, $error);
+ }
+
+ /**
+ * Called during conversion from internal UChar to destination encoding
+ */
+ public function fromUCallback($reason, $source, $codePoint, &$error) {
+ echo "fromUCallback(", UConverter::reasonText($reason), ", ...)\n";
+ return parent::fromUCallback($reason, $source, $codePoint, $error);
+ }
+
+}
+
+$c = new MyConverter('ascii', 'utf-8');
+foreach(array("regular", "irregul\xC1\xA1r", "\xC2\xA1unsupported!") as $word) {
+ $c->convert($word);
+}
+--EXPECT--
+toUCallback(REASON_RESET, ...)
+toUCallback(REASON_RESET, ...)
+fromUCallback(REASON_RESET, ...)
+fromUCallback(REASON_RESET, ...)
+toUCallback(REASON_RESET, ...)
+toUCallback(REASON_ILLEGAL, ...)
+toUCallback(REASON_RESET, ...)
+toUCallback(REASON_ILLEGAL, ...)
+fromUCallback(REASON_RESET, ...)
+fromUCallback(REASON_UNASSIGNED, ...)
+fromUCallback(REASON_RESET, ...)
+fromUCallback(REASON_UNASSIGNED, ...)
+toUCallback(REASON_RESET, ...)
+toUCallback(REASON_RESET, ...)
+fromUCallback(REASON_RESET, ...)
+fromUCallback(REASON_UNASSIGNED, ...)
+fromUCallback(REASON_RESET, ...)
+fromUCallback(REASON_UNASSIGNED, ...)
+toUCallback(REASON_CLOSE, ...)
+fromUCallback(REASON_CLOSE, ...)
+toUCallback(REASON_CLOSE, ...)
+fromUCallback(REASON_CLOSE, ...)
diff --git a/ext/intl/tests/uconverter_oop_callback_return.phpt b/ext/intl/tests/uconverter_oop_callback_return.phpt
new file mode 100644
index 0000000000..cd7e7a5834
--- /dev/null
+++ b/ext/intl/tests/uconverter_oop_callback_return.phpt
@@ -0,0 +1,40 @@
+--TEST--
+UConverter::convert() w/ Callback Return Values
+--SKIPIF--
+<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+--FILE--
+<?php
+class MyConverter extends UConverter {
+ public function toUCallback($reason, $source, $codeUnits, &$error) {
+ $error = U_ZERO_ERROR;
+ switch ($codeUnits) {
+ case "\x80": return NULL;
+ case "\x81": return 'a';
+ case "\x82": return ord('b');
+ case "\x83": return array('c');
+ }
+ }
+
+ /**
+ * Called during conversion from internal UChar to destination encoding
+ */
+ public function fromUCallback($reason, $source, $codePoint, &$error) {
+ $error = U_ZERO_ERROR;
+ switch ($codePoint) {
+ case 0x00F1: return "A";
+ case 0x00F2: return ord("B");
+ case 0x00F3: return array("C");
+ case 0x00F4: return NULL;
+ }
+ }
+
+}
+
+$c = new MyConverter('ascii', 'utf-8');
+// This line will trigger toUCallback
+var_dump($c->convert("\x80\x81\x82\x83"));
+// This line will trigger fromUCallback
+var_dump($c->convert("\xC3\xB1\xC3\xB2\xC3\xB3\xC3\xB4"));
+--EXPECT--
+string(3) "abc"
+string(3) "ABC"
diff --git a/ext/intl/tests/uconverter_oop_subst.phpt b/ext/intl/tests/uconverter_oop_subst.phpt
new file mode 100644
index 0000000000..d21d95f8d0
--- /dev/null
+++ b/ext/intl/tests/uconverter_oop_subst.phpt
@@ -0,0 +1,24 @@
+--TEST--
+Basic UConverter::convert() w/ Subsitution
+--SKIPIF--
+<?php if( !extension_loaded( 'intl' ) ) print 'skip'; ?>
+--INI--
+intl.use_exceptions=false
+--FILE--
+<?php
+$c = new UConverter('ascii', 'utf-8');
+
+foreach(array('?','','<unknown>') as $subst) {
+ if (!$c->setSubstChars($subst)) {
+ echo "**Disallowed\n";
+ continue;
+ }
+ var_dump($c->convert("This is an ascii string"));
+ var_dump($c->convert("Snowman: (\xE2\x98\x83)"));
+}
+
+--EXPECT--
+string(23) "This is an ascii string"
+string(12) "Snowman: (?)"
+**Disallowed
+**Disallowed
diff --git a/ext/intl/timezone/timezone_class.cpp b/ext/intl/timezone/timezone_class.cpp
new file mode 100644
index 0000000000..374b163851
--- /dev/null
+++ b/ext/intl/timezone/timezone_class.cpp
@@ -0,0 +1,540 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "../intl_cppshims.h"
+
+#include <unicode/timezone.h>
+#include <unicode/calendar.h>
+#include "../intl_convertcpp.h"
+
+#include "../common/common_date.h"
+
+extern "C" {
+#include "../intl_convert.h"
+#define USE_TIMEZONE_POINTER 1
+#include "timezone_class.h"
+#include "timezone_methods.h"
+#include <zend_exceptions.h>
+#include <zend_interfaces.h>
+#include <ext/date/php_date.h>
+}
+
+/* {{{ Global variables */
+U_CDECL_BEGIN
+zend_class_entry *TimeZone_ce_ptr = NULL;
+zend_object_handlers TimeZone_handlers;
+U_CDECL_END
+/* }}} */
+
+/* {{{ timezone_object_construct */
+U_CFUNC void timezone_object_construct(const TimeZone *zone, zval *object, int owned TSRMLS_DC)
+{
+ TimeZone_object *to;
+
+ object_init_ex(object, TimeZone_ce_ptr);
+ TIMEZONE_METHOD_FETCH_OBJECT_NO_CHECK; /* fetch zend object from zval "object" into "to" */
+ to->utimezone = zone;
+ to->should_delete = owned;
+}
+/* }}} */
+
+/* {{{ timezone_convert_to_datetimezone
+ * Convert from TimeZone to DateTimeZone object */
+U_CFUNC zval *timezone_convert_to_datetimezone(const TimeZone *timeZone,
+ intl_error *outside_error,
+ const char *func TSRMLS_DC)
+{
+ zval *ret = NULL;
+ UnicodeString id;
+ char *message = NULL;
+ php_timezone_obj *tzobj;
+ zval arg = zval_used_for_init;
+
+ timeZone->getID(id);
+ if (id.isBogus()) {
+ spprintf(&message, 0, "%s: could not obtain TimeZone id", func);
+ intl_errors_set(outside_error, U_ILLEGAL_ARGUMENT_ERROR,
+ message, 1 TSRMLS_CC);
+ goto error;
+ }
+
+ MAKE_STD_ZVAL(ret);
+ object_init_ex(ret, php_date_get_timezone_ce());
+ tzobj = (php_timezone_obj *)zend_objects_get_address(ret TSRMLS_CC);
+
+ if (id.compare(0, 3, UnicodeString("GMT", sizeof("GMT")-1, US_INV)) == 0) {
+ /* The DateTimeZone constructor doesn't support offset time zones,
+ * so we must mess with DateTimeZone structure ourselves */
+ tzobj->initialized = 1;
+ tzobj->type = TIMELIB_ZONETYPE_OFFSET;
+ //convert offset from milliseconds to minutes
+ tzobj->tzi.utc_offset = -1 * timeZone->getRawOffset() / (60 * 1000);
+ } else {
+ /* Call the constructor! */
+ Z_TYPE(arg) = IS_STRING;
+ if (intl_charFromString(id, &Z_STRVAL(arg), &Z_STRLEN(arg),
+ &INTL_ERROR_CODE(*outside_error)) == FAILURE) {
+ spprintf(&message, 0, "%s: could not convert id to UTF-8", func);
+ intl_errors_set(outside_error, INTL_ERROR_CODE(*outside_error),
+ message, 1 TSRMLS_CC);
+ goto error;
+ }
+ zend_call_method_with_1_params(&ret, NULL, NULL, "__construct",
+ NULL, &arg);
+ if (EG(exception)) {
+ spprintf(&message, 0,
+ "%s: DateTimeZone constructor threw exception", func);
+ intl_errors_set(outside_error, U_ILLEGAL_ARGUMENT_ERROR,
+ message, 1 TSRMLS_CC);
+ zend_object_store_ctor_failed(ret TSRMLS_CC);
+ goto error;
+ }
+ }
+
+ if (0) {
+error:
+ if (ret) {
+ zval_ptr_dtor(&ret);
+ }
+ ret = NULL;
+ }
+
+ if (message) {
+ efree(message);
+ }
+ if (Z_TYPE(arg) == IS_STRING) {
+ zval_dtor(&arg);
+ }
+ return ret;
+}
+/* }}} */
+
+/* {{{ timezone_process_timezone_argument
+ * TimeZone argument processor. outside_error may be NULL (for static functions/constructors) */
+U_CFUNC TimeZone *timezone_process_timezone_argument(zval **zv_timezone,
+ intl_error *outside_error,
+ const char *func TSRMLS_DC)
+{
+ zval local_zv_tz = zval_used_for_init,
+ *local_zv_tz_p = &local_zv_tz;
+ char *message = NULL;
+ TimeZone *timeZone;
+
+ if (zv_timezone == NULL || Z_TYPE_PP(zv_timezone) == IS_NULL) {
+ timelib_tzinfo *tzinfo = get_timezone_info(TSRMLS_C);
+ ZVAL_STRING(&local_zv_tz, tzinfo->name, 0);
+ zv_timezone = &local_zv_tz_p;
+ }
+
+ if (Z_TYPE_PP(zv_timezone) == IS_OBJECT &&
+ instanceof_function(Z_OBJCE_PP(zv_timezone), TimeZone_ce_ptr TSRMLS_CC)) {
+ TimeZone_object *to = (TimeZone_object*)zend_objects_get_address(
+ *zv_timezone TSRMLS_CC);
+ if (to->utimezone == NULL) {
+ spprintf(&message, 0, "%s: passed IntlTimeZone is not "
+ "properly constructed", func);
+ if (message) {
+ intl_errors_set(outside_error, U_ILLEGAL_ARGUMENT_ERROR, message, 1 TSRMLS_CC);
+ efree(message);
+ }
+ return NULL;
+ }
+ timeZone = to->utimezone->clone();
+ if (timeZone == NULL) {
+ spprintf(&message, 0, "%s: could not clone TimeZone", func);
+ if (message) {
+ intl_errors_set(outside_error, U_MEMORY_ALLOCATION_ERROR, message, 1 TSRMLS_CC);
+ efree(message);
+ }
+ return NULL;
+ }
+ } else if (Z_TYPE_PP(zv_timezone) == IS_OBJECT &&
+ instanceof_function(Z_OBJCE_PP(zv_timezone), php_date_get_timezone_ce() TSRMLS_CC)) {
+
+ php_timezone_obj *tzobj = (php_timezone_obj *)zend_objects_get_address(
+ *zv_timezone TSRMLS_CC);
+
+ return timezone_convert_datetimezone(tzobj->type, tzobj, 0,
+ outside_error, func TSRMLS_CC);
+ } else {
+ UnicodeString id,
+ gottenId;
+ UErrorCode status = U_ZERO_ERROR; /* outside_error may be NULL */
+ convert_to_string_ex(zv_timezone);
+ if (intl_stringFromChar(id, Z_STRVAL_PP(zv_timezone), Z_STRLEN_PP(zv_timezone),
+ &status) == FAILURE) {
+ spprintf(&message, 0, "%s: Time zone identifier given is not a "
+ "valid UTF-8 string", func);
+ if (message) {
+ intl_errors_set(outside_error, status, message, 1 TSRMLS_CC);
+ efree(message);
+ }
+ return NULL;
+ }
+ timeZone = TimeZone::createTimeZone(id);
+ if (timeZone == NULL) {
+ spprintf(&message, 0, "%s: could not create time zone", func);
+ if (message) {
+ intl_errors_set(outside_error, U_MEMORY_ALLOCATION_ERROR, message, 1 TSRMLS_CC);
+ efree(message);
+ }
+ return NULL;
+ }
+ if (timeZone->getID(gottenId) != id) {
+ spprintf(&message, 0, "%s: no such time zone: '%s'",
+ func, Z_STRVAL_PP(zv_timezone));
+ if (message) {
+ intl_errors_set(outside_error, U_ILLEGAL_ARGUMENT_ERROR, message, 1 TSRMLS_CC);
+ efree(message);
+ }
+ delete timeZone;
+ return NULL;
+ }
+ }
+
+ return timeZone;
+}
+/* }}} */
+
+/* {{{ clone handler for TimeZone */
+static zend_object_value TimeZone_clone_obj(zval *object TSRMLS_DC)
+{
+ TimeZone_object *to_orig,
+ *to_new;
+ zend_object_value ret_val;
+ intl_error_reset(NULL TSRMLS_CC);
+
+ to_orig = (TimeZone_object*)zend_object_store_get_object(object TSRMLS_CC);
+ intl_error_reset(TIMEZONE_ERROR_P(to_orig) TSRMLS_CC);
+
+ ret_val = TimeZone_ce_ptr->create_object(Z_OBJCE_P(object) TSRMLS_CC);
+ to_new = (TimeZone_object*)zend_object_store_get_object_by_handle(
+ ret_val.handle TSRMLS_CC);
+
+ zend_objects_clone_members(&to_new->zo, ret_val,
+ &to_orig->zo, Z_OBJ_HANDLE_P(object) TSRMLS_CC);
+
+ if (to_orig->utimezone != NULL) {
+ TimeZone *newTimeZone;
+
+ newTimeZone = to_orig->utimezone->clone();
+ to_new->should_delete = 1;
+ if (!newTimeZone) {
+ char *err_msg;
+ intl_errors_set_code(TIMEZONE_ERROR_P(to_orig),
+ U_MEMORY_ALLOCATION_ERROR TSRMLS_CC);
+ intl_errors_set_custom_msg(TIMEZONE_ERROR_P(to_orig),
+ "Could not clone IntlTimeZone", 0 TSRMLS_CC);
+ err_msg = intl_error_get_message(TIMEZONE_ERROR_P(to_orig) TSRMLS_CC);
+ zend_throw_exception(NULL, err_msg, 0 TSRMLS_CC);
+ efree(err_msg);
+ } else {
+ to_new->utimezone = newTimeZone;
+ }
+ } else {
+ zend_throw_exception(NULL, "Cannot clone unconstructed IntlTimeZone", 0 TSRMLS_CC);
+ }
+
+ return ret_val;
+}
+/* }}} */
+
+/* {{{ compare_objects handler for TimeZone
+ * Can't be used for >, >=, <, <= comparisons */
+static int TimeZone_compare_objects(zval *object1, zval *object2 TSRMLS_DC)
+{
+ TimeZone_object *to1,
+ *to2;
+ to1 = (TimeZone_object*)zend_object_store_get_object(object1 TSRMLS_CC);
+ to2 = (TimeZone_object*)zend_object_store_get_object(object2 TSRMLS_CC);
+
+ if (to1->utimezone == NULL || to2->utimezone == NULL) {
+ zend_throw_exception(NULL, "Comparison with at least one unconstructed "
+ "IntlTimeZone operand", 0 TSRMLS_CC);
+ /* intentionally not returning */
+ } else {
+ if (*to1->utimezone == *to2->utimezone) {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+/* }}} */
+
+/* {{{ get_debug_info handler for TimeZone */
+static HashTable *TimeZone_get_debug_info(zval *object, int *is_temp TSRMLS_DC)
+{
+ zval zv = zval_used_for_init;
+ TimeZone_object *to;
+ const TimeZone *tz;
+ UnicodeString ustr;
+ char *str;
+ int str_len;
+ UErrorCode uec = U_ZERO_ERROR;
+
+ *is_temp = 1;
+
+ array_init_size(&zv, 4);
+
+ to = (TimeZone_object*)zend_object_store_get_object(object TSRMLS_CC);
+ tz = to->utimezone;
+
+ if (tz == NULL) {
+ add_assoc_bool_ex(&zv, "valid", sizeof("valid"), 0);
+ return Z_ARRVAL(zv);
+ }
+
+ add_assoc_bool_ex(&zv, "valid", sizeof("valid"), 1);
+
+ tz->getID(ustr);
+ intl_convert_utf16_to_utf8(&str, &str_len,
+ ustr.getBuffer(), ustr.length(), &uec);
+ if (U_FAILURE(uec)) {
+ return Z_ARRVAL(zv);
+ }
+ add_assoc_stringl_ex(&zv, "id", sizeof("id"), str, str_len, 0);
+
+ int32_t rawOffset, dstOffset;
+ UDate now = Calendar::getNow();
+ tz->getOffset(now, FALSE, rawOffset, dstOffset, uec);
+ if (U_FAILURE(uec)) {
+ return Z_ARRVAL(zv);
+ }
+
+ add_assoc_long_ex(&zv, "rawOffset", sizeof("rawOffset"), (long)rawOffset);
+ add_assoc_long_ex(&zv, "currentOffset", sizeof("currentOffset"),
+ (long)(rawOffset + dstOffset));
+
+ return Z_ARRVAL(zv);
+}
+/* }}} */
+
+/* {{{ void TimeZone_object_init(TimeZone_object* to)
+ * Initialize internals of TImeZone_object not specific to zend standard objects.
+ */
+static void TimeZone_object_init(TimeZone_object *to TSRMLS_DC)
+{
+ intl_error_init(TIMEZONE_ERROR_P(to) TSRMLS_CC);
+ to->utimezone = NULL;
+ to->should_delete = 0;
+}
+/* }}} */
+
+/* {{{ TimeZone_objects_dtor */
+static void TimeZone_objects_dtor(zend_object *object,
+ zend_object_handle handle TSRMLS_DC)
+{
+ zend_objects_destroy_object(object, handle TSRMLS_CC);
+}
+/* }}} */
+
+/* {{{ TimeZone_objects_free */
+static void TimeZone_objects_free(zend_object *object TSRMLS_DC)
+{
+ TimeZone_object* to = (TimeZone_object*) object;
+
+ if (to->utimezone && to->should_delete) {
+ delete to->utimezone;
+ to->utimezone = NULL;
+ }
+ intl_error_reset(TIMEZONE_ERROR_P(to) TSRMLS_CC);
+
+ zend_object_std_dtor(&to->zo TSRMLS_CC);
+
+ efree(to);
+}
+/* }}} */
+
+/* {{{ TimeZone_object_create */
+static zend_object_value TimeZone_object_create(zend_class_entry *ce TSRMLS_DC)
+{
+ zend_object_value retval;
+ TimeZone_object* intern;
+
+ intern = (TimeZone_object*)ecalloc(1, sizeof(TimeZone_object));
+
+ zend_object_std_init(&intern->zo, ce TSRMLS_CC);
+#if PHP_VERSION_ID < 50399
+ zend_hash_copy(intern->zo.properties, &(ce->default_properties),
+ (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval*));
+#else
+ object_properties_init((zend_object*) intern, ce);
+#endif
+ TimeZone_object_init(intern TSRMLS_CC);
+
+ retval.handle = zend_objects_store_put(
+ intern,
+ (zend_objects_store_dtor_t) TimeZone_objects_dtor,
+ (zend_objects_free_object_storage_t) TimeZone_objects_free,
+ NULL TSRMLS_CC);
+
+ retval.handlers = &TimeZone_handlers;
+
+ return retval;
+}
+/* }}} */
+
+/* {{{ TimeZone methods arguments info */
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_tz_idarg, 0, 0, 1)
+ ZEND_ARG_INFO(0, zoneId)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_tz_fromDateTimeZone, 0, 0, 1)
+ ZEND_ARG_OBJ_INFO(0, otherTimeZone, IntlTimeZone, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_tz_createEnumeration, 0, 0, 0)
+ ZEND_ARG_INFO(0, countryOrRawOffset)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_tz_countEquivalentIDs, 0, 0, 1)
+ ZEND_ARG_INFO(0, zoneId)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_tz_createTimeZoneIDEnumeration, 0, 0, 1)
+ ZEND_ARG_INFO(0, zoneType)
+ ZEND_ARG_INFO(0, region)
+ ZEND_ARG_INFO(0, rawOffset)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_tz_getCanonicalID, 0, 0, 1)
+ ZEND_ARG_INFO(0, zoneId)
+ ZEND_ARG_INFO(1, isSystemID)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_tz_getEquivalentID, 0, 0, 2)
+ ZEND_ARG_INFO(0, zoneId)
+ ZEND_ARG_INFO(0, index)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_tz_getOffset, 0, 0, 4)
+ ZEND_ARG_INFO(0, date)
+ ZEND_ARG_INFO(0, local)
+ ZEND_ARG_INFO(1, rawOffset)
+ ZEND_ARG_INFO(1, dstOffset)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_tz_hasSameRules, 0, 0, 1)
+ ZEND_ARG_OBJ_INFO(0, otherTimeZone, IntlTimeZone, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_tz_getDisplayName, 0, 0, 0)
+ ZEND_ARG_INFO(0, isDaylight)
+ ZEND_ARG_INFO(0, style)
+ ZEND_ARG_INFO(0, locale)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(ainfo_tz_void, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+/* }}} */
+
+/* {{{ TimeZone_class_functions
+ * Every 'IntlTimeZone' class method has an entry in this table
+ */
+static zend_function_entry TimeZone_class_functions[] = {
+ PHP_ME(IntlTimeZone, __construct, ainfo_tz_void, ZEND_ACC_PRIVATE)
+ PHP_ME_MAPPING(createTimeZone, intltz_create_time_zone, ainfo_tz_idarg, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+ PHP_ME_MAPPING(fromDateTimeZone, intltz_from_date_time_zone, ainfo_tz_idarg, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+ PHP_ME_MAPPING(createDefault, intltz_create_default, ainfo_tz_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+ PHP_ME_MAPPING(getGMT, intltz_get_gmt, ainfo_tz_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+#if U_ICU_VERSION_MAJOR_NUM >= 49
+ PHP_ME_MAPPING(getUnknown, intltz_get_unknown, ainfo_tz_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+#endif
+ PHP_ME_MAPPING(createEnumeration, intltz_create_enumeration, ainfo_tz_createEnumeration, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+ PHP_ME_MAPPING(countEquivalentIDs, intltz_count_equivalent_ids, ainfo_tz_idarg, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+#if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 48
+ PHP_ME_MAPPING(createTimeZoneIDEnumeration, intltz_create_time_zone_id_enumeration, ainfo_tz_createTimeZoneIDEnumeration, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+#endif
+ PHP_ME_MAPPING(getCanonicalID, intltz_get_canonical_id, ainfo_tz_getCanonicalID, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+#if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 48
+ PHP_ME_MAPPING(getRegion, intltz_get_region, ainfo_tz_idarg, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+#endif
+ PHP_ME_MAPPING(getTZDataVersion, intltz_get_tz_data_version, ainfo_tz_void, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+ PHP_ME_MAPPING(getEquivalentID, intltz_get_equivalent_id, ainfo_tz_getEquivalentID, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+
+ PHP_ME_MAPPING(getID, intltz_get_id, ainfo_tz_void, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(useDaylightTime, intltz_use_daylight_time, ainfo_tz_void, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(getOffset, intltz_get_offset, ainfo_tz_getOffset, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(getRawOffset, intltz_get_raw_offset, ainfo_tz_void, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(hasSameRules, intltz_has_same_rules, ainfo_tz_hasSameRules, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(getDisplayName, intltz_get_display_name, ainfo_tz_getDisplayName, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(getDSTSavings, intltz_get_dst_savings, ainfo_tz_void, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(toDateTimeZone, intltz_to_date_time_zone, ainfo_tz_void, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(getErrorCode, intltz_get_error_code, ainfo_tz_void, ZEND_ACC_PUBLIC)
+ PHP_ME_MAPPING(getErrorMessage, intltz_get_error_message, ainfo_tz_void, ZEND_ACC_PUBLIC)
+ PHP_FE_END
+};
+/* }}} */
+
+/* {{{ timezone_register_IntlTimeZone_class
+ * Initialize 'IntlTimeZone' class
+ */
+U_CFUNC void timezone_register_IntlTimeZone_class(TSRMLS_D)
+{
+ zend_class_entry ce;
+
+ /* Create and register 'IntlTimeZone' class. */
+ INIT_CLASS_ENTRY(ce, "IntlTimeZone", TimeZone_class_functions);
+ ce.create_object = TimeZone_object_create;
+ TimeZone_ce_ptr = zend_register_internal_class(&ce TSRMLS_CC);
+ if (!TimeZone_ce_ptr) {
+ //can't happen now without bigger problems before
+ php_error_docref0(NULL TSRMLS_CC, E_ERROR,
+ "IntlTimeZone: class registration has failed.");
+ return;
+ }
+
+ memcpy(&TimeZone_handlers, zend_get_std_object_handlers(),
+ sizeof TimeZone_handlers);
+ TimeZone_handlers.clone_obj = TimeZone_clone_obj;
+ TimeZone_handlers.compare_objects = TimeZone_compare_objects;
+ TimeZone_handlers.get_debug_info = TimeZone_get_debug_info;
+
+ /* Declare 'IntlTimeZone' class constants */
+#define TIMEZONE_DECL_LONG_CONST(name, val) \
+ zend_declare_class_constant_long(TimeZone_ce_ptr, name, sizeof(name) - 1, \
+ val TSRMLS_CC)
+
+ TIMEZONE_DECL_LONG_CONST("DISPLAY_SHORT", TimeZone::SHORT);
+ TIMEZONE_DECL_LONG_CONST("DISPLAY_LONG", TimeZone::LONG);
+
+#if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 44
+ TIMEZONE_DECL_LONG_CONST("DISPLAY_SHORT_GENERIC", TimeZone::SHORT_GENERIC);
+ TIMEZONE_DECL_LONG_CONST("DISPLAY_LONG_GENERIC", TimeZone::LONG_GENERIC);
+ TIMEZONE_DECL_LONG_CONST("DISPLAY_SHORT_GMT", TimeZone::SHORT_GMT);
+ TIMEZONE_DECL_LONG_CONST("DISPLAY_LONG_GMT", TimeZone::LONG_GMT);
+ TIMEZONE_DECL_LONG_CONST("DISPLAY_SHORT_COMMONLY_USED", TimeZone::SHORT_COMMONLY_USED);
+ TIMEZONE_DECL_LONG_CONST("DISPLAY_GENERIC_LOCATION", TimeZone::GENERIC_LOCATION);
+#endif
+
+#if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 48
+ TIMEZONE_DECL_LONG_CONST("TYPE_ANY", UCAL_ZONE_TYPE_ANY);
+ TIMEZONE_DECL_LONG_CONST("TYPE_CANONICAL", UCAL_ZONE_TYPE_CANONICAL);
+ TIMEZONE_DECL_LONG_CONST("TYPE_CANONICAL_LOCATION", UCAL_ZONE_TYPE_CANONICAL_LOCATION);
+#endif
+
+ /* Declare 'IntlTimeZone' class properties */
+
+}
+/* }}} */
diff --git a/ext/intl/timezone/timezone_class.h b/ext/intl/timezone/timezone_class.h
new file mode 100644
index 0000000000..a638f6dbf4
--- /dev/null
+++ b/ext/intl/timezone/timezone_class.h
@@ -0,0 +1,72 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@netcabo.pt> |
+ +----------------------------------------------------------------------+
+ */
+
+#ifndef TIMEZONE_CLASS_H
+#define TIMEZONE_CLASS_H
+
+//redefinition of inline in PHP headers causes problems, so include this before
+#include <math.h>
+
+//fixes the build on windows for old versions of ICU
+#include <stdio.h>
+
+#include <php.h>
+#include "intl_error.h"
+#include "intl_data.h"
+
+#ifndef USE_TIMEZONE_POINTER
+typedef void TimeZone;
+#endif
+
+typedef struct {
+ zend_object zo;
+
+ // error handling
+ intl_error err;
+
+ // ICU TimeZone
+ const TimeZone *utimezone;
+
+ //whether to delete the timezone on object free
+ zend_bool should_delete;
+} TimeZone_object;
+
+#define TIMEZONE_ERROR(to) (to)->err
+#define TIMEZONE_ERROR_P(to) &(TIMEZONE_ERROR(to))
+
+#define TIMEZONE_ERROR_CODE(co) INTL_ERROR_CODE(TIMEZONE_ERROR(to))
+#define TIMEZONE_ERROR_CODE_P(co) &(INTL_ERROR_CODE(TIMEZONE_ERROR(to)))
+
+#define TIMEZONE_METHOD_INIT_VARS INTL_METHOD_INIT_VARS(TimeZone, to)
+#define TIMEZONE_METHOD_FETCH_OBJECT_NO_CHECK INTL_METHOD_FETCH_OBJECT(TimeZone, to)
+#define TIMEZONE_METHOD_FETCH_OBJECT\
+ TIMEZONE_METHOD_FETCH_OBJECT_NO_CHECK; \
+ if (to->utimezone == NULL) { \
+ intl_errors_set(&to->err, U_ILLEGAL_ARGUMENT_ERROR, "Found unconstructed IntlTimeZone", 0 TSRMLS_CC); \
+ RETURN_FALSE; \
+ }
+
+zval *timezone_convert_to_datetimezone(const TimeZone *timeZone, intl_error *outside_error, const char *func TSRMLS_DC);
+TimeZone *timezone_process_timezone_argument(zval **zv_timezone, intl_error *error, const char *func TSRMLS_DC);
+
+void timezone_object_construct(const TimeZone *zone, zval *object, int owned TSRMLS_DC);
+
+void timezone_register_IntlTimeZone_class(TSRMLS_D);
+
+extern zend_class_entry *TimeZone_ce_ptr;
+extern zend_object_handlers TimeZone_handlers;
+
+#endif /* #ifndef TIMEZONE_CLASS_H */
diff --git a/ext/intl/timezone/timezone_methods.cpp b/ext/intl/timezone/timezone_methods.cpp
new file mode 100644
index 0000000000..9ca6b44c89
--- /dev/null
+++ b/ext/intl/timezone/timezone_methods.cpp
@@ -0,0 +1,659 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "../intl_cppshims.h"
+
+#include <unicode/locid.h>
+#include <unicode/timezone.h>
+#include <unicode/ustring.h>
+#include "intl_convertcpp.h"
+
+#include "../common/common_date.h"
+
+extern "C" {
+#include "../php_intl.h"
+#define USE_TIMEZONE_POINTER 1
+#include "timezone_class.h"
+#include "intl_convert.h"
+#include <zend_exceptions.h>
+#include <ext/date/php_date.h>
+}
+#include "common/common_enum.h"
+
+U_CFUNC PHP_METHOD(IntlTimeZone, __construct)
+{
+ zend_throw_exception( NULL,
+ "An object of this type cannot be created with the new operator",
+ 0 TSRMLS_CC );
+}
+
+U_CFUNC PHP_FUNCTION(intltz_create_time_zone)
+{
+ char *str_id;
+ int str_id_len;
+ intl_error_reset(NULL TSRMLS_CC);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",
+ &str_id, &str_id_len) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intltz_create_time_zone: bad arguments", 0 TSRMLS_CC);
+ RETURN_NULL();
+ }
+
+ UErrorCode status = UErrorCode();
+ UnicodeString id = UnicodeString();
+ if (intl_stringFromChar(id, str_id, str_id_len, &status) == FAILURE) {
+ intl_error_set(NULL, status,
+ "intltz_create_time_zone: could not convert time zone id to UTF-16", 0 TSRMLS_CC);
+ RETURN_NULL();
+ }
+
+ //guaranteed non-null; GMT if timezone cannot be understood
+ TimeZone *tz = TimeZone::createTimeZone(id);
+ timezone_object_construct(tz, return_value, 1 TSRMLS_CC);
+}
+
+U_CFUNC PHP_FUNCTION(intltz_from_date_time_zone)
+{
+ zval *zv_timezone;
+ TimeZone *tz;
+ php_timezone_obj *tzobj;
+ intl_error_reset(NULL TSRMLS_CC);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O",
+ &zv_timezone, php_date_get_timezone_ce()) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intltz_from_date_time_zone: bad arguments", 0 TSRMLS_CC);
+ RETURN_NULL();
+ }
+
+ tzobj = (php_timezone_obj *)zend_objects_get_address(zv_timezone TSRMLS_CC);
+ if (!tzobj->initialized) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intltz_from_date_time_zone: DateTimeZone object is unconstructed",
+ 0 TSRMLS_CC);
+ RETURN_NULL();
+ }
+
+ tz = timezone_convert_datetimezone(tzobj->type, tzobj, FALSE, NULL,
+ "intltz_from_date_time_zone" TSRMLS_CC);
+ if (tz == NULL) {
+ RETURN_NULL();
+ }
+
+ timezone_object_construct(tz, return_value, 1 TSRMLS_CC);
+}
+
+U_CFUNC PHP_FUNCTION(intltz_create_default)
+{
+ intl_error_reset(NULL TSRMLS_CC);
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intltz_create_default: bad arguments", 0 TSRMLS_CC);
+ RETURN_NULL();
+ }
+
+ TimeZone *tz = TimeZone::createDefault();
+ timezone_object_construct(tz, return_value, 1 TSRMLS_CC);
+}
+
+U_CFUNC PHP_FUNCTION(intltz_get_gmt)
+{
+ intl_error_reset(NULL TSRMLS_CC);
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intltz_get_gmt: bad arguments", 0 TSRMLS_CC);
+ RETURN_NULL();
+ }
+
+ timezone_object_construct(TimeZone::getGMT(), return_value, 0 TSRMLS_CC);
+}
+
+#if U_ICU_VERSION_MAJOR_NUM >= 49
+U_CFUNC PHP_FUNCTION(intltz_get_unknown)
+{
+ intl_error_reset(NULL TSRMLS_CC);
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intltz_get_unknown: bad arguments", 0 TSRMLS_CC);
+ RETURN_NULL();
+ }
+
+ timezone_object_construct(&TimeZone::getUnknown(), return_value, 0 TSRMLS_CC);
+}
+#endif
+
+U_CFUNC PHP_FUNCTION(intltz_create_enumeration)
+{
+ zval **arg = NULL;
+ StringEnumeration *se = NULL;
+ intl_error_reset(NULL TSRMLS_CC);
+
+ /* double indirection to have the zend engine destroy the new zval that
+ * results from separation */
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|Z", &arg) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intltz_create_enumeration: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (arg == NULL || Z_TYPE_PP(arg) == IS_NULL) {
+ se = TimeZone::createEnumeration();
+ } else if (Z_TYPE_PP(arg) == IS_LONG) {
+int_offset:
+ if (Z_LVAL_PP(arg) < (long)INT32_MIN ||
+ Z_LVAL_PP(arg) > (long)INT32_MAX) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intltz_create_enumeration: value is out of range", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ } else {
+ se = TimeZone::createEnumeration((int32_t) Z_LVAL_PP(arg));
+ }
+ } else if (Z_TYPE_PP(arg) == IS_DOUBLE) {
+double_offset:
+ convert_to_long_ex(arg);
+ goto int_offset;
+ } else if (Z_TYPE_PP(arg) == IS_OBJECT || Z_TYPE_PP(arg) == IS_STRING) {
+ long lval;
+ double dval;
+ convert_to_string_ex(arg);
+ switch (is_numeric_string(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), &lval, &dval, 0)) {
+ case IS_DOUBLE:
+ SEPARATE_ZVAL(arg);
+ zval_dtor(*arg);
+ Z_TYPE_PP(arg) = IS_DOUBLE;
+ Z_DVAL_PP(arg) = dval;
+ goto double_offset;
+ case IS_LONG:
+ SEPARATE_ZVAL(arg);
+ zval_dtor(*arg);
+ Z_TYPE_PP(arg) = IS_LONG;
+ Z_LVAL_PP(arg) = lval;
+ goto int_offset;
+ }
+ /* else call string version */
+ se = TimeZone::createEnumeration(Z_STRVAL_PP(arg));
+ } else {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intltz_create_enumeration: invalid argument type", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (se) {
+ IntlIterator_from_StringEnumeration(se, return_value TSRMLS_CC);
+ } else {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intltz_create_enumeration: error obtaining enumeration", 0 TSRMLS_CC);
+ RETVAL_FALSE;
+ }
+}
+
+U_CFUNC PHP_FUNCTION(intltz_count_equivalent_ids)
+{
+ char *str_id;
+ int str_id_len;
+ intl_error_reset(NULL TSRMLS_CC);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",
+ &str_id, &str_id_len) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intltz_count_equivalent_ids: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ UErrorCode status = UErrorCode();
+ UnicodeString id = UnicodeString();
+ if (intl_stringFromChar(id, str_id, str_id_len, &status) == FAILURE) {
+ intl_error_set(NULL, status,
+ "intltz_count_equivalent_ids: could not convert time zone id to UTF-16", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ int32_t result = TimeZone::countEquivalentIDs(id);
+ RETURN_LONG((long)result);
+}
+
+#if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 48
+U_CFUNC PHP_FUNCTION(intltz_create_time_zone_id_enumeration)
+{
+ long zoneType,
+ offset_arg;
+ char *region = NULL;
+ int region_len = 0;
+ int32_t offset,
+ *offsetp = NULL;
+ int arg3isnull = 0;
+ intl_error_reset(NULL TSRMLS_CC);
+
+ /* must come before zpp because zpp would convert the arg in the stack to 0 */
+ if (ZEND_NUM_ARGS() == 3) {
+ zval **dummy, **zvoffset;
+ arg3isnull = zend_get_parameters_ex(3, &dummy, &dummy, &zvoffset)
+ != FAILURE && Z_TYPE_PP(zvoffset) == IS_NULL;
+ }
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|s!l",
+ &zoneType, &region, &region_len, &offset_arg) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intltz_create_time_zone_id_enumeration: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (zoneType != UCAL_ZONE_TYPE_ANY && zoneType != UCAL_ZONE_TYPE_CANONICAL
+ && zoneType != UCAL_ZONE_TYPE_CANONICAL_LOCATION) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intltz_create_time_zone_id_enumeration: bad zone type", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (ZEND_NUM_ARGS() == 3) {
+ if (offset_arg < (long)INT32_MIN || offset_arg > (long)INT32_MAX) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intltz_create_time_zone_id_enumeration: offset out of bounds", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (!arg3isnull) {
+ offset = (int32_t)offset_arg;
+ offsetp = &offset;
+ } //else leave offsetp NULL
+ }
+
+ StringEnumeration *se;
+ UErrorCode uec = UErrorCode();
+ se = TimeZone::createTimeZoneIDEnumeration((USystemTimeZoneType)zoneType,
+ region, offsetp, uec);
+ INTL_CHECK_STATUS(uec, "intltz_create_time_zone_id_enumeration: "
+ "Error obtaining time zone id enumeration")
+
+ IntlIterator_from_StringEnumeration(se, return_value TSRMLS_CC);
+}
+#endif
+
+U_CFUNC PHP_FUNCTION(intltz_get_canonical_id)
+{
+ char *str_id;
+ int str_id_len;
+ zval *is_systemid = NULL;
+ intl_error_reset(NULL TSRMLS_CC);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z",
+ &str_id, &str_id_len, &is_systemid) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intltz_get_canonical_id: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ UErrorCode status = UErrorCode();
+ UnicodeString id;
+ if (intl_stringFromChar(id, str_id, str_id_len, &status) == FAILURE) {
+ intl_error_set(NULL, status,
+ "intltz_get_canonical_id: could not convert time zone id to UTF-16", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ UnicodeString result;
+ UBool isSystemID;
+ TimeZone::getCanonicalID(id, result, isSystemID, status);
+ INTL_CHECK_STATUS(status, "intltz_get_canonical_id: error obtaining canonical ID");
+
+ intl_convert_utf16_to_utf8(&Z_STRVAL_P(return_value), &Z_STRLEN_P(return_value),
+ result.getBuffer(), result.length(), &status);
+ INTL_CHECK_STATUS(status,
+ "intltz_get_canonical_id: could not convert time zone id to UTF-16");
+ Z_TYPE_P(return_value) = IS_STRING;
+
+ if (is_systemid) { /* by-ref argument passed */
+ zval_dtor(is_systemid);
+ ZVAL_BOOL(is_systemid, isSystemID);
+ }
+}
+
+#if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 48
+U_CFUNC PHP_FUNCTION(intltz_get_region)
+{
+ char *str_id;
+ int str_id_len;
+ char outbuf[3];
+ intl_error_reset(NULL TSRMLS_CC);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",
+ &str_id, &str_id_len) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intltz_get_region: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ UErrorCode status = UErrorCode();
+ UnicodeString id;
+ if (intl_stringFromChar(id, str_id, str_id_len, &status) == FAILURE) {
+ intl_error_set(NULL, status,
+ "intltz_get_region: could not convert time zone id to UTF-16", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ int32_t region_len = TimeZone::getRegion(id, outbuf, sizeof(outbuf), status);
+ INTL_CHECK_STATUS(status, "intltz_get_region: Error obtaining region");
+
+ RETURN_STRINGL(outbuf, region_len, 1);
+}
+#endif
+
+U_CFUNC PHP_FUNCTION(intltz_get_tz_data_version)
+{
+ intl_error_reset(NULL TSRMLS_CC);
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intltz_get_tz_data_version: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ UErrorCode status = UErrorCode();
+ const char *res = TimeZone::getTZDataVersion(status);
+ INTL_CHECK_STATUS(status, "intltz_get_tz_data_version: "
+ "Error obtaining time zone data version");
+
+ RETURN_STRING(res, 1);
+}
+
+U_CFUNC PHP_FUNCTION(intltz_get_equivalent_id)
+{
+ char *str_id;
+ int str_id_len;
+ long index;
+ intl_error_reset(NULL TSRMLS_CC);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl",
+ &str_id, &str_id_len, &index) == FAILURE ||
+ index < (long)INT32_MIN || index > (long)INT32_MAX) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intltz_get_equivalent_id: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ UErrorCode status = UErrorCode();
+ UnicodeString id;
+ if (intl_stringFromChar(id, str_id, str_id_len, &status) == FAILURE) {
+ intl_error_set(NULL, status,
+ "intltz_get_equivalent_id: could not convert time zone id to UTF-16", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ const UnicodeString result = TimeZone::getEquivalentID(id, (int32_t)index);
+ intl_convert_utf16_to_utf8(&Z_STRVAL_P(return_value), &Z_STRLEN_P(return_value),
+ result.getBuffer(), result.length(), &status);
+ INTL_CHECK_STATUS(status, "intltz_get_equivalent_id: "
+ "could not convert resulting time zone id to UTF-16");
+ Z_TYPE_P(return_value) = IS_STRING;
+}
+
+U_CFUNC PHP_FUNCTION(intltz_get_id)
+{
+ TIMEZONE_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",
+ &object, TimeZone_ce_ptr) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intltz_get_id: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ TIMEZONE_METHOD_FETCH_OBJECT;
+
+ UnicodeString id_us;
+ to->utimezone->getID(id_us);
+
+ char *id = NULL;
+ int id_len = 0;
+
+ intl_convert_utf16_to_utf8(&id, &id_len,
+ id_us.getBuffer(), id_us.length(), TIMEZONE_ERROR_CODE_P(to));
+ INTL_METHOD_CHECK_STATUS(to, "intltz_get_id: Could not convert id to UTF-8");
+
+ RETURN_STRINGL(id, id_len, 0);
+}
+
+U_CFUNC PHP_FUNCTION(intltz_use_daylight_time)
+{
+ TIMEZONE_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",
+ &object, TimeZone_ce_ptr) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intltz_use_daylight_time: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ TIMEZONE_METHOD_FETCH_OBJECT;
+
+ RETURN_BOOL(to->utimezone->useDaylightTime());
+}
+
+U_CFUNC PHP_FUNCTION(intltz_get_offset)
+{
+ UDate date;
+ zend_bool local;
+ zval *rawOffsetArg,
+ *dstOffsetArg;
+ int32_t rawOffset,
+ dstOffset;
+ TIMEZONE_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "Odbzz", &object, TimeZone_ce_ptr, &date, &local, &rawOffsetArg,
+ &dstOffsetArg) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intltz_get_offset: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ TIMEZONE_METHOD_FETCH_OBJECT;
+
+ to->utimezone->getOffset(date, (UBool) local, rawOffset, dstOffset,
+ TIMEZONE_ERROR_CODE(to));
+
+ INTL_METHOD_CHECK_STATUS(to, "intltz_get_offset: error obtaining offset");
+
+ zval_dtor(rawOffsetArg);
+ ZVAL_LONG(rawOffsetArg, rawOffset);
+ zval_dtor(dstOffsetArg);
+ ZVAL_LONG(dstOffsetArg, dstOffset);
+
+ RETURN_TRUE;
+}
+
+U_CFUNC PHP_FUNCTION(intltz_get_raw_offset)
+{
+ TIMEZONE_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "O", &object, TimeZone_ce_ptr) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intltz_get_raw_offset: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ TIMEZONE_METHOD_FETCH_OBJECT;
+
+ RETURN_LONG(to->utimezone->getRawOffset());
+}
+
+U_CFUNC PHP_FUNCTION(intltz_has_same_rules)
+{
+ zval *other_object;
+ TimeZone_object *other_to;
+ TIMEZONE_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "OO", &object, TimeZone_ce_ptr, &other_object, TimeZone_ce_ptr)
+ == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intltz_has_same_rules: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+ TIMEZONE_METHOD_FETCH_OBJECT;
+ other_to = (TimeZone_object *) zend_object_store_get_object(other_object TSRMLS_CC);
+ if (other_to->utimezone == NULL) {
+ intl_errors_set(&to->err, U_ILLEGAL_ARGUMENT_ERROR,
+ "intltz_has_same_rules: The second IntlTimeZone is unconstructed", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ RETURN_BOOL(to->utimezone->hasSameRules(*other_to->utimezone));
+}
+
+static const TimeZone::EDisplayType display_types[] = {
+ TimeZone::SHORT, TimeZone::LONG,
+#if U_ICU_VERSION_MAJOR_NUM * 10 + U_ICU_VERSION_MINOR_NUM >= 44
+ TimeZone::SHORT_GENERIC, TimeZone::LONG_GENERIC,
+ TimeZone::SHORT_GMT, TimeZone::LONG_GMT,
+ TimeZone::SHORT_COMMONLY_USED, TimeZone::GENERIC_LOCATION
+#endif
+};
+
+U_CFUNC PHP_FUNCTION(intltz_get_display_name)
+{
+ zend_bool daylight = 0;
+ long display_type = TimeZone::LONG;
+ const char *locale_str = NULL;
+ int dummy = 0;
+ TIMEZONE_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "O|bls!", &object, TimeZone_ce_ptr, &daylight, &display_type,
+ &locale_str, &dummy) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intltz_get_display_name: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ bool found = false;
+ for (int i = 0; !found && i < sizeof(display_types)/sizeof(*display_types); i++) {
+ if (display_types[i] == display_type)
+ found = true;
+ }
+ if (!found) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intltz_get_display_name: wrong display type", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ if (!locale_str) {
+ locale_str = intl_locale_get_default(TSRMLS_C);
+ }
+
+ TIMEZONE_METHOD_FETCH_OBJECT;
+
+ UnicodeString result;
+ to->utimezone->getDisplayName((UBool)daylight, (TimeZone::EDisplayType)display_type,
+ Locale::createFromName(locale_str), result);
+
+ intl_convert_utf16_to_utf8(&Z_STRVAL_P(return_value), &Z_STRLEN_P(return_value),
+ result.getBuffer(), result.length(), TIMEZONE_ERROR_CODE_P(to));
+ INTL_METHOD_CHECK_STATUS(to, "intltz_get_display_name: "
+ "could not convert resulting time zone id to UTF-16");
+
+ Z_TYPE_P(return_value) = IS_STRING;
+}
+
+U_CFUNC PHP_FUNCTION(intltz_get_dst_savings)
+{
+ TIMEZONE_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "O", &object, TimeZone_ce_ptr) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intltz_get_dst_savings: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ TIMEZONE_METHOD_FETCH_OBJECT;
+
+ RETURN_LONG((long)to->utimezone->getDSTSavings());
+}
+
+U_CFUNC PHP_FUNCTION(intltz_to_date_time_zone)
+{
+ TIMEZONE_METHOD_INIT_VARS;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(),
+ "O", &object, TimeZone_ce_ptr) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intltz_to_date_time_zone: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ TIMEZONE_METHOD_FETCH_OBJECT;
+
+ zval *ret = timezone_convert_to_datetimezone(to->utimezone,
+ &TIMEZONE_ERROR(to), "intltz_to_date_time_zone" TSRMLS_CC);
+
+ if (ret) {
+ RETURN_ZVAL(ret, 1, 1);
+ } else {
+ RETURN_FALSE;
+ }
+}
+
+U_CFUNC PHP_FUNCTION(intltz_get_error_code)
+{
+ TIMEZONE_METHOD_INIT_VARS
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",
+ &object, TimeZone_ce_ptr) == FAILURE) {
+ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intltz_get_error_code: bad arguments", 0 TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ /* Fetch the object (without resetting its last error code ). */
+ to = (TimeZone_object*)zend_object_store_get_object(object TSRMLS_CC);
+ if (to == NULL)
+ RETURN_FALSE;
+
+ RETURN_LONG((long)TIMEZONE_ERROR_CODE(to));
+}
+
+U_CFUNC PHP_FUNCTION(intltz_get_error_message)
+{
+ const char* message = NULL;
+ TIMEZONE_METHOD_INIT_VARS
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O",
+ &object, TimeZone_ce_ptr) == FAILURE) {
+ intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
+ "intltz_get_error_message: bad arguments", 0 TSRMLS_CC );
+ RETURN_FALSE;
+ }
+
+
+ /* Fetch the object (without resetting its last error code ). */
+ to = (TimeZone_object*)zend_object_store_get_object(object TSRMLS_CC);
+ if (to == NULL)
+ RETURN_FALSE;
+
+ /* Return last error message. */
+ message = intl_error_get_message(TIMEZONE_ERROR_P(to) TSRMLS_CC);
+ RETURN_STRING(message, 0);
+}
diff --git a/ext/intl/timezone/timezone_methods.h b/ext/intl/timezone/timezone_methods.h
new file mode 100644
index 0000000000..28c39f4fd7
--- /dev/null
+++ b/ext/intl/timezone/timezone_methods.h
@@ -0,0 +1,68 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | 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: Gustavo Lopes <cataphract@netcabo.pt> |
+ +----------------------------------------------------------------------+
+ */
+
+#ifndef TIMEZONE_METHODS_H
+#define TIMEZONE_METHODS_H
+
+#include <php.h>
+
+PHP_METHOD(IntlTimeZone, __construct);
+
+PHP_FUNCTION(intltz_create_time_zone);
+
+PHP_FUNCTION(intltz_from_date_time_zone);
+
+PHP_FUNCTION(intltz_create_default);
+
+PHP_FUNCTION(intltz_get_id);
+
+PHP_FUNCTION(intltz_get_gmt);
+
+PHP_FUNCTION(intltz_get_unknown);
+
+PHP_FUNCTION(intltz_create_enumeration);
+
+PHP_FUNCTION(intltz_count_equivalent_ids);
+
+PHP_FUNCTION(intltz_create_time_zone_id_enumeration);
+
+PHP_FUNCTION(intltz_get_canonical_id);
+
+PHP_FUNCTION(intltz_get_region);
+
+PHP_FUNCTION(intltz_get_tz_data_version);
+
+PHP_FUNCTION(intltz_get_equivalent_id);
+
+PHP_FUNCTION(intltz_use_daylight_time);
+
+PHP_FUNCTION(intltz_get_offset);
+
+PHP_FUNCTION(intltz_get_raw_offset);
+
+PHP_FUNCTION(intltz_has_same_rules);
+
+PHP_FUNCTION(intltz_get_display_name);
+
+PHP_FUNCTION(intltz_get_dst_savings);
+
+PHP_FUNCTION(intltz_to_date_time_zone);
+
+PHP_FUNCTION(intltz_get_error_code);
+
+PHP_FUNCTION(intltz_get_error_message);
+
+#endif /* #ifndef TIMEZONE_METHODS_H */
diff --git a/ext/intl/transliterator/transliterator.c b/ext/intl/transliterator/transliterator.c
index 75c9eaabda..8ee49e1e51 100644
--- a/ext/intl/transliterator/transliterator.c
+++ b/ext/intl/transliterator/transliterator.c
@@ -49,85 +49,6 @@ void transliterator_register_constants( INIT_FUNC_ARGS )
}
/* }}} */
-/* {{{ transliterator_parse_error_to_string
- * Transforms parse errors in strings.
- */
-smart_str transliterator_parse_error_to_string( UParseError* pe )
-{
- smart_str ret = {0};
- char *buf;
- int u8len;
- UErrorCode status;
- int any = 0;
-
- assert( pe != NULL );
-
- smart_str_appends( &ret, "parse error " );
- if( pe->line > 0 )
- {
- smart_str_appends( &ret, "on line " );
- smart_str_append_long( &ret, (long ) pe->line );
- any = 1;
- }
- if( pe->offset >= 0 ) {
- if( any )
- smart_str_appends( &ret, ", " );
- else
- smart_str_appends( &ret, "at " );
-
- smart_str_appends( &ret, "offset " );
- smart_str_append_long( &ret, (long ) pe->offset );
- any = 1;
- }
-
- if (pe->preContext[0] != 0 ) {
- if( any )
- smart_str_appends( &ret, ", " );
-
- smart_str_appends( &ret, "after \"" );
- intl_convert_utf16_to_utf8( &buf, &u8len, pe->preContext, -1, &status );
- if( U_FAILURE( status ) )
- {
- smart_str_appends( &ret, "(could not convert parser error pre-context to UTF-8)" );
- }
- else {
- smart_str_appendl( &ret, buf, u8len );
- efree( buf );
- }
- smart_str_appends( &ret, "\"" );
- any = 1;
- }
-
- if( pe->postContext[0] != 0 )
- {
- if( any )
- smart_str_appends( &ret, ", " );
-
- smart_str_appends( &ret, "before or at \"" );
- intl_convert_utf16_to_utf8( &buf, &u8len, pe->postContext, -1, &status );
- if( U_FAILURE( status ) )
- {
- smart_str_appends( &ret, "(could not convert parser error post-context to UTF-8)" );
- }
- else
- {
- smart_str_appendl( &ret, buf, u8len );
- efree( buf );
- }
- smart_str_appends( &ret, "\"" );
- any = 1;
- }
-
- if( !any )
- {
- smart_str_free( &ret );
- smart_str_appends( &ret, "no parse error" );
- }
-
- smart_str_0( &ret );
- return ret;
-}
-
/*
* Local variables:
* tab-width: 4
diff --git a/ext/intl/transliterator/transliterator_class.c b/ext/intl/transliterator/transliterator_class.c
index 5ef80fb482..9891b35f4c 100644
--- a/ext/intl/transliterator/transliterator_class.c
+++ b/ext/intl/transliterator/transliterator_class.c
@@ -39,7 +39,7 @@ int transliterator_object_construct( zval *object,
char *str_id;
int str_id_len;
Transliterator_object *to;
-
+
TRANSLITERATOR_METHOD_FETCH_OBJECT_NO_CHECK;
assert( to->utrans == NULL );
@@ -54,7 +54,7 @@ int transliterator_object_construct( zval *object,
{
return FAILURE;
}
-
+
zend_update_property_stringl( Transliterator_ce_ptr, object,
"id", sizeof( "id" ) - 1, str_id, str_id_len TSRMLS_CC );
efree( str_id );
@@ -126,7 +126,7 @@ static zend_object_value Transliterator_object_create(
Transliterator_object* intern;
intern = ecalloc( 1, sizeof( Transliterator_object ) );
-
+
zend_object_std_init( &intern->zo, ce TSRMLS_CC );
#if PHP_VERSION_ID < 50399
zend_hash_copy( intern->zo.properties, &(ce->default_properties ),
@@ -247,7 +247,7 @@ err:
#if PHP_VERSION_ID < 50399
static zval **Transliterator_get_property_ptr_ptr( zval *object, zval *member TSRMLS_DC )
#else
-static zval **Transliterator_get_property_ptr_ptr( zval *object, zval *member,
+static zval **Transliterator_get_property_ptr_ptr( zval *object, zval *member, int type,
const struct _zend_literal *key TSRMLS_DC )
#endif
{
@@ -265,7 +265,7 @@ static zval **Transliterator_get_property_ptr_ptr( zval *object, zval *member,
#if PHP_VERSION_ID < 50399
retval = std_object_handlers.get_property_ptr_ptr( object, member TSRMLS_CC );
#else
- retval = std_object_handlers.get_property_ptr_ptr( object, member, key TSRMLS_CC );
+ retval = std_object_handlers.get_property_ptr_ptr( object, member, type, key TSRMLS_CC );
#endif
}
diff --git a/ext/intl/transliterator/transliterator_methods.c b/ext/intl/transliterator/transliterator_methods.c
index d0cfb9790d..1aa39c54b9 100644
--- a/ext/intl/transliterator/transliterator_methods.c
+++ b/ext/intl/transliterator/transliterator_methods.c
@@ -183,7 +183,7 @@ PHP_FUNCTION( transliterator_create_from_rules )
{
char *msg = NULL;
smart_str parse_error_str;
- parse_error_str = transliterator_parse_error_to_string( &parse_error );
+ parse_error_str = intl_parse_error_to_string( &parse_error );
spprintf( &msg, 0, "transliterator_create_from_rules: unable to "
"create ICU transliterator from rules (%s)", parse_error_str.c );
smart_str_free( &parse_error_str );
diff --git a/ext/json/JSON_parser.h b/ext/json/JSON_parser.h
index 541664b8c6..8671765b4d 100644
--- a/ext/json/JSON_parser.h
+++ b/ext/json/JSON_parser.h
@@ -25,7 +25,10 @@ enum error_codes {
PHP_JSON_ERROR_STATE_MISMATCH,
PHP_JSON_ERROR_CTRL_CHAR,
PHP_JSON_ERROR_SYNTAX,
- PHP_JSON_ERROR_UTF8
+ PHP_JSON_ERROR_UTF8,
+ PHP_JSON_ERROR_RECURSION,
+ PHP_JSON_ERROR_INF_OR_NAN,
+ PHP_JSON_ERROR_UNSUPPORTED_TYPE
};
extern JSON_parser new_JSON_parser(int depth);
diff --git a/ext/json/json.c b/ext/json/json.c
index 5b85b286bf..4ab6278d76 100644
--- a/ext/json/json.c
+++ b/ext/json/json.c
@@ -35,6 +35,7 @@ static PHP_MINFO_FUNCTION(json);
static PHP_FUNCTION(json_encode);
static PHP_FUNCTION(json_decode);
static PHP_FUNCTION(json_last_error);
+static PHP_FUNCTION(json_last_error_msg);
static const char digits[] = "0123456789abcdef";
@@ -46,6 +47,7 @@ ZEND_DECLARE_MODULE_GLOBALS(json)
ZEND_BEGIN_ARG_INFO_EX(arginfo_json_encode, 0, 0, 1)
ZEND_ARG_INFO(0, value)
ZEND_ARG_INFO(0, options)
+ ZEND_ARG_INFO(0, depth)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_json_decode, 0, 0, 1)
@@ -57,6 +59,9 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_json_last_error, 0)
ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_json_last_error_msg, 0)
+ZEND_END_ARG_INFO()
/* }}} */
/* {{{ json_functions[] */
@@ -64,6 +69,7 @@ static const zend_function_entry json_functions[] = {
PHP_FE(json_encode, arginfo_json_encode)
PHP_FE(json_decode, arginfo_json_decode)
PHP_FE(json_last_error, arginfo_json_last_error)
+ PHP_FE(json_last_error_msg, arginfo_json_last_error_msg)
PHP_FE_END
};
/* }}} */
@@ -96,6 +102,7 @@ static PHP_MINIT_FUNCTION(json)
REGISTER_LONG_CONSTANT("JSON_UNESCAPED_SLASHES", PHP_JSON_UNESCAPED_SLASHES, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("JSON_PRETTY_PRINT", PHP_JSON_PRETTY_PRINT, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("JSON_UNESCAPED_UNICODE", PHP_JSON_UNESCAPED_UNICODE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("JSON_PARTIAL_OUTPUT_ON_ERROR", PHP_JSON_PARTIAL_OUTPUT_ON_ERROR, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("JSON_ERROR_NONE", PHP_JSON_ERROR_NONE, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("JSON_ERROR_DEPTH", PHP_JSON_ERROR_DEPTH, CONST_CS | CONST_PERSISTENT);
@@ -103,6 +110,9 @@ static PHP_MINIT_FUNCTION(json)
REGISTER_LONG_CONSTANT("JSON_ERROR_CTRL_CHAR", PHP_JSON_ERROR_CTRL_CHAR, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("JSON_ERROR_SYNTAX", PHP_JSON_ERROR_SYNTAX, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("JSON_ERROR_UTF8", PHP_JSON_ERROR_UTF8, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("JSON_ERROR_RECURSION", PHP_JSON_ERROR_RECURSION, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("JSON_ERROR_INF_OR_NAN", PHP_JSON_ERROR_INF_OR_NAN, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("JSON_ERROR_UNSUPPORTED_TYPE", PHP_JSON_ERROR_UNSUPPORTED_TYPE, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("JSON_OBJECT_AS_ARRAY", PHP_JSON_OBJECT_AS_ARRAY, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("JSON_BIGINT_AS_STRING", PHP_JSON_BIGINT_AS_STRING, CONST_CS | CONST_PERSISTENT);
@@ -117,6 +127,7 @@ static PHP_GINIT_FUNCTION(json)
{
json_globals->encoder_depth = 0;
json_globals->error_code = 0;
+ json_globals->encode_max_depth = 0;
}
/* }}} */
@@ -174,7 +185,7 @@ static int json_determine_array_type(zval **val TSRMLS_DC) /* {{{ */
idx = 0;
for (;; zend_hash_move_forward_ex(myht, &pos)) {
i = zend_hash_get_current_key_ex(myht, &key, &key_len, &index, 0, &pos);
- if (i == HASH_KEY_NON_EXISTANT) {
+ if (i == HASH_KEY_NON_EXISTENT) {
break;
}
@@ -231,7 +242,7 @@ static void json_encode_array(smart_str *buf, zval **val, int options TSRMLS_DC)
}
if (myht && myht->nApplyCount > 1) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected");
+ JSON_G(error_code) = PHP_JSON_ERROR_RECURSION;
smart_str_appendl(buf, "null", 4);
return;
}
@@ -260,7 +271,7 @@ static void json_encode_array(smart_str *buf, zval **val, int options TSRMLS_DC)
zend_hash_internal_pointer_reset_ex(myht, &pos);
for (;; zend_hash_move_forward_ex(myht, &pos)) {
i = zend_hash_get_current_key_ex(myht, &key, &key_len, &index, 0, &pos);
- if (i == HASH_KEY_NON_EXISTANT)
+ if (i == HASH_KEY_NON_EXISTENT)
break;
if (zend_hash_get_current_data_ex(myht, (void **) &data, &pos) == SUCCESS) {
@@ -332,6 +343,9 @@ static void json_encode_array(smart_str *buf, zval **val, int options TSRMLS_DC)
}
}
+ if (JSON_G(encoder_depth) > JSON_G(encode_max_depth)) {
+ JSON_G(error_code) = PHP_JSON_ERROR_DEPTH;
+ }
--JSON_G(encoder_depth);
json_pretty_print_char(buf, options, '\n' TSRMLS_CC);
json_pretty_print_indent(buf, options TSRMLS_CC);
@@ -409,7 +423,7 @@ static void json_escape_string(smart_str *buf, char *s, int len, int options TSR
smart_str_appendl(buf, tmp, l);
efree(tmp);
} else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "double %.9g does not conform to the JSON spec, encoded as 0", d);
+ JSON_G(error_code) = PHP_JSON_ERROR_INF_OR_NAN;
smart_str_appendc(buf, '0');
}
}
@@ -426,9 +440,6 @@ static void json_escape_string(smart_str *buf, char *s, int len, int options TSR
}
if (ulen < 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");
- }
smart_str_appendl(buf, "null", 4);
} else {
smart_str_appendl(buf, "\"\"", 2);
@@ -556,7 +567,7 @@ static void json_encode_serializable_object(smart_str *buf, zval *val, int optio
}
if (myht && myht->nApplyCount > 1) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected");
+ JSON_G(error_code) = PHP_JSON_ERROR_RECURSION;
smart_str_appendl(buf, "null", 4);
return;
}
@@ -620,7 +631,7 @@ PHP_JSON_API void php_json_encode(smart_str *buf, zval *val, int options TSRMLS_
smart_str_appendl(buf, d, len);
efree(d);
} else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "double %.9g does not conform to the JSON spec, encoded as 0", dbl);
+ JSON_G(error_code) = PHP_JSON_ERROR_INF_OR_NAN;
smart_str_appendc(buf, '0');
}
}
@@ -641,7 +652,7 @@ PHP_JSON_API void php_json_encode(smart_str *buf, zval *val, int options TSRMLS_
break;
default:
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "type is unsupported, encoded as null");
+ JSON_G(error_code) = PHP_JSON_ERROR_UNSUPPORTED_TYPE;
smart_str_appendl(buf, "null", 4);
break;
}
@@ -759,23 +770,30 @@ PHP_JSON_API void php_json_decode_ex(zval *return_value, char *str, int str_len,
/* }}} */
-/* {{{ proto string json_encode(mixed data [, int options])
+/* {{{ proto string json_encode(mixed data [, int options[, int depth]])
Returns the JSON representation of a value */
static PHP_FUNCTION(json_encode)
{
zval *parameter;
smart_str buf = {0};
long options = 0;
+ long depth = JSON_PARSER_DEFAULT_DEPTH;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|l", &parameter, &options) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|ll", &parameter, &options, &depth) == FAILURE) {
return;
}
JSON_G(error_code) = PHP_JSON_ERROR_NONE;
+ JSON_G(encode_max_depth) = depth;
+
php_json_encode(&buf, parameter, options TSRMLS_CC);
- ZVAL_STRINGL(return_value, buf.c, buf.len, 1);
+ if (JSON_G(error_code) != PHP_JSON_ERROR_NONE && !(options & PHP_JSON_PARTIAL_OUTPUT_ON_ERROR)) {
+ ZVAL_FALSE(return_value);
+ } else {
+ ZVAL_STRINGL(return_value, buf.c, buf.len, 1);
+ }
smart_str_free(&buf);
}
@@ -813,7 +831,7 @@ static PHP_FUNCTION(json_decode)
/* }}} */
/* {{{ proto int json_last_error()
- Returns the error code of the last json_decode(). */
+ Returns the error code of the last json_encode() or json_decode() call. */
static PHP_FUNCTION(json_last_error)
{
if (zend_parse_parameters_none() == FAILURE) {
@@ -824,6 +842,40 @@ static PHP_FUNCTION(json_last_error)
}
/* }}} */
+/* {{{ proto string json_last_error_msg()
+ Returns the error string of the last json_encode() or json_decode() call. */
+static PHP_FUNCTION(json_last_error_msg)
+{
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ switch(JSON_G(error_code)) {
+ case PHP_JSON_ERROR_NONE:
+ RETURN_STRING("No error", 1);
+ case PHP_JSON_ERROR_DEPTH:
+ RETURN_STRING("Maximum stack depth exceeded", 1);
+ case PHP_JSON_ERROR_STATE_MISMATCH:
+ RETURN_STRING("State mismatch (invalid or malformed JSON)", 1);
+ case PHP_JSON_ERROR_CTRL_CHAR:
+ RETURN_STRING("Control character error, possibly incorrectly encoded", 1);
+ case PHP_JSON_ERROR_SYNTAX:
+ RETURN_STRING("Syntax error", 1);
+ case PHP_JSON_ERROR_UTF8:
+ RETURN_STRING("Malformed UTF-8 characters, possibly incorrectly encoded", 1);
+ case PHP_JSON_ERROR_RECURSION:
+ RETURN_STRING("Recursion detected", 1);
+ case PHP_JSON_ERROR_INF_OR_NAN:
+ RETURN_STRING("Inf and NaN cannot be JSON encoded", 1);
+ case PHP_JSON_ERROR_UNSUPPORTED_TYPE:
+ RETURN_STRING("Type is not supported", 1);
+ default:
+ RETURN_STRING("Unknown error", 1);
+ }
+
+}
+/* }}} */
+
/*
* Local variables:
* tab-width: 4
diff --git a/ext/json/php_json.h b/ext/json/php_json.h
index a306d2d154..637c5eae5e 100644
--- a/ext/json/php_json.h
+++ b/ext/json/php_json.h
@@ -40,6 +40,7 @@ extern zend_module_entry json_module_entry;
ZEND_BEGIN_MODULE_GLOBALS(json)
int encoder_depth;
int error_code;
+ int encode_max_depth;
ZEND_END_MODULE_GLOBALS(json)
#ifdef ZTS
@@ -63,6 +64,7 @@ extern zend_class_entry *php_json_serializable_ce;
#define PHP_JSON_UNESCAPED_SLASHES (1<<6)
#define PHP_JSON_PRETTY_PRINT (1<<7)
#define PHP_JSON_UNESCAPED_UNICODE (1<<8)
+#define PHP_JSON_PARTIAL_OUTPUT_ON_ERROR (1<<9)
/* Internal flags */
#define PHP_JSON_OUTPUT_ARRAY 0
diff --git a/ext/json/tests/003.phpt b/ext/json/tests/003.phpt
index 3b52fb0884..4ce5b0fde9 100644
--- a/ext/json/tests/003.phpt
+++ b/ext/json/tests/003.phpt
@@ -9,10 +9,16 @@ $a = array();
$a[] = &$a;
var_dump($a);
+
+echo "\n";
+
var_dump(json_encode($a));
+var_dump(json_last_error(), json_last_error_msg());
-/* Break circular data structure to prevent memory leaks */
-unset($a[0]);
+echo "\n";
+
+var_dump(json_encode($a, JSON_PARTIAL_OUTPUT_ON_ERROR));
+var_dump(json_last_error(), json_last_error_msg());
echo "Done\n";
?>
@@ -25,6 +31,11 @@ array(1) {
}
}
-Warning: json_encode(): recursion detected in %s on line %d
+bool(false)
+int(6)
+string(%d) "Recursion detected"
+
string(8) "[[null]]"
+int(6)
+string(%d) "Recursion detected"
Done
diff --git a/ext/json/tests/004.phpt b/ext/json/tests/004.phpt
index 1d282f9a96..70ef3ffd1b 100644
--- a/ext/json/tests/004.phpt
+++ b/ext/json/tests/004.phpt
@@ -9,7 +9,16 @@ $a = new stdclass;
$a->prop = $a;
var_dump($a);
+
+echo "\n";
+
var_dump(json_encode($a));
+var_dump(json_last_error(), json_last_error_msg());
+
+echo "\n";
+
+var_dump(json_encode($a, JSON_PARTIAL_OUTPUT_ON_ERROR));
+var_dump(json_last_error(), json_last_error_msg());
echo "Done\n";
?>
@@ -19,6 +28,11 @@ object(stdClass)#%d (1) {
*RECURSION*
}
-Warning: json_encode(): recursion detected in %s on line %d
+bool(false)
+int(6)
+string(%d) "Recursion detected"
+
string(22) "{"prop":{"prop":null}}"
+int(6)
+string(%d) "Recursion detected"
Done
diff --git a/ext/json/tests/007.phpt b/ext/json/tests/007.phpt
index 9ee190a24c..7557ac9ed7 100644
--- a/ext/json/tests/007.phpt
+++ b/ext/json/tests/007.phpt
@@ -5,15 +5,15 @@ json_last_error() tests
--FILE--
<?php
var_dump(json_decode("[1]"));
-var_dump(json_last_error());
+var_dump(json_last_error(), json_last_error_msg());
var_dump(json_decode("[[1]]", false, 2));
-var_dump(json_last_error());
+var_dump(json_last_error(), json_last_error_msg());
var_dump(json_decode("[1}"));
-var_dump(json_last_error());
+var_dump(json_last_error(), json_last_error_msg());
var_dump(json_decode('["' . chr(0) . 'abcd"]'));
-var_dump(json_last_error());
+var_dump(json_last_error(), json_last_error_msg());
var_dump(json_decode("[1"));
-var_dump(json_last_error());
+var_dump(json_last_error(), json_last_error_msg());
echo "Done\n";
@@ -24,13 +24,17 @@ array(1) {
int(1)
}
int(0)
+string(8) "No error"
NULL
int(1)
+string(28) "Maximum stack depth exceeded"
NULL
int(2)
+string(42) "State mismatch (invalid or malformed JSON)"
NULL
int(3)
+string(53) "Control character error, possibly incorrectly encoded"
NULL
int(4)
+string(12) "Syntax error"
Done
-
diff --git a/ext/json/tests/bug43941.phpt b/ext/json/tests/bug43941.phpt
index 0f86d1dfad..48bd7ad524 100644
--- a/ext/json/tests/bug43941.phpt
+++ b/ext/json/tests/bug43941.phpt
@@ -7,15 +7,14 @@ Bug #43941 (json_encode() invalid UTF-8)
var_dump(json_encode("abc"));
var_dump(json_encode("ab\xE0"));
-var_dump(json_encode("ab\xE0c"));
-var_dump(json_encode(array("ab\xE0", "ab\xE0c", "abc")));
+var_dump(json_encode("ab\xE0", JSON_PARTIAL_OUTPUT_ON_ERROR));
+var_dump(json_encode(array("ab\xE0", "ab\xE0c", "abc"), JSON_PARTIAL_OUTPUT_ON_ERROR));
echo "Done\n";
?>
--EXPECTF--
string(5) ""abc""
-string(4) "null"
+bool(false)
string(4) "null"
string(17) "[null,null,"abc"]"
Done
-
diff --git a/ext/json/tests/bug53946.phpt b/ext/json/tests/bug53946.phpt
index abbb81238b..111438ddc4 100644
--- a/ext/json/tests/bug53946.phpt
+++ b/ext/json/tests/bug53946.phpt
@@ -9,8 +9,8 @@ var_dump(json_encode("latin 1234 -/ russian мама мыла раму speci
var_dump(json_encode("ab\xE0"));
var_dump(json_encode("ab\xE0", JSON_UNESCAPED_UNICODE));
?>
---EXPECT--
+--EXPECTF--
string(156) ""latin 1234 -\/ russian \u043c\u0430\u043c\u0430 \u043c\u044b\u043b\u0430 \u0440\u0430\u043c\u0443 specialchars \u0002 \b \n U+1D11E >\ud834\udd1e<""
string(100) ""latin 1234 -\/ russian мама мыла раму specialchars \u0002 \b \n U+1D11E >𝄞<""
-string(4) "null"
-string(4) "null"
+bool(false)
+bool(false)
diff --git a/ext/json/tests/bug54058.phpt b/ext/json/tests/bug54058.phpt
index 3b1136bdd9..df1b3130f8 100644
--- a/ext/json/tests/bug54058.phpt
+++ b/ext/json/tests/bug54058.phpt
@@ -8,28 +8,33 @@ Bug #54058 (json_last_error() invalid UTF-8 produces wrong error)
$bad_utf8 = quoted_printable_decode('=B0');
json_encode($bad_utf8);
-var_dump(json_last_error());
+var_dump(json_last_error(), json_last_error_msg());
$a = new stdclass;
$a->foo = quoted_printable_decode('=B0');
json_encode($a);
-var_dump(json_last_error());
+var_dump(json_last_error(), json_last_error_msg());
$b = new stdclass;
$b->foo = $bad_utf8;
$b->bar = 1;
json_encode($b);
-var_dump(json_last_error());
+var_dump(json_last_error(), json_last_error_msg());
$c = array(
'foo' => $bad_utf8,
'bar' => 1
);
json_encode($c);
-var_dump(json_last_error());
+var_dump(json_last_error(), json_last_error_msg());
+
?>
--EXPECTF--
int(5)
+string(56) "Malformed UTF-8 characters, possibly incorrectly encoded"
int(5)
+string(56) "Malformed UTF-8 characters, possibly incorrectly encoded"
int(5)
+string(56) "Malformed UTF-8 characters, possibly incorrectly encoded"
int(5)
+string(56) "Malformed UTF-8 characters, possibly incorrectly encoded"
diff --git a/ext/json/tests/bug61537.phpt b/ext/json/tests/bug61537.phpt
new file mode 100644
index 0000000000..80ed051c9a
--- /dev/null
+++ b/ext/json/tests/bug61537.phpt
@@ -0,0 +1,39 @@
+--TEST--
+Bug #61537 (json_encode() incorrectly truncates/discards information)
+--SKIPIF--
+<?php if (!extension_loaded("json")) print "skip"; ?>
+--FILE--
+<?php
+$invalid_utf8 = "\x9f";
+
+var_dump(json_encode($invalid_utf8));
+var_dump(json_last_error(), json_last_error_msg());
+
+var_dump(json_encode($invalid_utf8, JSON_PARTIAL_OUTPUT_ON_ERROR));
+var_dump(json_last_error(), json_last_error_msg());
+
+echo "\n";
+
+$invalid_utf8 = "an invalid sequen\xce in the middle of a string";
+
+var_dump(json_encode($invalid_utf8));
+var_dump(json_last_error(), json_last_error_msg());
+
+var_dump(json_encode($invalid_utf8, JSON_PARTIAL_OUTPUT_ON_ERROR));
+var_dump(json_last_error(), json_last_error_msg());
+
+?>
+--EXPECTF--
+bool(false)
+int(5)
+string(56) "Malformed UTF-8 characters, possibly incorrectly encoded"
+string(4) "null"
+int(5)
+string(56) "Malformed UTF-8 characters, possibly incorrectly encoded"
+
+bool(false)
+int(5)
+string(56) "Malformed UTF-8 characters, possibly incorrectly encoded"
+string(4) "null"
+int(5)
+string(56) "Malformed UTF-8 characters, possibly incorrectly encoded"
diff --git a/ext/json/tests/bug61978.phpt b/ext/json/tests/bug61978.phpt
index 2c732979ef..c34b03f8f7 100644
--- a/ext/json/tests/bug61978.phpt
+++ b/ext/json/tests/bug61978.phpt
@@ -29,19 +29,15 @@ class JsonTest2 implements JsonSerializable {
$obj1 = new JsonTest1();
-var_dump(json_encode($obj1));
+var_dump(json_encode($obj1, JSON_PARTIAL_OUTPUT_ON_ERROR));
-echo "\n==\n";
+echo "==\n";
$obj2 = new JsonTest2();
-var_dump(json_encode($obj2));
+var_dump(json_encode($obj2, JSON_PARTIAL_OUTPUT_ON_ERROR));
?>
--EXPECTF--
-Warning: json_encode(): recursion detected in %s on line %d
string(44) "{"test":"123","me":{"test":"123","me":null}}"
-
==
-
-Warning: json_encode(): recursion detected in %s on line %d
string(44) "{"test":"123","me":{"test":"123","me":null}}"
diff --git a/ext/json/tests/bug62369.phpt b/ext/json/tests/bug62369.phpt
new file mode 100644
index 0000000000..a5efd802c5
--- /dev/null
+++ b/ext/json/tests/bug62369.phpt
@@ -0,0 +1,34 @@
+--TEST--
+FR #62369 (Segfault on json_encode(deeply_nested_array)
+--SKIPIF--
+<?php if (!extension_loaded("json")) print "skip"; ?>
+--FILE--
+<?php
+
+$array = array();
+for ($i=0; $i<550; $i++) {
+ $array = array($array);
+}
+
+json_encode($array, 0, 551);
+switch (json_last_error()) {
+ case JSON_ERROR_NONE:
+ echo 'OK'.PHP_EOL;
+ break;
+ case JSON_ERROR_DEPTH:
+ echo 'ERROR'.PHP_EOL;
+ break;
+}
+
+json_encode($array, 0, 540);
+switch (json_last_error()) {
+ case JSON_ERROR_NONE:
+ echo 'OK'.PHP_EOL;
+ break;
+ case JSON_ERROR_DEPTH:
+ echo 'ERROR'.PHP_EOL;
+ break;
+}
+--EXPECTF--
+OK
+ERROR
diff --git a/ext/json/tests/inf_nan_error.phpt b/ext/json/tests/inf_nan_error.phpt
new file mode 100644
index 0000000000..f9deecc469
--- /dev/null
+++ b/ext/json/tests/inf_nan_error.phpt
@@ -0,0 +1,45 @@
+--TEST--
+An error is thrown when INF or NaN are encoded
+--SKIPIF--
+<?php if (!extension_loaded("json")) print "skip"; ?>
+--FILE--
+<?php
+
+$inf = INF;
+
+var_dump($inf);
+
+var_dump(json_encode($inf));
+var_dump(json_last_error(), json_last_error_msg());
+
+var_dump(json_encode($inf, JSON_PARTIAL_OUTPUT_ON_ERROR));
+var_dump(json_last_error(), json_last_error_msg());
+
+echo "\n";
+
+$nan = NAN;
+
+var_dump($nan);
+
+var_dump(json_encode($nan));
+var_dump(json_last_error(), json_last_error_msg());
+
+var_dump(json_encode($nan, JSON_PARTIAL_OUTPUT_ON_ERROR));
+var_dump(json_last_error(), json_last_error_msg());
+?>
+--EXPECTF--
+float(INF)
+bool(false)
+int(7)
+string(34) "Inf and NaN cannot be JSON encoded"
+string(1) "0"
+int(7)
+string(34) "Inf and NaN cannot be JSON encoded"
+
+float(NAN)
+bool(false)
+int(7)
+string(34) "Inf and NaN cannot be JSON encoded"
+string(1) "0"
+int(7)
+string(34) "Inf and NaN cannot be JSON encoded"
diff --git a/ext/json/tests/json_encode_basic.phpt b/ext/json/tests/json_encode_basic.phpt
index 152e24444c..fc348eed81 100644
--- a/ext/json/tests/json_encode_basic.phpt
+++ b/ext/json/tests/json_encode_basic.phpt
@@ -150,9 +150,7 @@ string(4) "null"
-- Iteration 25 --
string(4) "null"
-- Iteration 26 --
-
-Warning: json_encode(): type is unsupported, encoded as null in %s on line %d
-string(4) "null"
+bool(false)
-- Iteration 27 --
string(82) "{"MyInt":99,"MyFloat":123.45,"MyBool":true,"MyNull":null,"MyString":"Hello World"}"
-===Done=== \ No newline at end of file
+===Done===
diff --git a/ext/json/tests/json_encode_error.phpt b/ext/json/tests/json_encode_error.phpt
index d130dd960c..547c8bef17 100644
--- a/ext/json/tests/json_encode_error.phpt
+++ b/ext/json/tests/json_encode_error.phpt
@@ -34,7 +34,5 @@ Warning: json_encode() expects at least 1 parameter, 0 given in %s on line %d
NULL
-- Testing json_encode() function with more than expected no. of arguments --
-
-Warning: json_encode() expects at most 2 parameters, 3 given in %s on line %d
-NULL
+string(5) ""abc""
===Done===
diff --git a/ext/json/tests/pass001.1.phpt b/ext/json/tests/pass001.1.phpt
index 7e15a7622a..a51f885780 100644
--- a/ext/json/tests/pass001.1.phpt
+++ b/ext/json/tests/pass001.1.phpt
@@ -90,10 +90,10 @@ $arr = json_decode($test, true);
var_dump($arr);
echo "ENCODE: FROM OBJECT\n";
-$obj_enc = json_encode($obj);
+$obj_enc = json_encode($obj, JSON_PARTIAL_OUTPUT_ON_ERROR);
echo $obj_enc . "\n";
echo "ENCODE: FROM ARRAY\n";
-$arr_enc = json_encode($arr);
+$arr_enc = json_encode($arr, JSON_PARTIAL_OUTPUT_ON_ERROR);
echo $arr_enc . "\n";
echo "DECODE AGAIN: AS OBJECT\n";
diff --git a/ext/json/tests/pass001.1_64bit.phpt b/ext/json/tests/pass001.1_64bit.phpt
index 9c3e669952..ff2714436d 100644
--- a/ext/json/tests/pass001.1_64bit.phpt
+++ b/ext/json/tests/pass001.1_64bit.phpt
@@ -90,10 +90,10 @@ $arr = json_decode($test, true);
var_dump($arr);
echo "ENCODE: FROM OBJECT\n";
-$obj_enc = json_encode($obj);
+$obj_enc = json_encode($obj, JSON_PARTIAL_OUTPUT_ON_ERROR);
echo $obj_enc . "\n";
echo "ENCODE: FROM ARRAY\n";
-$arr_enc = json_encode($arr);
+$arr_enc = json_encode($arr, JSON_PARTIAL_OUTPUT_ON_ERROR);
echo $arr_enc . "\n";
echo "DECODE AGAIN: AS OBJECT\n";
diff --git a/ext/json/tests/pass001.phpt b/ext/json/tests/pass001.phpt
index 43be11e2b0..1fd05fcdd8 100644
--- a/ext/json/tests/pass001.phpt
+++ b/ext/json/tests/pass001.phpt
@@ -79,10 +79,10 @@ $arr = json_decode($test, true);
var_dump($arr);
echo "ENCODE: FROM OBJECT\n";
-$obj_enc = json_encode($obj);
+$obj_enc = json_encode($obj, JSON_PARTIAL_OUTPUT_ON_ERROR);
echo $obj_enc . "\n";
echo "ENCODE: FROM ARRAY\n";
-$arr_enc = json_encode($arr);
+$arr_enc = json_encode($arr, JSON_PARTIAL_OUTPUT_ON_ERROR);
echo $arr_enc . "\n";
echo "DECODE AGAIN: AS OBJECT\n";
diff --git a/ext/json/tests/unsupported_type_error.phpt b/ext/json/tests/unsupported_type_error.phpt
new file mode 100644
index 0000000000..45a167a5ac
--- /dev/null
+++ b/ext/json/tests/unsupported_type_error.phpt
@@ -0,0 +1,26 @@
+--TEST--
+An error is thrown when an unsupported type is encoded
+--SKIPIF--
+<?php if (!extension_loaded("json")) print "skip"; ?>
+--FILE--
+<?php
+
+$resource = fopen(__FILE__, "r");
+
+var_dump($resource);
+
+var_dump(json_encode($resource));
+var_dump(json_last_error(), json_last_error_msg());
+
+var_dump(json_encode($resource, JSON_PARTIAL_OUTPUT_ON_ERROR));
+var_dump(json_last_error(), json_last_error_msg());
+
+?>
+--EXPECTF--
+resource(5) of type (stream)
+bool(false)
+int(8)
+string(21) "Type is not supported"
+string(4) "null"
+int(8)
+string(21) "Type is not supported"
diff --git a/ext/ldap/config.m4 b/ext/ldap/config.m4
index 58d994c10e..2804cd5968 100644
--- a/ext/ldap/config.m4
+++ b/ext/ldap/config.m4
@@ -15,6 +15,28 @@ AC_DEFUN([PHP_LDAP_CHECKS], [
LDAP_DIR=$1
LDAP_INCDIR=$1/ldap/public
LDAP_LIBDIR=$1/$PHP_LIBDIR
+ else
+
+ dnl Find Oracle Instant Client RPM header location corresponding to the given lib path e.g. for --with-ldap=/usr/lib/oracle/12.1/client64/lib
+ AC_CHECK_SIZEOF(long int, 4)
+ if test "$ac_cv_sizeof_long_int" = "4"; then
+ PHP_OCI8_IC_LIBDIR_SUFFIX=""
+ else
+ PHP_OCI8_IC_LIBDIR_SUFFIX=64
+ fi
+ OCISDKRPMINC=`echo "$1" | $SED -e 's!^/usr/lib/oracle/\(.*\)/client\('${PHP_OCI8_IC_LIBDIR_SUFFIX}'\)*/lib[/]*$!/usr/include/oracle/\1/client\2!'`
+
+ dnl Check for Oracle Instant Client RPM install
+ if test -f $OCISDKRPMINC/ldap.h; then
+ LDAP_DIR=$1
+ LDAP_INCDIR=$OCISDKRPMINC
+ LDAP_LIBDIR=$1
+ dnl Check for Oracle Instant Client ZIP install
+ elif test -f $1/sdk/include/ldap.h; then
+ LDAP_DIR=$1
+ LDAP_INCDIR=$1/sdk/include
+ LDAP_LIBDIR=$1
+ fi
fi
])
@@ -63,7 +85,7 @@ AC_DEFUN([PHP_LDAP_SASL_CHECKS], [
])
PHP_ARG_WITH(ldap,for LDAP support,
-[ --with-ldap[=DIR] Include LDAP support])
+[ --with-ldap[=DIR] Include LDAP support])
PHP_ARG_WITH(ldap-sasl,for LDAP Cyrus SASL support,
[ --with-ldap-sasl[=DIR] LDAP: Include Cyrus SASL support], no, no)
@@ -143,12 +165,21 @@ if test "$PHP_LDAP" != "no"; then
PHP_ADD_LIBRARY_WITH_PATH(umich_lber, $LDAP_LIBDIR, LDAP_SHARED_LIBADD)
PHP_ADD_LIBRARY_WITH_PATH(umich_ldap, $LDAP_LIBDIR, LDAP_SHARED_LIBADD)
- elif test -f $LDAP_LIBDIR/libclntsh.$SHLIB_SUFFIX_NAME; then
+ elif test -f $LDAP_LIBDIR/libclntsh.$SHLIB_SUFFIX_NAME.12.1; then
PHP_ADD_LIBRARY_WITH_PATH(clntsh, $LDAP_LIBDIR, LDAP_SHARED_LIBADD)
AC_DEFINE(HAVE_ORALDAP,1,[ ])
- if test -f $LDAP_LIBDIR/libclntsh.$SHLIB_SUFFIX_NAME.10.1; then
- AC_DEFINE(HAVE_ORALDAP_10,1,[ ])
- fi
+ AC_DEFINE(HAVE_ORALDAP_12,1,[ ])
+
+ elif test -f $LDAP_LIBDIR/libclntsh.$SHLIB_SUFFIX_NAME.11.1; then
+ PHP_ADD_LIBRARY_WITH_PATH(clntsh, $LDAP_LIBDIR, LDAP_SHARED_LIBADD)
+ AC_DEFINE(HAVE_ORALDAP,1,[ ])
+ AC_DEFINE(HAVE_ORALDAP_11,1,[ ])
+
+ elif test -f $LDAP_LIBDIR/libclntsh.$SHLIB_SUFFIX_NAME; then
+ PHP_ADD_LIBRARY_WITH_PATH(clntsh, $LDAP_LIBDIR, LDAP_SHARED_LIBADD)
+ AC_DEFINE(HAVE_ORALDAP,1,[ ])
+ AC_DEFINE(HAVE_ORALDAP_10,1,[ ])
+
else
AC_MSG_ERROR(Cannot find ldap libraries in $LDAP_LIBDIR.)
fi
diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c
index 25d6fa1159..836f76dc4a 100644
--- a/ext/ldap/ldap.c
+++ b/ext/ldap/ldap.c
@@ -152,7 +152,7 @@ PHP_MINIT_FUNCTION(ldap)
REGISTER_LONG_CONSTANT("LDAP_DEREF_FINDING", LDAP_DEREF_FINDING, CONST_PERSISTENT | CONST_CS);
REGISTER_LONG_CONSTANT("LDAP_DEREF_ALWAYS", LDAP_DEREF_ALWAYS, CONST_PERSISTENT | CONST_CS);
-#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10
+#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP
/* LDAP options */
REGISTER_LONG_CONSTANT("LDAP_OPT_DEREF", LDAP_OPT_DEREF, CONST_PERSISTENT | CONST_CS);
REGISTER_LONG_CONSTANT("LDAP_OPT_SIZELIMIT", LDAP_OPT_SIZELIMIT, CONST_PERSISTENT | CONST_CS);
@@ -361,7 +361,7 @@ PHP_FUNCTION(ldap_connect)
static int _get_lderrno(LDAP *ldap)
{
#if !HAVE_NSLDAP
-#if LDAP_API_VERSION > 2000 || HAVE_ORALDAP_10
+#if LDAP_API_VERSION > 2000 || HAVE_ORALDAP
int lderr;
/* New versions of OpenLDAP do it this way */
@@ -550,7 +550,7 @@ static void php_set_opts(LDAP *ldap, int sizelimit, int timelimit, int deref, in
{
/* sizelimit */
if (sizelimit > -1) {
-#if (LDAP_API_VERSION >= 2004) || HAVE_NSLDAP || HAVE_ORALDAP_10
+#if (LDAP_API_VERSION >= 2004) || HAVE_NSLDAP || HAVE_ORALDAP
ldap_get_option(ldap, LDAP_OPT_SIZELIMIT, old_sizelimit);
ldap_set_option(ldap, LDAP_OPT_SIZELIMIT, &sizelimit);
#else
@@ -561,7 +561,7 @@ static void php_set_opts(LDAP *ldap, int sizelimit, int timelimit, int deref, in
/* timelimit */
if (timelimit > -1) {
-#if (LDAP_API_VERSION >= 2004) || HAVE_NSLDAP || HAVE_ORALDAP_10
+#if (LDAP_API_VERSION >= 2004) || HAVE_NSLDAP || HAVE_ORALDAP
ldap_get_option(ldap, LDAP_OPT_SIZELIMIT, old_timelimit);
ldap_set_option(ldap, LDAP_OPT_TIMELIMIT, &timelimit);
#else
@@ -572,7 +572,7 @@ static void php_set_opts(LDAP *ldap, int sizelimit, int timelimit, int deref, in
/* deref */
if (deref > -1) {
-#if (LDAP_API_VERSION >= 2004) || HAVE_NSLDAP || HAVE_ORALDAP_10
+#if (LDAP_API_VERSION >= 2004) || HAVE_NSLDAP || HAVE_ORALDAP
ldap_get_option(ldap, LDAP_OPT_SIZELIMIT, old_deref);
ldap_set_option(ldap, LDAP_OPT_DEREF, &deref);
#else
@@ -975,12 +975,12 @@ PHP_FUNCTION(ldap_get_entries)
add_index_string(tmp1, num_attrib, attribute, 1);
num_attrib++;
-#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS
+#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP || WINDOWS
ldap_memfree(attribute);
#endif
attribute = ldap_next_attribute(ldap, ldap_result_entry, ber);
}
-#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS
+#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP || WINDOWS
if (ber != NULL) {
ber_free(ber, 0);
}
@@ -989,7 +989,7 @@ PHP_FUNCTION(ldap_get_entries)
add_assoc_long(tmp1, "count", num_attrib);
dn = ldap_get_dn(ldap, ldap_result_entry);
add_assoc_string(tmp1, "dn", dn, 1);
-#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS
+#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP || WINDOWS
ldap_memfree(dn);
#else
free(dn);
@@ -1027,7 +1027,7 @@ PHP_FUNCTION(ldap_first_attribute)
RETURN_FALSE;
} else {
RETVAL_STRING(attribute, 1);
-#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS
+#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP || WINDOWS
ldap_memfree(attribute);
#endif
}
@@ -1057,7 +1057,7 @@ PHP_FUNCTION(ldap_next_attribute)
}
if ((attribute = ldap_next_attribute(ld->link, resultentry->data, resultentry->ber)) == NULL) {
-#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS
+#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP || WINDOWS
if (resultentry->ber != NULL) {
ber_free(resultentry->ber, 0);
resultentry->ber = NULL;
@@ -1066,7 +1066,7 @@ PHP_FUNCTION(ldap_next_attribute)
RETURN_FALSE;
} else {
RETVAL_STRING(attribute, 1);
-#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS
+#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP || WINDOWS
ldap_memfree(attribute);
#endif
}
@@ -1113,12 +1113,12 @@ PHP_FUNCTION(ldap_get_attributes)
add_index_string(return_value, num_attrib, attribute, 1);
num_attrib++;
-#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS
+#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP || WINDOWS
ldap_memfree(attribute);
#endif
attribute = ldap_next_attribute(ld->link, resultentry->data, ber);
}
-#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS
+#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP || WINDOWS
if (ber != NULL) {
ber_free(ber, 0);
}
@@ -1183,7 +1183,7 @@ PHP_FUNCTION(ldap_get_dn)
text = ldap_get_dn(ld->link, resultentry->data);
if (text != NULL) {
RETVAL_STRING(text, 1);
-#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS
+#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP || WINDOWS
ldap_memfree(text);
#else
free(text);
@@ -1241,7 +1241,7 @@ PHP_FUNCTION(ldap_dn2ufn)
if (ufn != NULL) {
RETVAL_STRING(ufn, 1);
-#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 || WINDOWS
+#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP || WINDOWS
ldap_memfree(ufn);
#endif
} else {
@@ -1546,7 +1546,7 @@ PHP_FUNCTION(ldap_sort)
}
/* }}} */
-#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10
+#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP
/* {{{ proto bool ldap_get_option(resource link, int option, mixed retval)
Get the current value of various session-wide parameters */
PHP_FUNCTION(ldap_get_option)
@@ -2003,7 +2003,7 @@ PHP_FUNCTION(ldap_rename)
newparent = NULL;
}
-#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10
+#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP
rc = ldap_rename_s(ld->link, dn, newrdn, newparent, deleteoldrdn, NULL, NULL);
#else
if (newparent_len != 0) {
@@ -2047,7 +2047,7 @@ PHP_FUNCTION(ldap_start_tls)
}
/* }}} */
#endif
-#endif /* (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 */
+#endif /* (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP */
#if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(HAVE_3ARG_SETREBINDPROC)
/* {{{ _ldap_rebind_proc()
@@ -2567,7 +2567,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_control_paged_result_response, 0, 0, 2)
ZEND_END_ARG_INFO();
#endif
-#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10
+#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP
ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_rename, 0, 0, 5)
ZEND_ARG_INFO(0, link_identifier)
ZEND_ARG_INFO(0, dn)
@@ -2683,7 +2683,7 @@ const zend_function_entry ldap_functions[] = {
PHP_FE(ldap_compare, arginfo_ldap_compare)
PHP_FE(ldap_sort, arginfo_ldap_sort)
-#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10
+#if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP
PHP_FE(ldap_rename, arginfo_ldap_rename)
PHP_FE(ldap_get_option, arginfo_ldap_get_option)
PHP_FE(ldap_set_option, arginfo_ldap_set_option)
diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c
index b458d162c0..083d9f815e 100644
--- a/ext/libxml/libxml.c
+++ b/ext/libxml/libxml.c
@@ -44,6 +44,7 @@
#include <libxml/xmlsave.h>
#ifdef LIBXML_SCHEMAS_ENABLED
#include <libxml/relaxng.h>
+#include <libxml/xmlschemas.h>
#endif
#include "php_libxml.h"
@@ -798,6 +799,11 @@ static PHP_MINIT_FUNCTION(libxml)
#endif
REGISTER_LONG_CONSTANT("LIBXML_NOEMPTYTAG", LIBXML_SAVE_NOEMPTYTAG, CONST_CS | CONST_PERSISTENT);
+ /* Schema validation options */
+#if defined(LIBXML_SCHEMAS_ENABLED) && LIBXML_VERSION >= 20614
+ REGISTER_LONG_CONSTANT("LIBXML_SCHEMA_CREATE", XML_SCHEMA_VAL_VC_I_CREATE, CONST_CS | CONST_PERSISTENT);
+#endif
+
/* Additional constants for use with loading html */
#if LIBXML_VERSION >= 20707
REGISTER_LONG_CONSTANT("LIBXML_HTML_NOIMPLIED", HTML_PARSE_NOIMPLIED, CONST_CS | CONST_PERSISTENT);
diff --git a/ext/mbstring/config.m4 b/ext/mbstring/config.m4
index 5d70d45b80..25bf238761 100644
--- a/ext/mbstring/config.m4
+++ b/ext/mbstring/config.m4
@@ -344,19 +344,19 @@ PHP_ARG_ENABLE(mbstring, whether to enable multibyte string support,
[ --enable-mbstring Enable multibyte string support])
PHP_ARG_ENABLE([mbregex], [whether to enable multibyte regex support],
-[ --disable-mbregex MBSTRING: Disable multibyte regex support], yes, no)
+[ --disable-mbregex MBSTRING: Disable multibyte regex support], yes, no)
PHP_ARG_ENABLE([mbregex_backtrack], [whether to check multibyte regex backtrack],
[ --disable-mbregex-backtrack
- MBSTRING: Disable multibyte regex backtrack check], yes, no)
+ MBSTRING: Disable multibyte regex backtrack check], yes, no)
PHP_ARG_WITH(libmbfl, [for external libmbfl],
[ --with-libmbfl[=DIR] MBSTRING: Use external libmbfl. DIR is the libmbfl base
- install directory [BUNDLED]], no, no)
+ install directory [BUNDLED]], no, no)
PHP_ARG_WITH(onig, [for external oniguruma],
[ --with-onig[=DIR] MBSTRING: Use external oniguruma. DIR is the oniguruma install prefix.
- If DIR is not set, the bundled oniguruma will be used], no, no)
+ If DIR is not set, the bundled oniguruma will be used], no, no)
if test "$PHP_MBSTRING" != "no"; then
AC_DEFINE([HAVE_MBSTRING],1,[whether to have multibyte string support])
diff --git a/ext/mbstring/config.w32 b/ext/mbstring/config.w32
index 7bc9518cb8..6b7e05a329 100644
--- a/ext/mbstring/config.w32
+++ b/ext/mbstring/config.w32
@@ -37,7 +37,7 @@ if (PHP_MBSTRING != "no") {
mbfilter_uuencode.c mbfilter_armscii8.c mbfilter_cp850.c \
mbfilter_cp5022x.c mbfilter_sjis_open.c mbfilter_sjis_mobile.c \
mbfilter_sjis_mac.c \
- mbfilter_iso2022jp_2004.c mbfilter_iso2022jp_mobile.c \
+ mbfilter_iso2022jp_2004.c mbfilter_iso2022jp_mobile.c \
mbfilter_tl_jisx0201_jisx0208.c", "mbstring");
ADD_SOURCES("ext/mbstring/libmbfl/mbfl", "mbfilter.c mbfilter_8bit.c \
diff --git a/ext/mbstring/libmbfl/filters/mbfilter_sjis_mac.c b/ext/mbstring/libmbfl/filters/mbfilter_sjis_mac.c
index 2f84edff21..c134e5d585 100644
--- a/ext/mbstring/libmbfl/filters/mbfilter_sjis_mac.c
+++ b/ext/mbstring/libmbfl/filters/mbfilter_sjis_mac.c
@@ -424,7 +424,7 @@ mbfl_filt_conv_wchar_sjis_mac(int c, mbfl_convert_filter *filter)
} else if (c == 0xa0) {
s1 = 0x00a0;
} else if (c == 0xa5) { /* YEN SIGN */
- s1 = 0x216f; /* FULLWIDTH YEN SIGN */
+ s1 = 0x216f; /* FULLWIDTH YEN SIGN */
} else if (c == 0xff3c) { /* FULLWIDTH REVERSE SOLIDUS */
s1 = 0x2140;
}
diff --git a/ext/mbstring/libmbfl/filters/mbfilter_utf8_mobile.h b/ext/mbstring/libmbfl/filters/mbfilter_utf8_mobile.h
index ef5e6da7f9..c127b18404 100644
--- a/ext/mbstring/libmbfl/filters/mbfilter_utf8_mobile.h
+++ b/ext/mbstring/libmbfl/filters/mbfilter_utf8_mobile.h
@@ -49,6 +49,8 @@ extern const struct mbfl_convert_vtbl vtbl_wchar_utf8_kddi_b;
extern const struct mbfl_convert_vtbl vtbl_utf8_sb_wchar;
extern const struct mbfl_convert_vtbl vtbl_wchar_utf8_sb;
+
+
int mbfl_filt_conv_utf8_mobile_wchar(int c, mbfl_convert_filter *filter);
int mbfl_filt_conv_wchar_utf8_mobile(int c, mbfl_convert_filter *filter);
diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c
index 919d1f5a3a..7ac0b5349b 100644
--- a/ext/mbstring/mbstring.c
+++ b/ext/mbstring/mbstring.c
@@ -473,7 +473,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_ereg_replace_callback, 0, 0, 3)
ZEND_ARG_INFO(0, string)
ZEND_ARG_INFO(0, option)
ZEND_END_ARG_INFO()
-
+
ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_split, 0, 0, 2)
ZEND_ARG_INFO(0, pattern)
ZEND_ARG_INFO(0, string)
@@ -1688,12 +1688,12 @@ PHP_MINFO_FUNCTION(mbstring)
php_info_print_table_start();
php_info_print_table_row(2, "Multibyte Support", "enabled");
php_info_print_table_row(2, "Multibyte string engine", "libmbfl");
- php_info_print_table_row(2, "HTTP input encoding translation", MBSTRG(encoding_translation) ? "enabled": "disabled");
- {
- char tmp[256];
- snprintf(tmp, sizeof(tmp), "%d.%d.%d", MBFL_VERSION_MAJOR, MBFL_VERSION_MINOR, MBFL_VERSION_TEENY);
- php_info_print_table_row(2, "libmbfl version", tmp);
- }
+ php_info_print_table_row(2, "HTTP input encoding translation", MBSTRG(encoding_translation) ? "enabled": "disabled");
+ {
+ char tmp[256];
+ snprintf(tmp, sizeof(tmp), "%d.%d.%d", MBFL_VERSION_MAJOR, MBFL_VERSION_MINOR, MBFL_VERSION_TEENY);
+ php_info_print_table_row(2, "libmbfl version", tmp);
+ }
php_info_print_table_end();
php_info_print_table_start();
diff --git a/ext/mbstring/oniguruma/COPYING b/ext/mbstring/oniguruma/COPYING
index 4d321bb93b..2cee0bbec8 100644
--- a/ext/mbstring/oniguruma/COPYING
+++ b/ext/mbstring/oniguruma/COPYING
@@ -1,12 +1,8 @@
Oniguruma LICENSE
-----------------
-When this software is partly used or it is distributed with Ruby,
-this of Ruby follows the license of Ruby.
-It follows the BSD license in the case of the one except for it.
-
/*-
- * Copyright (c) 2002-2006 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2007 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/ext/mbstring/oniguruma/HISTORY b/ext/mbstring/oniguruma/HISTORY
index 647a460906..7add6f9a90 100644
--- a/ext/mbstring/oniguruma/HISTORY
+++ b/ext/mbstring/oniguruma/HISTORY
@@ -1,111 +1,316 @@
History
-2007/08/16: Version 4.7.1
-
-2007/08/16: [test] success in ruby 1.9.0 (2007-04-06) [i686-linux].
-2007/07/04: [spec] (thanks K.Takata)
+2010/01/09: Version 5.9.2
+
+2010/01/05: [bug] fix utf16be_code_to_mbc() and utf16le_code_to_mbc().
+2008/09/16: [bug] fix memory leaks in parse_exp().
+2008/08/01: [bug] fix memory leaks.
+2008/06/17: [bug] invalid type of argument was used
+ in onig_st_lookup_strend().
+2008/06/16: [bug] invalid CaseFoldMap entry in ISO-8859-5. 0xdf -> 0xde
+2008/02/19: [new] add: onig_reg_init().
+2008/02/19: [new] add: onig_free_body().
+2008/02/19: [new] add: onig_new_without_alloc().
+2008/02/19: [API] rename onig_alloc_init() to onig_reg_init(),
+ and argument type changed.
+2008/01/31: [impl] move UTF16_IS_SURROGATE_XXX() to regenc.h.
+2008/01/30: [bug] (thanks akr)
+ fix euctw_islead().
+2008/01/23: [bug] update enc/koi8.c.
+
+2007/12/22: Version 5.9.1
+
+2007/12/21: [impl] add sprint_byte().
+2007/11/28: [bug] (thanks Andy Armstrong)
+ don't overwrite error code in fetch_name().
+2007/11/12: [bug] utf8 mbc length of code 0xfe, 0xff are not 1,
+2007/10/23: [spec] onig_enc_len() takes three arguments. (not used)
+2007/10/15: [impl] (thanks Rui Hirokawa)
+ add check HAVE_STDARG_H.
+2007/09/07: [API] rename enc_len() to onig_enc_len() in oniguruma.h.
+2007/09/04: [API] remove ONIGENC_ERR_XXXXX.
+2007/09/03: [API] add error ONIGERR_INVALID_CODE_POINT_VALUE.
+2007/09/03: [impl] change error message to "invaid code point value"
+ for ONIGERR_INVALID_WIDE_CHAR_VALUE.
+2007/09/03: [bug] xxx_code_to_mbclen() should return
+ ONIGERR_INVALID_WIDE_CHAR_VALUE for invalid code point.
+ ex. /[\x{7fffffff}]/ for ASCII encoding.
+2007/08/28: [impl] remove "warning: no previous declaration ...".
+2007/08/21: [impl] remove warnings in enc/mktable.c.
+2007/08/20: [impl] remove "warning: unused parameter"
+2007/08/20: [impl] remove "warning: comparison between signed and unsigned".
+2007/08/06: [impl] remove clear_not_flag_cclass().
+2007/08/03: [bug] fix the case of undefined USE_NAMED_GROUP.
+2007/08/02: [spec] add backref by number.
+2007/08/01: [API] add OnigCtype.
+2007/07/27: [spec] add USE_CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS.
+2007/07/24: [impl] define PLATFORM_UNALIGNED_WORD_ACCESS.
+2007/07/23: [dist] fix doc/FAQ.ja.
+
+2007/07/14: Version 5.9.0
+
+2007/07/13: [bug] add check into onig_reduce_nested_quantifier().
+2007/06/26: [spec] (thanks K.Takata)
ONIG_OPTION_SINGLELINE: '$' -> '\Z' (as Perl)
-2007/07/04: [dist] (thanks K.Takata)
+2007/06/26: [dist] (thanks K.Takata)
fix documents API and API.ja.
-
-2007/06/18: Version 4.7.0
-
-2007/06/18: [test] success in ruby 1.9.0 (2007-04-06) [i686-linux].
+2007/06/19: [impl] remove IS_NOT_NULL() check before onig_node_free().
2007/06/18: [bug] (thanks KUBO Takehiro)
WORD_ALIGNMENT_SIZE must be sizeof(OnigCodePoint).
-2007/06/05: [impl] add #ifndef vsnprintf in regint.h.
-2007/06/05: [bug] should check USE_CRNL_AS_LINE_TERMINATOR case
+2007/06/18: [impl] rename CClassNode flags.
+2007/06/18: [bug] initialization miss.
+2007/06/13: [impl] change node type reference NXXXX.
+2007/06/11: [impl] add node type bit.
+2007/06/11: [spec] allow anchor in enclosed repeater. /(\z)*/
+2007/06/11: [impl] rename node types.
+2007/06/08: [impl] remove OP_SET_OPTION_PUSH and OP_SET_OPTION from match_at().
+2007/06/07: [impl] use xvsnprintf().
+2007/06/06: [tune] don't set qn->next_head_exact for string first byte is zero.
+2007/06/06: [impl] remove unused variables.
+
+2007/06/04: Version 5.8.0
+
+2007/06/04: [impl] add #ifndef vsnprintf into regint.h.
+2007/05/31: [dist] add configure option '--enable-crnl-as-line-terminator'.
+2007/05/30: [dist] add sample/crnl.c.
+2007/05/30: [bug] should check USE_CRNL_AS_LINE_TERMINATOR case
in onig_search().
+2007/05/29: [impl] move USE_CRNL_AS_LINE_TERMINATOR into regenc.h.
+2007/05/29: [impl] should check USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
+ in forward_search_range() and backward_search_range().
-2007/04/12: Version 4.6.2
+2007/04/27: Version 5.7.0
+2007/04/20: [spec] add config USE_MATCH_RANGE_IS_COMPLETE_RANGE.
+2007/04/20: [impl] refactoring in match_at().
+
+2007/04/12: Version 5.6.1
+
+2007/04/12: [bug] must not use UChar in oniguruma.h.
2007/04/09: [impl] change STATE_CHECK_BUFF_MAX_SIZE value from 0x8000
- to 0x4000.
+ to 0x4000. [ruby-core:10883]
+
+2007/04/04: Version 5.6.0 (mourning for Hideo Takamatsu)
+
+2007/04/03: [spec] add new notation (?'name'), \k'name', \g'name'.
+2007/04/03: [impl] remove unused variable.
2007/03/26: [impl] add 'void' to function declarations.
-2007/03/06: Version 4.6.1
+2007/03/06: Version 5.5.3
-2007/03/06: [test] success in ruby 1.9.0 (2006-10-23) [i686-linux].
2007/03/06: [bug] add #include <malloc.h> for bcc32.
(In bcc32, alloca() is declared in malloc.h.)
-2007/03/06: [impl] remove including version.h of Ruby.
2007/03/02: [bug] invalid optimization for semi-end-buf in onig_search().
ex. /\n\Z/.match("aaaaaaaaaa\n")
2007/03/02: [impl] move range > start check position in end_buf process.
-2007/02/08: Version 4.6.0
+2007/01/09: Version 5.5.2
-2007/02/08: [test] success in ruby 1.9.0 (2006-10-23) [i686-linux].
-2007/01/09: [tune] select_opt_exact_info() didn't work for empty info.
+2007/01/09: [impl] rename USE_EXTERNAL_LOWER_CASE_CONV_TABLE.
+2007/01/05: [tune] select_opt_exact_info() didn't work for empty info.
ex. /.a/ make MAP info instead of EXACT info.
-2006/12/29: [impl] add print_enc_string() for ONIG_DEBUG mode.
-2006/12/22: [spec] should check too short multibyte char in parse_exp().
- add USE_PAD_TO_SHORT_BYTE_CHAR.
- ex. /\x00/ in UTF16 should be error.
+2006/12/28: [impl] add print_enc_string() for ONIG_DEBUG mode.
+
+2006/12/22: Version 5.5.1
-2006/11/17: Version 4.5.1
+2006/12/22: [impl] rename ADD_PAD_TO_SHORT_BYTE_STRING
+ . to USE_PAD_TO_SHORT_BYTE_CHAR.
+2006/12/21: [spec] should check too short multibyte char in parse_exp().
+ add ADD_PAD_TO_SHORT_BYTE_STRING.
+ ex. /\x00/ in UTF16 should be error.
-2006/11/17: [test] success in ruby 1.9.0 (2006-10-23) [i686-linux].
-2006/11/15: [impl] remove CHECK_INTERRUPT.
+2006/12/06: Version 5.5.0
+
+2006/12/05: [bug] should add unfold-1 codes from folded code into
+ onigenc_unicode_get_case_fold_codes_by_str().
+ (ex. "S" -> "s" -> 0x017f)
+2006/12/05: [new] add flag ONIGENC_CASE_FOLD_TURKISH_AZERI and
+ USE_UNICODE_CASE_FOLD_TURKISH_AZERI. (disabled in default)
+2006/12/04: [spec] remove ONIGENC_CASE_FOLD_FULL.
+2006/11/30: [impl] remove unnecessary check in xxx_mbc_case_fold().
+
+2006/11/29: Version 5.4.0
+
+2006/11/28: [spec] INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR is enabled in
+ default case fold status.
+2006/11/28: [spec] rename ONIGENC_CASE_FOLD_MULTI_CHAR to
+ INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR.
+2006/11/28: [impl] remove USE_UNICODE_CASE_FOLD_MULTI_CHAR.
+2006/11/28: [impl] remove Fold[123]Table and add FoldTable.
+2006/11/27: [impl] change tool/unicode_fc.rb to see CaseFolding.txt.
+2006/11/24: [bug] should call callback for to[j] <-> to[k] in
+ onigenc_unicode_apply_all_case_fold().
+
+2006/11/22: Version 5.3.0
+
+2006/11/22: [dist] add index_ja.html.
+2006/11/22: [impl] undef ONIG_ESCAPE_UCHAR_COLLISION in regint.h and regenc.h.
+2006/11/21: [bug] invalid array access.
+2006/11/21: [impl] escape UChar collision from config.h.
+2006/11/20: [new] add Hiragana/Katakana properties into Shift_JIS.
+2006/11/20: [impl] fix CR_Katakana[] values in EUC-JP.
+2006/11/17: [impl] declare strend hash table functions in regint.h.
+2006/11/17: [impl] move property list functions to regenc.c.
+2006/11/17: [new] add Hiragana/Katakana properties into EUC-JP.
+2006/11/15: [impl] remove NOT_RUBY from AM_CFLAGS.
+
+2006/11/14: Version 5.2.0
+
+2006/11/14: [impl] remove program codes for Ruby.
+2006/11/14: [impl] reduce program codes for Ruby.
2006/11/10: [bug] 0x24, 0x2b, 0x3c, 0x3d, 0x3e, 0x5e, 0x60, 0x7c, 0x7e
should be [:punct:].
+2006/11/09: [new] (thanks Byte)
+ add new character encoding CP1251.
2006/11/08: [impl] rename QUALIFIER -> QUANTIFIER.
-2006/11/07: [bug] (thanks Byte)
- add 0xa3 <=> 0xb3 to CaseFoldMap[] for KOI8-R.
-2006/11/06: Version 4.5.0
+2006/11/07: Version 5.1.0
-2006/11/06: [test] success in ruby 1.9.0 (2006-10-23) [i686-linux].
-2006/11/06: [API] remove ONIGENC_AMBIGUOUS_MATCH_COMPOUND.
+2006/11/07: [dist] remove test.rb, testconv.rb and testconvu.rb.
+2006/11/07: [bug] get_case_fold_codes_by_str() should handle 'Ss' and 'sS'
+ combination for ess-tsett.
+2006/11/07: [impl] apply_all_case_fold() doesn't need to return all
+ case character combination for multi-character folding.
+ (ONIGENC_CASE_FOLD_MULTI_CHAR)
+2006/11/07: [bug] (thanks Byte)
+ add { 0xa3, 0xb3 } to CaseFoldMap[] for KOI8-R.
2006/11/06: [spec] change ONIG_OPTION_FIND_LONGEST to search all of
the string range.
add USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE.
-
-2006/10/30: Version 4.4.6
-
-2006/10/30: [test] success in ruby 1.9.0 (2006-10-23) [i686-linux].
+2006/11/02: [impl] re-implement expand_case_fold_string() for
+ ONIGENC_CASE_FOLD_MULTI_CHAR.
+2006/10/30: [impl] add NSTR_DONT_GET_OPTINFO flag.
2006/10/30: [impl] (thanks K.Takata)
add THREAD_SYSTEM_INIT and THREAD_SYSTEM_END.
2006/10/30: [bug] (thanks Wolfgang Nadasi-Donner)
invalid offset value was used in STATE_CHECK_BUFF_INIT().
-
-2006/10/24: Version 4.4.5
-
-2006/10/24: [test] success in ruby 1.9.0 (2006-10-23) [i686-linux].
-2006/10/24: [impl] escape -Wall warning.
-2006/10/24: [tune] (thanks Kornelius Kalnbach)
+2006/10/27: [tune] speed up ONIGENC_MBC_CASE_FOLD() for UTF-16, UTF-32.
+ (ASCII code check)
+2006/10/27: [tune] (thanks Kornelius Kalnbach)
String#scan for long string needs long time compare with
old Ruby
by initialization time for combination explosion check
ex. ("test " * 100_000).scan(/\w*\s?/)
change STATE_CHECK_BUFF_MAX_SIZE from 0x8000000 to 0x8000.
reduce initialization area of state_check_buff.
+2006/10/25: [impl] add DISABLE_CASE_FOLD_MULTI_CHAR().
+
+2006/10/23: Version 5.0.1
+
+2006/10/23: [bug] should fold string in expand_case_fold_string().
+2006/10/23: [bug] (thanks Km)
+ too many case fold/unfold expansion problem.
+ don't expand and set ambig flag to the string node.
+ (except ONIGENC_CASE_FOLD_MULTI_CHAR).
+2006/10/23: [bug] (thanks K.Takata)
+ invalid \p{Alnum}, \p{ASCII}, [:alnum:], [:ascii:].
+ fix OnigEncAsciiCtypeTable[] etc...
+2006/10/23: [spec] (thanks K.Takata)
+ add [:word:] POSIX bracket.
+2006/10/23: [bug] (thanks K.Takata)
+ \p{Word} doesn't work.
+2006/10/20: [impl] don't expand for AMBIG_FLAG string in
+ expand_case_fold_string().
+
+2006/10/19: Version 5.0.0
+
+2006/10/18: [bug] ONIGENC_GET_CASE_FOLD_CODES_MAX_NUM should be 13.
+2006/10/18: [impl] remove unused functions.
+2006/10/18: [dist] update documents.
+2006/10/18: [API] move OnigMetaCharTableType to OnigSyntaxType.
+2006/10/18: [dev] add too/unicode_fc.rb, unicode_pc.rb.
+2006/10/18: [dist] remove MANIFEST-RUBY from distribution.
+2006/10/18: [bug] return duplicated code in
+ onigenc_unicode_get_case_fold_codes_by_str().
+2006/10/18 [API] remove ONIG_SYN_OP2_CHAR_PROPERTY_PREFIX_IS.
+2006/10/18: [dev] add tool/19.
+2006/10/18: [dist] remove target 19 from Makefile.am.
+2006/10/17: [dist] add enc/unicode.c to target 19 of win32/Makefile.
+2006/10/17: [impl] change type for escape VC++ warning.
+2006/10/17: [API] rename ONIGENC_CASE_FOLD_NONE to ONIGENC_CASE_FOLD_MIN.
+2006/10/17: [dist] remove INSTALL-RUBY from distribution.
+2006/10/17: [dist] update LTVERSION to "2:0:0".
+2006/10/17: [impl] remove warnings for [make CFLAGS="-g -O2 -Wall"]
+ in the case USE_UNICODE_PROPERTIES and
+ USE_UNICODE_CASE_FOLD_MULTI_CHAR are undefined.
+2006/10/17: [impl] remove warnings for [make CFLAGS="-g -O2 -Wall"].
+2006/10/17: [impl] re-implement onigenc_unicode_apply_all_case_fold().
+ multi-char by case folded char-class is treated as
+ caseless-string (ambig flag on).
+ enable OP_EXACT1_IC and OP_EXACTN_IC.
+2006/10/16: [bug] unfold expand for 1->2, 1->3 folding in
+ onigenc_unicode_apply_all_case_fold().
+ add CaseFoldExpand_12[], CaseFoldExpand_13[].
2006/10/16: [bug] (thanks Akinori Musha)
first argument of rb_warn() should be format string.
-2006/10/10: [impl] add msa.state_check_buff_size initialization
+2006/10/16: [impl] add msa.state_check_buff_size initialization
in onig_search().
+2006/10/16: [spec] re-implement Unicode Caseless Match codes.
2006/10/10: [bug] should call onig_st_free_table() in
onig_free_shared_cclass_table().
+2006/10/10: [impl] remove OnigCompCaseFoldCodes.
+2006/10/10: [impl] remove onigenc_ascii_is_mbc_ambiguous() and
+ onigenc_mbn_is_mbc_ambiguous().
+2006/10/10: [API] remove is_mbc_ambiguous() member from OnigEncodingType.
+2006/10/10: [API] rename onig_set_default_ambig_flag() to
+ onig_set_default_case_fold_flag(),
+ onig_get_default_ambig_flag() to
+ onig_get_default_case_fold_flag(),
+ onig_get_ambig_flag() to onig_get_case_fold_flag().
+2006/10/10: [API] rename ambig_flag to case_fold_flag.
+2006/10/10: [API] rename OnigAmbigType to OnigCaseFoldType.
+2006/10/10: [impl] rename ONIGENC_IS_CODE_SB_WORD() to IS_CODE_SB_WORD()
+ and move to regint.h.
2006/10/10: [impl] remove OP_WORD_SB and OP_WORD_MB.
+2006/10/10: [impl] remove OP_EXACT1_IC and OP_EXACTN_IC from match_at().
+2006/10/10: [impl] should free new_str in expand_case_fold_string().
+2006/10/06: [dist] add test entrys to sample/encode.c.
+2006/10/06: [impl] re-implement caseless match (case-fold).
+2006/10/06: [impl] expand string node by case fold variations.
+ add expand_case_fold_string().
+2006/10/05: [spec] rename OnigCompAmbigCodeItem to OnigCaseFoldCodeItem.
+2006/10/05: [spec] add apply_all_case_fold() and get_case_fold_codes_by_str()
+ to OnigEncodingType.
+2006/10/05: [spec] remove ambig_flag, get_all_pair_ambig_codes() and
+ get_all_comp_ambig_codes() member from OnigEncodingType.
+2006/10/03: [impl] rename mbc_to_normalize() to mbc_case_fold().
+2006/10/03: [spec] rename ONIGENC_AMBIGUOUS_MATCH_XXX
+ to ONIGENC_CASE_FOLD_XXX.
+ rename ONIGENC_CASE_FOLD_COMPOUND
+ to ONIGENC_CASE_FOLD_MULTI_CHAR.
+2006/10/02: [impl] remove all ONIG_RUBY_M17N part.
2006/09/29: [impl] initialize state_check_buff_size in STATE_CHECK_BUFF_INIT().
make valgrind happy.
-2006/09/22: [impl] convert to ascii for parameter string in
+2006/09/22: [impl] remove parse time ctype values (CTYPE_WORD etc...)
+2006/09/22: [ruby] enable USE_BACKREF_AT_LEVEL for Ruby mode.
+2006/09/22: [spec] (thanks Allan Odgaard)
+ allow upper case letter as the first character
+ of group name.
+ fetch_name() and fetch_name_with_level()
+2006/09/21: [impl] convert to ascii for parameter string in
onig_error_code_to_str().
add enc member into OnigErrorInfo.
-
-2006/09/19: Version 4.4.4
-
-2006/09/19: [test] success in ruby 1.9.0 (2006-08-22) [i686-linux].
+2006/09/21: [dist] update documents for Unicode Property.
+2006/09/21: [new] add Unicode Properties. (enc/unicode.c)
+ Any, Assigned, C, Cc, L, Lm, Arabic, Greek etc...
+2006/09/21: [impl] add USE_UNICODE_PROPERTIES into regenc.h.
+2006/09/21: [impl] remove USE_UNICODE_FULL_RANGE_CTYPE.
+2006/09/20: [impl] change ONIGENC_CTYPE_XXXX to sequencial values.
+ add BIT_CTYPE_XXXX bit flags to regenc.h.
+ update XXXX_CtypeTable[] for BIT_CTYPE_ALNUM.
+2006/09/19: [memo] move from CVS to Subversion (1.3.2).
2006/09/19: [impl] (thanks KOYAMA Tetsuji)
HAVE_STDARG_PROTOTYPES was not defined in Mac OS X
by Xcode 2.4(gcc 4.0.1) problem. [php-dev 1312] etc...
-
-2006/09/15: Version 4.4.3
-
-2006/09/15: [test] success in ruby 1.9.0 (2006-08-22) [i686-linux].
2006/09/15: [bug] (thanks Allan Odgaard)
out of range access in bm_search_notrev().
(p < s)
+2006/09/13: [impl] add ONIGENC_CTYPE_ENC_EXT flag.
+2006/09/13: [spec] remove 'Is' prefix check for property name
+ from fetch_char_property_to_ctype().
+2006/09/13: [API] add property_name_to_ctype member to OnigEncodingType.
+2006/09/12: [spec][ruby] add ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY and
+ ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT to OnigSyntaxRuby.
2006/09/08: Version 4.4.2
@@ -1808,8 +2013,17 @@ History
[inst: changes for installation]
[dist: distribution change]
[test: test]
+[dev: development]
[memo: memo]
--
+<create tag>
+svn copy file:///home/kosako/svnreps/svnrep_onig/trunk file:///home/kosako/svnreps/svnrep_onig/tags/5.0.0 -m "ADD TAG: 5.0.0"
+
+<set ignore files by .cvsignore>
+svn propset svn:ignore -F .cvsignore .
+svn commit -m "..."
+
+
<CVS: show all tags>
cvs history -T
@@ -1820,7 +2034,7 @@ cvs rtag "VERSION_X_X_X" oniguruma
<GNU Autotools: bootstrap>
* write Makefile.am and configure.in.
> aclocal
-> libtoolize
+> libtoolize or glibtoolize
> automake --foreign --add-missing
> autoconf
> configure --with-rubydir=... CFLAGS="-O2 -Wall"
diff --git a/ext/mbstring/oniguruma/README b/ext/mbstring/oniguruma/README
index dff7fba562..8390afd050 100644
--- a/ext/mbstring/oniguruma/README
+++ b/ext/mbstring/oniguruma/README
@@ -1,9 +1,8 @@
-README 2007/06/18
+README 2007/05/31
Oniguruma ---- (C) K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
http://www.geocities.jp/kosako3/oniguruma/
-http://www.freebsd.org/cgi/cvsweb.cgi/ports/devel/oniguruma/
Oniguruma is a regular expressions library.
The characteristics of this library is that different character encoding
@@ -13,16 +12,20 @@ Supported character encodings:
ASCII, UTF-8, UTF-16BE, UTF-16LE, UTF-32BE, UTF-32LE,
EUC-JP, EUC-TW, EUC-KR, EUC-CN,
- Shift_JIS, Big5, GB 18030, KOI8-R, KOI8,
+ Shift_JIS, Big5, GB18030, KOI8-R, CP1251,
ISO-8859-1, ISO-8859-2, ISO-8859-3, ISO-8859-4, ISO-8859-5,
ISO-8859-6, ISO-8859-7, ISO-8859-8, ISO-8859-9, ISO-8859-10,
ISO-8859-11, ISO-8859-13, ISO-8859-14, ISO-8859-15, ISO-8859-16
-* GB 18030: contributed by KUBO Takehiro
-* KOI8 is not included in library archive by default setup.
- (need to edit Makefile if you want to use it.)
+* GB18030: contributed by KUBO Takehiro
+* CP1251: contributed by Byte
------------------------------------------------------------
+License
+
+ BSD license.
+
+
Install
Case 1: Unix and Cygwin platform
@@ -63,14 +66,6 @@ Install
-License
-
- When this software is partly used or it is distributed with Ruby,
- this of Ruby follows the license of Ruby.
- It follows the BSD license in the case of the one except for it.
-
-
-
Regular Expressions
See doc/RE (or doc/RE.ja for Japanese).
@@ -108,7 +103,10 @@ Sample Programs
sample/posix.c POSIX API sample.
sample/sql.c example of the variable meta characters.
(SQL-like pattern matching)
+
+Test Programs
sample/syntax.c Perl, Java and ASIS syntax test.
+ sample/crnl.c --enable-crnl-as-line-terminator test
Source Files
@@ -145,9 +143,10 @@ Source Files
enc/euc_kr.c EUC-KR, EUC-CN encoding.
enc/sjis.c Shift_JIS encoding.
enc/big5.c Big5 encoding.
- enc/gb18030.c GB 18030 encoding (contributed by KUBO Takehiro)
+ enc/gb18030.c GB18030 encoding.
enc/koi8.c KOI8 encoding.
enc/koi8_r.c KOI8-R encoding.
+ enc/cp1251.c CP1251 encoding.
enc/iso8859_1.c ISO-8859-1 encoding. (Latin-1)
enc/iso8859_2.c ISO-8859-2 encoding. (Latin-2)
enc/iso8859_3.c ISO-8859-3 encoding. (Latin-3)
@@ -176,14 +175,15 @@ Source Files
-API differences with Japanized GNU regex(version 0.12) of Ruby 1.8/1.6
-
- + re_compile_fastmap() is removed.
- + re_alloc_pattern() is added.
-
+ToDo
+ ? case fold flag: Katakana <-> Hiragana.
+ ? add ONIG_OPTION_NOTBOS/NOTEOS. (\A, \z, \Z)
+ ?? \X (== \PM\pM*)
+ ?? implement syntax behavior ONIG_SYN_CONTEXT_INDEP_ANCHORS.
+ ?? transmission stopper. (return ONIG_STOP from match_at())
-I'm thankful to Akinori MUSHA.
+and I'm thankful to Akinori MUSHA.
Mail Address: K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
diff --git a/ext/mbstring/oniguruma/README.ja b/ext/mbstring/oniguruma/README.ja
index 2dee793cae..b14822c9e6 100644
--- a/ext/mbstring/oniguruma/README.ja
+++ b/ext/mbstring/oniguruma/README.ja
@@ -1,9 +1,8 @@
-README.ja 2007/06/18
+README.ja 2007/05/31
---- (C) K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
http://www.geocities.jp/kosako3/oniguruma/
-http://www.freebsd.org/cgi/cvsweb.cgi/ports/devel/oniguruma/
֤ɽ饤֥Ǥ롣
Υ饤֥Ĺϡ줾ɽ֥ȤȤ
@@ -13,16 +12,20 @@ http://www.freebsd.org/cgi/cvsweb.cgi/ports/devel/oniguruma/
ASCII, UTF-8, UTF-16BE, UTF-16LE, UTF-32BE, UTF-32LE,
EUC-JP, EUC-TW, EUC-KR, EUC-CN,
- Shift_JIS, Big5, GB 18030, KOI8-R, KOI8,
+ Shift_JIS, Big5, GB18030, KOI8-R, CP1251,
ISO-8859-1, ISO-8859-2, ISO-8859-3, ISO-8859-4, ISO-8859-5,
ISO-8859-6, ISO-8859-7, ISO-8859-8, ISO-8859-9, ISO-8859-10,
ISO-8859-11, ISO-8859-13, ISO-8859-14, ISO-8859-15, ISO-8859-16
-* GB 18030: ݷλ
-* KOI8ϥǥեȤΥåȥåפǤϥ饤֥˴ޤޤʤ
- (ɬפǤMakefileԽ뤳)
+* GB18030: ݷλ
+* CP1251: Byte
------------------------------------------------------------
+饤
+
+ BSD饤󥹤˽
+
+
󥹥ȡ
: UnixCygwinĶ
@@ -63,12 +66,6 @@ http://www.freebsd.org/cgi/cvsweb.cgi/ports/devel/oniguruma/
5. nmake ctest
-饤
-
- ΥեȥRubyȰ˻Ѥޤۤˤϡ
- RubyΥ饤󥹤˽
- ʳξˤϡBSD饤󥹤˽
-
ɽ
@@ -97,7 +94,7 @@ http://www.freebsd.org/cgi/cvsweb.cgi/ports/devel/oniguruma/
GNU libtoolѤƤΤǡץåȥեबͭ饤֥򥵥ݡȤ
СѤǤ褦ˤʤäƤ롣
Ū饤֥ȶͭ饤֥ΤɤѤ뤫ꤹˡ¹ԻǤ
- ĶˡˤĤƤϡʬĴ٤Ʋ
+ ĶˡˤĤƤϡʬĴ٤Ʋ
Win32ǥƥå󥯥饤֥(onig_s.lib)󥯤ˤϡ
@@ -112,7 +109,10 @@ http://www.freebsd.org/cgi/cvsweb.cgi/ports/devel/oniguruma/
sample/listcap.c ǽλ
sample/posix.c POSIX API
sample/sql.c ѥ᥿ʸǽ (SQL-like ѥ)
+
+ƥȥץ
sample/syntax.c PerlJavaASISʸˡΥƥ
+ sample/crnl.c --enable-crnl-as-line-terminator ƥ
ե
@@ -149,9 +149,10 @@ http://www.freebsd.org/cgi/cvsweb.cgi/ports/devel/oniguruma/
enc/euc_kr.c EUC-KR, EUC-CN 󥳡ǥ
enc/sjis.c Shift_JIS 󥳡ǥ
enc/big5.c Big5 󥳡ǥ
- enc/gb18030.c GB 18030 󥳡ǥ (ݷλ )
+ enc/gb18030.c GB18030 󥳡ǥ
enc/koi8.c KOI8 󥳡ǥ
enc/koi8_r.c KOI8-R 󥳡ǥ
+ enc/cp1251.c CP1251 󥳡ǥ
enc/iso8859_1.c ISO-8859-1 (Latin-1)
enc/iso8859_2.c ISO-8859-2 (Latin-2)
enc/iso8859_3.c ISO-8859-3 (Latin-3)
@@ -180,13 +181,15 @@ http://www.freebsd.org/cgi/cvsweb.cgi/ports/devel/oniguruma/
-Ruby 1.8/1.6ܸ첽GNU regexȤAPIΰ㤤
-
- + re_compile_fastmap() Ϻ줿
- + re_alloc_pattern() ɲä줿
+ ? case fold flag: Katakana <-> Hiragana
+ ? ONIG_OPTION_NOTBOS/NOTEOSɲ (\A, \z, \Z)
+ ?? \X (== \PM\pM*)
+ ?? ʸˡ ONIG_SYN_CONTEXT_INDEP_ANCHORSμ
+ ?? ְư߱黻 (match_at()ONIG_STOP֤)
-I'm thankful to Akinori MUSHA.
+and I'm thankful to Akinori MUSHA.
ɥ쥹: K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
diff --git a/ext/mbstring/oniguruma/doc/API b/ext/mbstring/oniguruma/doc/API
index 2f66287d49..f3b88756bc 100644
--- a/ext/mbstring/oniguruma/doc/API
+++ b/ext/mbstring/oniguruma/doc/API
@@ -1,4 +1,4 @@
-Oniguruma API Version 4.7.1 2007/07/04
+Oniguruma API Version 5.9.2 2008/02/19
#include <oniguruma.h>
@@ -105,10 +105,10 @@ Oniguruma API Version 4.7.1 2007/07/04
ONIG_ENCODING_EUC_KR EUC-KR
ONIG_ENCODING_EUC_CN EUC-CN
ONIG_ENCODING_SJIS Shift_JIS
- ONIG_ENCODING_KOI8 KOI8
ONIG_ENCODING_KOI8_R KOI8-R
+ ONIG_ENCODING_CP1251 CP1251
ONIG_ENCODING_BIG5 Big5
- ONIG_ENCODING_GB18030 GB 18030
+ ONIG_ENCODING_GB18030 GB18030
or any OnigEncodingType data address defined by user.
@@ -134,6 +134,18 @@ Oniguruma API Version 4.7.1 2007/07/04
+# int onig_new_without_alloc(regex_t* reg, const UChar* pattern,
+ const UChar* pattern_end,
+ OnigOptionType option, OnigEncoding enc, OnigSyntaxType* syntax,
+ OnigErrorInfo* err_info)
+
+ Create a regex object.
+ reg object area is not allocated in this function.
+
+ normal return: ONIG_NORMAL
+
+
+
# int onig_new_deluxe(regex_t** reg, const UChar* pattern, const UChar* pattern_end,
OnigCompileInfo* ci, OnigErrorInfo* einfo)
@@ -153,15 +165,12 @@ Oniguruma API Version 4.7.1 2007/07/04
ci->target_enc: target string character encoding.
ci->syntax: address of pattern syntax definition.
ci->option: compile time option.
- ci->ambig_flag: character matching ambiguity bit flag for
+ ci->case_fold_flag: character matching case fold bit flag for
ONIG_OPTION_IGNORECASE mode.
- ONIGENC_AMBIGUOUS_MATCH_NONE: exact
- ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE: ignore case for ASCII
- ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE: ignore case for non-ASCII
- ONIGENC_AMBIGUOUS_MATCH_FULL: all ambiguity on
- ONIGENC_AMBIGUOUS_MATCH_DEFAULT: (ASCII | NONASCII)
- onig_set_default_ambig_flag()
+ ONIGENC_CASE_FOLD_MIN: minimum
+ ONIGENC_CASE_FOLD_DEFAULT: minimum
+ onig_set_default_case_fold_flag()
5 err_info: address for return optional error info.
Use this value as 3rd argument of onig_error_code_to_str().
@@ -188,6 +197,14 @@ Oniguruma API Version 4.7.1 2007/07/04
1 reg: regex object.
+# void onig_free_body(regex_t* reg)
+
+ Free memory used by regex object. (Except reg oneself.)
+
+ arguments
+ 1 reg: regex object.
+
+
# int onig_search(regex_t* reg, const UChar* str, const UChar* end, const UChar* start,
const UChar* range, OnigRegion* region, OnigOptionType option)
@@ -202,8 +219,8 @@ Oniguruma API Version 4.7.1 2007/07/04
3 end: terminate address of target string
4 start: search start address of target string
5 range: search terminate address of target string
- in forward search (start <= searched string head < range)
- in backward search (range <= searched string head <= start)
+ in forward search (start <= searched string < range)
+ in backward search (range <= searched string <= start)
6 region: address for return group match range info (NULL is allowed)
7 option: search time option
@@ -335,10 +352,10 @@ Oniguruma API Version 4.7.1 2007/07/04
1 reg: regex object.
-# OnigEncoding onig_get_encoding(regex_t* reg)
-# OnigOptionType onig_get_options(regex_t* reg)
-# OnigAmbigType onig_get_ambig_flag(regex_t* reg)
-# OnigSyntaxType* onig_get_syntax(regex_t* reg)
+# OnigEncoding onig_get_encoding(regex_t* reg)
+# OnigOptionType onig_get_options(regex_t* reg)
+# OnigCaseFoldType onig_get_case_fold_flag(regex_t* reg)
+# OnigSyntaxType* onig_get_syntax(regex_t* reg)
Return a value of the regex object.
@@ -518,7 +535,7 @@ Oniguruma API Version 4.7.1 2007/07/04
2 from: source address.
-# int onig_set_meta_char(OnigEncoding enc, unsigned int what,
+# int onig_set_meta_char(OnigSyntaxType* syntax, unsigned int what,
OnigCodePoint code)
Set a variable meta character to the code point value.
@@ -529,8 +546,8 @@ Oniguruma API Version 4.7.1 2007/07/04
normal return: ONIG_NORMAL
arguments
- 1 enc: target encoding
- 2 what: specifies which meta character it is.
+ 1 syntax: target syntax
+ 2 what: specifies which meta character it is.
ONIG_META_CHAR_ESCAPE
ONIG_META_CHAR_ANYCHAR
@@ -542,16 +559,16 @@ Oniguruma API Version 4.7.1 2007/07/04
3 code: meta character or ONIG_INEFFECTIVE_META_CHAR.
-# OnigAmbigType onig_get_default_ambig_flag()
+# OnigCaseFoldType onig_get_default_case_fold_flag()
- Get default ambig flag.
+ Get default case fold flag.
-# int onig_set_default_ambig_flag(OnigAmbigType ambig_flag)
+# int onig_set_default_case_fold_flag(OnigCaseFoldType case_fold_flag)
- Set default ambig flag.
+ Set default case fold flag.
- 1 ambig_flag: ambiguity flag
+ 1 case_fold_flag: case fold flag
# unsigned int onig_get_match_stack_limit_size(void)
@@ -580,6 +597,6 @@ Oniguruma API Version 4.7.1 2007/07/04
# const char* onig_version(void)
- Return version string. (ex. "2.2.8")
+ Return version string. (ex. "5.0.3")
// END
diff --git a/ext/mbstring/oniguruma/doc/API.ja b/ext/mbstring/oniguruma/doc/API.ja
index f2a8bd6f10..f681fa5460 100644
--- a/ext/mbstring/oniguruma/doc/API.ja
+++ b/ext/mbstring/oniguruma/doc/API.ja
@@ -1,4 +1,4 @@
-֥󥿡ե Version 4.7.1 2007/07/04
+֥󥿡ե Version 5.9.2 2008/02/19
#include <oniguruma.h>
@@ -106,10 +106,10 @@
ONIG_ENCODING_EUC_KR EUC-KR
ONIG_ENCODING_EUC_CN EUC-CN
ONIG_ENCODING_SJIS Shift_JIS
- ONIG_ENCODING_KOI8 KOI8
ONIG_ENCODING_KOI8_R KOI8-R
+ ONIG_ENCODING_CP1251 CP1251
ONIG_ENCODING_BIG5 Big5
- ONIG_ENCODING_GB18030 GB 18030
+ ONIG_ENCODING_GB18030 GB18030
ޤϡ桼OnigEncodingTypeǡΥɥ쥹
@@ -134,6 +134,19 @@
onig_error_code_to_str()λܤΰȤƻѤ
+
+# int onig_new_without_alloc(regex_t* reg, const UChar* pattern,
+ const UChar* pattern_end,
+ OnigOptionType option, OnigEncoding enc, OnigSyntaxType* syntax,
+ OnigErrorInfo* err_info)
+
+ ɽ֥(regex)롣
+ regΰdzƤʤ
+
+ ェλ: ONIG_NORMAL
+
+
+
# int onig_new_deluxe(regex_t** reg, const UChar* pattern, const UChar* pattern_end,
OnigCompileInfo* ci, OnigErrorInfo* einfo)
@@ -153,15 +166,12 @@
ci->target_enc: оʸʸ󥳡ǥ
ci->syntax: ɽѥʸˡ
ci->option: ɽѥץ
- ci->ambig_flag: ONIG_OPTION_IGNORECASE⡼ɤǤ
+ ci->case_fold_flag: ONIG_OPTION_IGNORECASE⡼ɤǤ
ʸۣޥåӥåȥե饰
- ONIGENC_AMBIGUOUS_MATCH_NONE: ̵ۣ
- ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE: ASCIIʸʸ
- ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE: ASCIIʳʸʸ
- ONIGENC_AMBIGUOUS_MATCH_FULL: Ƥۣե饰ͭ
- ONIGENC_AMBIGUOUS_MATCH_DEFAULT: (ASCII | NONASCII)
- onig_set_default_ambig_flag()
+ ONIGENC_CASE_FOLD_MIN: Ǿ
+ ONIGENC_CASE_FOLD_DEFAULT: Ǿ
+ onig_set_default_case_fold_flag()
5 err_info: 顼֤Υɥ쥹
onig_error_code_to_str()λܤΰȤƻѤ
@@ -187,6 +197,14 @@
1 reg: ɽ֥
+# void onig_free_body(regex_t* reg)
+
+ ɽ֥ȤΥ롣(regȤΰ)
+
+
+ 1 reg: ɽ֥
+
+
# int onig_search(regex_t* reg, const UChar* str, const UChar* end, const UChar* start,
const UChar* range, OnigRegion* region, OnigOptionType option)
@@ -200,10 +218,10 @@
1 reg: ɽ֥
2 str: оʸ
3 end: оʸνüɥ쥹
- 4 start: оʸθƬֳϥɥ쥹
- 5 range: оʸθƬֽüɥ쥹
- õ (start <= õʸƬ < range)
- õ (range <= õʸƬ <= start)
+ 4 start: оʸθƬ֥ɥ쥹
+ 5 range: оʸθλ֥ɥ쥹
+ õ (start <= õʸ < range)
+ õ (range <= õʸ <= start)
6 region: ޥåΰ(region) (NULL)
7 option: ץ
@@ -340,10 +358,10 @@
1 reg: ɽ֥
-# OnigEncoding onig_get_encoding(regex_t* reg)
-# OnigOptionType onig_get_options(regex_t* reg)
-# OnigAmbigType onig_get_ambig_flag(regex_t* reg)
-# OnigSyntaxType* onig_get_syntax(regex_t* reg)
+# OnigEncoding onig_get_encoding(regex_t* reg)
+# OnigOptionType onig_get_options(regex_t* reg)
+# OnigCaseFoldType onig_get_case_fold_flag(regex_t* reg)
+# OnigSyntaxType* onig_get_syntax(regex_t* reg)
ɽ֥ȤФơб֤ͤ
@@ -524,7 +542,7 @@
2 from:
-# int onig_set_meta_char(OnigEncoding enc, unsigned int what,
+# int onig_set_meta_char(OnigSyntaxType* syntax, unsigned int what,
OnigCodePoint code)
᥿ʸꤷɥݥͤ˥åȤ롣
@@ -535,8 +553,8 @@
ェλ: ONIG_NORMAL
- 1 enc: оʸ󥳡ǥ
- 2 what: ᥿ʸǽλ
+ 1 syntax: оʸˡ
+ 2 what: ᥿ʸǽλ
ONIG_META_CHAR_ESCAPE
ONIG_META_CHAR_ANYCHAR
@@ -548,17 +566,17 @@
3 code: ᥿ʸΥɥݥ ޤ ONIG_INEFFECTIVE_META_CHAR.
-# OnigAmbigType onig_get_default_ambig_flag()
+# OnigCaseFoldType onig_get_default_case_fold_flag()
- ǥեȤۣޥåե饰롣
+ ǥեȤcase foldե饰롣
-# int onig_set_default_ambig_flag(OnigAmbigType ambig_flag)
+# int onig_set_default_case_fold_flag(OnigCaseFoldType case_fold_flag)
- ǥեȤۣޥåե饰򥻥åȤ롣
+ ǥեȤcase foldե饰򥻥åȤ롣
- 1 ambig_flag: ۣޥåե饰
+ 1 case_fold_flag: case foldե饰
# unsigned int onig_get_match_stack_limit_size(void)
@@ -587,6 +605,6 @@
# const char* onig_version(void)
- Сʸ֤( "2.2.8")
+ Сʸ֤( "5.0.3")
// END
diff --git a/ext/mbstring/oniguruma/doc/FAQ b/ext/mbstring/oniguruma/doc/FAQ
index dccf242c8d..46a3e0e08b 100644
--- a/ext/mbstring/oniguruma/doc/FAQ
+++ b/ext/mbstring/oniguruma/doc/FAQ
@@ -1,4 +1,4 @@
-FAQ 2006/10/30
+FAQ 2006/11/14
1. Lognest match
@@ -12,7 +12,7 @@ FAQ 2006/10/30
(A) Oniguruma Layer
- Define the macro below at NOT_RUBY case in oniguruma/regint.h.
+ Define the macro below in oniguruma/regint.h.
USE_MULTI_THREAD_SYSTEM
THREAD_ATOMIC_START
diff --git a/ext/mbstring/oniguruma/doc/FAQ.ja b/ext/mbstring/oniguruma/doc/FAQ.ja
index 5582765ee6..1d65f9fb62 100644
--- a/ext/mbstring/oniguruma/doc/FAQ.ja
+++ b/ext/mbstring/oniguruma/doc/FAQ.ja
@@ -1,4 +1,4 @@
-FAQ 2006/10/30
+FAQ 2007/07/23
1. Ĺޥå
@@ -13,7 +13,7 @@ FAQ 2006/10/30
(A) Oniguruma Layer
- oniguruma/regint.hNOT_RUBYʬΰʲΥޥ롣
+ oniguruma/regint.hΰʲΥޥ롣
USE_MULTI_THREAD_SYSTEM
THREAD_ATOMIC_START
@@ -35,7 +35,16 @@ FAQ 2006/10/30
"åɥդ˴ؤ­"˽񤤤Ƥ
-3. ᡼󥰥ꥹ
+3. CR + LF
+
+ DOSβ(CR(0x0c) + LF(0x0a)Ϣ³)
+
+ regenc.hΡʲʬͭˤ롣
+
+ /* #define USE_CRNL_AS_LINE_TERMINATOR */
+
+
+4. ᡼󥰥ꥹ
֤˴ؤ᡼󥰥ꥹȤ¸ߤʤ
@@ -59,8 +68,7 @@ Oniguruma饤֥ǹԤɤ餫֤ȤǤޤ
(A) Onigurumaб
-oniguruma/regint.hNOT_RUBYǰϤޤƤʬ
-ʲΥޥƺƥѥ뤷Ƥ
+oniguruma/regint.hǰʲΥޥƺƥѥ뤷Ƥ
USE_MULTI_THREAD_SYSTEM
diff --git a/ext/mbstring/oniguruma/doc/RE b/ext/mbstring/oniguruma/doc/RE
index 5a2783d167..21efe531a4 100644
--- a/ext/mbstring/oniguruma/doc/RE
+++ b/ext/mbstring/oniguruma/doc/RE
@@ -1,4 +1,4 @@
-Oniguruma Regular Expressions Version 4.3.0 2006/08/17
+Oniguruma Regular Expressions Version 5.9.1 2007/09/05
syntax: ONIG_SYNTAX_RUBY (default)
@@ -70,6 +70,38 @@ syntax: ONIG_SYNTAX_RUBY (default)
\H non hexadecimal digit char
+ Character Property
+
+ * \p{property-name}
+ * \p{^property-name} (negative)
+ * \P{property-name} (negative)
+
+ property-name:
+
+ + works on all encodings
+ Alnum, Alpha, Blank, Cntrl, Digit, Graph, Lower,
+ Print, Punct, Space, Upper, XDigit, Word, ASCII,
+
+ + works on EUC_JP, Shift_JIS
+ Hiragana, Katakana
+
+ + works on UTF8, UTF16, UTF32
+ Any, Assigned, C, Cc, Cf, Cn, Co, Cs, L, Ll, Lm, Lo, Lt, Lu,
+ M, Mc, Me, Mn, N, Nd, Nl, No, P, Pc, Pd, Pe, Pf, Pi, Po, Ps,
+ S, Sc, Sk, Sm, So, Z, Zl, Zp, Zs,
+ Arabic, Armenian, Bengali, Bopomofo, Braille, Buginese,
+ Buhid, Canadian_Aboriginal, Cherokee, Common, Coptic,
+ Cypriot, Cyrillic, Deseret, Devanagari, Ethiopic, Georgian,
+ Glagolitic, Gothic, Greek, Gujarati, Gurmukhi, Han, Hangul,
+ Hanunoo, Hebrew, Hiragana, Inherited, Kannada, Katakana,
+ Kharoshthi, Khmer, Lao, Latin, Limbu, Linear_B, Malayalam,
+ Mongolian, Myanmar, New_Tai_Lue, Ogham, Old_Italic, Old_Persian,
+ Oriya, Osmanya, Runic, Shavian, Sinhala, Syloti_Nagri, Syriac,
+ Tagalog, Tagbanwa, Tai_Le, Tamil, Telugu, Thaana, Thai, Tibetan,
+ Tifinagh, Ugaritic, Yi
+
+
+
4. Quantifier
greedy
@@ -111,11 +143,7 @@ syntax: ONIG_SYNTAX_RUBY (default)
\A beginning of string
\Z end of string, or before newline at the end
\z end of string
- \G matching start position (*)
-
- * Ruby Regexp:
- previous end-of-match position
- (This specification is not related to this library.)
+ \G matching start position
6. Character class
@@ -135,40 +163,43 @@ syntax: ONIG_SYNTAX_RUBY (default)
Not Unicode Case:
- alnum alphabet or digit char
- alpha alphabet
- ascii code value: [0 - 127]
- blank \t, \x20
- cntrl
- digit 0-9
- graph include all of multibyte encoded characters
- lower
- print include all of multibyte encoded characters
- punct
- space \t, \n, \v, \f, \r, \x20
- upper
- xdigit 0-9, a-f, A-F
+ alnum alphabet or digit char
+ alpha alphabet
+ ascii code value: [0 - 127]
+ blank \t, \x20
+ cntrl
+ digit 0-9
+ graph include all of multibyte encoded characters
+ lower
+ print include all of multibyte encoded characters
+ punct
+ space \t, \n, \v, \f, \r, \x20
+ upper
+ xdigit 0-9, a-f, A-F
+ word alphanumeric, "_" and multibyte characters
Unicode Case:
- alnum Letter | Mark | Decimal_Number
- alpha Letter | Mark
- ascii 0000 - 007F
- blank Space_Separator | 0009
- cntrl Control | Format | Unassigned | Private_Use | Surrogate
- digit Decimal_Number
- graph [[:^space:]] && ^Control && ^Unassigned && ^Surrogate
- lower Lowercase_Letter
- print [[:graph:]] | [[:space:]]
- punct Connector_Punctuation | Dash_Punctuation | Close_Punctuation |
- Final_Punctuation | Initial_Punctuation | Other_Punctuation |
- Open_Punctuation
- space Space_Separator | Line_Separator | Paragraph_Separator |
- 0009 | 000A | 000B | 000C | 000D | 0085
- upper Uppercase_Letter
- xdigit 0030 - 0039 | 0041 - 0046 | 0061 - 0066
- (0-9, a-f, A-F)
+ alnum Letter | Mark | Decimal_Number
+ alpha Letter | Mark
+ ascii 0000 - 007F
+ blank Space_Separator | 0009
+ cntrl Control | Format | Unassigned | Private_Use | Surrogate
+ digit Decimal_Number
+ graph [[:^space:]] && ^Control && ^Unassigned && ^Surrogate
+ lower Lowercase_Letter
+ print [[:graph:]] | [[:space:]]
+ punct Connector_Punctuation | Dash_Punctuation | Close_Punctuation |
+ Final_Punctuation | Initial_Punctuation | Other_Punctuation |
+ Open_Punctuation
+ space Space_Separator | Line_Separator | Paragraph_Separator |
+ 0009 | 000A | 000B | 000C | 000D | 0085
+ upper Uppercase_Letter
+ xdigit 0030 - 0039 | 0041 - 0046 | 0061 - 0066
+ (0-9, a-f, A-F)
+ word Letter | Mark | Decimal_Number | Connector_Punctuation
+
7. Extended groups
@@ -200,9 +231,9 @@ syntax: ONIG_SYNTAX_RUBY (default)
(?>subexp) atomic group
don't backtrack in subexp.
- (?<name>subexp) define named group
- (All characters of the name must be a word character.
- And first character must not be a digit or uppper case)
+ (?<name>subexp), (?'name'subexp)
+ define named group
+ (All characters of the name must be a word character.)
Not only a name but a number is assigned like a captured
group.
@@ -215,7 +246,12 @@ syntax: ONIG_SYNTAX_RUBY (default)
8. Back reference
\n back reference by group number (n >= 1)
+ \k<n> back reference by group number (n >= 1)
+ \k'n' back reference by group number (n >= 1)
+ \k<-n> back reference by relative group number (n >= 1)
+ \k'-n' back reference by relative group number (n >= 1)
\k<name> back reference by group name
+ \k'name' back reference by group name
In the back reference by the multiplex definition name,
a subexp with a large number is referred to preferentially.
@@ -227,10 +263,17 @@ syntax: ONIG_SYNTAX_RUBY (default)
back reference with nest level
- (This function is disabled in Ruby 1.9.)
+ level: 0, 1, 2, ...
- \k<name+n> n: 0, 1, 2, ...
- \k<name-n> n: 0, 1, 2, ...
+ \k<n+level> (n >= 1)
+ \k<n-level> (n >= 1)
+ \k'n+level' (n >= 1)
+ \k'n-level' (n >= 1)
+
+ \k<name+level>
+ \k<name-level>
+ \k'name+level'
+ \k'name-level'
Destinate relative nest level from back reference position.
@@ -256,7 +299,11 @@ syntax: ONIG_SYNTAX_RUBY (default)
9. Subexp call ("Tanaka Akira special")
\g<name> call by group name
+ \g'name' call by group name
\g<n> call by group number (n >= 1)
+ \g'n' call by group number (n >= 1)
+ \g<-n> call by relative group number (n >= 1)
+ \g'-n' call by relative group number (n >= 1)
* left-most recursive call is not allowed.
ex. (?<name>a|\g<name>b) => error
@@ -300,7 +347,6 @@ syntax: ONIG_SYNTAX_RUBY (default)
('g' and 'G' options are argued in ruby-dev ML)
- These options are not implemented in Ruby level.
-----------------------------
@@ -317,14 +363,13 @@ A-1. Syntax depend options
A-2. Original extensions
+ hexadecimal digit char type \h, \H
- + named group (?<name>...)
+ + named group (?<name>...), (?'name'...)
+ named backref \k<name>
+ subexp call \g<name>, \g<group-num>
A-3. Lacked features compare with perl 5.8.0
- + [:word:]
+ \N{name}
+ \l,\u,\L,\U, \X, \C
+ (?{code})
@@ -334,20 +379,10 @@ A-3. Lacked features compare with perl 5.8.0
* \Q...\E
This is effective on ONIG_SYNTAX_PERL and ONIG_SYNTAX_JAVA.
- * \p{property}, \P{property}
- This is effective on ONIG_SYNTAX_PERL and ONIG_SYNTAX_JAVA.
- Alnum, Alpha, Blank, Cntrl, Digit, Graph, Lower,
- Print, Punct, Space, Upper, XDigit, ASCII are supported.
-
- Prefix 'Is' of property name is allowed in ONIG_SYNTAX_PERL only.
- ex. \p{IsXDigit}.
-
- Negation operator of property is supported in ONIG_SYNTAX_PERL only.
- \p{^...}, \P{^...}
+A-4. Differences with Japanized GNU regex(version 0.12) of Ruby 1.8
-A-4. Differences with Japanized GNU regex(version 0.12) of Ruby
-
+ + add character property (\p{property}, \P{property})
+ add hexadecimal digit char type (\h, \H)
+ add look-behind
(?<=fixed-char-length-pattern), (?<!fixed-char-length-pattern)
@@ -401,7 +436,9 @@ A-5. Disabled functions by default syntax
A-6. Problems
- + Invalid encoding byte sequence is not checked in UTF-8.
+ + Invalid encoding byte sequence is not checked.
+
+ ex. UTF-8
* Invalid first byte is treated as a character.
/./u =~ "\xa3"
diff --git a/ext/mbstring/oniguruma/doc/RE.ja b/ext/mbstring/oniguruma/doc/RE.ja
index 51681715c4..abde849fe4 100644
--- a/ext/mbstring/oniguruma/doc/RE.ja
+++ b/ext/mbstring/oniguruma/doc/RE.ja
@@ -1,4 +1,4 @@
- ɽ Version 4.3.0 2006/08/17
+ ɽ Version 5.9.1 2007/09/05
ʸˡ: ONIG_SYNTAX_RUBY ()
@@ -70,6 +70,37 @@
\H 16ʿ
+ Character Property
+
+ * \p{property-name}
+ * \p{^property-name} (negative)
+ * \P{property-name} (negative)
+
+ property-name:
+
+ + ƤΥ󥳡ǥ󥰤ͭ
+ Alnum, Alpha, Blank, Cntrl, Digit, Graph, Lower,
+ Print, Punct, Space, Upper, XDigit, Word, ASCII,
+
+ + EUC-JP, Shift_JISͭ
+ Hiragana, Katakana
+
+ + UTF8, UTF16, UTF32ͭ
+ Any, Assigned, C, Cc, Cf, Cn, Co, Cs, L, Ll, Lm, Lo, Lt, Lu,
+ M, Mc, Me, Mn, N, Nd, Nl, No, P, Pc, Pd, Pe, Pf, Pi, Po, Ps,
+ S, Sc, Sk, Sm, So, Z, Zl, Zp, Zs,
+ Arabic, Armenian, Bengali, Bopomofo, Braille, Buginese,
+ Buhid, Canadian_Aboriginal, Cherokee, Common, Coptic,
+ Cypriot, Cyrillic, Deseret, Devanagari, Ethiopic, Georgian,
+ Glagolitic, Gothic, Greek, Gujarati, Gurmukhi, Han, Hangul,
+ Hanunoo, Hebrew, Hiragana, Inherited, Kannada, Katakana,
+ Kharoshthi, Khmer, Lao, Latin, Limbu, Linear_B, Malayalam,
+ Mongolian, Myanmar, New_Tai_Lue, Ogham, Old_Italic, Old_Persian,
+ Oriya, Osmanya, Runic, Shavian, Sinhala, Syloti_Nagri, Syriac,
+ Tagalog, Tagbanwa, Tai_Le, Tamil, Telugu, Thaana, Thai, Tibetan,
+ Tifinagh, Ugaritic, Yi
+
+
4. ̻
@@ -112,12 +143,7 @@
\A ʸƬ
\Z ʸޤʸβԤľ
\z ʸ
- \G ȹ糫ϰ(*)
-
- * Ruby Regexp:
- ȹ
- (λͤRubyμ˴ؤΤǤꡢ
- ɽ饤֥Ȥ̵ط)
+ \G ȹ糫ϰ
6. ʸ
@@ -137,39 +163,42 @@
Unicodeʳξ:
- alnum ѿ
- alpha ѻ
- ascii 0 - 127
- blank \t, \x20
- cntrl
- digit 0-9
- graph ¿Хʸޤ
- lower
- print ¿Хʸޤ
- punct
- space \t, \n, \v, \f, \r, \x20
- upper
- xdigit 0-9, a-f, A-F
+ alnum ѿ
+ alpha ѻ
+ ascii 0 - 127
+ blank \t, \x20
+ cntrl
+ digit 0-9
+ graph ¿Хʸޤ
+ lower
+ print ¿Хʸޤ
+ punct
+ space \t, \n, \v, \f, \r, \x20
+ upper
+ xdigit 0-9, a-f, A-F
+ word ѿ, "_" ¿Хʸ
Unicodeξ:
- alnum Letter | Mark | Decimal_Number
- alpha Letter | Mark
- ascii 0000 - 007F
- blank Space_Separator | 0009
- cntrl Control | Format | Unassigned | Private_Use | Surrogate
- digit Decimal_Number
- graph [[:^space:]] && ^Control && ^Unassigned && ^Surrogate
- lower Lowercase_Letter
- print [[:graph:]] | [[:space:]]
- punct Connector_Punctuation | Dash_Punctuation | Close_Punctuation |
- Final_Punctuation | Initial_Punctuation | Other_Punctuation |
- Open_Punctuation
- space Space_Separator | Line_Separator | Paragraph_Separator |
- 0009 | 000A | 000B | 000C | 000D | 0085
- upper Uppercase_Letter
- xdigit 0030 - 0039 | 0041 - 0046 | 0061 - 0066
- (0-9, a-f, A-F)
+ alnum Letter | Mark | Decimal_Number
+ alpha Letter | Mark
+ ascii 0000 - 007F
+ blank Space_Separator | 0009
+ cntrl Control | Format | Unassigned | Private_Use | Surrogate
+ digit Decimal_Number
+ graph [[:^space:]] && ^Control && ^Unassigned && ^Surrogate
+ lower Lowercase_Letter
+ print [[:graph:]] | [[:space:]]
+ punct Connector_Punctuation | Dash_Punctuation | Close_Punctuation |
+ Final_Punctuation | Initial_Punctuation | Other_Punctuation |
+ Open_Punctuation
+ space Space_Separator | Line_Separator | Paragraph_Separator |
+ 0009 | 000A | 000B | 000C | 000D | 0085
+ upper Uppercase_Letter
+ xdigit 0030 - 0039 | 0041 - 0046 | 0061 - 0066
+ (0-9, a-f, A-F)
+ word Letter | Mark | Decimal_Number | Connector_Punctuation
+
7. ĥ
@@ -199,10 +228,10 @@
(?>) Ū
Τ̲ᤷȤǤθƻԤԤʤʤ
- (?<name>) ̾դͼ
+ (?<name>), (?'name')
+ ̾դͼ
̾Ƥ()
- (̾ñ칽ʸǤʤФʤʤǽʸ
- ʸǤäƤϤʤ)
+ (̾ñ칽ʸǤʤФʤʤ)
̾ǤʤͼƱֹͤƤ롣
ֹ꤬ػߤƤʤ (10. ͼ 򻲾)
@@ -215,8 +244,13 @@
8.
- \n ֹ껲 (n >= 1)
+ \n ֹ껲 (n >= 1)
+ \k<n> ֹ껲 (n >= 1)
+ \k'n' ֹ껲 (n >= 1)
+ \k<-n> ֹ껲 (n >= 1)
+ \k'-n' ֹ껲 (n >= 1)
\k<name> ̾껲
+ \k'name' ̾껲
̾껲Ȥǡ̾ʣμ¿Ƥˤϡ
ֹ礭礫ͥŪ˻Ȥ롣
@@ -229,10 +263,17 @@
ͥȥ٥դ
- εǽϸߡRuby 1.9Ǥ̵ˤƤ롣
+ level: 0, 1, 2, ...
+
+ \k<n+level> (n >= 1)
+ \k<n-level> (n >= 1)
+ \k'n+level' (n >= 1)
+ \k'n-level' (n >= 1)
- \k<name+n> n: 0, 1, 2, ...
- \k<name-n> n: 0, 1, 2, ...
+ \k<name+level>
+ \k<name-level>
+ \k'name+level'
+ \k'name-level'
Ȥΰ֤ŪʬƽФͥȥ٥ꤷơΥ٥Ǥ
ͤ򻲾Ȥ롣
@@ -259,7 +300,11 @@
9. ʬƽФ ("ůڥ")
\g<name> ̾ƽФ
- \g<n> ֹƽФ (n >= 1)
+ \g'name' ̾ƽФ
+ \g<n> ֹƽФ (n >= 1)
+ \g'n' ֹƽФ (n >= 1)
+ \g<-n> ֹƽФ (n >= 1)
+ \g'-n' ֹƽФ (n >= 1)
Ǻ֤ǤκƵƽФ϶ػߤ롣
. (?<name>a|\g<name>b) => error
@@ -306,7 +351,6 @@
οΰ̣ϡ
̾դ̵ͤ̾ͤƱ˻ѤɬΤ̤ϾʤǤ
Ȥͳͤ줿ΤǤ롣
- ΥץˤĤƤϡRubyǤϸ߼Ƥʤ
-----------------------------
@@ -323,14 +367,13 @@
䵭 2. ȼĥǽ
+ 16ʿ16ʿ \h, \H
- + ̾դͼ (?<name>...)
+ + ̾դͼ (?<name>...), (?'name'...)
+ ̾ \k<name>
+ ʬƽФ \g<name>, \g<group-num>
䵭 3. Perl 5.8.0Ӥ¸ߤʤǽ
- + [:word:]
+ \N{name}
+ \l,\u,\L,\U, \X, \C
+ (?{code})
@@ -340,21 +383,10 @@
* \Q...\E
âONIG_SYNTAX_PERLONIG_SYNTAX_JAVAǤͭ
- * \p{property}, \P{property}
- âONIG_SYNTAX_PERLONIG_SYNTAX_JAVAǤͭ
- Alnum, Alpha, Blank, Cntrl, Digit, Graph, Lower,
- Print, Punct, Space, Upper, XDigit, ASCIIǤ롣
-
- ̾ 'Is'ֻѤ뤳ȤϡONIG_SYNTAX_PERLǤΤ
- Ƥ롣
- ex. \p{IsXDigit}.
- 黻ҤϡONIG_SYNTAX_PERLǤΤߵƤ롣
- \p{^...}, \P{^...}
-
-
-䵭 4. Rubyܸ첽 GNU regex(version 0.12)Ȥΰ㤤
+䵭 4. Ruby 1.8 ܸ첽 GNU regex(version 0.12)Ȥΰ㤤
+ + ʸPropertyǽɲ (\p{property}, \P{Property})
+ 16ʿɲ (\h, \H)
+ ɤߵǽɲ
+ ߤʷ֤Ҥɲ (?+, *+, ++)
@@ -411,14 +443,18 @@
䵭 6.
- + UTF-8ǡХͤŬʲɤΥåϹԤʤäƤʤ
+ + 󥳡ǥ󥰥ХͤŬʲɤΥåϹԤʤäƤʤ
+
+ : UTF-8
* ƬХȤȤʥХȤʸȤߤʤ
/./u =~ "\xa3"
* ԴʥХȥ󥹤Υå򤷤ʤ
- /\w+/ =~ "a\xf3\x8ec"
+ /\w+/u =~ "a\xf3\x8ec"
Ĵ٤뤳ȤϲǽǤϤ뤬٤ʤΤǹԤʤʤ
+ ʸȤơΤ褦ʥХꤷưݾڤʤ
+
diff --git a/ext/mbstring/oniguruma/enc/ascii.c b/ext/mbstring/oniguruma/enc/ascii.c
index 64be21d7ff..c2715f4e0d 100644
--- a/ext/mbstring/oniguruma/enc/ascii.c
+++ b/ext/mbstring/oniguruma/enc/ascii.c
@@ -2,7 +2,7 @@
ascii.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2004 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2006 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -43,23 +43,14 @@ OnigEncodingType OnigEncodingASCII = {
"US-ASCII", /* name */
1, /* max byte length */
1, /* min byte length */
- ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE,
- {
- (OnigCodePoint )'\\' /* esc */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
- },
onigenc_is_mbc_newline_0x0a,
onigenc_single_byte_mbc_to_code,
onigenc_single_byte_code_to_mbclen,
onigenc_single_byte_code_to_mbc,
- onigenc_ascii_mbc_to_normalize,
- onigenc_ascii_is_mbc_ambiguous,
- onigenc_ascii_get_all_pair_ambig_codes,
- onigenc_nothing_get_all_comp_ambig_codes,
+ onigenc_ascii_mbc_case_fold,
+ onigenc_ascii_apply_all_case_fold,
+ onigenc_ascii_get_case_fold_codes_by_str,
+ onigenc_minimum_property_name_to_ctype,
ascii_is_code_ctype,
onigenc_not_support_get_ctype_code_range,
onigenc_single_byte_left_adjust_char_head,
diff --git a/ext/mbstring/oniguruma/enc/big5.c b/ext/mbstring/oniguruma/enc/big5.c
index 86792666a4..ca1e01b463 100644
--- a/ext/mbstring/oniguruma/enc/big5.c
+++ b/ext/mbstring/oniguruma/enc/big5.c
@@ -2,7 +2,7 @@
big5.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2005 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2007 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -67,18 +67,21 @@ big5_code_to_mbc(OnigCodePoint code, UChar *buf)
}
static int
-big5_mbc_to_normalize(OnigAmbigType flag, const UChar** pp, const UChar* end,
- UChar* lower)
+big5_mbc_case_fold(OnigCaseFoldType flag, const UChar** pp, const UChar* end,
+ UChar* lower)
{
- return onigenc_mbn_mbc_to_normalize(ONIG_ENCODING_BIG5, flag,
- pp, end, lower);
+ return onigenc_mbn_mbc_case_fold(ONIG_ENCODING_BIG5, flag,
+ pp, end, lower);
}
+#if 0
static int
-big5_is_mbc_ambiguous(OnigAmbigType flag, const UChar** pp, const UChar* end)
+big5_is_mbc_ambiguous(OnigCaseFoldType flag,
+ const UChar** pp, const UChar* end)
{
return onigenc_mbn_is_mbc_ambiguous(ONIG_ENCODING_BIG5, flag, pp, end);
}
+#endif
static int
big5_is_code_ctype(OnigCodePoint code, unsigned int ctype)
@@ -125,14 +128,14 @@ big5_left_adjust_char_head(const UChar* start, const UChar* s)
}
}
}
- len = enc_len(ONIG_ENCODING_BIG5, p);
+ len = enclen(ONIG_ENCODING_BIG5, p);
if (p + len > s) return (UChar* )p;
p += len;
return (UChar* )(p + ((s - p) & ~1));
}
static int
-big5_is_allowed_reverse_match(const UChar* s, const UChar* end)
+big5_is_allowed_reverse_match(const UChar* s, const UChar* end ARG_UNUSED)
{
const UChar c = *s;
@@ -144,23 +147,14 @@ OnigEncodingType OnigEncodingBIG5 = {
"Big5", /* name */
2, /* max enc length */
1, /* min enc length */
- ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE,
- {
- (OnigCodePoint )'\\' /* esc */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
- },
onigenc_is_mbc_newline_0x0a,
big5_mbc_to_code,
onigenc_mb2_code_to_mbclen,
big5_code_to_mbc,
- big5_mbc_to_normalize,
- big5_is_mbc_ambiguous,
- onigenc_ascii_get_all_pair_ambig_codes,
- onigenc_nothing_get_all_comp_ambig_codes,
+ big5_mbc_case_fold,
+ onigenc_ascii_apply_all_case_fold,
+ onigenc_ascii_get_case_fold_codes_by_str,
+ onigenc_minimum_property_name_to_ctype,
big5_is_code_ctype,
onigenc_not_support_get_ctype_code_range,
big5_left_adjust_char_head,
diff --git a/ext/mbstring/oniguruma/enc/cp1251.c b/ext/mbstring/oniguruma/enc/cp1251.c
new file mode 100644
index 0000000000..63e58d2cd8
--- /dev/null
+++ b/ext/mbstring/oniguruma/enc/cp1251.c
@@ -0,0 +1,200 @@
+/**********************************************************************
+ cp1251.c - Oniguruma (regular expression library)
+**********************************************************************/
+/*-
+ * Copyright (c) 2006-2007 Byte <byte AT mail DOT kna DOT ru>
+ * K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ */
+
+#include "regenc.h"
+
+#define ENC_CP1251_TO_LOWER_CASE(c) EncCP1251_ToLowerCaseTable[c]
+#define ENC_IS_CP1251_CTYPE(code,ctype) \
+ ((EncCP1251_CtypeTable[code] & CTYPE_TO_BIT(ctype)) != 0)
+
+static const UChar EncCP1251_ToLowerCaseTable[256] = {
+ '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
+ '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
+ '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
+ '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
+ '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
+ '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
+ '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
+ '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
+ '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+ '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
+ '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
+ '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
+ '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
+ '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
+ '\220', '\203', '\202', '\203', '\204', '\205', '\206', '\207',
+ '\210', '\211', '\232', '\213', '\234', '\235', '\236', '\237',
+ '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
+ '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
+ '\240', '\242', '\242', '\274', '\244', '\264', '\246', '\247',
+ '\270', '\251', '\272', '\253', '\254', '\255', '\256', '\277',
+ '\260', '\261', '\263', '\263', '\264', '\265', '\266', '\267',
+ '\270', '\271', '\272', '\273', '\274', '\276', '\276', '\277',
+ '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
+ '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
+ '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
+ '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
+ '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
+ '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
+ '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
+ '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377'
+};
+
+static const unsigned short EncCP1251_CtypeTable[256] = {
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x428c, 0x4209, 0x4208, 0x4208, 0x4208, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4284, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0,
+ 0x78b0, 0x78b0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x51a0,
+ 0x41a0, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x4008,
+ 0x34a2, 0x34a2, 0x01a0, 0x30e2, 0x01a0, 0x01a0, 0x01a0, 0x01a0,
+ 0x0000, 0x01a0, 0x34a2, 0x01a0, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x30e2, 0x01a0, 0x01a0, 0x01a0, 0x01a0, 0x01a0, 0x01a0, 0x01a0,
+ 0x0008, 0x0000, 0x30e2, 0x01a0, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x0280, 0x34a2, 0x30e2, 0x34a2, 0x01a0, 0x34a2, 0x01a0, 0x01a0,
+ 0x34a2, 0x01a0, 0x34a2, 0x01a0, 0x01a0, 0x01a0, 0x01a0, 0x34a2,
+ 0x01a0, 0x01a0, 0x34a2, 0x30e2, 0x30e2, 0x31e2, 0x01a0, 0x01a0,
+ 0x30e2, 0x0000, 0x30e2, 0x01a0, 0x30e2, 0x34a2, 0x30e2, 0x30e2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2
+};
+
+static int
+cp1251_mbc_case_fold(OnigCaseFoldType flag ARG_UNUSED,
+ const UChar** pp, const UChar* end ARG_UNUSED, UChar* lower)
+{
+ const UChar* p = *pp;
+
+ *lower = ENC_CP1251_TO_LOWER_CASE(*p);
+ (*pp)++;
+ return 1;
+}
+
+static int
+cp1251_is_code_ctype(OnigCodePoint code, unsigned int ctype)
+{
+ if (code < 256)
+ return ENC_IS_CP1251_CTYPE(code, ctype);
+ else
+ return FALSE;
+}
+
+static const OnigPairCaseFoldCodes CaseFoldMap[] = {
+ { 0xb8, 0xa8 },
+
+ { 0xe0, 0xc0 },
+ { 0xe1, 0xc1 },
+ { 0xe2, 0xc2 },
+ { 0xe3, 0xc3 },
+ { 0xe4, 0xc4 },
+ { 0xe5, 0xc5 },
+ { 0xe6, 0xc6 },
+ { 0xe7, 0xc7 },
+ { 0xe8, 0xc8 },
+ { 0xe9, 0xc9 },
+ { 0xea, 0xca },
+ { 0xeb, 0xcb },
+ { 0xec, 0xcc },
+ { 0xed, 0xcd },
+ { 0xee, 0xce },
+ { 0xef, 0xcf },
+
+ { 0xf0, 0xd0 },
+ { 0xf1, 0xd1 },
+ { 0xf2, 0xd2 },
+ { 0xf3, 0xd3 },
+ { 0xf4, 0xd4 },
+ { 0xf5, 0xd5 },
+ { 0xf6, 0xd6 },
+ { 0xf7, 0xd7 },
+ { 0xf8, 0xd8 },
+ { 0xf9, 0xd9 },
+ { 0xfa, 0xda },
+ { 0xfb, 0xdb },
+ { 0xfc, 0xdc },
+ { 0xfd, 0xdd },
+ { 0xfe, 0xde },
+ { 0xff, 0xdf }
+};
+
+static int
+cp1251_apply_all_case_fold(OnigCaseFoldType flag,
+ OnigApplyAllCaseFoldFunc f, void* arg)
+{
+ return onigenc_apply_all_case_fold_with_map(
+ sizeof(CaseFoldMap)/sizeof(OnigPairCaseFoldCodes), CaseFoldMap, 0,
+ flag, f, arg);
+}
+
+static int
+cp1251_get_case_fold_codes_by_str(OnigCaseFoldType flag,
+ const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[])
+{
+ return onigenc_get_case_fold_codes_by_str_with_map(
+ sizeof(CaseFoldMap)/sizeof(OnigPairCaseFoldCodes), CaseFoldMap, 0,
+ flag, p, end, items);
+}
+
+OnigEncodingType OnigEncodingCP1251 = {
+ onigenc_single_byte_mbc_enc_len,
+ "CP1251", /* name */
+ 1, /* max enc length */
+ 1, /* min enc length */
+ onigenc_is_mbc_newline_0x0a,
+ onigenc_single_byte_mbc_to_code,
+ onigenc_single_byte_code_to_mbclen,
+ onigenc_single_byte_code_to_mbc,
+ cp1251_mbc_case_fold,
+ cp1251_apply_all_case_fold,
+ cp1251_get_case_fold_codes_by_str,
+ onigenc_minimum_property_name_to_ctype,
+ cp1251_is_code_ctype,
+ onigenc_not_support_get_ctype_code_range,
+ onigenc_single_byte_left_adjust_char_head,
+ onigenc_always_true_is_allowed_reverse_match
+};
diff --git a/ext/mbstring/oniguruma/enc/euc_jp.c b/ext/mbstring/oniguruma/enc/euc_jp.c
index 71c81ee9fe..f605297cc3 100644
--- a/ext/mbstring/oniguruma/enc/euc_jp.c
+++ b/ext/mbstring/oniguruma/enc/euc_jp.c
@@ -2,7 +2,7 @@
euc_jp.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2005 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2008 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
* SUCH DAMAGE.
*/
-#include "regenc.h"
+#include "regint.h"
#define eucjp_islead(c) ((UChar )((c) - 0xa1) > 0xfe - 0xa1)
@@ -51,18 +51,18 @@ static const int EncLen_EUCJP[] = {
};
static int
-eucjp_mbc_enc_len(const UChar* p)
+mbc_enc_len(const UChar* p)
{
return EncLen_EUCJP[*p];
}
static OnigCodePoint
-eucjp_mbc_to_code(const UChar* p, const UChar* end)
+mbc_to_code(const UChar* p, const UChar* end)
{
int c, i, len;
OnigCodePoint n;
- len = enc_len(ONIG_ENCODING_EUC_JP, p);
+ len = enclen(ONIG_ENCODING_EUC_JP, p);
n = (OnigCodePoint )*p++;
if (len == 1) return n;
@@ -75,17 +75,18 @@ eucjp_mbc_to_code(const UChar* p, const UChar* end)
}
static int
-eucjp_code_to_mbclen(OnigCodePoint code)
+code_to_mbclen(OnigCodePoint code)
{
if (ONIGENC_IS_CODE_ASCII(code)) return 1;
else if ((code & 0xff0000) != 0) return 3;
else if ((code & 0xff00) != 0) return 2;
- else return 0;
+ else
+ return ONIGERR_INVALID_CODE_POINT_VALUE;
}
#if 0
static int
-eucjp_code_to_mbc_first(OnigCodePoint code)
+code_to_mbc_first(OnigCodePoint code)
{
int first;
@@ -103,7 +104,7 @@ eucjp_code_to_mbc_first(OnigCodePoint code)
#endif
static int
-eucjp_code_to_mbc(OnigCodePoint code, UChar *buf)
+code_to_mbc(OnigCodePoint code, UChar *buf)
{
UChar *p = buf;
@@ -112,66 +113,38 @@ eucjp_code_to_mbc(OnigCodePoint code, UChar *buf)
*p++ = (UChar )(code & 0xff);
#if 1
- if (enc_len(ONIG_ENCODING_EUC_JP, buf) != (p - buf))
- return ONIGENCERR_INVALID_WIDE_CHAR_VALUE;
+ if (enclen(ONIG_ENCODING_EUC_JP, buf) != (p - buf))
+ return ONIGERR_INVALID_CODE_POINT_VALUE;
#endif
return p - buf;
}
static int
-eucjp_mbc_to_normalize(OnigAmbigType flag,
- const UChar** pp, const UChar* end, UChar* lower)
+mbc_case_fold(OnigCaseFoldType flag ARG_UNUSED,
+ const UChar** pp, const UChar* end ARG_UNUSED, UChar* lower)
{
int len;
const UChar* p = *pp;
if (ONIGENC_IS_MBC_ASCII(p)) {
- if ((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0) {
- *lower = ONIGENC_ASCII_CODE_TO_LOWER_CASE(*p);
- }
- else {
- *lower = *p;
- }
-
+ *lower = ONIGENC_ASCII_CODE_TO_LOWER_CASE(*p);
(*pp)++;
return 1;
}
else {
- len = enc_len(ONIG_ENCODING_EUC_JP, p);
- if (lower != p) {
- int i;
- for (i = 0; i < len; i++) {
- *lower++ = *p++;
- }
+ int i;
+
+ len = enclen(ONIG_ENCODING_EUC_JP, p);
+ for (i = 0; i < len; i++) {
+ *lower++ = *p++;
}
(*pp) += len;
return len; /* return byte length of converted char to lower */
}
}
-static int
-eucjp_is_mbc_ambiguous(OnigAmbigType flag, const UChar** pp, const UChar* end)
-{
- return onigenc_mbn_is_mbc_ambiguous(ONIG_ENCODING_EUC_JP, flag, pp, end);
-}
-
-static int
-eucjp_is_code_ctype(OnigCodePoint code, unsigned int ctype)
-{
- if (code < 128)
- return ONIGENC_IS_ASCII_CODE_CTYPE(code, ctype);
- else {
- if ((ctype & (ONIGENC_CTYPE_WORD |
- ONIGENC_CTYPE_GRAPH | ONIGENC_CTYPE_PRINT)) != 0) {
- return (eucjp_code_to_mbclen(code) > 1 ? TRUE : FALSE);
- }
- }
-
- return FALSE;
-}
-
static UChar*
-eucjp_left_adjust_char_head(const UChar* start, const UChar* s)
+left_adjust_char_head(const UChar* start, const UChar* s)
{
/* In this encoding
mb-trail bytes doesn't mix with single bytes.
@@ -183,14 +156,14 @@ eucjp_left_adjust_char_head(const UChar* start, const UChar* s)
p = s;
while (!eucjp_islead(*p) && p > start) p--;
- len = enc_len(ONIG_ENCODING_EUC_JP, p);
+ len = enclen(ONIG_ENCODING_EUC_JP, p);
if (p + len > s) return (UChar* )p;
p += len;
return (UChar* )(p + ((s - p) & ~1));
}
static int
-eucjp_is_allowed_reverse_match(const UChar* s, const UChar* end)
+is_allowed_reverse_match(const UChar* s, const UChar* end ARG_UNUSED)
{
const UChar c = *s;
if (c <= 0x7e || c == 0x8e || c == 0x8f)
@@ -199,30 +172,114 @@ eucjp_is_allowed_reverse_match(const UChar* s, const UChar* end)
return FALSE;
}
+
+static int PropertyInited = 0;
+static const OnigCodePoint** PropertyList;
+static int PropertyListNum;
+static int PropertyListSize;
+static hash_table_type* PropertyNameTable;
+
+static const OnigCodePoint CR_Hiragana[] = {
+ 1,
+ 0xa4a1, 0xa4f3
+}; /* CR_Hiragana */
+
+static const OnigCodePoint CR_Katakana[] = {
+ 3,
+ 0xa5a1, 0xa5f6,
+ 0xaaa6, 0xaaaf,
+ 0xaab1, 0xaadd
+}; /* CR_Katakana */
+
+static int
+init_property_list(void)
+{
+ int r;
+
+ PROPERTY_LIST_ADD_PROP("Hiragana", CR_Hiragana);
+ PROPERTY_LIST_ADD_PROP("Katakana", CR_Katakana);
+ PropertyInited = 1;
+
+ end:
+ return r;
+}
+
+static int
+property_name_to_ctype(OnigEncoding enc, UChar* p, UChar* end)
+{
+ hash_data_type ctype;
+
+ PROPERTY_LIST_INIT_CHECK;
+
+ if (onig_st_lookup_strend(PropertyNameTable, p, end, &ctype) == 0) {
+ return onigenc_minimum_property_name_to_ctype(enc, p, end);
+ }
+
+ return (int )ctype;
+}
+
+static int
+is_code_ctype(OnigCodePoint code, unsigned int ctype)
+{
+ if (ctype <= ONIGENC_MAX_STD_CTYPE) {
+ if (code < 128)
+ return ONIGENC_IS_ASCII_CODE_CTYPE(code, ctype);
+ else {
+ if (CTYPE_IS_WORD_GRAPH_PRINT(ctype)) {
+ return (code_to_mbclen(code) > 1 ? TRUE : FALSE);
+ }
+ }
+ }
+ else {
+ PROPERTY_LIST_INIT_CHECK;
+
+ ctype -= (ONIGENC_MAX_STD_CTYPE + 1);
+ if (ctype >= (unsigned int )PropertyListNum)
+ return ONIGERR_TYPE_BUG;
+
+ return onig_is_in_code_range((UChar* )PropertyList[ctype], code);
+ }
+
+ return FALSE;
+}
+
+static int
+get_ctype_code_range(OnigCtype ctype, OnigCodePoint* sb_out,
+ const OnigCodePoint* ranges[])
+{
+ if (ctype <= ONIGENC_MAX_STD_CTYPE) {
+ return ONIG_NO_SUPPORT_CONFIG;
+ }
+ else {
+ *sb_out = 0x80;
+
+ PROPERTY_LIST_INIT_CHECK;
+
+ ctype -= (ONIGENC_MAX_STD_CTYPE + 1);
+ if (ctype >= (OnigCtype )PropertyListNum)
+ return ONIGERR_TYPE_BUG;
+
+ *ranges = PropertyList[ctype];
+ return 0;
+ }
+}
+
+
OnigEncodingType OnigEncodingEUC_JP = {
- eucjp_mbc_enc_len,
+ mbc_enc_len,
"EUC-JP", /* name */
3, /* max enc length */
1, /* min enc length */
- ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE,
- {
- (OnigCodePoint )'\\' /* esc */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
- },
onigenc_is_mbc_newline_0x0a,
- eucjp_mbc_to_code,
- eucjp_code_to_mbclen,
- eucjp_code_to_mbc,
- eucjp_mbc_to_normalize,
- eucjp_is_mbc_ambiguous,
- onigenc_ascii_get_all_pair_ambig_codes,
- onigenc_nothing_get_all_comp_ambig_codes,
- eucjp_is_code_ctype,
- onigenc_not_support_get_ctype_code_range,
- eucjp_left_adjust_char_head,
- eucjp_is_allowed_reverse_match
+ mbc_to_code,
+ code_to_mbclen,
+ code_to_mbc,
+ mbc_case_fold,
+ onigenc_ascii_apply_all_case_fold,
+ onigenc_ascii_get_case_fold_codes_by_str,
+ property_name_to_ctype,
+ is_code_ctype,
+ get_ctype_code_range,
+ left_adjust_char_head,
+ is_allowed_reverse_match
};
diff --git a/ext/mbstring/oniguruma/enc/euc_kr.c b/ext/mbstring/oniguruma/enc/euc_kr.c
index 57bf801536..1beef09001 100644
--- a/ext/mbstring/oniguruma/enc/euc_kr.c
+++ b/ext/mbstring/oniguruma/enc/euc_kr.c
@@ -2,7 +2,7 @@
euc_kr.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2005 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2007 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -67,18 +67,21 @@ euckr_code_to_mbc(OnigCodePoint code, UChar *buf)
}
static int
-euckr_mbc_to_normalize(OnigAmbigType flag, const UChar** pp, const UChar* end,
- UChar* lower)
+euckr_mbc_case_fold(OnigCaseFoldType flag, const UChar** pp, const UChar* end,
+ UChar* lower)
{
- return onigenc_mbn_mbc_to_normalize(ONIG_ENCODING_EUC_KR, flag,
- pp, end, lower);
+ return onigenc_mbn_mbc_case_fold(ONIG_ENCODING_EUC_KR, flag,
+ pp, end, lower);
}
+#if 0
static int
-euckr_is_mbc_ambiguous(OnigAmbigType flag, const UChar** pp, const UChar* end)
+euckr_is_mbc_ambiguous(OnigCaseFoldType flag,
+ const UChar** pp, const UChar* end)
{
return onigenc_mbn_is_mbc_ambiguous(ONIG_ENCODING_EUC_KR, flag, pp, end);
}
+#endif
static int
euckr_is_code_ctype(OnigCodePoint code, unsigned int ctype)
@@ -101,14 +104,14 @@ euckr_left_adjust_char_head(const UChar* start, const UChar* s)
p = s;
while (!euckr_islead(*p) && p > start) p--;
- len = enc_len(ONIG_ENCODING_EUC_KR, p);
+ len = enclen(ONIG_ENCODING_EUC_KR, p);
if (p + len > s) return (UChar* )p;
p += len;
return (UChar* )(p + ((s - p) & ~1));
}
static int
-euckr_is_allowed_reverse_match(const UChar* s, const UChar* end)
+euckr_is_allowed_reverse_match(const UChar* s, const UChar* end ARG_UNUSED)
{
const UChar c = *s;
if (c <= 0x7e) return TRUE;
@@ -120,23 +123,14 @@ OnigEncodingType OnigEncodingEUC_KR = {
"EUC-KR", /* name */
2, /* max enc length */
1, /* min enc length */
- ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE,
- {
- (OnigCodePoint )'\\' /* esc */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
- },
onigenc_is_mbc_newline_0x0a,
euckr_mbc_to_code,
onigenc_mb2_code_to_mbclen,
euckr_code_to_mbc,
- euckr_mbc_to_normalize,
- euckr_is_mbc_ambiguous,
- onigenc_ascii_get_all_pair_ambig_codes,
- onigenc_nothing_get_all_comp_ambig_codes,
+ euckr_mbc_case_fold,
+ onigenc_ascii_apply_all_case_fold,
+ onigenc_ascii_get_case_fold_codes_by_str,
+ onigenc_minimum_property_name_to_ctype,
euckr_is_code_ctype,
onigenc_not_support_get_ctype_code_range,
euckr_left_adjust_char_head,
@@ -149,23 +143,14 @@ OnigEncodingType OnigEncodingEUC_CN = {
"EUC-CN", /* name */
2, /* max enc length */
1, /* min enc length */
- ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE,
- {
- (OnigCodePoint )'\\' /* esc */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
- },
onigenc_is_mbc_newline_0x0a,
euckr_mbc_to_code,
onigenc_mb2_code_to_mbclen,
euckr_code_to_mbc,
- euckr_mbc_to_normalize,
- euckr_is_mbc_ambiguous,
- onigenc_ascii_get_all_pair_ambig_codes,
- onigenc_nothing_get_all_comp_ambig_codes,
+ euckr_mbc_case_fold,
+ onigenc_ascii_apply_all_case_fold,
+ onigenc_ascii_get_case_fold_codes_by_str,
+ onigenc_minimum_property_name_to_ctype,
euckr_is_code_ctype,
onigenc_not_support_get_ctype_code_range,
euckr_left_adjust_char_head,
diff --git a/ext/mbstring/oniguruma/enc/euc_tw.c b/ext/mbstring/oniguruma/enc/euc_tw.c
index 6f396e75e6..2ddeb9318a 100644
--- a/ext/mbstring/oniguruma/enc/euc_tw.c
+++ b/ext/mbstring/oniguruma/enc/euc_tw.c
@@ -2,7 +2,7 @@
euc_tw.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2005 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2008 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -67,17 +67,11 @@ euctw_code_to_mbc(OnigCodePoint code, UChar *buf)
}
static int
-euctw_mbc_to_normalize(OnigAmbigType flag, const UChar** pp, const UChar* end,
- UChar* lower)
+euctw_mbc_case_fold(OnigCaseFoldType flag, const UChar** pp, const UChar* end,
+ UChar* lower)
{
- return onigenc_mbn_mbc_to_normalize(ONIG_ENCODING_EUC_TW, flag,
- pp, end, lower);
-}
-
-static int
-euctw_is_mbc_ambiguous(OnigAmbigType flag, const UChar** pp, const UChar* end)
-{
- return onigenc_mbn_is_mbc_ambiguous(ONIG_ENCODING_EUC_TW, flag, pp, end);
+ return onigenc_mbn_mbc_case_fold(ONIG_ENCODING_EUC_TW, flag,
+ pp, end, lower);
}
static int
@@ -86,7 +80,7 @@ euctw_is_code_ctype(OnigCodePoint code, unsigned int ctype)
return onigenc_mb4_is_code_ctype(ONIG_ENCODING_EUC_TW, code, ctype);
}
-#define euctw_islead(c) (((c) < 0xa1 && (c) != 0x8e) || (c) == 0xff)
+#define euctw_islead(c) ((UChar )((c) - 0xa1) > 0xfe - 0xa1)
static UChar*
euctw_left_adjust_char_head(const UChar* start, const UChar* s)
@@ -101,14 +95,14 @@ euctw_left_adjust_char_head(const UChar* start, const UChar* s)
p = s;
while (!euctw_islead(*p) && p > start) p--;
- len = enc_len(ONIG_ENCODING_EUC_TW, p);
+ len = enclen(ONIG_ENCODING_EUC_TW, p);
if (p + len > s) return (UChar* )p;
p += len;
return (UChar* )(p + ((s - p) & ~1));
}
static int
-euctw_is_allowed_reverse_match(const UChar* s, const UChar* end)
+euctw_is_allowed_reverse_match(const UChar* s, const UChar* end ARG_UNUSED)
{
const UChar c = *s;
if (c <= 0x7e) return TRUE;
@@ -120,23 +114,14 @@ OnigEncodingType OnigEncodingEUC_TW = {
"EUC-TW", /* name */
4, /* max enc length */
1, /* min enc length */
- ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE,
- {
- (OnigCodePoint )'\\' /* esc */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
- },
onigenc_is_mbc_newline_0x0a,
euctw_mbc_to_code,
onigenc_mb4_code_to_mbclen,
euctw_code_to_mbc,
- euctw_mbc_to_normalize,
- euctw_is_mbc_ambiguous,
- onigenc_ascii_get_all_pair_ambig_codes,
- onigenc_nothing_get_all_comp_ambig_codes,
+ euctw_mbc_case_fold,
+ onigenc_ascii_apply_all_case_fold,
+ onigenc_ascii_get_case_fold_codes_by_str,
+ onigenc_minimum_property_name_to_ctype,
euctw_is_code_ctype,
onigenc_not_support_get_ctype_code_range,
euctw_left_adjust_char_head,
diff --git a/ext/mbstring/oniguruma/enc/gb18030.c b/ext/mbstring/oniguruma/enc/gb18030.c
index 01995ea094..6bbd109eab 100644
--- a/ext/mbstring/oniguruma/enc/gb18030.c
+++ b/ext/mbstring/oniguruma/enc/gb18030.c
@@ -2,8 +2,8 @@
gb18030.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2005 KUBO Takehiro <kubo AT jiubao DOT org>
- * K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2005-2007 KUBO Takehiro <kubo AT jiubao DOT org>
+ * K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -88,18 +88,21 @@ gb18030_code_to_mbc(OnigCodePoint code, UChar *buf)
}
static int
-gb18030_mbc_to_normalize(OnigAmbigType flag, const UChar** pp, const UChar* end,
- UChar* lower)
+gb18030_mbc_case_fold(OnigCaseFoldType flag, const UChar** pp, const UChar* end,
+ UChar* lower)
{
- return onigenc_mbn_mbc_to_normalize(ONIG_ENCODING_GB18030, flag,
- pp, end, lower);
+ return onigenc_mbn_mbc_case_fold(ONIG_ENCODING_GB18030, flag,
+ pp, end, lower);
}
+#if 0
static int
-gb18030_is_mbc_ambiguous(OnigAmbigType flag, const UChar** pp, const UChar* end)
+gb18030_is_mbc_ambiguous(OnigCaseFoldType flag,
+ const UChar** pp, const UChar* end)
{
return onigenc_mbn_is_mbc_ambiguous(ONIG_ENCODING_GB18030, flag, pp, end);
}
+#endif
static int
gb18030_is_code_ctype(OnigCodePoint code, unsigned int ctype)
@@ -467,7 +470,7 @@ gb18030_left_adjust_char_head(const UChar* start, const UChar* s)
}
static int
-gb18030_is_allowed_reverse_match(const UChar* s, const UChar* end)
+gb18030_is_allowed_reverse_match(const UChar* s, const UChar* end ARG_UNUSED)
{
return GB18030_MAP[*s] == C1 ? TRUE : FALSE;
}
@@ -477,23 +480,14 @@ OnigEncodingType OnigEncodingGB18030 = {
"GB18030", /* name */
4, /* max enc length */
1, /* min enc length */
- ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE,
- {
- (OnigCodePoint )'\\' /* esc */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
- },
onigenc_is_mbc_newline_0x0a,
gb18030_mbc_to_code,
onigenc_mb4_code_to_mbclen,
gb18030_code_to_mbc,
- gb18030_mbc_to_normalize,
- gb18030_is_mbc_ambiguous,
- onigenc_ascii_get_all_pair_ambig_codes,
- onigenc_nothing_get_all_comp_ambig_codes,
+ gb18030_mbc_case_fold,
+ onigenc_ascii_apply_all_case_fold,
+ onigenc_ascii_get_case_fold_codes_by_str,
+ onigenc_minimum_property_name_to_ctype,
gb18030_is_code_ctype,
onigenc_not_support_get_ctype_code_range,
gb18030_left_adjust_char_head,
diff --git a/ext/mbstring/oniguruma/enc/iso8859_1.c b/ext/mbstring/oniguruma/enc/iso8859_1.c
index 5646f26c10..174b97f026 100644
--- a/ext/mbstring/oniguruma/enc/iso8859_1.c
+++ b/ext/mbstring/oniguruma/enc/iso8859_1.c
@@ -2,7 +2,7 @@
iso8859_1.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2006 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2007 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,90 +30,221 @@
#include "regenc.h"
#define ENC_IS_ISO_8859_1_CTYPE(code,ctype) \
- ((EncISO_8859_1_CtypeTable[code] & ctype) != 0)
+ ((EncISO_8859_1_CtypeTable[code] & CTYPE_TO_BIT(ctype)) != 0)
static const unsigned short EncISO_8859_1_CtypeTable[256] = {
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x220c, 0x2209, 0x2208, 0x2208, 0x2208, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2284, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0,
- 0x38b0, 0x38b0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x31a0,
- 0x21a0, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x2008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x420c, 0x4209, 0x4208, 0x4208, 0x4208, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4284, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0,
+ 0x78b0, 0x78b0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x51a0,
+ 0x41a0, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x4008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0284, 0x01a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0,
- 0x00a0, 0x00a0, 0x10e2, 0x01a0, 0x00a0, 0x01a0, 0x00a0, 0x00a0,
- 0x00a0, 0x00a0, 0x10a0, 0x10a0, 0x00a0, 0x10e2, 0x00a0, 0x01a0,
- 0x00a0, 0x10a0, 0x10e2, 0x01a0, 0x10a0, 0x10a0, 0x10a0, 0x01a0,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x00a0,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x00a0,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2
+ 0x00a0, 0x00a0, 0x30e2, 0x01a0, 0x00a0, 0x01a0, 0x00a0, 0x00a0,
+ 0x00a0, 0x00a0, 0x10a0, 0x10a0, 0x00a0, 0x30e2, 0x00a0, 0x01a0,
+ 0x00a0, 0x10a0, 0x30e2, 0x01a0, 0x10a0, 0x10a0, 0x10a0, 0x01a0,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x00a0,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x00a0,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2
+};
+
+static const OnigPairCaseFoldCodes CaseFoldMap[] = {
+ { 0xc0, 0xe0 },
+ { 0xc1, 0xe1 },
+ { 0xc2, 0xe2 },
+ { 0xc3, 0xe3 },
+ { 0xc4, 0xe4 },
+ { 0xc5, 0xe5 },
+ { 0xc6, 0xe6 },
+ { 0xc7, 0xe7 },
+ { 0xc8, 0xe8 },
+ { 0xc9, 0xe9 },
+ { 0xca, 0xea },
+ { 0xcb, 0xeb },
+ { 0xcc, 0xec },
+ { 0xcd, 0xed },
+ { 0xce, 0xee },
+ { 0xcf, 0xef },
+
+ { 0xd0, 0xf0 },
+ { 0xd1, 0xf1 },
+ { 0xd2, 0xf2 },
+ { 0xd3, 0xf3 },
+ { 0xd4, 0xf4 },
+ { 0xd5, 0xf5 },
+ { 0xd6, 0xf6 },
+ { 0xd8, 0xf8 },
+ { 0xd9, 0xf9 },
+ { 0xda, 0xfa },
+ { 0xdb, 0xfb },
+ { 0xdc, 0xfc },
+ { 0xdd, 0xfd },
+ { 0xde, 0xfe }
};
static int
-iso_8859_1_mbc_to_normalize(OnigAmbigType flag, const UChar** pp, const UChar* end, UChar* lower)
+apply_all_case_fold(OnigCaseFoldType flag,
+ OnigApplyAllCaseFoldFunc f, void* arg)
{
- const UChar* p = *pp;
+ return onigenc_apply_all_case_fold_with_map(
+ sizeof(CaseFoldMap)/sizeof(OnigPairCaseFoldCodes), CaseFoldMap, 1,
+ flag, f, arg);
+}
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- *lower = ONIGENC_ISO_8859_1_TO_LOWER_CASE(*p);
+static int
+get_case_fold_codes_by_str(OnigCaseFoldType flag ARG_UNUSED,
+ const OnigUChar* p, const OnigUChar* end,
+ OnigCaseFoldCodeItem items[])
+{
+ if (0x41 <= *p && *p <= 0x5a) {
+ items[0].byte_len = 1;
+ items[0].code_len = 1;
+ items[0].code[0] = (OnigCodePoint )(*p + 0x20);
+ if (*p == 0x53 && end > p + 1
+ && (*(p+1) == 0x53 || *(p+1) == 0x73)) { /* SS */
+ items[1].byte_len = 2;
+ items[1].code_len = 1;
+ items[1].code[0] = (OnigCodePoint )0xdf;
+ return 2;
+ }
+ else
+ return 1;
}
- else {
- *lower = *p;
+ else if (0x61 <= *p && *p <= 0x7a) {
+ items[0].byte_len = 1;
+ items[0].code_len = 1;
+ items[0].code[0] = (OnigCodePoint )(*p - 0x20);
+ if (*p == 0x73 && end > p + 1
+ && (*(p+1) == 0x73 || *(p+1) == 0x53)) { /* ss */
+ items[1].byte_len = 2;
+ items[1].code_len = 1;
+ items[1].code[0] = (OnigCodePoint )0xdf;
+ return 2;
+ }
+ else
+ return 1;
}
- (*pp)++;
- return 1; /* return byte length of converted char to lower */
+ else if (0xc0 <= *p && *p <= 0xcf) {
+ items[0].byte_len = 1;
+ items[0].code_len = 1;
+ items[0].code[0] = (OnigCodePoint )(*p + 0x20);
+ return 1;
+ }
+ else if (0xd0 <= *p && *p <= 0xdf) {
+ if (*p == 0xdf) {
+ items[0].byte_len = 1;
+ items[0].code_len = 2;
+ items[0].code[0] = (OnigCodePoint )'s';
+ items[0].code[1] = (OnigCodePoint )'s';
+
+ items[1].byte_len = 1;
+ items[1].code_len = 2;
+ items[1].code[0] = (OnigCodePoint )'S';
+ items[1].code[1] = (OnigCodePoint )'S';
+
+ items[2].byte_len = 1;
+ items[2].code_len = 2;
+ items[2].code[0] = (OnigCodePoint )'s';
+ items[2].code[1] = (OnigCodePoint )'S';
+
+ items[3].byte_len = 1;
+ items[3].code_len = 2;
+ items[3].code[0] = (OnigCodePoint )'S';
+ items[3].code[1] = (OnigCodePoint )'s';
+
+ return 4;
+ }
+ else if (*p != 0xd7) {
+ items[0].byte_len = 1;
+ items[0].code_len = 1;
+ items[0].code[0] = (OnigCodePoint )(*p + 0x20);
+ return 1;
+ }
+ }
+ else if (0xe0 <= *p && *p <= 0xef) {
+ items[0].byte_len = 1;
+ items[0].code_len = 1;
+ items[0].code[0] = (OnigCodePoint )(*p - 0x20);
+ return 1;
+ }
+ else if (0xf0 <= *p && *p <= 0xfe) {
+ if (*p != 0xf7) {
+ items[0].byte_len = 1;
+ items[0].code_len = 1;
+ items[0].code[0] = (OnigCodePoint )(*p - 0x20);
+ return 1;
+ }
+ }
+
+ return 0;
}
static int
-iso_8859_1_is_mbc_ambiguous(OnigAmbigType flag,
- const UChar** pp, const UChar* end)
+mbc_case_fold(OnigCaseFoldType flag, const UChar** pp,
+ const UChar* end ARG_UNUSED, UChar* lower)
{
const UChar* p = *pp;
+ if (*p == 0xdf && (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
+ *lower++ = 's';
+ *lower = 's';
+ (*pp)++;
+ return 2;
+ }
+
+ *lower = ONIGENC_ISO_8859_1_TO_LOWER_CASE(*p);
(*pp)++;
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- int v = (EncISO_8859_1_CtypeTable[*p] &
- (ONIGENC_CTYPE_UPPER | ONIGENC_CTYPE_LOWER));
-
- if ((v | ONIGENC_CTYPE_LOWER) != 0) {
- /* 0xdf, 0xaa, 0xb5, 0xba are lower case letter, but can't convert. */
- if (*p == 0xdf || (*p >= 0xaa && *p <= 0xba))
- return FALSE;
- else
- return TRUE;
- }
+ return 1;
+}
+
+#if 0
+static int
+is_mbc_ambiguous(OnigCaseFoldType flag,
+ const UChar** pp, const UChar* end)
+{
+ int v;
+ const UChar* p = *pp;
- return (v != 0 ? TRUE : FALSE);
+ if (*p == 0xdf && (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
+ (*pp)++;
+ return TRUE;
}
- return FALSE;
+
+ (*pp)++;
+ v = (EncISO_8859_1_CtypeTable[*p] & (BIT_CTYPE_UPPER | BIT_CTYPE_LOWER));
+ if ((v | BIT_CTYPE_LOWER) != 0) {
+ /* 0xdf, 0xaa, 0xb5, 0xba are lower case letter, but can't convert. */
+ if (*p >= 0xaa && *p <= 0xba)
+ return FALSE;
+ else
+ return TRUE;
+ }
+
+ return (v != 0 ? TRUE : FALSE);
}
+#endif
static int
-iso_8859_1_is_code_ctype(OnigCodePoint code, unsigned int ctype)
+is_code_ctype(OnigCodePoint code, unsigned int ctype)
{
if (code < 256)
return ENC_IS_ISO_8859_1_CTYPE(code, ctype);
@@ -126,25 +257,15 @@ OnigEncodingType OnigEncodingISO_8859_1 = {
"ISO-8859-1", /* name */
1, /* max enc length */
1, /* min enc length */
- (ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE |
- ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE ),
- {
- (OnigCodePoint )'\\' /* esc */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
- },
onigenc_is_mbc_newline_0x0a,
onigenc_single_byte_mbc_to_code,
onigenc_single_byte_code_to_mbclen,
onigenc_single_byte_code_to_mbc,
- iso_8859_1_mbc_to_normalize,
- iso_8859_1_is_mbc_ambiguous,
- onigenc_iso_8859_1_get_all_pair_ambig_codes,
- onigenc_ess_tsett_get_all_comp_ambig_codes,
- iso_8859_1_is_code_ctype,
+ mbc_case_fold,
+ apply_all_case_fold,
+ get_case_fold_codes_by_str,
+ onigenc_minimum_property_name_to_ctype,
+ is_code_ctype,
onigenc_not_support_get_ctype_code_range,
onigenc_single_byte_left_adjust_char_head,
onigenc_always_true_is_allowed_reverse_match
diff --git a/ext/mbstring/oniguruma/enc/iso8859_10.c b/ext/mbstring/oniguruma/enc/iso8859_10.c
index 8081ef8010..e35c19d78f 100644
--- a/ext/mbstring/oniguruma/enc/iso8859_10.c
+++ b/ext/mbstring/oniguruma/enc/iso8859_10.c
@@ -2,7 +2,7 @@
iso8859_10.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2006 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2007 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
#define ENC_ISO_8859_10_TO_LOWER_CASE(c) EncISO_8859_10_ToLowerCaseTable[c]
#define ENC_IS_ISO_8859_10_CTYPE(code,ctype) \
- ((EncISO_8859_10_CtypeTable[code] & ctype) != 0)
+ ((EncISO_8859_10_CtypeTable[code] & CTYPE_TO_BIT(ctype)) != 0)
static const UChar EncISO_8859_10_ToLowerCaseTable[256] = {
'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
@@ -69,88 +69,82 @@ static const UChar EncISO_8859_10_ToLowerCaseTable[256] = {
};
static const unsigned short EncISO_8859_10_CtypeTable[256] = {
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x220c, 0x2209, 0x2208, 0x2208, 0x2208, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2284, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0,
- 0x38b0, 0x38b0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x31a0,
- 0x21a0, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x2008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x420c, 0x4209, 0x4208, 0x4208, 0x4208, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4284, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0,
+ 0x78b0, 0x78b0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x51a0,
+ 0x41a0, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x4008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
- 0x0284, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x00a0,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x01a0, 0x14a2, 0x14a2,
- 0x00a0, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x01a0,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x01a0, 0x10e2, 0x10e2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2
+ 0x0284, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x00a0,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x01a0, 0x34a2, 0x34a2,
+ 0x00a0, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x01a0,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x01a0, 0x30e2, 0x30e2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2
};
static int
-iso_8859_10_mbc_to_normalize(OnigAmbigType flag,
- const UChar** pp, const UChar* end, UChar* lower)
+mbc_case_fold(OnigCaseFoldType flag,
+ const UChar** pp, const UChar* end ARG_UNUSED, UChar* lower)
{
const UChar* p = *pp;
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- *lower = ENC_ISO_8859_10_TO_LOWER_CASE(*p);
- }
- else {
- *lower = *p;
+ if (*p == 0xdf && (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
+ *lower++ = 's';
+ *lower = 's';
+ (*pp)++;
+ return 2;
}
+
+ *lower = ENC_ISO_8859_10_TO_LOWER_CASE(*p);
(*pp)++;
- return 1; /* return byte length of converted char to lower */
+ return 1;
}
+#if 0
static int
-iso_8859_10_is_mbc_ambiguous(OnigAmbigType flag,
- const UChar** pp, const UChar* end)
+is_mbc_ambiguous(OnigCaseFoldType flag, const UChar** pp, const UChar* end)
{
+ int v;
const UChar* p = *pp;
- (*pp)++;
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- int v = (EncISO_8859_10_CtypeTable[*p] &
- (ONIGENC_CTYPE_UPPER | ONIGENC_CTYPE_LOWER));
-
- if ((v | ONIGENC_CTYPE_LOWER) != 0) {
- /* 0xdf is lower case letter, but can't convert. */
- if (*p == 0xdf)
- return FALSE;
- else
- return TRUE;
- }
+ if (*p == 0xdf && (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
+ (*pp)++;
+ return TRUE;
+ }
- return (v != 0 ? TRUE : FALSE);
+ (*pp)++;
+ v = (EncISO_8859_10_CtypeTable[*p] & (BIT_CTYPE_UPPER | BIT_CTYPE_LOWER));
+ if ((v | BIT_CTYPE_LOWER) != 0) {
+ return TRUE;
}
- return FALSE;
+
+ return (v != 0 ? TRUE : FALSE);
}
+#endif
static int
-iso_8859_10_is_code_ctype(OnigCodePoint code, unsigned int ctype)
+is_code_ctype(OnigCodePoint code, unsigned int ctype)
{
if (code < 256)
return ENC_IS_ISO_8859_10_CTYPE(code, ctype);
@@ -158,116 +152,71 @@ iso_8859_10_is_code_ctype(OnigCodePoint code, unsigned int ctype)
return FALSE;
}
+static const OnigPairCaseFoldCodes CaseFoldMap[] = {
+ { 0xa1, 0xb1 },
+ { 0xa2, 0xb2 },
+ { 0xa3, 0xb3 },
+ { 0xa4, 0xb4 },
+ { 0xa5, 0xb5 },
+ { 0xa6, 0xb6 },
+ { 0xa8, 0xb8 },
+ { 0xa9, 0xb9 },
+ { 0xaa, 0xba },
+ { 0xab, 0xbb },
+ { 0xac, 0xbc },
+ { 0xae, 0xbe },
+ { 0xaf, 0xbf },
+
+ { 0xc0, 0xe0 },
+ { 0xc1, 0xe1 },
+ { 0xc2, 0xe2 },
+ { 0xc3, 0xe3 },
+ { 0xc4, 0xe4 },
+ { 0xc5, 0xe5 },
+ { 0xc6, 0xe6 },
+ { 0xc7, 0xe7 },
+ { 0xc8, 0xe8 },
+ { 0xc9, 0xe9 },
+ { 0xca, 0xea },
+ { 0xcb, 0xeb },
+ { 0xcc, 0xec },
+ { 0xcd, 0xed },
+ { 0xce, 0xee },
+ { 0xcf, 0xef },
+
+ { 0xd0, 0xf0 },
+ { 0xd1, 0xf1 },
+ { 0xd2, 0xf2 },
+ { 0xd3, 0xf3 },
+ { 0xd4, 0xf4 },
+ { 0xd5, 0xf5 },
+ { 0xd6, 0xf6 },
+ { 0xd7, 0xf7 },
+ { 0xd8, 0xf8 },
+ { 0xd9, 0xf9 },
+ { 0xda, 0xfa },
+ { 0xdb, 0xfb },
+ { 0xdc, 0xfc },
+ { 0xdd, 0xfd },
+ { 0xde, 0xfe }
+};
+
static int
-iso_8859_10_get_all_pair_ambig_codes(OnigAmbigType flag,
- const OnigPairAmbigCodes** ccs)
+apply_all_case_fold(OnigCaseFoldType flag,
+ OnigApplyAllCaseFoldFunc f, void* arg)
{
- static const OnigPairAmbigCodes cc[] = {
- { 0xa1, 0xb1 },
- { 0xa2, 0xb2 },
- { 0xa3, 0xb3 },
- { 0xa4, 0xb4 },
- { 0xa5, 0xb5 },
- { 0xa6, 0xb6 },
- { 0xa8, 0xb8 },
- { 0xa9, 0xb9 },
- { 0xaa, 0xba },
- { 0xab, 0xbb },
- { 0xac, 0xbc },
- { 0xae, 0xbe },
- { 0xaf, 0xbf },
-
- { 0xb1, 0xa1 },
- { 0xb2, 0xa2 },
- { 0xb3, 0xa3 },
- { 0xb4, 0xa4 },
- { 0xb5, 0xa5 },
- { 0xb6, 0xa6 },
- { 0xb8, 0xa8 },
- { 0xb9, 0xa9 },
- { 0xba, 0xaa },
- { 0xbb, 0xab },
- { 0xbc, 0xac },
- { 0xbe, 0xae },
- { 0xbf, 0xaf },
-
- { 0xc0, 0xe0 },
- { 0xc1, 0xe1 },
- { 0xc2, 0xe2 },
- { 0xc3, 0xe3 },
- { 0xc4, 0xe4 },
- { 0xc5, 0xe5 },
- { 0xc6, 0xe6 },
- { 0xc7, 0xe7 },
- { 0xc8, 0xe8 },
- { 0xc9, 0xe9 },
- { 0xca, 0xea },
- { 0xcb, 0xeb },
- { 0xcc, 0xec },
- { 0xcd, 0xed },
- { 0xce, 0xee },
- { 0xcf, 0xef },
-
- { 0xd0, 0xf0 },
- { 0xd1, 0xf1 },
- { 0xd2, 0xf2 },
- { 0xd3, 0xf3 },
- { 0xd4, 0xf4 },
- { 0xd5, 0xf5 },
- { 0xd6, 0xf6 },
- { 0xd7, 0xf7 },
- { 0xd8, 0xf8 },
- { 0xd9, 0xf9 },
- { 0xda, 0xfa },
- { 0xdb, 0xfb },
- { 0xdc, 0xfc },
- { 0xdd, 0xfd },
- { 0xde, 0xfe },
-
- { 0xe0, 0xc0 },
- { 0xe1, 0xc1 },
- { 0xe2, 0xc2 },
- { 0xe3, 0xc3 },
- { 0xe4, 0xc4 },
- { 0xe5, 0xc5 },
- { 0xe6, 0xc6 },
- { 0xe7, 0xc7 },
- { 0xe8, 0xc8 },
- { 0xe9, 0xc9 },
- { 0xea, 0xca },
- { 0xeb, 0xcb },
- { 0xec, 0xcc },
- { 0xed, 0xcd },
- { 0xee, 0xce },
- { 0xef, 0xcf },
-
- { 0xf0, 0xd0 },
- { 0xf1, 0xd1 },
- { 0xf2, 0xd2 },
- { 0xf3, 0xd3 },
- { 0xf4, 0xd4 },
- { 0xf5, 0xd5 },
- { 0xf6, 0xd6 },
- { 0xf7, 0xd7 },
- { 0xf8, 0xd8 },
- { 0xf9, 0xd9 },
- { 0xfa, 0xda },
- { 0xfb, 0xdb },
- { 0xfc, 0xdc },
- { 0xfd, 0xdd },
- { 0xfe, 0xde }
- };
+ return onigenc_apply_all_case_fold_with_map(
+ sizeof(CaseFoldMap)/sizeof(OnigPairCaseFoldCodes), CaseFoldMap, 1,
+ flag, f, arg);
+}
- if (flag == ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) {
- *ccs = OnigAsciiPairAmbigCodes;
- return 52;
- }
- if (flag == ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) {
- *ccs = cc;
- return sizeof(cc) / sizeof(OnigPairAmbigCodes);
- }
- else
- return 0;
+static int
+get_case_fold_codes_by_str(OnigCaseFoldType flag,
+ const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[])
+{
+ return onigenc_get_case_fold_codes_by_str_with_map(
+ sizeof(CaseFoldMap)/sizeof(OnigPairCaseFoldCodes), CaseFoldMap, 1,
+ flag, p, end, items);
}
OnigEncodingType OnigEncodingISO_8859_10 = {
@@ -275,25 +224,15 @@ OnigEncodingType OnigEncodingISO_8859_10 = {
"ISO-8859-10", /* name */
1, /* max enc length */
1, /* min enc length */
- (ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE |
- ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE ),
- {
- (OnigCodePoint )'\\' /* esc */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
- },
onigenc_is_mbc_newline_0x0a,
onigenc_single_byte_mbc_to_code,
onigenc_single_byte_code_to_mbclen,
onigenc_single_byte_code_to_mbc,
- iso_8859_10_mbc_to_normalize,
- iso_8859_10_is_mbc_ambiguous,
- iso_8859_10_get_all_pair_ambig_codes,
- onigenc_ess_tsett_get_all_comp_ambig_codes,
- iso_8859_10_is_code_ctype,
+ mbc_case_fold,
+ apply_all_case_fold,
+ get_case_fold_codes_by_str,
+ onigenc_minimum_property_name_to_ctype,
+ is_code_ctype,
onigenc_not_support_get_ctype_code_range,
onigenc_single_byte_left_adjust_char_head,
onigenc_always_true_is_allowed_reverse_match
diff --git a/ext/mbstring/oniguruma/enc/iso8859_11.c b/ext/mbstring/oniguruma/enc/iso8859_11.c
index de9bb3b825..8a460a3047 100644
--- a/ext/mbstring/oniguruma/enc/iso8859_11.c
+++ b/ext/mbstring/oniguruma/enc/iso8859_11.c
@@ -2,7 +2,7 @@
iso8859_11.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2004 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2007 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,45 +30,45 @@
#include "regenc.h"
#define ENC_IS_ISO_8859_11_CTYPE(code,ctype) \
- ((EncISO_8859_11_CtypeTable[code] & ctype) != 0)
+ ((EncISO_8859_11_CtypeTable[code] & CTYPE_TO_BIT(ctype)) != 0)
static const unsigned short EncISO_8859_11_CtypeTable[256] = {
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x220c, 0x2209, 0x2208, 0x2208, 0x2208, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2284, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0,
- 0x38b0, 0x38b0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x31a0,
- 0x21a0, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x2008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x420c, 0x4209, 0x4208, 0x4208, 0x4208, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4284, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0,
+ 0x78b0, 0x78b0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x51a0,
+ 0x41a0, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x4008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
- 0x0284, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2,
- 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2,
- 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2,
- 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2,
- 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2,
- 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2,
- 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2,
- 0x10a2, 0x10a2, 0x10a2, 0x0000, 0x0000, 0x0000, 0x0000, 0x10a2,
- 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2,
- 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2,
- 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2,
- 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x0000, 0x0000, 0x0000, 0x0000
+ 0x0284, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2,
+ 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2,
+ 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2,
+ 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2,
+ 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2,
+ 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2,
+ 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2,
+ 0x30a2, 0x30a2, 0x30a2, 0x0000, 0x0000, 0x0000, 0x0000, 0x30a2,
+ 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2,
+ 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2,
+ 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2,
+ 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x0000, 0x0000, 0x0000, 0x0000
};
static int
-iso_8859_11_is_code_ctype(OnigCodePoint code, unsigned int ctype)
+is_code_ctype(OnigCodePoint code, unsigned int ctype)
{
if (code < 256)
return ENC_IS_ISO_8859_11_CTYPE(code, ctype);
@@ -81,24 +81,15 @@ OnigEncodingType OnigEncodingISO_8859_11 = {
"ISO-8859-11", /* name */
1, /* max enc length */
1, /* min enc length */
- ( ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE ),
- {
- (OnigCodePoint )'\\' /* esc */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
- },
onigenc_is_mbc_newline_0x0a,
onigenc_single_byte_mbc_to_code,
onigenc_single_byte_code_to_mbclen,
onigenc_single_byte_code_to_mbc,
- onigenc_ascii_mbc_to_normalize,
- onigenc_ascii_is_mbc_ambiguous,
- onigenc_ascii_get_all_pair_ambig_codes,
- onigenc_nothing_get_all_comp_ambig_codes,
- iso_8859_11_is_code_ctype,
+ onigenc_ascii_mbc_case_fold,
+ onigenc_ascii_apply_all_case_fold,
+ onigenc_ascii_get_case_fold_codes_by_str,
+ onigenc_minimum_property_name_to_ctype,
+ is_code_ctype,
onigenc_not_support_get_ctype_code_range,
onigenc_single_byte_left_adjust_char_head,
onigenc_always_true_is_allowed_reverse_match
diff --git a/ext/mbstring/oniguruma/enc/iso8859_13.c b/ext/mbstring/oniguruma/enc/iso8859_13.c
index 69316edfc3..3670d92ea5 100644
--- a/ext/mbstring/oniguruma/enc/iso8859_13.c
+++ b/ext/mbstring/oniguruma/enc/iso8859_13.c
@@ -31,7 +31,7 @@
#define ENC_ISO_8859_13_TO_LOWER_CASE(c) EncISO_8859_13_ToLowerCaseTable[c]
#define ENC_IS_ISO_8859_13_CTYPE(code,ctype) \
- ((EncISO_8859_13_CtypeTable[code] & ctype) != 0)
+ ((EncISO_8859_13_CtypeTable[code] & CTYPE_TO_BIT(ctype)) != 0)
static const UChar EncISO_8859_13_ToLowerCaseTable[256] = {
'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
@@ -69,84 +69,83 @@ static const UChar EncISO_8859_13_ToLowerCaseTable[256] = {
};
static const unsigned short EncISO_8859_13_CtypeTable[256] = {
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x220c, 0x2209, 0x2208, 0x2208, 0x2208, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2284, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0,
- 0x38b0, 0x38b0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x31a0,
- 0x21a0, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x2008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x420c, 0x4209, 0x4208, 0x4208, 0x4208, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4284, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0,
+ 0x78b0, 0x78b0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x51a0,
+ 0x41a0, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x4008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0284, 0x01a0, 0x00a0, 0x00a0, 0x00a0, 0x01a0, 0x00a0, 0x00a0,
- 0x14a2, 0x00a0, 0x14a2, 0x01a0, 0x00a0, 0x01a0, 0x00a0, 0x14a2,
- 0x00a0, 0x00a0, 0x10a0, 0x10a0, 0x01a0, 0x10e2, 0x00a0, 0x01a0,
- 0x10e2, 0x10a0, 0x10e2, 0x01a0, 0x10a0, 0x10a0, 0x10a0, 0x10e2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x00a0,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x00a0,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x01a0
+ 0x34a2, 0x00a0, 0x34a2, 0x01a0, 0x00a0, 0x01a0, 0x00a0, 0x34a2,
+ 0x00a0, 0x00a0, 0x10a0, 0x10a0, 0x01a0, 0x30e2, 0x00a0, 0x01a0,
+ 0x30e2, 0x10a0, 0x30e2, 0x01a0, 0x10a0, 0x10a0, 0x10a0, 0x30e2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x00a0,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x00a0,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x01a0
};
static int
-mbc_to_normalize(OnigAmbigType flag,
- const UChar** pp, const UChar* end, UChar* lower)
+mbc_case_fold(OnigCaseFoldType flag,
+ const UChar** pp, const UChar* end ARG_UNUSED, UChar* lower)
{
const UChar* p = *pp;
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- *lower = ENC_ISO_8859_13_TO_LOWER_CASE(*p);
- }
- else {
- *lower = *p;
+ if (*p == 0xdf && (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
+ *lower++ = 's';
+ *lower = 's';
+ (*pp)++;
+ return 2;
}
+
+ *lower = ENC_ISO_8859_13_TO_LOWER_CASE(*p);
(*pp)++;
- return 1; /* return byte length of converted char to lower */
+ return 1;
}
+#if 0
static int
-is_mbc_ambiguous(OnigAmbigType flag, const UChar** pp, const UChar* end)
+is_mbc_ambiguous(OnigCaseFoldType flag, const UChar** pp, const UChar* end)
{
+ int v;
const UChar* p = *pp;
- (*pp)++;
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- int v = (EncISO_8859_13_CtypeTable[*p] &
- (ONIGENC_CTYPE_UPPER | ONIGENC_CTYPE_LOWER));
-
- if ((v | ONIGENC_CTYPE_LOWER) != 0) {
- /* 0xdf, 0xb5 are lower case letter, but can't convert. */
- if (*p == 0xdf || *p == 0xb5)
- return FALSE;
- else
- return TRUE;
- }
+ if (*p == 0xdf && (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
+ (*pp)++;
+ return TRUE;
+ }
- return (v != 0 ? TRUE : FALSE);
+ (*pp)++;
+ v = (EncISO_8859_13_CtypeTable[*p] & (BIT_CTYPE_UPPER | BIT_CTYPE_LOWER));
+ if ((v | BIT_CTYPE_LOWER) != 0) {
+ /* 0xdf, 0xb5 are lower case letter, but can't convert. */
+ if (*p == 0xb5)
+ return FALSE;
+ else
+ return TRUE;
}
- return FALSE;
+
+ return (v != 0 ? TRUE : FALSE);
}
+#endif
static int
is_code_ctype(OnigCodePoint code, unsigned int ctype)
@@ -157,85 +156,56 @@ is_code_ctype(OnigCodePoint code, unsigned int ctype)
return FALSE;
}
+static const OnigPairCaseFoldCodes CaseFoldMap[] = {
+ { 0xc0, 0xe0 },
+ { 0xc1, 0xe1 },
+ { 0xc2, 0xe2 },
+ { 0xc3, 0xe3 },
+ { 0xc4, 0xe4 },
+ { 0xc5, 0xe5 },
+ { 0xc6, 0xe6 },
+ { 0xc7, 0xe7 },
+ { 0xc8, 0xe8 },
+ { 0xc9, 0xe9 },
+ { 0xca, 0xea },
+ { 0xcb, 0xeb },
+ { 0xcc, 0xec },
+ { 0xcd, 0xed },
+ { 0xce, 0xee },
+ { 0xcf, 0xef },
+
+ { 0xd0, 0xf0 },
+ { 0xd1, 0xf1 },
+ { 0xd2, 0xf2 },
+ { 0xd3, 0xf3 },
+ { 0xd4, 0xf4 },
+ { 0xd5, 0xf5 },
+ { 0xd6, 0xf6 },
+ { 0xd8, 0xf8 },
+ { 0xd9, 0xf9 },
+ { 0xda, 0xfa },
+ { 0xdb, 0xfb },
+ { 0xdc, 0xfc },
+ { 0xdd, 0xfd },
+ { 0xde, 0xfe }
+};
+
static int
-get_all_pair_ambig_codes(OnigAmbigType flag, const OnigPairAmbigCodes** ccs)
+apply_all_case_fold(OnigCaseFoldType flag,
+ OnigApplyAllCaseFoldFunc f, void* arg)
{
- static const OnigPairAmbigCodes cc[] = {
- { 0xc0, 0xe0 },
- { 0xc1, 0xe1 },
- { 0xc2, 0xe2 },
- { 0xc3, 0xe3 },
- { 0xc4, 0xe4 },
- { 0xc5, 0xe5 },
- { 0xc6, 0xe6 },
- { 0xc7, 0xe7 },
- { 0xc8, 0xe8 },
- { 0xc9, 0xe9 },
- { 0xca, 0xea },
- { 0xcb, 0xeb },
- { 0xcc, 0xec },
- { 0xcd, 0xed },
- { 0xce, 0xee },
- { 0xcf, 0xef },
-
- { 0xd0, 0xf0 },
- { 0xd1, 0xf1 },
- { 0xd2, 0xf2 },
- { 0xd3, 0xf3 },
- { 0xd4, 0xf4 },
- { 0xd5, 0xf5 },
- { 0xd6, 0xf6 },
- { 0xd8, 0xf8 },
- { 0xd9, 0xf9 },
- { 0xda, 0xfa },
- { 0xdb, 0xfb },
- { 0xdc, 0xfc },
- { 0xdd, 0xfd },
- { 0xde, 0xfe },
-
- { 0xe0, 0xc0 },
- { 0xe1, 0xc1 },
- { 0xe2, 0xc2 },
- { 0xe3, 0xc3 },
- { 0xe4, 0xc4 },
- { 0xe5, 0xc5 },
- { 0xe6, 0xc6 },
- { 0xe7, 0xc7 },
- { 0xe8, 0xc8 },
- { 0xe9, 0xc9 },
- { 0xea, 0xca },
- { 0xeb, 0xcb },
- { 0xec, 0xcc },
- { 0xed, 0xcd },
- { 0xee, 0xce },
- { 0xef, 0xcf },
-
- { 0xf0, 0xd0 },
- { 0xf1, 0xd1 },
- { 0xf2, 0xd2 },
- { 0xf3, 0xd3 },
- { 0xf4, 0xd4 },
- { 0xf5, 0xd5 },
- { 0xf6, 0xd6 },
- { 0xf8, 0xd8 },
- { 0xf9, 0xd9 },
- { 0xfa, 0xda },
- { 0xfb, 0xdb },
- { 0xfc, 0xdc },
- { 0xfd, 0xdd },
- { 0xfe, 0xde }
- };
+ return onigenc_apply_all_case_fold_with_map(
+ sizeof(CaseFoldMap)/sizeof(OnigPairCaseFoldCodes), CaseFoldMap, 1,
+ flag, f, arg);
+}
- if (flag == ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) {
- *ccs = OnigAsciiPairAmbigCodes;
- return 52;
- }
- if (flag == ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) {
- *ccs = cc;
- return sizeof(cc) / sizeof(OnigPairAmbigCodes);
- }
- else
- return 0;
+static int
+get_case_fold_codes_by_str(OnigCaseFoldType flag,
+ const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[])
+{
+ return onigenc_get_case_fold_codes_by_str_with_map(
+ sizeof(CaseFoldMap)/sizeof(OnigPairCaseFoldCodes), CaseFoldMap, 1,
+ flag, p, end, items);
}
OnigEncodingType OnigEncodingISO_8859_13 = {
@@ -243,24 +213,14 @@ OnigEncodingType OnigEncodingISO_8859_13 = {
"ISO-8859-13", /* name */
1, /* max enc length */
1, /* min enc length */
- (ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE |
- ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE ),
- {
- (OnigCodePoint )'\\' /* esc */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
- },
onigenc_is_mbc_newline_0x0a,
onigenc_single_byte_mbc_to_code,
onigenc_single_byte_code_to_mbclen,
onigenc_single_byte_code_to_mbc,
- mbc_to_normalize,
- is_mbc_ambiguous,
- get_all_pair_ambig_codes,
- onigenc_ess_tsett_get_all_comp_ambig_codes,
+ mbc_case_fold,
+ apply_all_case_fold,
+ get_case_fold_codes_by_str,
+ onigenc_minimum_property_name_to_ctype,
is_code_ctype,
onigenc_not_support_get_ctype_code_range,
onigenc_single_byte_left_adjust_char_head,
diff --git a/ext/mbstring/oniguruma/enc/iso8859_14.c b/ext/mbstring/oniguruma/enc/iso8859_14.c
index 44638cf13a..3596d4479a 100644
--- a/ext/mbstring/oniguruma/enc/iso8859_14.c
+++ b/ext/mbstring/oniguruma/enc/iso8859_14.c
@@ -31,7 +31,7 @@
#define ENC_ISO_8859_14_TO_LOWER_CASE(c) EncISO_8859_14_ToLowerCaseTable[c]
#define ENC_IS_ISO_8859_14_CTYPE(code,ctype) \
- ((EncISO_8859_14_CtypeTable[code] & ctype) != 0)
+ ((EncISO_8859_14_CtypeTable[code] & CTYPE_TO_BIT(ctype)) != 0)
static const UChar EncISO_8859_14_ToLowerCaseTable[256] = {
'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
@@ -69,84 +69,80 @@ static const UChar EncISO_8859_14_ToLowerCaseTable[256] = {
};
static const unsigned short EncISO_8859_14_CtypeTable[256] = {
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x220c, 0x2209, 0x2208, 0x2208, 0x2208, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2284, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0,
- 0x38b0, 0x38b0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x31a0,
- 0x21a0, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x2008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x420c, 0x4209, 0x4208, 0x4208, 0x4208, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4284, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0,
+ 0x78b0, 0x78b0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x51a0,
+ 0x41a0, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x4008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
- 0x0284, 0x14a2, 0x10e2, 0x00a0, 0x14a2, 0x10e2, 0x14a2, 0x00a0,
- 0x14a2, 0x00a0, 0x14a2, 0x10e2, 0x14a2, 0x01a0, 0x00a0, 0x14a2,
- 0x14a2, 0x10e2, 0x14a2, 0x10e2, 0x14a2, 0x10e2, 0x00a0, 0x14a2,
- 0x10e2, 0x10e2, 0x10e2, 0x14a2, 0x10e2, 0x14a2, 0x10e2, 0x10e2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2
+ 0x0284, 0x34a2, 0x30e2, 0x00a0, 0x34a2, 0x30e2, 0x34a2, 0x00a0,
+ 0x34a2, 0x00a0, 0x34a2, 0x30e2, 0x34a2, 0x01a0, 0x00a0, 0x34a2,
+ 0x34a2, 0x30e2, 0x34a2, 0x30e2, 0x34a2, 0x30e2, 0x00a0, 0x34a2,
+ 0x30e2, 0x30e2, 0x30e2, 0x34a2, 0x30e2, 0x34a2, 0x30e2, 0x30e2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2
};
static int
-mbc_to_normalize(OnigAmbigType flag,
- const UChar** pp, const UChar* end, UChar* lower)
+mbc_case_fold(OnigCaseFoldType flag,
+ const UChar** pp, const UChar* end ARG_UNUSED, UChar* lower)
{
const UChar* p = *pp;
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- *lower = ENC_ISO_8859_14_TO_LOWER_CASE(*p);
- }
- else {
- *lower = *p;
+ if (*p == 0xdf && (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
+ *lower++ = 's';
+ *lower = 's';
+ (*pp)++;
+ return 2;
}
+
+ *lower = ENC_ISO_8859_14_TO_LOWER_CASE(*p);
(*pp)++;
return 1; /* return byte length of converted char to lower */
}
+#if 0
static int
-is_mbc_ambiguous(OnigAmbigType flag, const UChar** pp, const UChar* end)
+is_mbc_ambiguous(OnigCaseFoldType flag,
+ const UChar** pp, const UChar* end)
{
+ int v;
const UChar* p = *pp;
- (*pp)++;
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- int v = (EncISO_8859_14_CtypeTable[*p] &
- (ONIGENC_CTYPE_UPPER | ONIGENC_CTYPE_LOWER));
-
- if ((v | ONIGENC_CTYPE_LOWER) != 0) {
- /* 0xdf is lower case letter, but can't convert. */
- if (*p == 0xdf)
- return FALSE;
- else
- return TRUE;
- }
+ if (*p == 0xdf && (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
+ (*pp)++;
+ return TRUE;
+ }
- return (v != 0 ? TRUE : FALSE);
+ (*pp)++;
+ v = (EncISO_8859_14_CtypeTable[*p] & (BIT_CTYPE_UPPER | BIT_CTYPE_LOWER));
+ if ((v | BIT_CTYPE_LOWER) != 0) {
+ return TRUE;
}
- return FALSE;
+
+ return (v != 0 ? TRUE : FALSE);
}
+#endif
static int
is_code_ctype(OnigCodePoint code, unsigned int ctype)
@@ -157,115 +153,72 @@ is_code_ctype(OnigCodePoint code, unsigned int ctype)
return FALSE;
}
+static const OnigPairCaseFoldCodes CaseFoldMap[] = {
+ { 0xa1, 0xa2 },
+ { 0xa4, 0xa5 },
+ { 0xa6, 0xab },
+ { 0xa8, 0xb8 },
+ { 0xaa, 0xba },
+ { 0xac, 0xbc },
+ { 0xaf, 0xff },
+
+ { 0xb0, 0xb1 },
+ { 0xb2, 0xb3 },
+ { 0xb4, 0xb5 },
+ { 0xb7, 0xb9 },
+ { 0xbb, 0xbf },
+ { 0xbd, 0xbe },
+
+ { 0xc0, 0xe0 },
+ { 0xc1, 0xe1 },
+ { 0xc2, 0xe2 },
+ { 0xc3, 0xe3 },
+ { 0xc4, 0xe4 },
+ { 0xc5, 0xe5 },
+ { 0xc6, 0xe6 },
+ { 0xc7, 0xe7 },
+ { 0xc8, 0xe8 },
+ { 0xc9, 0xe9 },
+ { 0xca, 0xea },
+ { 0xcb, 0xeb },
+ { 0xcc, 0xec },
+ { 0xcd, 0xed },
+ { 0xce, 0xee },
+ { 0xcf, 0xef },
+
+ { 0xd0, 0xf0 },
+ { 0xd1, 0xf1 },
+ { 0xd2, 0xf2 },
+ { 0xd3, 0xf3 },
+ { 0xd4, 0xf4 },
+ { 0xd5, 0xf5 },
+ { 0xd6, 0xf6 },
+ { 0xd7, 0xf7 },
+ { 0xd8, 0xf8 },
+ { 0xd9, 0xf9 },
+ { 0xda, 0xfa },
+ { 0xdb, 0xfb },
+ { 0xdc, 0xfc },
+ { 0xdd, 0xfd },
+ { 0xde, 0xfe }
+};
+
static int
-get_all_pair_ambig_codes(OnigAmbigType flag, const OnigPairAmbigCodes** ccs)
+apply_all_case_fold(OnigCaseFoldType flag,
+ OnigApplyAllCaseFoldFunc f, void* arg)
{
- static const OnigPairAmbigCodes cc[] = {
- { 0xa1, 0xa2 },
- { 0xa2, 0xa1 },
- { 0xa4, 0xa5 },
- { 0xa5, 0xa4 },
- { 0xa6, 0xab },
- { 0xa8, 0xb8 },
- { 0xaa, 0xba },
- { 0xab, 0xa6 },
- { 0xac, 0xbc },
- { 0xaf, 0xff },
-
- { 0xb0, 0xb1 },
- { 0xb1, 0xb0 },
- { 0xb2, 0xb3 },
- { 0xb3, 0xb2 },
- { 0xb4, 0xb5 },
- { 0xb5, 0xb4 },
- { 0xb7, 0xb9 },
- { 0xb8, 0xa8 },
- { 0xb9, 0xb7 },
- { 0xba, 0xaa },
- { 0xbb, 0xbf },
- { 0xbc, 0xac },
- { 0xbd, 0xbe },
- { 0xbe, 0xbd },
- { 0xbf, 0xbb },
-
- { 0xc0, 0xe0 },
- { 0xc1, 0xe1 },
- { 0xc2, 0xe2 },
- { 0xc3, 0xe3 },
- { 0xc4, 0xe4 },
- { 0xc5, 0xe5 },
- { 0xc6, 0xe6 },
- { 0xc7, 0xe7 },
- { 0xc8, 0xe8 },
- { 0xc9, 0xe9 },
- { 0xca, 0xea },
- { 0xcb, 0xeb },
- { 0xcc, 0xec },
- { 0xcd, 0xed },
- { 0xce, 0xee },
- { 0xcf, 0xef },
-
- { 0xd0, 0xf0 },
- { 0xd1, 0xf1 },
- { 0xd2, 0xf2 },
- { 0xd3, 0xf3 },
- { 0xd4, 0xf4 },
- { 0xd5, 0xf5 },
- { 0xd6, 0xf6 },
- { 0xd7, 0xf7 },
- { 0xd8, 0xf8 },
- { 0xd9, 0xf9 },
- { 0xda, 0xfa },
- { 0xdb, 0xfb },
- { 0xdc, 0xfc },
- { 0xdd, 0xfd },
- { 0xde, 0xfe },
-
- { 0xe0, 0xc0 },
- { 0xe1, 0xc1 },
- { 0xe2, 0xc2 },
- { 0xe3, 0xc3 },
- { 0xe4, 0xc4 },
- { 0xe5, 0xc5 },
- { 0xe6, 0xc6 },
- { 0xe7, 0xc7 },
- { 0xe8, 0xc8 },
- { 0xe9, 0xc9 },
- { 0xea, 0xca },
- { 0xeb, 0xcb },
- { 0xec, 0xcc },
- { 0xed, 0xcd },
- { 0xee, 0xce },
- { 0xef, 0xcf },
-
- { 0xf0, 0xd0 },
- { 0xf1, 0xd1 },
- { 0xf2, 0xd2 },
- { 0xf3, 0xd3 },
- { 0xf4, 0xd4 },
- { 0xf5, 0xd5 },
- { 0xf6, 0xd6 },
- { 0xf7, 0xd7 },
- { 0xf8, 0xd8 },
- { 0xf9, 0xd9 },
- { 0xfa, 0xda },
- { 0xfb, 0xdb },
- { 0xfc, 0xdc },
- { 0xfd, 0xdd },
- { 0xfe, 0xde },
- { 0xff, 0xaf }
- };
+ return onigenc_apply_all_case_fold_with_map(
+ sizeof(CaseFoldMap)/sizeof(OnigPairCaseFoldCodes), CaseFoldMap, 1,
+ flag, f, arg);
+}
- if (flag == ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) {
- *ccs = OnigAsciiPairAmbigCodes;
- return 52;
- }
- if (flag == ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) {
- *ccs = cc;
- return sizeof(cc) / sizeof(OnigPairAmbigCodes);
- }
- else
- return 0;
+static int
+get_case_fold_codes_by_str(OnigCaseFoldType flag,
+ const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[])
+{
+ return onigenc_get_case_fold_codes_by_str_with_map(
+ sizeof(CaseFoldMap)/sizeof(OnigPairCaseFoldCodes), CaseFoldMap, 1,
+ flag, p, end, items);
}
OnigEncodingType OnigEncodingISO_8859_14 = {
@@ -273,24 +226,14 @@ OnigEncodingType OnigEncodingISO_8859_14 = {
"ISO-8859-14", /* name */
1, /* max enc length */
1, /* min enc length */
- (ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE |
- ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE ),
- {
- (OnigCodePoint )'\\' /* esc */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
- },
onigenc_is_mbc_newline_0x0a,
onigenc_single_byte_mbc_to_code,
onigenc_single_byte_code_to_mbclen,
onigenc_single_byte_code_to_mbc,
- mbc_to_normalize,
- is_mbc_ambiguous,
- get_all_pair_ambig_codes,
- onigenc_ess_tsett_get_all_comp_ambig_codes,
+ mbc_case_fold,
+ apply_all_case_fold,
+ get_case_fold_codes_by_str,
+ onigenc_minimum_property_name_to_ctype,
is_code_ctype,
onigenc_not_support_get_ctype_code_range,
onigenc_single_byte_left_adjust_char_head,
diff --git a/ext/mbstring/oniguruma/enc/iso8859_15.c b/ext/mbstring/oniguruma/enc/iso8859_15.c
index f643b895df..08492fb4d9 100644
--- a/ext/mbstring/oniguruma/enc/iso8859_15.c
+++ b/ext/mbstring/oniguruma/enc/iso8859_15.c
@@ -31,7 +31,7 @@
#define ENC_ISO_8859_15_TO_LOWER_CASE(c) EncISO_8859_15_ToLowerCaseTable[c]
#define ENC_IS_ISO_8859_15_CTYPE(code,ctype) \
- ((EncISO_8859_15_CtypeTable[code] & ctype) != 0)
+ ((EncISO_8859_15_CtypeTable[code] & CTYPE_TO_BIT(ctype)) != 0)
static const UChar EncISO_8859_15_ToLowerCaseTable[256] = {
'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
@@ -69,84 +69,84 @@ static const UChar EncISO_8859_15_ToLowerCaseTable[256] = {
};
static const unsigned short EncISO_8859_15_CtypeTable[256] = {
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x220c, 0x2209, 0x2208, 0x2208, 0x2208, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2284, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0,
- 0x38b0, 0x38b0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x31a0,
- 0x21a0, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x2008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x420c, 0x4209, 0x4208, 0x4208, 0x4208, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4284, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0,
+ 0x78b0, 0x78b0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x51a0,
+ 0x41a0, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x4008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
- 0x0284, 0x01a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x14a2, 0x00a0,
- 0x10e2, 0x00a0, 0x10e2, 0x01a0, 0x00a0, 0x01a0, 0x00a0, 0x00a0,
- 0x00a0, 0x00a0, 0x10a0, 0x10a0, 0x14a2, 0x10e2, 0x00a0, 0x01a0,
- 0x10e2, 0x10a0, 0x10e2, 0x01a0, 0x14a2, 0x10e2, 0x14a2, 0x01a0,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x00a0,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x00a0,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2
+ 0x0284, 0x01a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x34a2, 0x00a0,
+ 0x30e2, 0x00a0, 0x30e2, 0x01a0, 0x00a0, 0x01a0, 0x00a0, 0x00a0,
+ 0x00a0, 0x00a0, 0x10a0, 0x10a0, 0x34a2, 0x30e2, 0x00a0, 0x01a0,
+ 0x30e2, 0x10a0, 0x30e2, 0x01a0, 0x34a2, 0x30e2, 0x34a2, 0x01a0,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x00a0,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x00a0,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2
};
static int
-mbc_to_normalize(OnigAmbigType flag,
- const UChar** pp, const UChar* end, UChar* lower)
+mbc_case_fold(OnigCaseFoldType flag,
+ const UChar** pp, const UChar* end ARG_UNUSED, UChar* lower)
{
const UChar* p = *pp;
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- *lower = ENC_ISO_8859_15_TO_LOWER_CASE(*p);
- }
- else {
- *lower = *p;
+ if (*p == 0xdf && (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
+ *lower++ = 's';
+ *lower = 's';
+ (*pp)++;
+ return 2;
}
+
+ *lower = ENC_ISO_8859_15_TO_LOWER_CASE(*p);
(*pp)++;
return 1; /* return byte length of converted char to lower */
}
+#if 0
static int
-is_mbc_ambiguous(OnigAmbigType flag, const UChar** pp, const UChar* end)
+is_mbc_ambiguous(OnigCaseFoldType flag,
+ const UChar** pp, const UChar* end)
{
+ int v;
const UChar* p = *pp;
- (*pp)++;
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- int v = (EncISO_8859_15_CtypeTable[*p] &
- (ONIGENC_CTYPE_UPPER | ONIGENC_CTYPE_LOWER));
-
- if ((v | ONIGENC_CTYPE_LOWER) != 0) {
- /* 0xdf etc.. are lower case letter, but can't convert. */
- if (*p == 0xdf || *p == 0xaa || *p == 0xb5 || *p == 0xba)
- return FALSE;
- else
- return TRUE;
- }
+ if (*p == 0xdf && (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
+ (*pp)++;
+ return TRUE;
+ }
- return (v != 0 ? TRUE : FALSE);
+ (*pp)++;
+ v = (EncISO_8859_15_CtypeTable[*p] & (BIT_CTYPE_UPPER | BIT_CTYPE_LOWER));
+ if ((v | BIT_CTYPE_LOWER) != 0) {
+ /* 0xdf etc.. are lower case letter, but can't convert. */
+ if (*p == 0xaa || *p == 0xb5 || *p == 0xba)
+ return FALSE;
+ else
+ return TRUE;
}
- return FALSE;
+
+ return (v != 0 ? TRUE : FALSE);
}
+#endif
static int
is_code_ctype(OnigCodePoint code, unsigned int ctype)
@@ -157,96 +157,62 @@ is_code_ctype(OnigCodePoint code, unsigned int ctype)
return FALSE;
}
+static const OnigPairCaseFoldCodes CaseFoldMap[] = {
+ { 0xa6, 0xa8 },
+
+ { 0xb4, 0xb8 },
+ { 0xbc, 0xbd },
+ { 0xbe, 0xff },
+
+ { 0xc0, 0xe0 },
+ { 0xc1, 0xe1 },
+ { 0xc2, 0xe2 },
+ { 0xc3, 0xe3 },
+ { 0xc4, 0xe4 },
+ { 0xc5, 0xe5 },
+ { 0xc6, 0xe6 },
+ { 0xc7, 0xe7 },
+ { 0xc8, 0xe8 },
+ { 0xc9, 0xe9 },
+ { 0xca, 0xea },
+ { 0xcb, 0xeb },
+ { 0xcc, 0xec },
+ { 0xcd, 0xed },
+ { 0xce, 0xee },
+ { 0xcf, 0xef },
+
+ { 0xd0, 0xf0 },
+ { 0xd1, 0xf1 },
+ { 0xd2, 0xf2 },
+ { 0xd3, 0xf3 },
+ { 0xd4, 0xf4 },
+ { 0xd5, 0xf5 },
+ { 0xd6, 0xf6 },
+ { 0xd8, 0xf8 },
+ { 0xd9, 0xf9 },
+ { 0xda, 0xfa },
+ { 0xdb, 0xfb },
+ { 0xdc, 0xfc },
+ { 0xdd, 0xfd },
+ { 0xde, 0xfe }
+};
+
static int
-get_all_pair_ambig_codes(OnigAmbigType flag,
- const OnigPairAmbigCodes** ccs)
+apply_all_case_fold(OnigCaseFoldType flag,
+ OnigApplyAllCaseFoldFunc f, void* arg)
{
- static const OnigPairAmbigCodes cc[] = {
- { 0xa6, 0xa8 },
- { 0xa8, 0xa6 },
-
- { 0xb4, 0xb8 },
- { 0xb8, 0xb4 },
- { 0xbc, 0xbd },
- { 0xbd, 0xbc },
- { 0xbe, 0xff },
-
- { 0xc0, 0xe0 },
- { 0xc1, 0xe1 },
- { 0xc2, 0xe2 },
- { 0xc3, 0xe3 },
- { 0xc4, 0xe4 },
- { 0xc5, 0xe5 },
- { 0xc6, 0xe6 },
- { 0xc7, 0xe7 },
- { 0xc8, 0xe8 },
- { 0xc9, 0xe9 },
- { 0xca, 0xea },
- { 0xcb, 0xeb },
- { 0xcc, 0xec },
- { 0xcd, 0xed },
- { 0xce, 0xee },
- { 0xcf, 0xef },
-
- { 0xd0, 0xf0 },
- { 0xd1, 0xf1 },
- { 0xd2, 0xf2 },
- { 0xd3, 0xf3 },
- { 0xd4, 0xf4 },
- { 0xd5, 0xf5 },
- { 0xd6, 0xf6 },
- { 0xd8, 0xf8 },
- { 0xd9, 0xf9 },
- { 0xda, 0xfa },
- { 0xdb, 0xfb },
- { 0xdc, 0xfc },
- { 0xdd, 0xfd },
- { 0xde, 0xfe },
-
- { 0xe0, 0xc0 },
- { 0xe1, 0xc1 },
- { 0xe2, 0xc2 },
- { 0xe3, 0xc3 },
- { 0xe4, 0xc4 },
- { 0xe5, 0xc5 },
- { 0xe6, 0xc6 },
- { 0xe7, 0xc7 },
- { 0xe8, 0xc8 },
- { 0xe9, 0xc9 },
- { 0xea, 0xca },
- { 0xeb, 0xcb },
- { 0xec, 0xcc },
- { 0xed, 0xcd },
- { 0xee, 0xce },
- { 0xef, 0xcf },
-
- { 0xf0, 0xd0 },
- { 0xf1, 0xd1 },
- { 0xf2, 0xd2 },
- { 0xf3, 0xd3 },
- { 0xf4, 0xd4 },
- { 0xf5, 0xd5 },
- { 0xf6, 0xd6 },
- { 0xf8, 0xd8 },
- { 0xf9, 0xd9 },
- { 0xfa, 0xda },
- { 0xfb, 0xdb },
- { 0xfc, 0xdc },
- { 0xfd, 0xdd },
- { 0xfe, 0xde },
- { 0xff, 0xbe }
- };
+ return onigenc_apply_all_case_fold_with_map(
+ sizeof(CaseFoldMap)/sizeof(OnigPairCaseFoldCodes), CaseFoldMap, 1,
+ flag, f, arg);
+}
- if (flag == ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) {
- *ccs = OnigAsciiPairAmbigCodes;
- return 52;
- }
- if (flag == ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) {
- *ccs = cc;
- return sizeof(cc) / sizeof(OnigPairAmbigCodes);
- }
- else
- return 0;
+static int
+get_case_fold_codes_by_str(OnigCaseFoldType flag,
+ const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[])
+{
+ return onigenc_get_case_fold_codes_by_str_with_map(
+ sizeof(CaseFoldMap)/sizeof(OnigPairCaseFoldCodes), CaseFoldMap, 1,
+ flag, p, end, items);
}
OnigEncodingType OnigEncodingISO_8859_15 = {
@@ -254,24 +220,14 @@ OnigEncodingType OnigEncodingISO_8859_15 = {
"ISO-8859-15", /* name */
1, /* max enc length */
1, /* min enc length */
- (ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE |
- ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE ),
- {
- (OnigCodePoint )'\\' /* esc */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
- },
onigenc_is_mbc_newline_0x0a,
onigenc_single_byte_mbc_to_code,
onigenc_single_byte_code_to_mbclen,
onigenc_single_byte_code_to_mbc,
- mbc_to_normalize,
- is_mbc_ambiguous,
- get_all_pair_ambig_codes,
- onigenc_ess_tsett_get_all_comp_ambig_codes,
+ mbc_case_fold,
+ apply_all_case_fold,
+ get_case_fold_codes_by_str,
+ onigenc_minimum_property_name_to_ctype,
is_code_ctype,
onigenc_not_support_get_ctype_code_range,
onigenc_single_byte_left_adjust_char_head,
diff --git a/ext/mbstring/oniguruma/enc/iso8859_16.c b/ext/mbstring/oniguruma/enc/iso8859_16.c
index 921ae36d9d..8b39c58a6b 100644
--- a/ext/mbstring/oniguruma/enc/iso8859_16.c
+++ b/ext/mbstring/oniguruma/enc/iso8859_16.c
@@ -31,7 +31,7 @@
#define ENC_ISO_8859_16_TO_LOWER_CASE(c) EncISO_8859_16_ToLowerCaseTable[c]
#define ENC_IS_ISO_8859_16_CTYPE(code,ctype) \
- ((EncISO_8859_16_CtypeTable[code] & ctype) != 0)
+ ((EncISO_8859_16_CtypeTable[code] & CTYPE_TO_BIT(ctype)) != 0)
static const UChar EncISO_8859_16_ToLowerCaseTable[256] = {
'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
@@ -69,84 +69,79 @@ static const UChar EncISO_8859_16_ToLowerCaseTable[256] = {
};
static const unsigned short EncISO_8859_16_CtypeTable[256] = {
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x220c, 0x2209, 0x2208, 0x2208, 0x2208, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2284, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0,
- 0x38b0, 0x38b0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x31a0,
- 0x21a0, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x2008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x420c, 0x4209, 0x4208, 0x4208, 0x4208, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4284, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0,
+ 0x78b0, 0x78b0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x51a0,
+ 0x41a0, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x4008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
- 0x0284, 0x14a2, 0x10e2, 0x14a2, 0x00a0, 0x01a0, 0x14a2, 0x00a0,
- 0x10e2, 0x00a0, 0x14a2, 0x01a0, 0x14a2, 0x01a0, 0x10e2, 0x14a2,
- 0x00a0, 0x00a0, 0x14a2, 0x10e2, 0x14a2, 0x01a0, 0x00a0, 0x01a0,
- 0x10e2, 0x10e2, 0x10e2, 0x01a0, 0x14a2, 0x10e2, 0x14a2, 0x10e2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2
+ 0x0284, 0x34a2, 0x30e2, 0x34a2, 0x00a0, 0x01a0, 0x34a2, 0x00a0,
+ 0x30e2, 0x00a0, 0x34a2, 0x01a0, 0x34a2, 0x01a0, 0x30e2, 0x34a2,
+ 0x00a0, 0x00a0, 0x34a2, 0x30e2, 0x34a2, 0x01a0, 0x00a0, 0x01a0,
+ 0x30e2, 0x30e2, 0x30e2, 0x01a0, 0x34a2, 0x30e2, 0x34a2, 0x30e2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2
};
static int
-mbc_to_normalize(OnigAmbigType flag,
- const UChar** pp, const UChar* end, UChar* lower)
+mbc_case_fold(OnigCaseFoldType flag,
+ const UChar** pp, const UChar* end ARG_UNUSED, UChar* lower)
{
const UChar* p = *pp;
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- *lower = ENC_ISO_8859_16_TO_LOWER_CASE(*p);
- }
- else {
- *lower = *p;
+ if (*p == 0xdf && (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
+ *lower++ = 's';
+ *lower = 's';
+ (*pp)++;
+ return 2;
}
+
+ *lower = ENC_ISO_8859_16_TO_LOWER_CASE(*p);
(*pp)++;
return 1; /* return byte length of converted char to lower */
}
+#if 0
static int
-is_mbc_ambiguous(OnigAmbigType flag, const UChar** pp, const UChar* end)
+is_mbc_ambiguous(OnigCaseFoldType flag, const UChar** pp, const UChar* end)
{
+ int v;
const UChar* p = *pp;
- (*pp)++;
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- int v = (EncISO_8859_16_CtypeTable[*p] &
- (ONIGENC_CTYPE_UPPER | ONIGENC_CTYPE_LOWER));
-
- if ((v | ONIGENC_CTYPE_LOWER) != 0) {
- /* 0xdf is lower case letter, but can't convert. */
- if (*p == 0xdf)
- return FALSE;
- else
- return TRUE;
- }
+ if (*p == 0xdf && (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
+ (*pp)++;
+ return TRUE;
+ }
- return (v != 0 ? TRUE : FALSE);
+ (*pp)++;
+ v = (EncISO_8859_16_CtypeTable[*p] & (BIT_CTYPE_UPPER | BIT_CTYPE_LOWER));
+ if ((v | BIT_CTYPE_LOWER) != 0) {
+ return TRUE;
}
- return FALSE;
+
+ return (v != 0 ? TRUE : FALSE);
}
+#endif
static int
is_code_ctype(OnigCodePoint code, unsigned int ctype)
@@ -157,109 +152,69 @@ is_code_ctype(OnigCodePoint code, unsigned int ctype)
return FALSE;
}
+static const OnigPairCaseFoldCodes CaseFoldMap[] = {
+ { 0xa1, 0xa2 },
+ { 0xa3, 0xb3 },
+ { 0xa6, 0xa8 },
+ { 0xaa, 0xba },
+ { 0xac, 0xae },
+ { 0xaf, 0xbf },
+
+ { 0xb2, 0xb9 },
+ { 0xb4, 0xb8 },
+ { 0xbc, 0xbd },
+ { 0xbe, 0xff },
+
+ { 0xc0, 0xe0 },
+ { 0xc1, 0xe1 },
+ { 0xc2, 0xe2 },
+ { 0xc3, 0xe3 },
+ { 0xc4, 0xe4 },
+ { 0xc5, 0xe5 },
+ { 0xc6, 0xe6 },
+ { 0xc7, 0xe7 },
+ { 0xc8, 0xe8 },
+ { 0xc9, 0xe9 },
+ { 0xca, 0xea },
+ { 0xcb, 0xeb },
+ { 0xcc, 0xec },
+ { 0xcd, 0xed },
+ { 0xce, 0xee },
+ { 0xcf, 0xef },
+
+ { 0xd0, 0xf0 },
+ { 0xd1, 0xf1 },
+ { 0xd2, 0xf2 },
+ { 0xd3, 0xf3 },
+ { 0xd4, 0xf4 },
+ { 0xd5, 0xf5 },
+ { 0xd6, 0xf6 },
+ { 0xd7, 0xf7 },
+ { 0xd8, 0xf8 },
+ { 0xd9, 0xf9 },
+ { 0xda, 0xfa },
+ { 0xdb, 0xfb },
+ { 0xdc, 0xfc },
+ { 0xdd, 0xfd },
+ { 0xde, 0xfe }
+};
+
static int
-get_all_pair_ambig_codes(OnigAmbigType flag, const OnigPairAmbigCodes** ccs)
+apply_all_case_fold(OnigCaseFoldType flag,
+ OnigApplyAllCaseFoldFunc f, void* arg)
{
- static const OnigPairAmbigCodes cc[] = {
- { 0xa1, 0xa2 },
- { 0xa2, 0xa1 },
- { 0xa3, 0xb3 },
- { 0xa6, 0xa8 },
- { 0xa8, 0xa6 },
- { 0xaa, 0xba },
- { 0xac, 0xae },
- { 0xae, 0xac },
- { 0xaf, 0xbf },
-
- { 0xb2, 0xb9 },
- { 0xb3, 0xa3 },
- { 0xb4, 0xb8 },
- { 0xb8, 0xb4 },
- { 0xb9, 0xb2 },
- { 0xba, 0xaa },
- { 0xbc, 0xbd },
- { 0xbd, 0xbc },
- { 0xbe, 0xff },
- { 0xbf, 0xaf },
-
- { 0xc0, 0xe0 },
- { 0xc1, 0xe1 },
- { 0xc2, 0xe2 },
- { 0xc3, 0xe3 },
- { 0xc4, 0xe4 },
- { 0xc5, 0xe5 },
- { 0xc6, 0xe6 },
- { 0xc7, 0xe7 },
- { 0xc8, 0xe8 },
- { 0xc9, 0xe9 },
- { 0xca, 0xea },
- { 0xcb, 0xeb },
- { 0xcc, 0xec },
- { 0xcd, 0xed },
- { 0xce, 0xee },
- { 0xcf, 0xef },
-
- { 0xd0, 0xf0 },
- { 0xd1, 0xf1 },
- { 0xd2, 0xf2 },
- { 0xd3, 0xf3 },
- { 0xd4, 0xf4 },
- { 0xd5, 0xf5 },
- { 0xd6, 0xf6 },
- { 0xd7, 0xf7 },
- { 0xd8, 0xf8 },
- { 0xd9, 0xf9 },
- { 0xda, 0xfa },
- { 0xdb, 0xfb },
- { 0xdc, 0xfc },
- { 0xdd, 0xfd },
- { 0xde, 0xfe },
-
- { 0xe0, 0xc0 },
- { 0xe1, 0xc1 },
- { 0xe2, 0xc2 },
- { 0xe3, 0xc3 },
- { 0xe4, 0xc4 },
- { 0xe5, 0xc5 },
- { 0xe6, 0xc6 },
- { 0xe7, 0xc7 },
- { 0xe8, 0xc8 },
- { 0xe9, 0xc9 },
- { 0xea, 0xca },
- { 0xeb, 0xcb },
- { 0xec, 0xcc },
- { 0xed, 0xcd },
- { 0xee, 0xce },
- { 0xef, 0xcf },
-
- { 0xf0, 0xd0 },
- { 0xf1, 0xd1 },
- { 0xf2, 0xd2 },
- { 0xf3, 0xd3 },
- { 0xf4, 0xd4 },
- { 0xf5, 0xd5 },
- { 0xf6, 0xd6 },
- { 0xf7, 0xd7 },
- { 0xf8, 0xd8 },
- { 0xf9, 0xd9 },
- { 0xfa, 0xda },
- { 0xfb, 0xdb },
- { 0xfc, 0xdc },
- { 0xfd, 0xdd },
- { 0xfe, 0xde },
- { 0xff, 0xbe }
- };
+ return onigenc_apply_all_case_fold_with_map(
+ sizeof(CaseFoldMap)/sizeof(OnigPairCaseFoldCodes), CaseFoldMap, 1,
+ flag, f, arg);
+}
- if (flag == ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) {
- *ccs = OnigAsciiPairAmbigCodes;
- return 52;
- }
- if (flag == ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) {
- *ccs = cc;
- return sizeof(cc) / sizeof(OnigPairAmbigCodes);
- }
- else
- return 0;
+static int
+get_case_fold_codes_by_str(OnigCaseFoldType flag,
+ const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[])
+{
+ return onigenc_get_case_fold_codes_by_str_with_map(
+ sizeof(CaseFoldMap)/sizeof(OnigPairCaseFoldCodes), CaseFoldMap, 1,
+ flag, p, end, items);
}
OnigEncodingType OnigEncodingISO_8859_16 = {
@@ -267,24 +222,14 @@ OnigEncodingType OnigEncodingISO_8859_16 = {
"ISO-8859-16", /* name */
1, /* max enc length */
1, /* min enc length */
- (ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE |
- ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE ),
- {
- (OnigCodePoint )'\\' /* esc */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
- },
onigenc_is_mbc_newline_0x0a,
onigenc_single_byte_mbc_to_code,
onigenc_single_byte_code_to_mbclen,
onigenc_single_byte_code_to_mbc,
- mbc_to_normalize,
- is_mbc_ambiguous,
- get_all_pair_ambig_codes,
- onigenc_ess_tsett_get_all_comp_ambig_codes,
+ mbc_case_fold,
+ apply_all_case_fold,
+ get_case_fold_codes_by_str,
+ onigenc_minimum_property_name_to_ctype,
is_code_ctype,
onigenc_not_support_get_ctype_code_range,
onigenc_single_byte_left_adjust_char_head,
diff --git a/ext/mbstring/oniguruma/enc/iso8859_2.c b/ext/mbstring/oniguruma/enc/iso8859_2.c
index f8cb3756f2..80b93ba1ba 100644
--- a/ext/mbstring/oniguruma/enc/iso8859_2.c
+++ b/ext/mbstring/oniguruma/enc/iso8859_2.c
@@ -2,7 +2,7 @@
iso8859_2.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2006 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2007 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
#define ENC_ISO_8859_2_TO_LOWER_CASE(c) EncISO_8859_2_ToLowerCaseTable[c]
#define ENC_IS_ISO_8859_2_CTYPE(code,ctype) \
- ((EncISO_8859_2_CtypeTable[code] & ctype) != 0)
+ ((EncISO_8859_2_CtypeTable[code] & CTYPE_TO_BIT(ctype)) != 0)
static const UChar EncISO_8859_2_ToLowerCaseTable[256] = {
'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
@@ -69,192 +69,145 @@ static const UChar EncISO_8859_2_ToLowerCaseTable[256] = {
};
static const unsigned short EncISO_8859_2_CtypeTable[256] = {
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x220c, 0x2209, 0x2208, 0x2208, 0x2208, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2284, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0,
- 0x38b0, 0x38b0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x31a0,
- 0x21a0, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x2008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x420c, 0x4209, 0x4208, 0x4208, 0x4208, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4284, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0,
+ 0x78b0, 0x78b0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x51a0,
+ 0x41a0, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x4008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
- 0x0284, 0x14a2, 0x00a0, 0x14a2, 0x00a0, 0x14a2, 0x14a2, 0x00a0,
- 0x00a0, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x01a0, 0x14a2, 0x14a2,
- 0x00a0, 0x10e2, 0x00a0, 0x10e2, 0x00a0, 0x10e2, 0x10e2, 0x00a0,
- 0x00a0, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x00a0, 0x10e2, 0x10e2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x00a0,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x00a0,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x00a0
+ 0x0284, 0x34a2, 0x00a0, 0x34a2, 0x00a0, 0x34a2, 0x34a2, 0x00a0,
+ 0x00a0, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x01a0, 0x34a2, 0x34a2,
+ 0x00a0, 0x30e2, 0x00a0, 0x30e2, 0x00a0, 0x30e2, 0x30e2, 0x00a0,
+ 0x00a0, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x00a0, 0x30e2, 0x30e2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x00a0,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x00a0,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x00a0
};
static int
-iso_8859_2_mbc_to_normalize(OnigAmbigType flag,
- const UChar** pp, const UChar* end, UChar* lower)
+mbc_case_fold(OnigCaseFoldType flag,
+ const UChar** pp, const UChar* end ARG_UNUSED, UChar* lower)
{
const UChar* p = *pp;
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- *lower = ENC_ISO_8859_2_TO_LOWER_CASE(*p);
- }
- else {
- *lower = *p;
+ if (*p == 0xdf && (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
+ *lower++ = 's';
+ *lower = 's';
+ (*pp)++;
+ return 2;
}
+
+ *lower = ENC_ISO_8859_2_TO_LOWER_CASE(*p);
(*pp)++;
return 1; /* return byte length of converted char to lower */
}
+#if 0
static int
-iso_8859_2_is_mbc_ambiguous(OnigAmbigType flag,
- const UChar** pp, const UChar* end)
+is_mbc_ambiguous(OnigCaseFoldType flag, const UChar** pp, const UChar* end)
{
+ int v;
const UChar* p = *pp;
- (*pp)++;
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- int v = (EncISO_8859_2_CtypeTable[*p] &
- (ONIGENC_CTYPE_UPPER | ONIGENC_CTYPE_LOWER));
-
- if ((v | ONIGENC_CTYPE_LOWER) != 0) {
- /* 0xdf is lower case letter, but can't convert. */
- if (*p == 0xdf)
- return FALSE;
- else
- return TRUE;
- }
+ if (*p == 0xdf && (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
+ (*pp)++;
+ return TRUE;
+ }
- return (v != 0 ? TRUE : FALSE);
+ (*pp)++;
+ v = (EncISO_8859_2_CtypeTable[*p] & (BIT_CTYPE_UPPER | BIT_CTYPE_LOWER));
+ if ((v | BIT_CTYPE_LOWER) != 0) {
+ return TRUE;
}
- return FALSE;
+
+ return (v != 0 ? TRUE : FALSE);
}
+#endif
+
+static const OnigPairCaseFoldCodes CaseFoldMap[] = {
+ { 0xa1, 0xb1 },
+ { 0xa3, 0xb3 },
+ { 0xa5, 0xb5 },
+ { 0xa6, 0xb6 },
+ { 0xa9, 0xb9 },
+ { 0xaa, 0xba },
+ { 0xab, 0xbb },
+ { 0xac, 0xbc },
+ { 0xae, 0xbe },
+ { 0xaf, 0xbf },
+
+ { 0xc0, 0xe0 },
+ { 0xc1, 0xe1 },
+ { 0xc2, 0xe2 },
+ { 0xc3, 0xe3 },
+ { 0xc4, 0xe4 },
+ { 0xc5, 0xe5 },
+ { 0xc6, 0xe6 },
+ { 0xc7, 0xe7 },
+ { 0xc8, 0xe8 },
+ { 0xc9, 0xe9 },
+ { 0xca, 0xea },
+ { 0xcb, 0xeb },
+ { 0xcc, 0xec },
+ { 0xcd, 0xed },
+ { 0xce, 0xee },
+ { 0xcf, 0xef },
+
+ { 0xd0, 0xf0 },
+ { 0xd1, 0xf1 },
+ { 0xd2, 0xf2 },
+ { 0xd3, 0xf3 },
+ { 0xd4, 0xf4 },
+ { 0xd5, 0xf5 },
+ { 0xd6, 0xf6 },
+ { 0xd8, 0xf8 },
+ { 0xd9, 0xf9 },
+ { 0xda, 0xfa },
+ { 0xdb, 0xfb },
+ { 0xdc, 0xfc },
+ { 0xdd, 0xfd },
+ { 0xde, 0xfe }
+};
static int
-iso_8859_2_get_all_pair_ambig_codes(OnigAmbigType flag,
- const OnigPairAmbigCodes** ccs)
+apply_all_case_fold(OnigCaseFoldType flag,
+ OnigApplyAllCaseFoldFunc f, void* arg)
{
- static const OnigPairAmbigCodes cc[] = {
- { 0xa1, 0xb1 },
- { 0xa3, 0xb3 },
- { 0xa5, 0xb5 },
- { 0xa6, 0xb6 },
- { 0xa9, 0xb9 },
- { 0xaa, 0xba },
- { 0xab, 0xbb },
- { 0xac, 0xbc },
- { 0xae, 0xbe },
- { 0xaf, 0xbf },
-
- { 0xb1, 0xa1 },
- { 0xb3, 0xa3 },
- { 0xb5, 0xa5 },
- { 0xb6, 0xa6 },
- { 0xb9, 0xa9 },
- { 0xba, 0xaa },
- { 0xbb, 0xab },
- { 0xbc, 0xac },
- { 0xbe, 0xae },
- { 0xbf, 0xaf },
-
- { 0xc0, 0xe0 },
- { 0xc1, 0xe1 },
- { 0xc2, 0xe2 },
- { 0xc3, 0xe3 },
- { 0xc4, 0xe4 },
- { 0xc5, 0xe5 },
- { 0xc6, 0xe6 },
- { 0xc7, 0xe7 },
- { 0xc8, 0xe8 },
- { 0xc9, 0xe9 },
- { 0xca, 0xea },
- { 0xcb, 0xeb },
- { 0xcc, 0xec },
- { 0xcd, 0xed },
- { 0xce, 0xee },
- { 0xcf, 0xef },
-
- { 0xd0, 0xf0 },
- { 0xd1, 0xf1 },
- { 0xd2, 0xf2 },
- { 0xd3, 0xf3 },
- { 0xd4, 0xf4 },
- { 0xd5, 0xf5 },
- { 0xd6, 0xf6 },
- { 0xd8, 0xf8 },
- { 0xd9, 0xf9 },
- { 0xda, 0xfa },
- { 0xdb, 0xfb },
- { 0xdc, 0xfc },
- { 0xdd, 0xfd },
- { 0xde, 0xfe },
-
- { 0xe0, 0xc0 },
- { 0xe1, 0xc1 },
- { 0xe2, 0xc2 },
- { 0xe3, 0xc3 },
- { 0xe4, 0xc4 },
- { 0xe5, 0xc5 },
- { 0xe6, 0xc6 },
- { 0xe7, 0xc7 },
- { 0xe8, 0xc8 },
- { 0xe9, 0xc9 },
- { 0xea, 0xca },
- { 0xeb, 0xcb },
- { 0xec, 0xcc },
- { 0xed, 0xcd },
- { 0xee, 0xce },
- { 0xef, 0xcf },
-
- { 0xf0, 0xd0 },
- { 0xf1, 0xd1 },
- { 0xf2, 0xd2 },
- { 0xf3, 0xd3 },
- { 0xf4, 0xd4 },
- { 0xf5, 0xd5 },
- { 0xf6, 0xd6 },
- { 0xf8, 0xd8 },
- { 0xf9, 0xd9 },
- { 0xfa, 0xda },
- { 0xfb, 0xdb },
- { 0xfc, 0xdc },
- { 0xfd, 0xdd },
- { 0xfe, 0xde }
- };
+ return onigenc_apply_all_case_fold_with_map(
+ sizeof(CaseFoldMap)/sizeof(OnigPairCaseFoldCodes), CaseFoldMap, 1,
+ flag, f, arg);
+}
- if (flag == ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) {
- *ccs = OnigAsciiPairAmbigCodes;
- return 52;
- }
- if (flag == ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) {
- *ccs = cc;
- return sizeof(cc) / sizeof(OnigPairAmbigCodes);
- }
- else
- return 0;
+static int
+get_case_fold_codes_by_str(OnigCaseFoldType flag,
+ const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[])
+{
+ return onigenc_get_case_fold_codes_by_str_with_map(
+ sizeof(CaseFoldMap)/sizeof(OnigPairCaseFoldCodes), CaseFoldMap, 1,
+ flag, p, end, items);
}
static int
-iso_8859_2_is_code_ctype(OnigCodePoint code, unsigned int ctype)
+is_code_ctype(OnigCodePoint code, unsigned int ctype)
{
if (code < 256)
return ENC_IS_ISO_8859_2_CTYPE(code, ctype);
@@ -267,25 +220,15 @@ OnigEncodingType OnigEncodingISO_8859_2 = {
"ISO-8859-2", /* name */
1, /* max enc length */
1, /* min enc length */
- (ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE |
- ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE ),
- {
- (OnigCodePoint )'\\' /* esc */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
- },
onigenc_is_mbc_newline_0x0a,
onigenc_single_byte_mbc_to_code,
onigenc_single_byte_code_to_mbclen,
onigenc_single_byte_code_to_mbc,
- iso_8859_2_mbc_to_normalize,
- iso_8859_2_is_mbc_ambiguous,
- iso_8859_2_get_all_pair_ambig_codes,
- onigenc_ess_tsett_get_all_comp_ambig_codes,
- iso_8859_2_is_code_ctype,
+ mbc_case_fold,
+ apply_all_case_fold,
+ get_case_fold_codes_by_str,
+ onigenc_minimum_property_name_to_ctype,
+ is_code_ctype,
onigenc_not_support_get_ctype_code_range,
onigenc_single_byte_left_adjust_char_head,
onigenc_always_true_is_allowed_reverse_match
diff --git a/ext/mbstring/oniguruma/enc/iso8859_3.c b/ext/mbstring/oniguruma/enc/iso8859_3.c
index e62d20de7b..fd1168c381 100644
--- a/ext/mbstring/oniguruma/enc/iso8859_3.c
+++ b/ext/mbstring/oniguruma/enc/iso8859_3.c
@@ -2,7 +2,7 @@
iso8859_3.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2006 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2007 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
#define ENC_ISO_8859_3_TO_LOWER_CASE(c) EncISO_8859_3_ToLowerCaseTable[c]
#define ENC_IS_ISO_8859_3_CTYPE(code,ctype) \
- ((EncISO_8859_3_CtypeTable[code] & ctype) != 0)
+ ((EncISO_8859_3_CtypeTable[code] & CTYPE_TO_BIT(ctype)) != 0)
static const UChar EncISO_8859_3_ToLowerCaseTable[256] = {
'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
@@ -69,88 +69,86 @@ static const UChar EncISO_8859_3_ToLowerCaseTable[256] = {
};
static const unsigned short EncISO_8859_3_CtypeTable[256] = {
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x220c, 0x2209, 0x2208, 0x2208, 0x2208, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2284, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0,
- 0x38b0, 0x38b0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x31a0,
- 0x21a0, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x2008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x420c, 0x4209, 0x4208, 0x4208, 0x4208, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4284, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0,
+ 0x78b0, 0x78b0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x51a0,
+ 0x41a0, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x4008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
- 0x0284, 0x14a2, 0x00a0, 0x00a0, 0x00a0, 0x0000, 0x14a2, 0x00a0,
- 0x00a0, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x01a0, 0x0000, 0x14a2,
- 0x00a0, 0x10e2, 0x10a0, 0x10a0, 0x00a0, 0x10e2, 0x10e2, 0x01a0,
- 0x00a0, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x11a0, 0x0000, 0x10e2,
- 0x14a2, 0x14a2, 0x14a2, 0x0000, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x0000, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x00a0,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x0000, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x0000, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x00a0,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x00a0
+ 0x0284, 0x34a2, 0x00a0, 0x00a0, 0x00a0, 0x0000, 0x34a2, 0x00a0,
+ 0x00a0, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x01a0, 0x0000, 0x34a2,
+ 0x00a0, 0x30e2, 0x10a0, 0x10a0, 0x00a0, 0x30e2, 0x30e2, 0x01a0,
+ 0x00a0, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x11a0, 0x0000, 0x30e2,
+ 0x34a2, 0x34a2, 0x34a2, 0x0000, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x0000, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x00a0,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x0000, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x0000, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x00a0,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x00a0
};
static int
-iso_8859_3_mbc_to_normalize(OnigAmbigType flag,
- const UChar** pp, const UChar* end, UChar* lower)
+mbc_case_fold(OnigCaseFoldType flag, const UChar** pp,
+ const UChar* end ARG_UNUSED, UChar* lower)
{
const UChar* p = *pp;
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- *lower = ENC_ISO_8859_3_TO_LOWER_CASE(*p);
- }
- else {
- *lower = *p;
+ if (*p == 0xdf && (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
+ *lower++ = 's';
+ *lower = 's';
+ (*pp)++;
+ return 2;
}
+
+ *lower = ENC_ISO_8859_3_TO_LOWER_CASE(*p);
(*pp)++;
- return 1; /* return byte length of converted char to lower */
+ return 1;
}
+#if 0
static int
-iso_8859_3_is_mbc_ambiguous(OnigAmbigType flag,
- const UChar** pp, const UChar* end)
+is_mbc_ambiguous(OnigCaseFoldType flag, const UChar** pp, const UChar* end)
{
+ int v;
const UChar* p = *pp;
- (*pp)++;
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- int v = (EncISO_8859_3_CtypeTable[*p] &
- (ONIGENC_CTYPE_UPPER | ONIGENC_CTYPE_LOWER));
-
- if ((v | ONIGENC_CTYPE_LOWER) != 0) {
- /* 0xdf, 0xaa, 0xb5, 0xba are lower case letter, but can't convert. */
- if (*p == 0xdf || *p == 0xb5)
- return FALSE;
- else
- return TRUE;
- }
+ if (*p == 0xdf && (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
+ (*pp)++;
+ return TRUE;
+ }
- return (v != 0 ? TRUE : FALSE);
+ (*pp)++;
+ v = (EncISO_8859_3_CtypeTable[*p] & (BIT_CTYPE_UPPER | BIT_CTYPE_LOWER));
+ if ((v | BIT_CTYPE_LOWER) != 0) {
+ /* 0xaa, 0xb5, 0xba are lower case letter, but can't convert. */
+ if (*p == 0xb5)
+ return FALSE;
+ else
+ return TRUE;
}
- return FALSE;
+
+ return (v != 0 ? TRUE : FALSE);
}
+#endif
static int
-iso_8859_3_is_code_ctype(OnigCodePoint code, unsigned int ctype)
+is_code_ctype(OnigCodePoint code, unsigned int ctype)
{
if (code < 256)
return ENC_IS_ISO_8859_3_CTYPE(code, ctype);
@@ -158,97 +156,63 @@ iso_8859_3_is_code_ctype(OnigCodePoint code, unsigned int ctype)
return FALSE;
}
-static int
-iso_8859_3_get_all_pair_ambig_codes(OnigAmbigType flag,
- const OnigPairAmbigCodes** ccs)
-{
- static const OnigPairAmbigCodes cc[] = {
- { 0xa1, 0xb1 },
- { 0xa6, 0xb6 },
- { 0xa9, 0xb9 },
- { 0xaa, 0xba },
- { 0xab, 0xbb },
- { 0xac, 0xbc },
- { 0xaf, 0xbf },
- { 0xb1, 0xa1 },
- { 0xb6, 0xa6 },
- { 0xb9, 0xa9 },
- { 0xba, 0xaa },
- { 0xbb, 0xab },
- { 0xbc, 0xac },
- { 0xbf, 0xaf },
-
- { 0xc0, 0xe0 },
- { 0xc1, 0xe1 },
- { 0xc2, 0xe2 },
- { 0xc4, 0xe4 },
- { 0xc5, 0xe5 },
- { 0xc6, 0xe6 },
- { 0xc7, 0xe7 },
- { 0xc8, 0xe8 },
- { 0xc9, 0xe9 },
- { 0xca, 0xea },
- { 0xcb, 0xeb },
- { 0xcc, 0xec },
- { 0xcd, 0xed },
- { 0xce, 0xee },
- { 0xcf, 0xef },
-
- { 0xd1, 0xf1 },
- { 0xd2, 0xf2 },
- { 0xd3, 0xf3 },
- { 0xd4, 0xf4 },
- { 0xd5, 0xf5 },
- { 0xd6, 0xf6 },
- { 0xd8, 0xf8 },
- { 0xd9, 0xf9 },
- { 0xda, 0xfa },
- { 0xdb, 0xfb },
- { 0xdc, 0xfc },
- { 0xdd, 0xfd },
- { 0xde, 0xfe },
+static const OnigPairCaseFoldCodes CaseFoldMap[] = {
+ { 0xa1, 0xb1 },
+ { 0xa6, 0xb6 },
+ { 0xa9, 0xb9 },
+ { 0xaa, 0xba },
+ { 0xab, 0xbb },
+ { 0xac, 0xbc },
+ { 0xaf, 0xbf },
+
+ { 0xc0, 0xe0 },
+ { 0xc1, 0xe1 },
+ { 0xc2, 0xe2 },
+ { 0xc4, 0xe4 },
+ { 0xc5, 0xe5 },
+ { 0xc6, 0xe6 },
+ { 0xc7, 0xe7 },
+ { 0xc8, 0xe8 },
+ { 0xc9, 0xe9 },
+ { 0xca, 0xea },
+ { 0xcb, 0xeb },
+ { 0xcc, 0xec },
+ { 0xcd, 0xed },
+ { 0xce, 0xee },
+ { 0xcf, 0xef },
+
+ { 0xd1, 0xf1 },
+ { 0xd2, 0xf2 },
+ { 0xd3, 0xf3 },
+ { 0xd4, 0xf4 },
+ { 0xd5, 0xf5 },
+ { 0xd6, 0xf6 },
+ { 0xd8, 0xf8 },
+ { 0xd9, 0xf9 },
+ { 0xda, 0xfa },
+ { 0xdb, 0xfb },
+ { 0xdc, 0xfc },
+ { 0xdd, 0xfd },
+ { 0xde, 0xfe }
+};
- { 0xe0, 0xc0 },
- { 0xe1, 0xc1 },
- { 0xe2, 0xc2 },
- { 0xe4, 0xc4 },
- { 0xe5, 0xc5 },
- { 0xe6, 0xc6 },
- { 0xe7, 0xc7 },
- { 0xe8, 0xc8 },
- { 0xe9, 0xc9 },
- { 0xea, 0xca },
- { 0xeb, 0xcb },
- { 0xec, 0xcc },
- { 0xed, 0xcd },
- { 0xee, 0xce },
- { 0xef, 0xcf },
- { 0xf1, 0xd1 },
- { 0xf2, 0xd2 },
- { 0xf3, 0xd3 },
- { 0xf4, 0xd4 },
- { 0xf5, 0xd5 },
- { 0xf6, 0xd6 },
- { 0xf8, 0xd8 },
- { 0xf9, 0xd9 },
- { 0xfa, 0xda },
- { 0xfb, 0xdb },
- { 0xfc, 0xdc },
- { 0xfd, 0xdd },
- { 0xfe, 0xde }
- };
+static int
+apply_all_case_fold(OnigCaseFoldType flag,
+ OnigApplyAllCaseFoldFunc f, void* arg)
+{
+ return onigenc_apply_all_case_fold_with_map(
+ sizeof(CaseFoldMap)/sizeof(OnigPairCaseFoldCodes), CaseFoldMap, 1,
+ flag, f, arg);
+}
- if (flag == ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) {
- *ccs = OnigAsciiPairAmbigCodes;
- return 52;
- }
- if (flag == ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) {
- *ccs = cc;
- return sizeof(cc) / sizeof(OnigPairAmbigCodes);
- }
- else
- return 0;
+static int
+get_case_fold_codes_by_str(OnigCaseFoldType flag,
+ const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[])
+{
+ return onigenc_get_case_fold_codes_by_str_with_map(
+ sizeof(CaseFoldMap)/sizeof(OnigPairCaseFoldCodes), CaseFoldMap, 1,
+ flag, p, end, items);
}
OnigEncodingType OnigEncodingISO_8859_3 = {
@@ -256,25 +220,15 @@ OnigEncodingType OnigEncodingISO_8859_3 = {
"ISO-8859-3", /* name */
1, /* max enc length */
1, /* min enc length */
- (ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE |
- ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE ),
- {
- (OnigCodePoint )'\\' /* esc */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
- },
onigenc_is_mbc_newline_0x0a,
onigenc_single_byte_mbc_to_code,
onigenc_single_byte_code_to_mbclen,
onigenc_single_byte_code_to_mbc,
- iso_8859_3_mbc_to_normalize,
- iso_8859_3_is_mbc_ambiguous,
- iso_8859_3_get_all_pair_ambig_codes,
- onigenc_ess_tsett_get_all_comp_ambig_codes,
- iso_8859_3_is_code_ctype,
+ mbc_case_fold,
+ apply_all_case_fold,
+ get_case_fold_codes_by_str,
+ onigenc_minimum_property_name_to_ctype,
+ is_code_ctype,
onigenc_not_support_get_ctype_code_range,
onigenc_single_byte_left_adjust_char_head,
onigenc_always_true_is_allowed_reverse_match
diff --git a/ext/mbstring/oniguruma/enc/iso8859_4.c b/ext/mbstring/oniguruma/enc/iso8859_4.c
index dd6bd7dfe3..c124f5653d 100644
--- a/ext/mbstring/oniguruma/enc/iso8859_4.c
+++ b/ext/mbstring/oniguruma/enc/iso8859_4.c
@@ -2,7 +2,7 @@
iso8859_4.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2006 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2007 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
#define ENC_ISO_8859_4_TO_LOWER_CASE(c) EncISO_8859_4_ToLowerCaseTable[c]
#define ENC_IS_ISO_8859_4_CTYPE(code,ctype) \
- ((EncISO_8859_4_CtypeTable[code] & ctype) != 0)
+ ((EncISO_8859_4_CtypeTable[code] & CTYPE_TO_BIT(ctype)) != 0)
static const UChar EncISO_8859_4_ToLowerCaseTable[256] = {
'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
@@ -69,88 +69,85 @@ static const UChar EncISO_8859_4_ToLowerCaseTable[256] = {
};
static const unsigned short EncISO_8859_4_CtypeTable[256] = {
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x220c, 0x2209, 0x2208, 0x2208, 0x2208, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2284, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0,
- 0x38b0, 0x38b0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x31a0,
- 0x21a0, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x2008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x420c, 0x4209, 0x4208, 0x4208, 0x4208, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4284, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0,
+ 0x78b0, 0x78b0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x51a0,
+ 0x41a0, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x4008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
- 0x0284, 0x14a2, 0x10e2, 0x14a2, 0x00a0, 0x14a2, 0x14a2, 0x00a0,
- 0x00a0, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x01a0, 0x14a2, 0x00a0,
- 0x00a0, 0x10e2, 0x00a0, 0x10e2, 0x00a0, 0x10e2, 0x10e2, 0x00a0,
- 0x00a0, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x14a2, 0x10e2, 0x10e2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x00a0,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x00a0,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x00a0
+ 0x0284, 0x34a2, 0x30e2, 0x34a2, 0x00a0, 0x34a2, 0x34a2, 0x00a0,
+ 0x00a0, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x01a0, 0x34a2, 0x00a0,
+ 0x00a0, 0x30e2, 0x00a0, 0x30e2, 0x00a0, 0x30e2, 0x30e2, 0x00a0,
+ 0x00a0, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x34a2, 0x30e2, 0x30e2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x00a0,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x00a0,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x00a0
};
static int
-iso_8859_4_mbc_to_normalize(OnigAmbigType flag,
- const UChar** pp, const UChar* end, UChar* lower)
+mbc_case_fold(OnigCaseFoldType flag,
+ const UChar** pp, const UChar* end ARG_UNUSED, UChar* lower)
{
const UChar* p = *pp;
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- *lower = ENC_ISO_8859_4_TO_LOWER_CASE(*p);
- }
- else {
- *lower = *p;
+ if (*p == 0xdf && (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
+ *lower++ = 's';
+ *lower = 's';
+ (*pp)++;
+ return 2;
}
+
+ *lower = ENC_ISO_8859_4_TO_LOWER_CASE(*p);
(*pp)++;
return 1; /* return byte length of converted char to lower */
}
+#if 0
static int
-iso_8859_4_is_mbc_ambiguous(OnigAmbigType flag,
- const UChar** pp, const UChar* end)
+is_mbc_ambiguous(OnigCaseFoldType flag, const UChar** pp, const UChar* end)
{
+ int v;
const UChar* p = *pp;
- (*pp)++;
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- int v = (EncISO_8859_4_CtypeTable[*p] &
- (ONIGENC_CTYPE_UPPER | ONIGENC_CTYPE_LOWER));
-
- if ((v | ONIGENC_CTYPE_LOWER) != 0) {
- /* 0xdf, 0xaa, 0xb5, 0xba are lower case letter, but can't convert. */
- if (*p == 0xdf || *p == 0xa2)
- return FALSE;
- else
- return TRUE;
- }
+ if (*p == 0xdf && (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
+ (*pp)++;
+ return TRUE;
+ }
- return (v != 0 ? TRUE : FALSE);
+ (*pp)++;
+ v = (EncISO_8859_4_CtypeTable[*p] & (BIT_CTYPE_UPPER | BIT_CTYPE_LOWER));
+ if ((v | BIT_CTYPE_LOWER) != 0) {
+ if (*p == 0xa2)
+ return FALSE;
+ else
+ return TRUE;
}
- return FALSE;
+
+ return (v != 0 ? TRUE : FALSE);
}
+#endif
static int
-iso_8859_4_is_code_ctype(OnigCodePoint code, unsigned int ctype)
+is_code_ctype(OnigCodePoint code, unsigned int ctype)
{
if (code < 256)
return ENC_IS_ISO_8859_4_CTYPE(code, ctype);
@@ -158,106 +155,66 @@ iso_8859_4_is_code_ctype(OnigCodePoint code, unsigned int ctype)
return FALSE;
}
+static const OnigPairCaseFoldCodes CaseFoldMap[] = {
+ { 0xa1, 0xb1 },
+ { 0xa3, 0xb3 },
+ { 0xa5, 0xb5 },
+ { 0xa6, 0xb6 },
+ { 0xa9, 0xb9 },
+ { 0xaa, 0xba },
+ { 0xab, 0xbb },
+ { 0xac, 0xbc },
+ { 0xae, 0xbe },
+
+ { 0xc0, 0xe0 },
+ { 0xc1, 0xe1 },
+ { 0xc2, 0xe2 },
+ { 0xc3, 0xe3 },
+ { 0xc4, 0xe4 },
+ { 0xc5, 0xe5 },
+ { 0xc6, 0xe6 },
+ { 0xc7, 0xe7 },
+ { 0xc8, 0xe8 },
+ { 0xc9, 0xe9 },
+ { 0xca, 0xea },
+ { 0xcb, 0xeb },
+ { 0xcc, 0xec },
+ { 0xcd, 0xed },
+ { 0xce, 0xee },
+ { 0xcf, 0xef },
+
+ { 0xd0, 0xf0 },
+ { 0xd1, 0xf1 },
+ { 0xd2, 0xf2 },
+ { 0xd3, 0xf3 },
+ { 0xd4, 0xf4 },
+ { 0xd5, 0xf5 },
+ { 0xd6, 0xf6 },
+ { 0xd8, 0xf8 },
+ { 0xd9, 0xf9 },
+ { 0xda, 0xfa },
+ { 0xdb, 0xfb },
+ { 0xdc, 0xfc },
+ { 0xdd, 0xfd },
+ { 0xde, 0xfe }
+};
+
static int
-iso_8859_4_get_all_pair_ambig_codes(OnigAmbigType flag,
- const OnigPairAmbigCodes** ccs)
+apply_all_case_fold(OnigCaseFoldType flag,
+ OnigApplyAllCaseFoldFunc f, void* arg)
{
- static const OnigPairAmbigCodes cc[] = {
- { 0xa1, 0xb1 },
- { 0xa3, 0xb3 },
- { 0xa5, 0xb5 },
- { 0xa6, 0xb6 },
- { 0xa9, 0xb9 },
- { 0xaa, 0xba },
- { 0xab, 0xbb },
- { 0xac, 0xbc },
- { 0xae, 0xbe },
-
- { 0xb1, 0xa1 },
- { 0xb3, 0xa3 },
- { 0xb5, 0xa5 },
- { 0xb6, 0xa6 },
- { 0xb9, 0xa9 },
- { 0xba, 0xaa },
- { 0xbb, 0xab },
- { 0xbc, 0xac },
- { 0xbe, 0xae },
-
- { 0xc0, 0xe0 },
- { 0xc1, 0xe1 },
- { 0xc2, 0xe2 },
- { 0xc3, 0xe3 },
- { 0xc4, 0xe4 },
- { 0xc5, 0xe5 },
- { 0xc6, 0xe6 },
- { 0xc7, 0xe7 },
- { 0xc8, 0xe8 },
- { 0xc9, 0xe9 },
- { 0xca, 0xea },
- { 0xcb, 0xeb },
- { 0xcc, 0xec },
- { 0xcd, 0xed },
- { 0xce, 0xee },
- { 0xcf, 0xef },
-
- { 0xd0, 0xf0 },
- { 0xd1, 0xf1 },
- { 0xd2, 0xf2 },
- { 0xd3, 0xf3 },
- { 0xd4, 0xf4 },
- { 0xd5, 0xf5 },
- { 0xd6, 0xf6 },
- { 0xd8, 0xf8 },
- { 0xd9, 0xf9 },
- { 0xda, 0xfa },
- { 0xdb, 0xfb },
- { 0xdc, 0xfc },
- { 0xdd, 0xfd },
- { 0xde, 0xfe },
-
- { 0xe0, 0xc0 },
- { 0xe1, 0xc1 },
- { 0xe2, 0xc2 },
- { 0xe3, 0xc3 },
- { 0xe4, 0xc4 },
- { 0xe5, 0xc5 },
- { 0xe6, 0xc6 },
- { 0xe7, 0xc7 },
- { 0xe8, 0xc8 },
- { 0xe9, 0xc9 },
- { 0xea, 0xca },
- { 0xeb, 0xcb },
- { 0xec, 0xcc },
- { 0xed, 0xcd },
- { 0xee, 0xce },
- { 0xef, 0xcf },
-
- { 0xf0, 0xd0 },
- { 0xf1, 0xd1 },
- { 0xf2, 0xd2 },
- { 0xf3, 0xd3 },
- { 0xf4, 0xd4 },
- { 0xf5, 0xd5 },
- { 0xf6, 0xd6 },
- { 0xf8, 0xd8 },
- { 0xf9, 0xd9 },
- { 0xfa, 0xda },
- { 0xfb, 0xdb },
- { 0xfc, 0xdc },
- { 0xfd, 0xdd },
- { 0xfe, 0xde }
- };
+ return onigenc_apply_all_case_fold_with_map(
+ sizeof(CaseFoldMap)/sizeof(OnigPairCaseFoldCodes), CaseFoldMap, 1,
+ flag, f, arg);
+}
- if (flag == ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) {
- *ccs = OnigAsciiPairAmbigCodes;
- return 52;
- }
- if (flag == ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) {
- *ccs = cc;
- return sizeof(cc) / sizeof(OnigPairAmbigCodes);
- }
- else
- return 0;
+static int
+get_case_fold_codes_by_str(OnigCaseFoldType flag,
+ const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[])
+{
+ return onigenc_get_case_fold_codes_by_str_with_map(
+ sizeof(CaseFoldMap)/sizeof(OnigPairCaseFoldCodes), CaseFoldMap, 1,
+ flag, p, end, items);
}
OnigEncodingType OnigEncodingISO_8859_4 = {
@@ -265,25 +222,15 @@ OnigEncodingType OnigEncodingISO_8859_4 = {
"ISO-8859-4", /* name */
1, /* max enc length */
1, /* min enc length */
- (ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE |
- ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE ),
- {
- (OnigCodePoint )'\\' /* esc */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
- },
onigenc_is_mbc_newline_0x0a,
onigenc_single_byte_mbc_to_code,
onigenc_single_byte_code_to_mbclen,
onigenc_single_byte_code_to_mbc,
- iso_8859_4_mbc_to_normalize,
- iso_8859_4_is_mbc_ambiguous,
- iso_8859_4_get_all_pair_ambig_codes,
- onigenc_ess_tsett_get_all_comp_ambig_codes,
- iso_8859_4_is_code_ctype,
+ mbc_case_fold,
+ apply_all_case_fold,
+ get_case_fold_codes_by_str,
+ onigenc_minimum_property_name_to_ctype,
+ is_code_ctype,
onigenc_not_support_get_ctype_code_range,
onigenc_single_byte_left_adjust_char_head,
onigenc_always_true_is_allowed_reverse_match
diff --git a/ext/mbstring/oniguruma/enc/iso8859_5.c b/ext/mbstring/oniguruma/enc/iso8859_5.c
index 87b7fb8a29..1ca67e735f 100644
--- a/ext/mbstring/oniguruma/enc/iso8859_5.c
+++ b/ext/mbstring/oniguruma/enc/iso8859_5.c
@@ -2,7 +2,7 @@
iso8859_5.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2005 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2008 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
#define ENC_ISO_8859_5_TO_LOWER_CASE(c) EncISO_8859_5_ToLowerCaseTable[c]
#define ENC_IS_ISO_8859_5_CTYPE(code,ctype) \
- ((EncISO_8859_5_CtypeTable[code] & ctype) != 0)
+ ((EncISO_8859_5_CtypeTable[code] & CTYPE_TO_BIT(ctype)) != 0)
static const UChar EncISO_8859_5_ToLowerCaseTable[256] = {
'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
@@ -69,80 +69,66 @@ static const UChar EncISO_8859_5_ToLowerCaseTable[256] = {
};
static const unsigned short EncISO_8859_5_CtypeTable[256] = {
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x220c, 0x2209, 0x2208, 0x2208, 0x2208, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2284, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0,
- 0x38b0, 0x38b0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x31a0,
- 0x21a0, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x2008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x420c, 0x4209, 0x4208, 0x4208, 0x4208, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4284, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0,
+ 0x78b0, 0x78b0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x51a0,
+ 0x41a0, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x4008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
- 0x0284, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x01a0, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x00a0, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x00a0, 0x10e2, 0x10e2
+ 0x0284, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x01a0, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x00a0, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x00a0, 0x30e2, 0x30e2
};
static int
-iso_8859_5_mbc_to_normalize(OnigAmbigType flag,
- const UChar** pp, const UChar* end, UChar* lower)
+mbc_case_fold(OnigCaseFoldType flag ARG_UNUSED,
+ const UChar** pp, const UChar* end ARG_UNUSED, UChar* lower)
{
const UChar* p = *pp;
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- *lower = ENC_ISO_8859_5_TO_LOWER_CASE(*p);
- }
- else {
- *lower = *p;
- }
-
+ *lower = ENC_ISO_8859_5_TO_LOWER_CASE(*p);
(*pp)++;
- return 1; /* return byte length of converted char to lower */
+ return 1;
}
+#if 0
static int
-iso_8859_5_is_mbc_ambiguous(OnigAmbigType flag,
- const UChar** pp, const UChar* end)
+is_mbc_ambiguous(OnigCaseFoldType flag, const UChar** pp, const UChar* end)
{
+ int v;
const UChar* p = *pp;
(*pp)++;
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- int v = (EncISO_8859_5_CtypeTable[*p] &
- (ONIGENC_CTYPE_UPPER | ONIGENC_CTYPE_LOWER));
- return (v != 0 ? TRUE : FALSE);
- }
- return FALSE;
+ v = (EncISO_8859_5_CtypeTable[*p] & (BIT_CTYPE_UPPER | BIT_CTYPE_LOWER));
+ return (v != 0 ? TRUE : FALSE);
}
+#endif
static int
-iso_8859_5_is_code_ctype(OnigCodePoint code, unsigned int ctype)
+is_code_ctype(OnigCodePoint code, unsigned int ctype)
{
if (code < 256)
return ENC_IS_ISO_8859_5_CTYPE(code, ctype);
@@ -150,120 +136,74 @@ iso_8859_5_is_code_ctype(OnigCodePoint code, unsigned int ctype)
return FALSE;
}
+static const OnigPairCaseFoldCodes CaseFoldMap[] = {
+ { 0xa1, 0xf1 },
+ { 0xa2, 0xf2 },
+ { 0xa3, 0xf3 },
+ { 0xa4, 0xf4 },
+ { 0xa5, 0xf5 },
+ { 0xa6, 0xf6 },
+ { 0xa7, 0xf7 },
+ { 0xa8, 0xf8 },
+ { 0xa9, 0xf9 },
+ { 0xaa, 0xfa },
+ { 0xab, 0xfb },
+ { 0xac, 0xfc },
+ { 0xae, 0xfe },
+ { 0xaf, 0xff },
+
+ { 0xb0, 0xd0 },
+ { 0xb1, 0xd1 },
+ { 0xb2, 0xd2 },
+ { 0xb3, 0xd3 },
+ { 0xb4, 0xd4 },
+ { 0xb5, 0xd5 },
+ { 0xb6, 0xd6 },
+ { 0xb7, 0xd7 },
+ { 0xb8, 0xd8 },
+ { 0xb9, 0xd9 },
+ { 0xba, 0xda },
+ { 0xbb, 0xdb },
+ { 0xbc, 0xdc },
+ { 0xbd, 0xdd },
+ { 0xbe, 0xde },
+ { 0xbf, 0xdf },
+
+ { 0xc0, 0xe0 },
+ { 0xc1, 0xe1 },
+ { 0xc2, 0xe2 },
+ { 0xc3, 0xe3 },
+ { 0xc4, 0xe4 },
+ { 0xc5, 0xe5 },
+ { 0xc6, 0xe6 },
+ { 0xc7, 0xe7 },
+ { 0xc8, 0xe8 },
+ { 0xc9, 0xe9 },
+ { 0xca, 0xea },
+ { 0xcb, 0xeb },
+ { 0xcc, 0xec },
+ { 0xcd, 0xed },
+ { 0xce, 0xee },
+ { 0xcf, 0xef }
+};
+
static int
-iso_8859_5_get_all_pair_ambig_codes(OnigAmbigType flag,
- const OnigPairAmbigCodes** ccs)
+apply_all_case_fold(OnigCaseFoldType flag,
+ OnigApplyAllCaseFoldFunc f, void* arg)
{
- static const OnigPairAmbigCodes cc[] = {
- { 0xa1, 0xf1 },
- { 0xa2, 0xf2 },
- { 0xa3, 0xf3 },
- { 0xa4, 0xf4 },
- { 0xa5, 0xf5 },
- { 0xa6, 0xf6 },
- { 0xa7, 0xf7 },
- { 0xa8, 0xf8 },
- { 0xa9, 0xf9 },
- { 0xaa, 0xfa },
- { 0xab, 0xfb },
- { 0xac, 0xfc },
- { 0xae, 0xfe },
- { 0xaf, 0xff },
-
- { 0xb0, 0xd0 },
- { 0xb1, 0xd1 },
- { 0xb2, 0xd2 },
- { 0xb3, 0xd3 },
- { 0xb4, 0xd4 },
- { 0xb5, 0xd5 },
- { 0xb6, 0xd6 },
- { 0xb7, 0xd7 },
- { 0xb8, 0xd8 },
- { 0xb9, 0xd9 },
- { 0xba, 0xda },
- { 0xbb, 0xdb },
- { 0xbc, 0xdc },
- { 0xbd, 0xdd },
- { 0xbe, 0xdf },
- { 0xbf, 0xdf },
-
- { 0xc0, 0xe0 },
- { 0xc1, 0xe1 },
- { 0xc2, 0xe2 },
- { 0xc3, 0xe3 },
- { 0xc4, 0xe4 },
- { 0xc5, 0xe5 },
- { 0xc6, 0xe6 },
- { 0xc7, 0xe7 },
- { 0xc8, 0xe8 },
- { 0xc9, 0xe9 },
- { 0xca, 0xea },
- { 0xcb, 0xeb },
- { 0xcc, 0xec },
- { 0xcd, 0xed },
- { 0xce, 0xee },
- { 0xcf, 0xef },
-
- { 0xd0, 0xb0 },
- { 0xd1, 0xb1 },
- { 0xd2, 0xb2 },
- { 0xd3, 0xb3 },
- { 0xd4, 0xb4 },
- { 0xd5, 0xb5 },
- { 0xd6, 0xb6 },
- { 0xd7, 0xb7 },
- { 0xd8, 0xb8 },
- { 0xd9, 0xb9 },
- { 0xda, 0xba },
- { 0xdb, 0xbb },
- { 0xdc, 0xbc },
- { 0xdd, 0xbd },
- { 0xde, 0xbe },
- { 0xdf, 0xbf },
-
- { 0xe0, 0xc0 },
- { 0xe1, 0xc1 },
- { 0xe2, 0xc2 },
- { 0xe3, 0xc3 },
- { 0xe4, 0xc4 },
- { 0xe5, 0xc5 },
- { 0xe6, 0xc6 },
- { 0xe7, 0xc7 },
- { 0xe8, 0xc8 },
- { 0xe9, 0xc9 },
- { 0xea, 0xca },
- { 0xeb, 0xcb },
- { 0xec, 0xcc },
- { 0xed, 0xcd },
- { 0xee, 0xce },
- { 0xef, 0xcf },
-
- { 0xf1, 0xa1 },
- { 0xf2, 0xa2 },
- { 0xf3, 0xa3 },
- { 0xf4, 0xa4 },
- { 0xf5, 0xa5 },
- { 0xf6, 0xa6 },
- { 0xf7, 0xa7 },
- { 0xf8, 0xa8 },
- { 0xf9, 0xa9 },
- { 0xfa, 0xaa },
- { 0xfb, 0xab },
- { 0xfc, 0xac },
- { 0xfe, 0xae },
- { 0xff, 0xaf }
- };
+ return onigenc_apply_all_case_fold_with_map(
+ sizeof(CaseFoldMap)/sizeof(OnigPairCaseFoldCodes), CaseFoldMap, 0,
+ flag, f, arg);
+}
- if (flag == ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) {
- *ccs = OnigAsciiPairAmbigCodes;
- return 52;
- }
- if (flag == ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) {
- *ccs = cc;
- return sizeof(cc) / sizeof(OnigPairAmbigCodes);
- }
- else
- return 0;
+static int
+get_case_fold_codes_by_str(OnigCaseFoldType flag,
+ const OnigUChar* p, const OnigUChar* end,
+ OnigCaseFoldCodeItem items[])
+{
+ return onigenc_get_case_fold_codes_by_str_with_map(
+ sizeof(CaseFoldMap)/sizeof(OnigPairCaseFoldCodes), CaseFoldMap, 0,
+ flag, p, end, items);
}
OnigEncodingType OnigEncodingISO_8859_5 = {
@@ -271,25 +211,15 @@ OnigEncodingType OnigEncodingISO_8859_5 = {
"ISO-8859-5", /* name */
1, /* max enc length */
1, /* min enc length */
- (ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE |
- ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE ),
- {
- (OnigCodePoint )'\\' /* esc */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
- },
onigenc_is_mbc_newline_0x0a,
onigenc_single_byte_mbc_to_code,
onigenc_single_byte_code_to_mbclen,
onigenc_single_byte_code_to_mbc,
- iso_8859_5_mbc_to_normalize,
- iso_8859_5_is_mbc_ambiguous,
- iso_8859_5_get_all_pair_ambig_codes,
- onigenc_nothing_get_all_comp_ambig_codes,
- iso_8859_5_is_code_ctype,
+ mbc_case_fold,
+ apply_all_case_fold,
+ get_case_fold_codes_by_str,
+ onigenc_minimum_property_name_to_ctype,
+ is_code_ctype,
onigenc_not_support_get_ctype_code_range,
onigenc_single_byte_left_adjust_char_head,
onigenc_always_true_is_allowed_reverse_match
diff --git a/ext/mbstring/oniguruma/enc/iso8859_6.c b/ext/mbstring/oniguruma/enc/iso8859_6.c
index fffcd0e7d1..ab42eeed31 100644
--- a/ext/mbstring/oniguruma/enc/iso8859_6.c
+++ b/ext/mbstring/oniguruma/enc/iso8859_6.c
@@ -2,7 +2,7 @@
iso8859_6.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2005 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2007 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,25 +30,25 @@
#include "regenc.h"
#define ENC_IS_ISO_8859_6_CTYPE(code,ctype) \
- ((EncISO_8859_6_CtypeTable[code] & ctype) != 0)
+ ((EncISO_8859_6_CtypeTable[code] & CTYPE_TO_BIT(ctype)) != 0)
static const unsigned short EncISO_8859_6_CtypeTable[256] = {
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x220c, 0x2209, 0x2208, 0x2208, 0x2208, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2284, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0,
- 0x38b0, 0x38b0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x31a0,
- 0x21a0, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x2008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x420c, 0x4209, 0x4208, 0x4208, 0x4208, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4284, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0,
+ 0x78b0, 0x78b0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x51a0,
+ 0x41a0, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x4008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
@@ -57,18 +57,18 @@ static const unsigned short EncISO_8859_6_CtypeTable[256] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x01a0, 0x01a0, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x01a0, 0x0000, 0x0000, 0x0000, 0x01a0,
- 0x0000, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2,
- 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2,
- 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2,
- 0x10a2, 0x10a2, 0x10a2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2,
- 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2,
- 0x10a2, 0x10a2, 0x10a2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2,
+ 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2,
+ 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2,
+ 0x30a2, 0x30a2, 0x30a2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2,
+ 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2,
+ 0x30a2, 0x30a2, 0x30a2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
};
static int
-iso_8859_6_is_code_ctype(OnigCodePoint code, unsigned int ctype)
+is_code_ctype(OnigCodePoint code, unsigned int ctype)
{
if (code < 256)
return ENC_IS_ISO_8859_6_CTYPE(code, ctype);
@@ -81,24 +81,15 @@ OnigEncodingType OnigEncodingISO_8859_6 = {
"ISO-8859-6", /* name */
1, /* max enc length */
1, /* min enc length */
- ( ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE ),
- {
- (OnigCodePoint )'\\' /* esc */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
- },
onigenc_is_mbc_newline_0x0a,
onigenc_single_byte_mbc_to_code,
onigenc_single_byte_code_to_mbclen,
onigenc_single_byte_code_to_mbc,
- onigenc_ascii_mbc_to_normalize,
- onigenc_ascii_is_mbc_ambiguous,
- onigenc_ascii_get_all_pair_ambig_codes,
- onigenc_nothing_get_all_comp_ambig_codes,
- iso_8859_6_is_code_ctype,
+ onigenc_ascii_mbc_case_fold,
+ onigenc_ascii_apply_all_case_fold,
+ onigenc_ascii_get_case_fold_codes_by_str,
+ onigenc_minimum_property_name_to_ctype,
+ is_code_ctype,
onigenc_not_support_get_ctype_code_range,
onigenc_single_byte_left_adjust_char_head,
onigenc_always_true_is_allowed_reverse_match
diff --git a/ext/mbstring/oniguruma/enc/iso8859_7.c b/ext/mbstring/oniguruma/enc/iso8859_7.c
index e87661d84b..1090064d74 100644
--- a/ext/mbstring/oniguruma/enc/iso8859_7.c
+++ b/ext/mbstring/oniguruma/enc/iso8859_7.c
@@ -2,7 +2,7 @@
iso8859_7.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2005 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2007 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
#define ENC_ISO_8859_7_TO_LOWER_CASE(c) EncISO_8859_7_ToLowerCaseTable[c]
#define ENC_IS_ISO_8859_7_CTYPE(code,ctype) \
- ((EncISO_8859_7_CtypeTable[code] & ctype) != 0)
+ ((EncISO_8859_7_CtypeTable[code] & CTYPE_TO_BIT(ctype)) != 0)
static const UChar EncISO_8859_7_ToLowerCaseTable[256] = {
'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
@@ -69,87 +69,74 @@ static const UChar EncISO_8859_7_ToLowerCaseTable[256] = {
};
static const unsigned short EncISO_8859_7_CtypeTable[256] = {
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x220c, 0x2209, 0x2208, 0x2208, 0x2208, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2284, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0,
- 0x38b0, 0x38b0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x31a0,
- 0x21a0, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x2008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x420c, 0x4209, 0x4208, 0x4208, 0x4208, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4284, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0,
+ 0x78b0, 0x78b0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x51a0,
+ 0x41a0, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x4008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0284, 0x01a0, 0x01a0, 0x00a0, 0x0000, 0x0000, 0x00a0, 0x00a0,
0x00a0, 0x00a0, 0x0000, 0x01a0, 0x00a0, 0x01a0, 0x0000, 0x01a0,
- 0x00a0, 0x00a0, 0x10a0, 0x10a0, 0x00a0, 0x00a0, 0x14a2, 0x01a0,
- 0x14a2, 0x14a2, 0x14a2, 0x01a0, 0x14a2, 0x10a0, 0x14a2, 0x14a2,
- 0x10e2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x0000, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x0000
+ 0x00a0, 0x00a0, 0x10a0, 0x10a0, 0x00a0, 0x00a0, 0x34a2, 0x01a0,
+ 0x34a2, 0x34a2, 0x34a2, 0x01a0, 0x34a2, 0x10a0, 0x34a2, 0x34a2,
+ 0x30e2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x0000, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x0000
};
static int
-iso_8859_7_mbc_to_normalize(OnigAmbigType flag,
- const UChar** pp, const UChar* end, UChar* lower)
+mbc_case_fold(OnigCaseFoldType flag ARG_UNUSED,
+ const UChar** pp, const UChar* end ARG_UNUSED, UChar* lower)
{
const UChar* p = *pp;
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- *lower = ENC_ISO_8859_7_TO_LOWER_CASE(*p);
- }
- else {
- *lower = *p;
- }
+ *lower = ENC_ISO_8859_7_TO_LOWER_CASE(*p);
(*pp)++;
- return 1; /* return byte length of converted char to lower */
+ return 1;
}
+#if 0
static int
-iso_8859_7_is_mbc_ambiguous(OnigAmbigType flag,
- const UChar** pp, const UChar* end)
+is_mbc_ambiguous(OnigCaseFoldType flag,
+ const UChar** pp, const UChar* end)
{
+ int v;
const UChar* p = *pp;
(*pp)++;
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- int v = (EncISO_8859_7_CtypeTable[*p] &
- (ONIGENC_CTYPE_UPPER | ONIGENC_CTYPE_LOWER));
-
- if ((v | ONIGENC_CTYPE_LOWER) != 0) {
- if (*p == 0xc0 || *p == 0xe0)
- return FALSE;
- else
- return TRUE;
- }
-
- return (v != 0 ? TRUE : FALSE);
+ v = (EncISO_8859_7_CtypeTable[*p] & (BIT_CTYPE_UPPER | BIT_CTYPE_LOWER));
+ if ((v | BIT_CTYPE_LOWER) != 0) {
+ if (*p == 0xc0 || *p == 0xe0)
+ return FALSE;
+ else
+ return TRUE;
}
- return FALSE;
+
+ return (v != 0 ? TRUE : FALSE);
}
+#endif
static int
-iso_8859_7_is_code_ctype(OnigCodePoint code, unsigned int ctype)
+is_code_ctype(OnigCodePoint code, unsigned int ctype)
{
if (code < 256)
return ENC_IS_ISO_8859_7_CTYPE(code, ctype);
@@ -157,121 +144,78 @@ iso_8859_7_is_code_ctype(OnigCodePoint code, unsigned int ctype)
return FALSE;
}
+static const OnigPairCaseFoldCodes CaseFoldMap[] = {
+ { 0xb6, 0xdc },
+ { 0xb8, 0xdd },
+ { 0xb9, 0xde },
+ { 0xba, 0xdf },
+ { 0xbc, 0xfc },
+ { 0xbe, 0xfd },
+ { 0xbf, 0xfe },
+
+ { 0xc1, 0xe1 },
+ { 0xc2, 0xe2 },
+ { 0xc3, 0xe3 },
+ { 0xc4, 0xe4 },
+ { 0xc5, 0xe5 },
+ { 0xc6, 0xe6 },
+ { 0xc7, 0xe7 },
+ { 0xc8, 0xe8 },
+ { 0xc9, 0xe9 },
+ { 0xca, 0xea },
+ { 0xcb, 0xeb },
+ { 0xcc, 0xec },
+ { 0xcd, 0xed },
+ { 0xce, 0xee },
+ { 0xcf, 0xef },
+
+ { 0xd0, 0xf0 },
+ { 0xd1, 0xf1 },
+ { 0xd2, 0xf2 },
+ { 0xd3, 0xf3 },
+ { 0xd4, 0xf4 },
+ { 0xd5, 0xf5 },
+ { 0xd6, 0xf6 },
+ { 0xd7, 0xf7 },
+ { 0xd8, 0xf8 },
+ { 0xd9, 0xf9 },
+ { 0xda, 0xfa },
+ { 0xdb, 0xfb }
+};
+
static int
-iso_8859_7_get_all_pair_ambig_codes(OnigAmbigType flag,
- const OnigPairAmbigCodes** ccs)
+apply_all_case_fold(OnigCaseFoldType flag,
+ OnigApplyAllCaseFoldFunc f, void* arg)
{
- static const OnigPairAmbigCodes cc[] = {
- { 0xb6, 0xdc },
- { 0xb8, 0xdd },
- { 0xb9, 0xde },
- { 0xba, 0xdf },
- { 0xbc, 0xfc },
- { 0xbe, 0xfd },
- { 0xbf, 0xfe },
-
- { 0xc1, 0xe1 },
- { 0xc2, 0xe2 },
- { 0xc3, 0xe3 },
- { 0xc4, 0xe4 },
- { 0xc5, 0xe5 },
- { 0xc6, 0xe6 },
- { 0xc7, 0xe7 },
- { 0xc8, 0xe8 },
- { 0xc9, 0xe9 },
- { 0xca, 0xea },
- { 0xcb, 0xeb },
- { 0xcc, 0xec },
- { 0xcd, 0xed },
- { 0xce, 0xee },
- { 0xcf, 0xef },
-
- { 0xd0, 0xf0 },
- { 0xd1, 0xf1 },
- { 0xd2, 0xf2 },
- { 0xd3, 0xf3 },
- { 0xd4, 0xf4 },
- { 0xd5, 0xf5 },
- { 0xd6, 0xf6 },
- { 0xd7, 0xf7 },
- { 0xd8, 0xf8 },
- { 0xd9, 0xf9 },
- { 0xda, 0xfa },
- { 0xdb, 0xfb },
- { 0xdc, 0xb6 },
- { 0xdd, 0xb8 },
- { 0xde, 0xb9 },
- { 0xdf, 0xba },
-
- { 0xe1, 0xc1 },
- { 0xe2, 0xc2 },
- { 0xe3, 0xc3 },
- { 0xe4, 0xc4 },
- { 0xe5, 0xc5 },
- { 0xe6, 0xc6 },
- { 0xe7, 0xc7 },
- { 0xe8, 0xc8 },
- { 0xe9, 0xc9 },
- { 0xea, 0xca },
- { 0xeb, 0xcb },
- { 0xec, 0xcc },
- { 0xed, 0xcd },
- { 0xee, 0xce },
- { 0xef, 0xcf },
-
- { 0xf0, 0xd0 },
- { 0xf1, 0xd1 },
- { 0xf2, 0xd2 },
- { 0xf3, 0xd3 },
- { 0xf4, 0xd4 },
- { 0xf5, 0xd5 },
- { 0xf6, 0xd6 },
- { 0xf7, 0xd7 },
- { 0xf8, 0xd8 },
- { 0xf9, 0xd9 },
- { 0xfa, 0xda },
- { 0xfb, 0xdb },
- { 0xfc, 0xbc },
- { 0xfd, 0xbe },
- { 0xfe, 0xbf }
- };
+ return onigenc_apply_all_case_fold_with_map(
+ sizeof(CaseFoldMap)/sizeof(OnigPairCaseFoldCodes), CaseFoldMap, 0,
+ flag, f, arg);
+}
- if (flag == ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) {
- *ccs = OnigAsciiPairAmbigCodes;
- return 52;
- }
- if (flag == ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) {
- *ccs = cc;
- return sizeof(cc) / sizeof(OnigPairAmbigCodes);
- }
- else
- return 0;
+static int
+get_case_fold_codes_by_str(OnigCaseFoldType flag,
+ const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[])
+{
+ return onigenc_get_case_fold_codes_by_str_with_map(
+ sizeof(CaseFoldMap)/sizeof(OnigPairCaseFoldCodes), CaseFoldMap, 0,
+ flag, p, end, items);
}
+
OnigEncodingType OnigEncodingISO_8859_7 = {
onigenc_single_byte_mbc_enc_len,
"ISO-8859-7", /* name */
1, /* max enc length */
1, /* min enc length */
- (ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE |
- ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE ),
- {
- (OnigCodePoint )'\\' /* esc */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
- },
onigenc_is_mbc_newline_0x0a,
onigenc_single_byte_mbc_to_code,
onigenc_single_byte_code_to_mbclen,
onigenc_single_byte_code_to_mbc,
- iso_8859_7_mbc_to_normalize,
- iso_8859_7_is_mbc_ambiguous,
- iso_8859_7_get_all_pair_ambig_codes,
- onigenc_nothing_get_all_comp_ambig_codes,
- iso_8859_7_is_code_ctype,
+ mbc_case_fold,
+ apply_all_case_fold,
+ get_case_fold_codes_by_str,
+ onigenc_minimum_property_name_to_ctype,
+ is_code_ctype,
onigenc_not_support_get_ctype_code_range,
onigenc_single_byte_left_adjust_char_head,
onigenc_always_true_is_allowed_reverse_match
diff --git a/ext/mbstring/oniguruma/enc/iso8859_8.c b/ext/mbstring/oniguruma/enc/iso8859_8.c
index e76966c667..fb9846f25f 100644
--- a/ext/mbstring/oniguruma/enc/iso8859_8.c
+++ b/ext/mbstring/oniguruma/enc/iso8859_8.c
@@ -2,7 +2,7 @@
iso8859_8.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2004 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2007 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,45 +30,45 @@
#include "regenc.h"
#define ENC_IS_ISO_8859_8_CTYPE(code,ctype) \
- ((EncISO_8859_8_CtypeTable[code] & ctype) != 0)
+ ((EncISO_8859_8_CtypeTable[code] & CTYPE_TO_BIT(ctype)) != 0)
static const unsigned short EncISO_8859_8_CtypeTable[256] = {
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x220c, 0x2209, 0x2208, 0x2208, 0x2208, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2284, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0,
- 0x38b0, 0x38b0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x31a0,
- 0x21a0, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x2008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x420c, 0x4209, 0x4208, 0x4208, 0x4208, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4284, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0,
+ 0x78b0, 0x78b0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x51a0,
+ 0x41a0, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x4008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0284, 0x0000, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0,
0x00a0, 0x00a0, 0x00a0, 0x01a0, 0x00a0, 0x01a0, 0x00a0, 0x00a0,
- 0x00a0, 0x00a0, 0x10a0, 0x10a0, 0x00a0, 0x10e2, 0x00a0, 0x01a0,
+ 0x00a0, 0x00a0, 0x10a0, 0x10a0, 0x00a0, 0x30e2, 0x00a0, 0x01a0,
0x00a0, 0x10a0, 0x00a0, 0x01a0, 0x10a0, 0x10a0, 0x10a0, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x01a0,
- 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2,
- 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2,
- 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2, 0x10a2,
- 0x10a2, 0x10a2, 0x10a2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+ 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2,
+ 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2,
+ 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2, 0x30a2,
+ 0x30a2, 0x30a2, 0x30a2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
};
static int
-iso_8859_8_is_code_ctype(OnigCodePoint code, unsigned int ctype)
+is_code_ctype(OnigCodePoint code, unsigned int ctype)
{
if (code < 256)
return ENC_IS_ISO_8859_8_CTYPE(code, ctype);
@@ -81,24 +81,15 @@ OnigEncodingType OnigEncodingISO_8859_8 = {
"ISO-8859-8", /* name */
1, /* max enc length */
1, /* min enc length */
- ( ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE ),
- {
- (OnigCodePoint )'\\' /* esc */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
- },
onigenc_is_mbc_newline_0x0a,
onigenc_single_byte_mbc_to_code,
onigenc_single_byte_code_to_mbclen,
onigenc_single_byte_code_to_mbc,
- onigenc_ascii_mbc_to_normalize,
- onigenc_ascii_is_mbc_ambiguous,
- onigenc_ascii_get_all_pair_ambig_codes,
- onigenc_nothing_get_all_comp_ambig_codes,
- iso_8859_8_is_code_ctype,
+ onigenc_ascii_mbc_case_fold,
+ onigenc_ascii_apply_all_case_fold,
+ onigenc_ascii_get_case_fold_codes_by_str,
+ onigenc_minimum_property_name_to_ctype,
+ is_code_ctype,
onigenc_not_support_get_ctype_code_range,
onigenc_single_byte_left_adjust_char_head,
onigenc_always_true_is_allowed_reverse_match
diff --git a/ext/mbstring/oniguruma/enc/iso8859_9.c b/ext/mbstring/oniguruma/enc/iso8859_9.c
index 16a30c5f24..079d681c21 100644
--- a/ext/mbstring/oniguruma/enc/iso8859_9.c
+++ b/ext/mbstring/oniguruma/enc/iso8859_9.c
@@ -2,7 +2,7 @@
iso8859_9.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2006 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2007 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
#define ENC_ISO_8859_9_TO_LOWER_CASE(c) EncISO_8859_9_ToLowerCaseTable[c]
#define ENC_IS_ISO_8859_9_CTYPE(code,ctype) \
- ((EncISO_8859_9_CtypeTable[code] & ctype) != 0)
+ ((EncISO_8859_9_CtypeTable[code] & CTYPE_TO_BIT(ctype)) != 0)
static const UChar EncISO_8859_9_ToLowerCaseTable[256] = {
'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
@@ -69,88 +69,86 @@ static const UChar EncISO_8859_9_ToLowerCaseTable[256] = {
};
static const unsigned short EncISO_8859_9_CtypeTable[256] = {
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x220c, 0x2209, 0x2208, 0x2208, 0x2208, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2284, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0,
- 0x38b0, 0x38b0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x31a0,
- 0x21a0, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x2008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x420c, 0x4209, 0x4208, 0x4208, 0x4208, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4284, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0,
+ 0x78b0, 0x78b0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x51a0,
+ 0x41a0, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x4008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0284, 0x01a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0,
- 0x00a0, 0x00a0, 0x10e2, 0x01a0, 0x00a0, 0x01a0, 0x00a0, 0x00a0,
- 0x00a0, 0x00a0, 0x10a0, 0x10a0, 0x00a0, 0x10e2, 0x00a0, 0x01a0,
- 0x00a0, 0x10a0, 0x10e2, 0x01a0, 0x10a0, 0x10a0, 0x10a0, 0x01a0,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x00a0,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x00a0,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2
+ 0x00a0, 0x00a0, 0x30e2, 0x01a0, 0x00a0, 0x01a0, 0x00a0, 0x00a0,
+ 0x00a0, 0x00a0, 0x10a0, 0x10a0, 0x00a0, 0x30e2, 0x00a0, 0x01a0,
+ 0x00a0, 0x10a0, 0x30e2, 0x01a0, 0x10a0, 0x10a0, 0x10a0, 0x01a0,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x00a0,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x00a0,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2
};
static int
-iso_8859_9_mbc_to_normalize(OnigAmbigType flag,
- const UChar** pp, const UChar* end, UChar* lower)
+mbc_case_fold(OnigCaseFoldType flag,
+ const UChar** pp, const UChar* end ARG_UNUSED, UChar* lower)
{
const UChar* p = *pp;
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- *lower = ENC_ISO_8859_9_TO_LOWER_CASE(*p);
- }
- else {
- *lower = *p;
+ if (*p == 0xdf && (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
+ *lower++ = 's';
+ *lower = 's';
+ (*pp)++;
+ return 2;
}
+
+ *lower = ENC_ISO_8859_9_TO_LOWER_CASE(*p);
(*pp)++;
- return 1; /* return byte length of converted char to lower */
+ return 1;
}
+#if 0
static int
-iso_8859_9_is_mbc_ambiguous(OnigAmbigType flag,
- const UChar** pp, const UChar* end)
+is_mbc_ambiguous(OnigCaseFoldType flag, const UChar** pp, const UChar* end)
{
+ int v;
const UChar* p = *pp;
- (*pp)++;
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- int v = (EncISO_8859_9_CtypeTable[*p] &
- (ONIGENC_CTYPE_UPPER | ONIGENC_CTYPE_LOWER));
-
- if ((v | ONIGENC_CTYPE_LOWER) != 0) {
- /* 0xdf etc.. are lower case letter, but can't convert. */
- if (*p == 0xdf || (*p >= 0xaa && *p <= 0xba))
- return FALSE;
- else
- return TRUE;
- }
+ if (*p == 0xdf && (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
+ (*pp)++;
+ return TRUE;
+ }
- return (v != 0 ? TRUE : FALSE);
+ (*pp)++;
+ v = (EncISO_8859_9_CtypeTable[*p] & (BIT_CTYPE_UPPER | BIT_CTYPE_LOWER));
+ if ((v | BIT_CTYPE_LOWER) != 0) {
+ /* 0xdf etc.. are lower case letter, but can't convert. */
+ if (*p >= 0xaa && *p <= 0xba)
+ return FALSE;
+ else
+ return TRUE;
}
- return FALSE;
+
+ return (v != 0 ? TRUE : FALSE);
}
+#endif
static int
-iso_8859_9_is_code_ctype(OnigCodePoint code, unsigned int ctype)
+is_code_ctype(OnigCodePoint code, unsigned int ctype)
{
if (code < 256)
return ENC_IS_ISO_8859_9_CTYPE(code, ctype);
@@ -158,86 +156,56 @@ iso_8859_9_is_code_ctype(OnigCodePoint code, unsigned int ctype)
return FALSE;
}
+static const OnigPairCaseFoldCodes CaseFoldMap[] = {
+ { 0xc0, 0xe0 },
+ { 0xc1, 0xe1 },
+ { 0xc2, 0xe2 },
+ { 0xc3, 0xe3 },
+ { 0xc4, 0xe4 },
+ { 0xc5, 0xe5 },
+ { 0xc6, 0xe6 },
+ { 0xc7, 0xe7 },
+ { 0xc8, 0xe8 },
+ { 0xc9, 0xe9 },
+ { 0xca, 0xea },
+ { 0xcb, 0xeb },
+ { 0xcc, 0xec },
+ { 0xcd, 0xed },
+ { 0xce, 0xee },
+ { 0xcf, 0xef },
+
+ { 0xd0, 0xf0 },
+ { 0xd1, 0xf1 },
+ { 0xd2, 0xf2 },
+ { 0xd3, 0xf3 },
+ { 0xd4, 0xf4 },
+ { 0xd5, 0xf5 },
+ { 0xd6, 0xf6 },
+ { 0xd8, 0xf8 },
+ { 0xd9, 0xf9 },
+ { 0xda, 0xfa },
+ { 0xdb, 0xfb },
+ { 0xdc, 0xfc },
+ { 0xdd, 0xfd },
+ { 0xde, 0xfe }
+};
+
static int
-iso_8859_9_get_all_pair_ambig_codes(OnigAmbigType flag,
- const OnigPairAmbigCodes** ccs)
+apply_all_case_fold(OnigCaseFoldType flag,
+ OnigApplyAllCaseFoldFunc f, void* arg)
{
- static const OnigPairAmbigCodes cc[] = {
- { 0xc0, 0xe0 },
- { 0xc1, 0xe1 },
- { 0xc2, 0xe2 },
- { 0xc3, 0xe3 },
- { 0xc4, 0xe4 },
- { 0xc5, 0xe5 },
- { 0xc6, 0xe6 },
- { 0xc7, 0xe7 },
- { 0xc8, 0xe8 },
- { 0xc9, 0xe9 },
- { 0xca, 0xea },
- { 0xcb, 0xeb },
- { 0xcc, 0xec },
- { 0xcd, 0xed },
- { 0xce, 0xee },
- { 0xcf, 0xef },
-
- { 0xd0, 0xf0 },
- { 0xd1, 0xf1 },
- { 0xd2, 0xf2 },
- { 0xd3, 0xf3 },
- { 0xd4, 0xf4 },
- { 0xd5, 0xf5 },
- { 0xd6, 0xf6 },
- { 0xd8, 0xf8 },
- { 0xd9, 0xf9 },
- { 0xda, 0xfa },
- { 0xdb, 0xfb },
- { 0xdc, 0xfc },
- { 0xdd, 0xfd },
- { 0xde, 0xfe },
-
- { 0xe0, 0xc0 },
- { 0xe1, 0xc1 },
- { 0xe2, 0xc2 },
- { 0xe3, 0xc3 },
- { 0xe4, 0xc4 },
- { 0xe5, 0xc5 },
- { 0xe6, 0xc6 },
- { 0xe7, 0xc7 },
- { 0xe8, 0xc8 },
- { 0xe9, 0xc9 },
- { 0xea, 0xca },
- { 0xeb, 0xcb },
- { 0xec, 0xcc },
- { 0xed, 0xcd },
- { 0xee, 0xce },
- { 0xef, 0xcf },
-
- { 0xf0, 0xd0 },
- { 0xf1, 0xd1 },
- { 0xf2, 0xd2 },
- { 0xf3, 0xd3 },
- { 0xf4, 0xd4 },
- { 0xf5, 0xd5 },
- { 0xf6, 0xd6 },
- { 0xf8, 0xd8 },
- { 0xf9, 0xd9 },
- { 0xfa, 0xda },
- { 0xfb, 0xdb },
- { 0xfc, 0xdc },
- { 0xfd, 0xdd },
- { 0xfe, 0xde }
- };
+ return onigenc_apply_all_case_fold_with_map(
+ sizeof(CaseFoldMap)/sizeof(OnigPairCaseFoldCodes), CaseFoldMap, 1,
+ flag, f, arg);
+}
- if (flag == ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) {
- *ccs = OnigAsciiPairAmbigCodes;
- return 52;
- }
- if (flag == ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) {
- *ccs = cc;
- return sizeof(cc) / sizeof(OnigPairAmbigCodes);
- }
- else
- return 0;
+static int
+get_case_fold_codes_by_str(OnigCaseFoldType flag,
+ const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[])
+{
+ return onigenc_get_case_fold_codes_by_str_with_map(
+ sizeof(CaseFoldMap)/sizeof(OnigPairCaseFoldCodes), CaseFoldMap, 1,
+ flag, p, end, items);
}
OnigEncodingType OnigEncodingISO_8859_9 = {
@@ -245,25 +213,15 @@ OnigEncodingType OnigEncodingISO_8859_9 = {
"ISO-8859-9", /* name */
1, /* max enc length */
1, /* min enc length */
- (ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE |
- ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE ),
- {
- (OnigCodePoint )'\\' /* esc */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
- },
onigenc_is_mbc_newline_0x0a,
onigenc_single_byte_mbc_to_code,
onigenc_single_byte_code_to_mbclen,
onigenc_single_byte_code_to_mbc,
- iso_8859_9_mbc_to_normalize,
- iso_8859_9_is_mbc_ambiguous,
- iso_8859_9_get_all_pair_ambig_codes,
- onigenc_ess_tsett_get_all_comp_ambig_codes,
- iso_8859_9_is_code_ctype,
+ mbc_case_fold,
+ apply_all_case_fold,
+ get_case_fold_codes_by_str,
+ onigenc_minimum_property_name_to_ctype,
+ is_code_ctype,
onigenc_not_support_get_ctype_code_range,
onigenc_single_byte_left_adjust_char_head,
onigenc_always_true_is_allowed_reverse_match
diff --git a/ext/mbstring/oniguruma/enc/koi8.c b/ext/mbstring/oniguruma/enc/koi8.c
index d7277e862e..c6649572f5 100644
--- a/ext/mbstring/oniguruma/enc/koi8.c
+++ b/ext/mbstring/oniguruma/enc/koi8.c
@@ -2,7 +2,7 @@
koi8.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2004 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2008 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
#define ENC_KOI8_TO_LOWER_CASE(c) EncKOI8_ToLowerCaseTable[c]
#define ENC_IS_KOI8_CTYPE(code,ctype) \
- ((EncKOI8_CtypeTable[code] & ctype) != 0)
+ ((EncKOI8_CtypeTable[code] & CTYPE_TO_BIT(ctype)) != 0)
static const UChar EncKOI8_ToLowerCaseTable[256] = {
'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
@@ -69,22 +69,22 @@ static const UChar EncKOI8_ToLowerCaseTable[256] = {
};
static const unsigned short EncKOI8_CtypeTable[256] = {
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x220c, 0x2209, 0x2208, 0x2208, 0x2208, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2284, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0,
- 0x38b0, 0x38b0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x31a0,
- 0x21a0, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x2008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x420c, 0x4209, 0x4208, 0x4208, 0x4208, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4284, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0,
+ 0x78b0, 0x78b0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x51a0,
+ 0x41a0, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x4008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
@@ -93,52 +93,46 @@ static const unsigned short EncKOI8_CtypeTable[256] = {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2
};
+
static int
-koi8_mbc_to_normalize(OnigAmbigType flag,
- const OnigUChar** pp, const OnigUChar* end, OnigUChar* lower)
+koi8_mbc_case_fold(OnigCaseFoldType flag ARG_UNUSED,
+ const UChar** pp, const UChar* end ARG_UNUSED, UChar* lower)
{
- const OnigUChar* p = *pp;
+ const UChar* p = *pp;
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- *lower = ENC_KOI8_TO_LOWER_CASE(*p);
- }
- else {
- *lower = *p;
- }
+ *lower = ENC_KOI8_TO_LOWER_CASE(*p);
(*pp)++;
- return 1; /* return byte length of converted char to lower */
+ return 1;
}
+#if 0
static int
koi8_is_mbc_ambiguous(OnigAmbigType flag, const OnigUChar** pp, const OnigUChar* end)
{
const OnigUChar* p = *pp;
(*pp)++;
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
+ if (((flag & ONIGENC_CASE_FOLD_ASCII_CASE) != 0 &&
ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
+ ((flag & ONIGENC_CASE_FOLD_NONASCII_CASE) != 0 &&
!ONIGENC_IS_MBC_ASCII(p))) {
int v = (EncKOI8_CtypeTable[*p] &
- (ONIGENC_CTYPE_UPPER | ONIGENC_CTYPE_LOWER));
+ (BIT_CTYPE_UPPER | BIT_CTYPE_LOWER));
return (v != 0 ? TRUE : FALSE);
}
return FALSE;
}
-
+#endif
static int
koi8_is_code_ctype(OnigCodePoint code, unsigned int ctype)
@@ -149,89 +143,91 @@ koi8_is_code_ctype(OnigCodePoint code, unsigned int ctype)
return FALSE;
}
+static const OnigPairCaseFoldCodes CaseFoldMap[] = {
+ { 0xc0, 0xe0 },
+ { 0xc1, 0xe1 },
+ { 0xc2, 0xe2 },
+ { 0xc3, 0xe3 },
+ { 0xc4, 0xe4 },
+ { 0xc5, 0xe5 },
+ { 0xc6, 0xe6 },
+ { 0xc7, 0xe7 },
+ { 0xc8, 0xe8 },
+ { 0xc9, 0xe9 },
+ { 0xca, 0xea },
+ { 0xcb, 0xeb },
+ { 0xcc, 0xec },
+ { 0xcd, 0xed },
+ { 0xce, 0xee },
+ { 0xcf, 0xef },
+
+ { 0xd0, 0xf0 },
+ { 0xd1, 0xf1 },
+ { 0xd2, 0xf2 },
+ { 0xd3, 0xf3 },
+ { 0xd4, 0xf4 },
+ { 0xd5, 0xf5 },
+ { 0xd6, 0xf6 },
+ { 0xd7, 0xf7 },
+ { 0xd8, 0xf8 },
+ { 0xd9, 0xf9 },
+ { 0xda, 0xfa },
+ { 0xdb, 0xfb },
+ { 0xdc, 0xfc },
+ { 0xdd, 0xfd },
+ { 0xde, 0xfe },
+ { 0xdf, 0xff },
+
+ { 0xe0, 0xc0 },
+ { 0xe1, 0xc1 },
+ { 0xe2, 0xc2 },
+ { 0xe3, 0xc3 },
+ { 0xe4, 0xc4 },
+ { 0xe5, 0xc5 },
+ { 0xe6, 0xc6 },
+ { 0xe7, 0xc7 },
+ { 0xe8, 0xc8 },
+ { 0xe9, 0xc9 },
+ { 0xea, 0xca },
+ { 0xeb, 0xcb },
+ { 0xec, 0xcc },
+ { 0xed, 0xcd },
+ { 0xee, 0xce },
+ { 0xef, 0xcf },
+
+ { 0xf0, 0xd0 },
+ { 0xf1, 0xd1 },
+ { 0xf2, 0xd2 },
+ { 0xf3, 0xd3 },
+ { 0xf4, 0xd4 },
+ { 0xf5, 0xd5 },
+ { 0xf6, 0xd6 },
+ { 0xf7, 0xd7 },
+ { 0xf8, 0xd8 },
+ { 0xf9, 0xd9 },
+ { 0xfa, 0xda },
+ { 0xfb, 0xdb },
+ { 0xfc, 0xdc },
+ { 0xfe, 0xde },
+ { 0xff, 0xdf }
+};
+
static int
-koi8_get_all_pair_ambig_codes(OnigAmbigType flag,
- const OnigPairAmbigCodes** ccs)
+koi8_apply_all_case_fold(OnigCaseFoldType flag,
+ OnigApplyAllCaseFoldFunc f, void* arg)
{
- static const OnigPairAmbigCodes cc[] = {
- { 0xc0, 0xe0 },
- { 0xc1, 0xe1 },
- { 0xc2, 0xe2 },
- { 0xc3, 0xe3 },
- { 0xc4, 0xe4 },
- { 0xc5, 0xe5 },
- { 0xc6, 0xe6 },
- { 0xc7, 0xe7 },
- { 0xc8, 0xe8 },
- { 0xc9, 0xe9 },
- { 0xca, 0xea },
- { 0xcb, 0xeb },
- { 0xcc, 0xec },
- { 0xcd, 0xed },
- { 0xce, 0xee },
- { 0xcf, 0xef },
-
- { 0xd0, 0xf0 },
- { 0xd1, 0xf1 },
- { 0xd2, 0xf2 },
- { 0xd3, 0xf3 },
- { 0xd4, 0xf4 },
- { 0xd5, 0xf5 },
- { 0xd6, 0xf6 },
- { 0xd7, 0xf7 },
- { 0xd8, 0xf8 },
- { 0xd9, 0xf9 },
- { 0xda, 0xfa },
- { 0xdb, 0xfb },
- { 0xdc, 0xfc },
- { 0xdd, 0xfd },
- { 0xde, 0xfe },
- { 0xdf, 0xff },
-
- { 0xe0, 0xc0 },
- { 0xe1, 0xc1 },
- { 0xe2, 0xc2 },
- { 0xe3, 0xc3 },
- { 0xe4, 0xc4 },
- { 0xe5, 0xc5 },
- { 0xe6, 0xc6 },
- { 0xe7, 0xc7 },
- { 0xe8, 0xc8 },
- { 0xe9, 0xc9 },
- { 0xea, 0xca },
- { 0xeb, 0xcb },
- { 0xec, 0xcc },
- { 0xed, 0xcd },
- { 0xee, 0xce },
- { 0xef, 0xcf },
-
- { 0xf0, 0xd0 },
- { 0xf1, 0xd1 },
- { 0xf2, 0xd2 },
- { 0xf3, 0xd3 },
- { 0xf4, 0xd4 },
- { 0xf5, 0xd5 },
- { 0xf6, 0xd6 },
- { 0xf7, 0xd7 },
- { 0xf8, 0xd8 },
- { 0xf9, 0xd9 },
- { 0xfa, 0xda },
- { 0xfb, 0xdb },
- { 0xfc, 0xdc },
- { 0xfe, 0xde },
- { 0xff, 0xdf }
- };
+ return onigenc_apply_all_case_fold_with_map(
+ sizeof(CaseFoldMap)/sizeof(OnigPairCaseFoldCodes), CaseFoldMap, 0,
+ flag, f, arg);
+}
- if (flag == ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) {
- *ccs = OnigAsciiPairAmbigCodes;
- return 52;
- }
- if (flag == ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) {
- *ccs = cc;
- return sizeof(cc) / sizeof(OnigPairAmbigCodes);
- }
- else
- return 0;
+static int
+koi8_get_case_fold_codes_by_str(OnigCaseFoldType flag,
+ const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[])
+{
+ return onigenc_get_case_fold_codes_by_str_with_map(
+ sizeof(CaseFoldMap)/sizeof(OnigPairCaseFoldCodes), CaseFoldMap, 0,
+ flag, p, end, items);
}
OnigEncodingType OnigEncodingKOI8 = {
@@ -239,24 +235,14 @@ OnigEncodingType OnigEncodingKOI8 = {
"KOI8", /* name */
1, /* max enc length */
1, /* min enc length */
- (ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE |
- ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE ),
- {
- (OnigCodePoint )'\\' /* esc */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
- },
onigenc_is_mbc_newline_0x0a,
onigenc_single_byte_mbc_to_code,
onigenc_single_byte_code_to_mbclen,
onigenc_single_byte_code_to_mbc,
- koi8_mbc_to_normalize,
- koi8_is_mbc_ambiguous,
- koi8_get_all_pair_ambig_codes,
- onigenc_nothing_get_all_comp_ambig_codes,
+ koi8_mbc_case_fold,
+ koi8_apply_all_case_fold,
+ koi8_get_case_fold_codes_by_str,
+ onigenc_minimum_property_name_to_ctype,
koi8_is_code_ctype,
onigenc_not_support_get_ctype_code_range,
onigenc_single_byte_left_adjust_char_head,
diff --git a/ext/mbstring/oniguruma/enc/koi8_r.c b/ext/mbstring/oniguruma/enc/koi8_r.c
index 1010f5ff93..364dda1516 100644
--- a/ext/mbstring/oniguruma/enc/koi8_r.c
+++ b/ext/mbstring/oniguruma/enc/koi8_r.c
@@ -2,7 +2,7 @@
koi8_r.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2006 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2007 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
#define ENC_KOI8_R_TO_LOWER_CASE(c) EncKOI8_R_ToLowerCaseTable[c]
#define ENC_IS_KOI8_R_CTYPE(code,ctype) \
- ((EncKOI8_R_CtypeTable[code] & ctype) != 0)
+ ((EncKOI8_R_CtypeTable[code] & CTYPE_TO_BIT(ctype)) != 0)
static const UChar EncKOI8_R_ToLowerCaseTable[256] = {
'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
@@ -69,75 +69,63 @@ static const UChar EncKOI8_R_ToLowerCaseTable[256] = {
};
static const unsigned short EncKOI8_R_CtypeTable[256] = {
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x220c, 0x2209, 0x2208, 0x2208, 0x2208, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2284, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0,
- 0x38b0, 0x38b0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x31a0,
- 0x21a0, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x2008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x420c, 0x4209, 0x4208, 0x4208, 0x4208, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4284, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0,
+ 0x78b0, 0x78b0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x51a0,
+ 0x41a0, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x4008,
0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0,
0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0,
0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0,
0x00a0, 0x00a0, 0x0284, 0x00a0, 0x00a0, 0x10a0, 0x01a0, 0x00a0,
- 0x00a0, 0x00a0, 0x00a0, 0x10e2, 0x00a0, 0x00a0, 0x00a0, 0x00a0,
+ 0x00a0, 0x00a0, 0x00a0, 0x30e2, 0x00a0, 0x00a0, 0x00a0, 0x00a0,
0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0,
- 0x00a0, 0x00a0, 0x00a0, 0x14a2, 0x00a0, 0x00a0, 0x00a0, 0x00a0,
+ 0x00a0, 0x00a0, 0x00a0, 0x34a2, 0x00a0, 0x00a0, 0x00a0, 0x00a0,
0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2
};
static int
-koi8_r_mbc_to_normalize(OnigAmbigType flag,
- const UChar** pp, const UChar* end, UChar* lower)
+koi8_r_mbc_case_fold(OnigCaseFoldType flag ARG_UNUSED,
+ const UChar** pp, const UChar* end ARG_UNUSED, UChar* lower)
{
const UChar* p = *pp;
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- *lower = ENC_KOI8_R_TO_LOWER_CASE(*p);
- }
- else {
- *lower = *p;
- }
+ *lower = ENC_KOI8_R_TO_LOWER_CASE(*p);
(*pp)++;
- return 1; /* return byte length of converted char to lower */
+ return 1;
}
+#if 0
static int
-koi8_r_is_mbc_ambiguous(OnigAmbigType flag, const UChar** pp, const UChar* end)
+koi8_r_is_mbc_ambiguous(OnigCaseFoldType flag, const UChar** pp, const UChar* end)
{
+ int v;
const UChar* p = *pp;
(*pp)++;
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- int v = (EncKOI8_R_CtypeTable[*p] &
- (ONIGENC_CTYPE_UPPER | ONIGENC_CTYPE_LOWER));
- return (v != 0 ? TRUE : FALSE);
- }
- return FALSE;
+ v = (EncKOI8_R_CtypeTable[*p] & (BIT_CTYPE_UPPER | BIT_CTYPE_LOWER));
+ return (v != 0 ? TRUE : FALSE);
}
+#endif
static int
koi8_r_is_code_ctype(OnigCodePoint code, unsigned int ctype)
@@ -148,92 +136,60 @@ koi8_r_is_code_ctype(OnigCodePoint code, unsigned int ctype)
return FALSE;
}
+static const OnigPairCaseFoldCodes CaseFoldMap[] = {
+ { 0xa3, 0xb3 },
+
+ { 0xc0, 0xe0 },
+ { 0xc1, 0xe1 },
+ { 0xc2, 0xe2 },
+ { 0xc3, 0xe3 },
+ { 0xc4, 0xe4 },
+ { 0xc5, 0xe5 },
+ { 0xc6, 0xe6 },
+ { 0xc7, 0xe7 },
+ { 0xc8, 0xe8 },
+ { 0xc9, 0xe9 },
+ { 0xca, 0xea },
+ { 0xcb, 0xeb },
+ { 0xcc, 0xec },
+ { 0xcd, 0xed },
+ { 0xce, 0xee },
+ { 0xcf, 0xef },
+
+ { 0xd0, 0xf0 },
+ { 0xd1, 0xf1 },
+ { 0xd2, 0xf2 },
+ { 0xd3, 0xf3 },
+ { 0xd4, 0xf4 },
+ { 0xd5, 0xf5 },
+ { 0xd6, 0xf6 },
+ { 0xd7, 0xf7 },
+ { 0xd8, 0xf8 },
+ { 0xd9, 0xf9 },
+ { 0xda, 0xfa },
+ { 0xdb, 0xfb },
+ { 0xdc, 0xfc },
+ { 0xdd, 0xfd },
+ { 0xde, 0xfe },
+ { 0xdf, 0xff }
+};
+
static int
-koi8_r_get_all_pair_ambig_codes(OnigAmbigType flag,
- const OnigPairAmbigCodes** ccs)
+koi8_r_apply_all_case_fold(OnigCaseFoldType flag,
+ OnigApplyAllCaseFoldFunc f, void* arg)
{
- static const OnigPairAmbigCodes cc[] = {
- { 0xa3, 0xb3 },
- { 0xb3, 0xa3 },
-
- { 0xc0, 0xe0 },
- { 0xc1, 0xe1 },
- { 0xc2, 0xe2 },
- { 0xc3, 0xe3 },
- { 0xc4, 0xe4 },
- { 0xc5, 0xe5 },
- { 0xc6, 0xe6 },
- { 0xc7, 0xe7 },
- { 0xc8, 0xe8 },
- { 0xc9, 0xe9 },
- { 0xca, 0xea },
- { 0xcb, 0xeb },
- { 0xcc, 0xec },
- { 0xcd, 0xed },
- { 0xce, 0xee },
- { 0xcf, 0xef },
-
- { 0xd0, 0xf0 },
- { 0xd1, 0xf1 },
- { 0xd2, 0xf2 },
- { 0xd3, 0xf3 },
- { 0xd4, 0xf4 },
- { 0xd5, 0xf5 },
- { 0xd6, 0xf6 },
- { 0xd7, 0xf7 },
- { 0xd8, 0xf8 },
- { 0xd9, 0xf9 },
- { 0xda, 0xfa },
- { 0xdb, 0xfb },
- { 0xdc, 0xfc },
- { 0xdd, 0xfd },
- { 0xde, 0xfe },
- { 0xdf, 0xff },
-
- { 0xe0, 0xc0 },
- { 0xe1, 0xc1 },
- { 0xe2, 0xc2 },
- { 0xe3, 0xc3 },
- { 0xe4, 0xc4 },
- { 0xe5, 0xc5 },
- { 0xe6, 0xc6 },
- { 0xe7, 0xc7 },
- { 0xe8, 0xc8 },
- { 0xe9, 0xc9 },
- { 0xea, 0xca },
- { 0xeb, 0xcb },
- { 0xec, 0xcc },
- { 0xed, 0xcd },
- { 0xee, 0xce },
- { 0xef, 0xcf },
-
- { 0xf0, 0xd0 },
- { 0xf1, 0xd1 },
- { 0xf2, 0xd2 },
- { 0xf3, 0xd3 },
- { 0xf4, 0xd4 },
- { 0xf5, 0xd5 },
- { 0xf6, 0xd6 },
- { 0xf7, 0xd7 },
- { 0xf8, 0xd8 },
- { 0xf9, 0xd9 },
- { 0xfa, 0xda },
- { 0xfb, 0xdb },
- { 0xfc, 0xdc },
- { 0xfe, 0xde },
- { 0xff, 0xdf }
- };
+ return onigenc_apply_all_case_fold_with_map(
+ sizeof(CaseFoldMap)/sizeof(OnigPairCaseFoldCodes), CaseFoldMap, 0,
+ flag, f, arg);
+}
- if (flag == ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) {
- *ccs = OnigAsciiPairAmbigCodes;
- return 52;
- }
- if (flag == ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) {
- *ccs = cc;
- return sizeof(cc) / sizeof(OnigPairAmbigCodes);
- }
- else
- return 0;
+static int
+koi8_r_get_case_fold_codes_by_str(OnigCaseFoldType flag,
+ const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[])
+{
+ return onigenc_get_case_fold_codes_by_str_with_map(
+ sizeof(CaseFoldMap)/sizeof(OnigPairCaseFoldCodes), CaseFoldMap, 0,
+ flag, p, end, items);
}
OnigEncodingType OnigEncodingKOI8_R = {
@@ -241,24 +197,14 @@ OnigEncodingType OnigEncodingKOI8_R = {
"KOI8-R", /* name */
1, /* max enc length */
1, /* min enc length */
- (ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE |
- ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE ),
- {
- (OnigCodePoint )'\\' /* esc */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
- },
onigenc_is_mbc_newline_0x0a,
onigenc_single_byte_mbc_to_code,
onigenc_single_byte_code_to_mbclen,
onigenc_single_byte_code_to_mbc,
- koi8_r_mbc_to_normalize,
- koi8_r_is_mbc_ambiguous,
- koi8_r_get_all_pair_ambig_codes,
- onigenc_nothing_get_all_comp_ambig_codes,
+ koi8_r_mbc_case_fold,
+ koi8_r_apply_all_case_fold,
+ koi8_r_get_case_fold_codes_by_str,
+ onigenc_minimum_property_name_to_ctype,
koi8_r_is_code_ctype,
onigenc_not_support_get_ctype_code_range,
onigenc_single_byte_left_adjust_char_head,
diff --git a/ext/mbstring/oniguruma/enc/mktable.c b/ext/mbstring/oniguruma/enc/mktable.c
index fcf057423c..285216ebda 100644
--- a/ext/mbstring/oniguruma/enc/mktable.c
+++ b/ext/mbstring/oniguruma/enc/mktable.c
@@ -2,7 +2,7 @@
mktable.c
**********************************************************************/
/*-
- * Copyright (c) 2002-2006 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2007 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -29,28 +29,32 @@
#include <stdlib.h>
#include <stdio.h>
+#include <locale.h>
+
+#define __USE_ISOC99
+#include <ctype.h>
-#define NOT_RUBY
#include "regenc.h"
-#define UNICODE_ISO_8859_1 0
-#define ISO_8859_1 1
-#define ISO_8859_2 2
-#define ISO_8859_3 3
-#define ISO_8859_4 4
-#define ISO_8859_5 5
-#define ISO_8859_6 6
-#define ISO_8859_7 7
-#define ISO_8859_8 8
-#define ISO_8859_9 9
-#define ISO_8859_10 10
-#define ISO_8859_11 11
-#define ISO_8859_13 12
-#define ISO_8859_14 13
-#define ISO_8859_15 14
-#define ISO_8859_16 15
-#define KOI8 16
-#define KOI8_R 17
+#define ASCII 0
+#define UNICODE_ISO_8859_1 1
+#define ISO_8859_1 2
+#define ISO_8859_2 3
+#define ISO_8859_3 4
+#define ISO_8859_4 5
+#define ISO_8859_5 6
+#define ISO_8859_6 7
+#define ISO_8859_7 8
+#define ISO_8859_8 9
+#define ISO_8859_9 10
+#define ISO_8859_10 11
+#define ISO_8859_11 12
+#define ISO_8859_13 13
+#define ISO_8859_14 14
+#define ISO_8859_15 15
+#define ISO_8859_16 16
+#define KOI8 17
+#define KOI8_R 18
typedef struct {
int num;
@@ -58,6 +62,7 @@ typedef struct {
} ENC_INFO;
static ENC_INFO Info[] = {
+ { ASCII, "ASCII" },
{ UNICODE_ISO_8859_1, "UNICODE_ISO_8859_1" },
{ ISO_8859_1, "ISO_8859_1" },
{ ISO_8859_2, "ISO_8859_2" },
@@ -81,6 +86,9 @@ static ENC_INFO Info[] = {
static int IsAlpha(int enc, int c)
{
+ if (enc == ASCII)
+ return isalpha(c);
+
if (c >= 0x41 && c <= 0x5a) return 1;
if (c >= 0x61 && c <= 0x7a) return 1;
@@ -255,6 +263,9 @@ static int IsAlpha(int enc, int c)
static int IsBlank(int enc, int c)
{
+ if (enc == ASCII)
+ return isblank(c);
+
if (c == 0x09 || c == 0x20) return 1;
switch (enc) {
@@ -291,6 +302,9 @@ static int IsBlank(int enc, int c)
static int IsCntrl(int enc, int c)
{
+ if (enc == ASCII)
+ return iscntrl(c);
+
if (c >= 0x00 && c <= 0x1F) return 1;
switch (enc) {
@@ -328,7 +342,7 @@ static int IsCntrl(int enc, int c)
return 0;
}
-static int IsDigit(int enc, int c)
+static int IsDigit(int enc ARG_UNUSED, int c)
{
if (c >= 0x30 && c <= 0x39) return 1;
return 0;
@@ -336,6 +350,9 @@ static int IsDigit(int enc, int c)
static int IsGraph(int enc, int c)
{
+ if (enc == ASCII)
+ return isgraph(c);
+
if (c >= 0x21 && c <= 0x7e) return 1;
switch (enc) {
@@ -405,6 +422,9 @@ static int IsGraph(int enc, int c)
static int IsLower(int enc, int c)
{
+ if (enc == ASCII)
+ return islower(c);
+
if (c >= 0x61 && c <= 0x7a) return 1;
switch (enc) {
@@ -534,6 +554,9 @@ static int IsLower(int enc, int c)
static int IsPrint(int enc, int c)
{
+ if (enc == ASCII)
+ return isprint(c);
+
if (c >= 0x20 && c <= 0x7e) return 1;
switch (enc) {
@@ -609,6 +632,9 @@ static int IsPrint(int enc, int c)
static int IsPunct(int enc, int c)
{
+ if (enc == ASCII)
+ return ispunct(c);
+
if (enc == UNICODE_ISO_8859_1) {
if (c == 0x24 || c == 0x2b || c == 0x5e || c == 0x60 ||
c == 0x7c || c == 0x7e) return 1;
@@ -705,6 +731,9 @@ static int IsPunct(int enc, int c)
static int IsSpace(int enc, int c)
{
+ if (enc == ASCII)
+ return isspace(c);
+
if (c >= 0x09 && c <= 0x0d) return 1;
if (c == 0x20) return 1;
@@ -744,6 +773,9 @@ static int IsSpace(int enc, int c)
static int IsUpper(int enc, int c)
{
+ if (enc == ASCII)
+ return isupper(c);
+
if (c >= 0x41 && c <= 0x5a) return 1;
switch (enc) {
@@ -868,6 +900,9 @@ static int IsUpper(int enc, int c)
static int IsXDigit(int enc, int c)
{
+ if (enc == ASCII)
+ return isxdigit(c);
+
if (c >= 0x30 && c <= 0x39) return 1;
if (c >= 0x41 && c <= 0x46) return 1;
if (c >= 0x61 && c <= 0x66) return 1;
@@ -876,6 +911,10 @@ static int IsXDigit(int enc, int c)
static int IsWord(int enc, int c)
{
+ if (enc == ASCII) {
+ return (isalpha(c) || isdigit(c) || c == 0x5f);
+ }
+
if (c >= 0x30 && c <= 0x39) return 1;
if (c >= 0x41 && c <= 0x5a) return 1;
if (c == 0x5f) return 1;
@@ -1052,13 +1091,13 @@ static int IsWord(int enc, int c)
return 0;
}
-static int IsAscii(int enc, int c)
+static int IsAscii(int enc ARG_UNUSED, int c)
{
if (c >= 0x00 && c <= 0x7f) return 1;
return 0;
}
-static int IsNewline(int enc, int c)
+static int IsNewline(int enc ARG_UNUSED, int c)
{
if (c == 0x0a) return 1;
return 0;
@@ -1072,25 +1111,25 @@ static int exec(FILE* fp, ENC_INFO* einfo)
enc = einfo->num;
- fprintf(fp, "static unsigned short Enc%s_CtypeTable[256] = {\n",
+ fprintf(fp, "static const unsigned short Enc%s_CtypeTable[256] = {\n",
einfo->name);
for (c = 0; c < 256; c++) {
val = 0;
- if (IsNewline(enc, c)) val |= ONIGENC_CTYPE_NEWLINE;
- if (IsAlpha (enc, c)) val |= ONIGENC_CTYPE_ALPHA;
- if (IsBlank (enc, c)) val |= ONIGENC_CTYPE_BLANK;
- if (IsCntrl (enc, c)) val |= ONIGENC_CTYPE_CNTRL;
- if (IsDigit (enc, c)) val |= ONIGENC_CTYPE_DIGIT;
- if (IsGraph (enc, c)) val |= ONIGENC_CTYPE_GRAPH;
- if (IsLower (enc, c)) val |= ONIGENC_CTYPE_LOWER;
- if (IsPrint (enc, c)) val |= ONIGENC_CTYPE_PRINT;
- if (IsPunct (enc, c)) val |= ONIGENC_CTYPE_PUNCT;
- if (IsSpace (enc, c)) val |= ONIGENC_CTYPE_SPACE;
- if (IsUpper (enc, c)) val |= ONIGENC_CTYPE_UPPER;
- if (IsXDigit(enc, c)) val |= ONIGENC_CTYPE_XDIGIT;
- if (IsWord (enc, c)) val |= ONIGENC_CTYPE_WORD;
- if (IsAscii (enc, c)) val |= ONIGENC_CTYPE_ASCII;
+ if (IsNewline(enc, c)) val |= BIT_CTYPE_NEWLINE;
+ if (IsAlpha (enc, c)) val |= (BIT_CTYPE_ALPHA | BIT_CTYPE_ALNUM);
+ if (IsBlank (enc, c)) val |= BIT_CTYPE_BLANK;
+ if (IsCntrl (enc, c)) val |= BIT_CTYPE_CNTRL;
+ if (IsDigit (enc, c)) val |= (BIT_CTYPE_DIGIT | BIT_CTYPE_ALNUM);
+ if (IsGraph (enc, c)) val |= BIT_CTYPE_GRAPH;
+ if (IsLower (enc, c)) val |= BIT_CTYPE_LOWER;
+ if (IsPrint (enc, c)) val |= BIT_CTYPE_PRINT;
+ if (IsPunct (enc, c)) val |= BIT_CTYPE_PUNCT;
+ if (IsSpace (enc, c)) val |= BIT_CTYPE_SPACE;
+ if (IsUpper (enc, c)) val |= BIT_CTYPE_UPPER;
+ if (IsXDigit(enc, c)) val |= BIT_CTYPE_XDIGIT;
+ if (IsWord (enc, c)) val |= BIT_CTYPE_WORD;
+ if (IsAscii (enc, c)) val |= BIT_CTYPE_ASCII;
if (c % NCOL == 0) fputs(" ", fp);
fprintf(fp, "0x%04x", val);
@@ -1104,12 +1143,20 @@ static int exec(FILE* fp, ENC_INFO* einfo)
return 0;
}
-extern int main(int argc, char* argv[])
+extern int main(int argc ARG_UNUSED, char* argv[] ARG_UNUSED)
{
int i;
FILE* fp = stdout;
- for (i = 0; i < sizeof(Info)/sizeof(ENC_INFO); i++) {
+ setlocale(LC_ALL, "C");
+ /* setlocale(LC_ALL, "POSIX"); */
+ /* setlocale(LC_ALL, "en_GB.iso88591"); */
+ /* setlocale(LC_ALL, "de_BE.iso88591"); */
+ /* setlocale(LC_ALL, "fr_FR.iso88591"); */
+
+ for (i = 0; i < (int )(sizeof(Info)/sizeof(ENC_INFO)); i++) {
exec(fp, &Info[i]);
}
+
+ return 0;
}
diff --git a/ext/mbstring/oniguruma/enc/sjis.c b/ext/mbstring/oniguruma/enc/sjis.c
index f7d7d52265..7a54c9fb3a 100644
--- a/ext/mbstring/oniguruma/enc/sjis.c
+++ b/ext/mbstring/oniguruma/enc/sjis.c
@@ -2,7 +2,7 @@
sjis.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2005 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2008 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
* SUCH DAMAGE.
*/
-#include "regenc.h"
+#include "regint.h"
static const int EncLen_SJIS[] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -71,13 +71,13 @@ static const char SJIS_CAN_BE_TRAIL_TABLE[256] = {
#define SJIS_ISMB_TRAIL(byte) SJIS_CAN_BE_TRAIL_TABLE[(byte)]
static int
-sjis_mbc_enc_len(const UChar* p)
+mbc_enc_len(const UChar* p)
{
return EncLen_SJIS[*p];
}
static int
-sjis_code_to_mbclen(OnigCodePoint code)
+code_to_mbclen(OnigCodePoint code)
{
if (code < 256) {
if (EncLen_SJIS[(int )code] == 1)
@@ -89,16 +89,16 @@ sjis_code_to_mbclen(OnigCodePoint code)
return 2;
}
else
- return 0;
+ return ONIGERR_INVALID_CODE_POINT_VALUE;
}
static OnigCodePoint
-sjis_mbc_to_code(const UChar* p, const UChar* end)
+mbc_to_code(const UChar* p, const UChar* end)
{
int c, i, len;
OnigCodePoint n;
- len = enc_len(ONIG_ENCODING_SJIS, p);
+ len = enclen(ONIG_ENCODING_SJIS, p);
c = *p++;
n = c;
if (len == 1) return n;
@@ -112,7 +112,7 @@ sjis_mbc_to_code(const UChar* p, const UChar* end)
}
static int
-sjis_code_to_mbc(OnigCodePoint code, UChar *buf)
+code_to_mbc(OnigCodePoint code, UChar *buf)
{
UChar *p = buf;
@@ -120,67 +120,63 @@ sjis_code_to_mbc(OnigCodePoint code, UChar *buf)
*p++ = (UChar )(code & 0xff);
#if 0
- if (enc_len(ONIG_ENCODING_SJIS, buf) != (p - buf))
- return REGERR_INVALID_WIDE_CHAR_VALUE;
+ if (enclen(ONIG_ENCODING_SJIS, buf) != (p - buf))
+ return REGERR_INVALID_CODE_POINT_VALUE;
#endif
return p - buf;
}
static int
-sjis_mbc_to_normalize(OnigAmbigType flag,
- const UChar** pp, const UChar* end, UChar* lower)
+mbc_case_fold(OnigCaseFoldType flag ARG_UNUSED,
+ const UChar** pp, const UChar* end ARG_UNUSED, UChar* lower)
{
const UChar* p = *pp;
if (ONIGENC_IS_MBC_ASCII(p)) {
- if ((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0) {
- *lower = ONIGENC_ASCII_CODE_TO_LOWER_CASE(*p);
- }
- else {
- *lower = *p;
- }
-
+ *lower = ONIGENC_ASCII_CODE_TO_LOWER_CASE(*p);
(*pp)++;
return 1;
}
else {
- int len = enc_len(ONIG_ENCODING_SJIS, p);
+ int i;
+ int len = enclen(ONIG_ENCODING_SJIS, p);
- if (lower != p) {
- int i;
- for (i = 0; i < len; i++) {
- *lower++ = *p++;
- }
+ for (i = 0; i < len; i++) {
+ *lower++ = *p++;
}
(*pp) += len;
return len; /* return byte length of converted char to lower */
}
}
+#if 0
static int
-sjis_is_mbc_ambiguous(OnigAmbigType flag, const UChar** pp, const UChar* end)
+is_mbc_ambiguous(OnigCaseFoldType flag,
+ const UChar** pp, const UChar* end)
{
return onigenc_mbn_is_mbc_ambiguous(ONIG_ENCODING_SJIS, flag, pp, end);
}
+#endif
+#if 0
static int
-sjis_is_code_ctype(OnigCodePoint code, unsigned int ctype)
+is_code_ctype(OnigCodePoint code, unsigned int ctype)
{
if (code < 128)
return ONIGENC_IS_ASCII_CODE_CTYPE(code, ctype);
else {
- if ((ctype & (ONIGENC_CTYPE_WORD |
- ONIGENC_CTYPE_GRAPH | ONIGENC_CTYPE_PRINT)) != 0) {
- return (sjis_code_to_mbclen(code) > 1 ? TRUE : FALSE);
+ if (CTYPE_IS_WORD_GRAPH_PRINT(ctype)) {
+ return (code_to_mbclen(code) > 1 ? TRUE : FALSE);
}
}
return FALSE;
}
+#endif
static UChar*
-sjis_left_adjust_char_head(const UChar* start, const UChar* s)
+left_adjust_char_head(const UChar* start, const UChar* s)
{
const UChar *p;
int len;
@@ -196,43 +192,127 @@ sjis_left_adjust_char_head(const UChar* start, const UChar* s)
}
}
}
- len = enc_len(ONIG_ENCODING_SJIS, p);
+ len = enclen(ONIG_ENCODING_SJIS, p);
if (p + len > s) return (UChar* )p;
p += len;
return (UChar* )(p + ((s - p) & ~1));
}
static int
-sjis_is_allowed_reverse_match(const UChar* s, const UChar* end)
+is_allowed_reverse_match(const UChar* s, const UChar* end ARG_UNUSED)
{
const UChar c = *s;
return (SJIS_ISMB_TRAIL(c) ? FALSE : TRUE);
}
+
+static int PropertyInited = 0;
+static const OnigCodePoint** PropertyList;
+static int PropertyListNum;
+static int PropertyListSize;
+static hash_table_type* PropertyNameTable;
+
+static const OnigCodePoint CR_Hiragana[] = {
+ 1,
+ 0x829f, 0x82f1
+}; /* CR_Hiragana */
+
+static const OnigCodePoint CR_Katakana[] = {
+ 4,
+ 0x00a6, 0x00af,
+ 0x00b1, 0x00dd,
+ 0x8340, 0x837e,
+ 0x8380, 0x8396,
+}; /* CR_Katakana */
+
+static int
+init_property_list(void)
+{
+ int r;
+
+ PROPERTY_LIST_ADD_PROP("Hiragana", CR_Hiragana);
+ PROPERTY_LIST_ADD_PROP("Katakana", CR_Katakana);
+ PropertyInited = 1;
+
+ end:
+ return r;
+}
+
+static int
+property_name_to_ctype(OnigEncoding enc, UChar* p, UChar* end)
+{
+ hash_data_type ctype;
+
+ PROPERTY_LIST_INIT_CHECK;
+
+ if (onig_st_lookup_strend(PropertyNameTable, p, end, &ctype) == 0) {
+ return onigenc_minimum_property_name_to_ctype(enc, p, end);
+ }
+
+ return (int )ctype;
+}
+
+static int
+is_code_ctype(OnigCodePoint code, unsigned int ctype)
+{
+ if (ctype <= ONIGENC_MAX_STD_CTYPE) {
+ if (code < 128)
+ return ONIGENC_IS_ASCII_CODE_CTYPE(code, ctype);
+ else {
+ if (CTYPE_IS_WORD_GRAPH_PRINT(ctype)) {
+ return (code_to_mbclen(code) > 1 ? TRUE : FALSE);
+ }
+ }
+ }
+ else {
+ PROPERTY_LIST_INIT_CHECK;
+
+ ctype -= (ONIGENC_MAX_STD_CTYPE + 1);
+ if (ctype >= (unsigned int )PropertyListNum)
+ return ONIGERR_TYPE_BUG;
+
+ return onig_is_in_code_range((UChar* )PropertyList[ctype], code);
+ }
+
+ return FALSE;
+}
+
+static int
+get_ctype_code_range(OnigCtype ctype, OnigCodePoint* sb_out,
+ const OnigCodePoint* ranges[])
+{
+ if (ctype <= ONIGENC_MAX_STD_CTYPE) {
+ return ONIG_NO_SUPPORT_CONFIG;
+ }
+ else {
+ *sb_out = 0x80;
+
+ PROPERTY_LIST_INIT_CHECK;
+
+ ctype -= (ONIGENC_MAX_STD_CTYPE + 1);
+ if (ctype >= (OnigCtype )PropertyListNum)
+ return ONIGERR_TYPE_BUG;
+
+ *ranges = PropertyList[ctype];
+ return 0;
+ }
+}
+
OnigEncodingType OnigEncodingSJIS = {
- sjis_mbc_enc_len,
+ mbc_enc_len,
"Shift_JIS", /* name */
2, /* max byte length */
1, /* min byte length */
- ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE,
- {
- (OnigCodePoint )'\\' /* esc */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
- },
onigenc_is_mbc_newline_0x0a,
- sjis_mbc_to_code,
- sjis_code_to_mbclen,
- sjis_code_to_mbc,
- sjis_mbc_to_normalize,
- sjis_is_mbc_ambiguous,
- onigenc_ascii_get_all_pair_ambig_codes,
- onigenc_nothing_get_all_comp_ambig_codes,
- sjis_is_code_ctype,
- onigenc_not_support_get_ctype_code_range,
- sjis_left_adjust_char_head,
- sjis_is_allowed_reverse_match
+ mbc_to_code,
+ code_to_mbclen,
+ code_to_mbc,
+ mbc_case_fold,
+ onigenc_ascii_apply_all_case_fold,
+ onigenc_ascii_get_case_fold_codes_by_str,
+ property_name_to_ctype,
+ is_code_ctype,
+ get_ctype_code_range,
+ left_adjust_char_head,
+ is_allowed_reverse_match
};
diff --git a/ext/mbstring/oniguruma/enc/unicode.c b/ext/mbstring/oniguruma/enc/unicode.c
index a8cf539014..af7a86e088 100644
--- a/ext/mbstring/oniguruma/enc/unicode.c
+++ b/ext/mbstring/oniguruma/enc/unicode.c
@@ -2,7 +2,7 @@
unicode.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2004 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2008 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,475 +27,59 @@
* SUCH DAMAGE.
*/
-#include "regenc.h"
+#include "regint.h"
+#define ONIGENC_IS_UNICODE_ISO_8859_1_CTYPE(code,ctype) \
+ ((EncUNICODE_ISO_8859_1_CtypeTable[code] & CTYPE_TO_BIT(ctype)) != 0)
+#if 0
+#define ONIGENC_IS_UNICODE_ISO_8859_1_BIT_CTYPE(code,cbit) \
+ ((EncUNICODE_ISO_8859_1_CtypeTable[code] & (cbit)) != 0)
+#endif
-const unsigned short OnigEnc_Unicode_ISO_8859_1_CtypeTable[256] = {
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x228c, 0x2289, 0x2288, 0x2288, 0x2288, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2284, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0,
- 0x38b0, 0x38b0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x31a0,
- 0x21a0, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x2008,
+static const unsigned short EncUNICODE_ISO_8859_1_CtypeTable[256] = {
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x428c, 0x4289, 0x4288, 0x4288, 0x4288, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4284, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0,
+ 0x78b0, 0x78b0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x51a0,
+ 0x41a0, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x4008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0288, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
0x0284, 0x01a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0,
- 0x00a0, 0x00a0, 0x10e2, 0x01a0, 0x00a0, 0x00a8, 0x00a0, 0x00a0,
- 0x00a0, 0x00a0, 0x10a0, 0x10a0, 0x00a0, 0x10e2, 0x00a0, 0x01a0,
- 0x00a0, 0x10a0, 0x10e2, 0x01a0, 0x10a0, 0x10a0, 0x10a0, 0x01a0,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x00a0,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x00a0,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2
+ 0x00a0, 0x00a0, 0x30e2, 0x01a0, 0x00a0, 0x00a8, 0x00a0, 0x00a0,
+ 0x00a0, 0x00a0, 0x10a0, 0x10a0, 0x00a0, 0x30e2, 0x00a0, 0x01a0,
+ 0x00a0, 0x10a0, 0x30e2, 0x01a0, 0x10a0, 0x10a0, 0x10a0, 0x01a0,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x00a0,
+ 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x00a0,
+ 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2
};
-static const OnigCodePoint CRAlnum[] = {
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- 414,
-#else
- 9,
-#endif
- 0x0030, 0x0039,
- 0x0041, 0x005a,
- 0x0061, 0x007a,
- 0x00aa, 0x00aa,
- 0x00b5, 0x00b5,
- 0x00ba, 0x00ba,
- 0x00c0, 0x00d6,
- 0x00d8, 0x00f6,
- 0x00f8, 0x0236
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- ,
- 0x0250, 0x02c1,
- 0x02c6, 0x02d1,
- 0x02e0, 0x02e4,
- 0x02ee, 0x02ee,
- 0x0300, 0x0357,
- 0x035d, 0x036f,
- 0x037a, 0x037a,
- 0x0386, 0x0386,
- 0x0388, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x03ce,
- 0x03d0, 0x03f5,
- 0x03f7, 0x03fb,
- 0x0400, 0x0481,
- 0x0483, 0x0486,
- 0x0488, 0x04ce,
- 0x04d0, 0x04f5,
- 0x04f8, 0x04f9,
- 0x0500, 0x050f,
- 0x0531, 0x0556,
- 0x0559, 0x0559,
- 0x0561, 0x0587,
- 0x0591, 0x05a1,
- 0x05a3, 0x05b9,
- 0x05bb, 0x05bd,
- 0x05bf, 0x05bf,
- 0x05c1, 0x05c2,
- 0x05c4, 0x05c4,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f2,
- 0x0610, 0x0615,
- 0x0621, 0x063a,
- 0x0640, 0x0658,
- 0x0660, 0x0669,
- 0x066e, 0x06d3,
- 0x06d5, 0x06dc,
- 0x06de, 0x06e8,
- 0x06ea, 0x06fc,
- 0x06ff, 0x06ff,
- 0x0710, 0x074a,
- 0x074d, 0x074f,
- 0x0780, 0x07b1,
- 0x0901, 0x0939,
- 0x093c, 0x094d,
- 0x0950, 0x0954,
- 0x0958, 0x0963,
- 0x0966, 0x096f,
- 0x0981, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09cd,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09e6, 0x09f1,
- 0x0a01, 0x0a03,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a74,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abc, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae3,
- 0x0ae6, 0x0aef,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3c, 0x0b43,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b61,
- 0x0b66, 0x0b6f,
- 0x0b71, 0x0b71,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb5,
- 0x0bb7, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd7, 0x0bd7,
- 0x0be7, 0x0bef,
- 0x0c01, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c33,
- 0x0c35, 0x0c39,
- 0x0c3e, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c60, 0x0c61,
- 0x0c66, 0x0c6f,
- 0x0c82, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbc, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce1,
- 0x0ce6, 0x0cef,
- 0x0d02, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d28,
- 0x0d2a, 0x0d39,
- 0x0d3e, 0x0d43,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4d,
- 0x0d57, 0x0d57,
- 0x0d60, 0x0d61,
- 0x0d66, 0x0d6f,
- 0x0d82, 0x0d83,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dca, 0x0dca,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0df2, 0x0df3,
- 0x0e01, 0x0e3a,
- 0x0e40, 0x0e4e,
- 0x0e50, 0x0e59,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edd,
- 0x0f00, 0x0f00,
- 0x0f18, 0x0f19,
- 0x0f20, 0x0f29,
- 0x0f35, 0x0f35,
- 0x0f37, 0x0f37,
- 0x0f39, 0x0f39,
- 0x0f3e, 0x0f47,
- 0x0f49, 0x0f6a,
- 0x0f71, 0x0f84,
- 0x0f86, 0x0f8b,
- 0x0f90, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fc6, 0x0fc6,
- 0x1000, 0x1021,
- 0x1023, 0x1027,
- 0x1029, 0x102a,
- 0x102c, 0x1032,
- 0x1036, 0x1039,
- 0x1040, 0x1049,
- 0x1050, 0x1059,
- 0x10a0, 0x10c5,
- 0x10d0, 0x10f8,
- 0x1100, 0x1159,
- 0x115f, 0x11a2,
- 0x11a8, 0x11f9,
- 0x1200, 0x1206,
- 0x1208, 0x1246,
- 0x1248, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1286,
- 0x1288, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12ae,
- 0x12b0, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12ce,
- 0x12d0, 0x12d6,
- 0x12d8, 0x12ee,
- 0x12f0, 0x130e,
- 0x1310, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x131e,
- 0x1320, 0x1346,
- 0x1348, 0x135a,
- 0x1369, 0x1371,
- 0x13a0, 0x13f4,
- 0x1401, 0x166c,
- 0x166f, 0x1676,
- 0x1681, 0x169a,
- 0x16a0, 0x16ea,
- 0x1700, 0x170c,
- 0x170e, 0x1714,
- 0x1720, 0x1734,
- 0x1740, 0x1753,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1772, 0x1773,
- 0x1780, 0x17b3,
- 0x17b6, 0x17d3,
- 0x17d7, 0x17d7,
- 0x17dc, 0x17dd,
- 0x17e0, 0x17e9,
- 0x180b, 0x180d,
- 0x1810, 0x1819,
- 0x1820, 0x1877,
- 0x1880, 0x18a9,
- 0x1900, 0x191c,
- 0x1920, 0x192b,
- 0x1930, 0x193b,
- 0x1946, 0x196d,
- 0x1970, 0x1974,
- 0x1d00, 0x1d6b,
- 0x1e00, 0x1e9b,
- 0x1ea0, 0x1ef9,
- 0x1f00, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fbc,
- 0x1fbe, 0x1fbe,
- 0x1fc2, 0x1fc4,
- 0x1fc6, 0x1fcc,
- 0x1fd0, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fe0, 0x1fec,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffc,
- 0x2071, 0x2071,
- 0x207f, 0x207f,
- 0x20d0, 0x20ea,
- 0x2102, 0x2102,
- 0x2107, 0x2107,
- 0x210a, 0x2113,
- 0x2115, 0x2115,
- 0x2119, 0x211d,
- 0x2124, 0x2124,
- 0x2126, 0x2126,
- 0x2128, 0x2128,
- 0x212a, 0x212d,
- 0x212f, 0x2131,
- 0x2133, 0x2139,
- 0x213d, 0x213f,
- 0x2145, 0x2149,
- 0x3005, 0x3006,
- 0x302a, 0x302f,
- 0x3031, 0x3035,
- 0x303b, 0x303c,
- 0x3041, 0x3096,
- 0x3099, 0x309a,
- 0x309d, 0x309f,
- 0x30a1, 0x30fa,
- 0x30fc, 0x30ff,
- 0x3105, 0x312c,
- 0x3131, 0x318e,
- 0x31a0, 0x31b7,
- 0x31f0, 0x31ff,
- 0x3400, 0x4db5,
- 0x4e00, 0x9fa5,
- 0xa000, 0xa48c,
- 0xac00, 0xd7a3,
- 0xf900, 0xfa2d,
- 0xfa30, 0xfa6a,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb28,
- 0xfb2a, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbb1,
- 0xfbd3, 0xfd3d,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdf0, 0xfdfb,
- 0xfe00, 0xfe0f,
- 0xfe20, 0xfe23,
- 0xfe70, 0xfe74,
- 0xfe76, 0xfefc,
- 0xff10, 0xff19,
- 0xff21, 0xff3a,
- 0xff41, 0xff5a,
- 0xff66, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0x10000, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
- 0x10300, 0x1031e,
- 0x10330, 0x10349,
- 0x10380, 0x1039d,
- 0x10400, 0x1049d,
- 0x104a0, 0x104a9,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x1083f,
- 0x1d165, 0x1d169,
- 0x1d16d, 0x1d172,
- 0x1d17b, 0x1d182,
- 0x1d185, 0x1d18b,
- 0x1d1aa, 0x1d1ad,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a3,
- 0x1d6a8, 0x1d6c0,
- 0x1d6c2, 0x1d6da,
- 0x1d6dc, 0x1d6fa,
- 0x1d6fc, 0x1d714,
- 0x1d716, 0x1d734,
- 0x1d736, 0x1d74e,
- 0x1d750, 0x1d76e,
- 0x1d770, 0x1d788,
- 0x1d78a, 0x1d7a8,
- 0x1d7aa, 0x1d7c2,
- 0x1d7c4, 0x1d7c9,
- 0x1d7ce, 0x1d7ff,
- 0x20000, 0x2a6d6,
- 0x2f800, 0x2fa1d,
- 0xe0100, 0xe01ef
-#endif /* USE_UNICODE_FULL_RANGE_CTYPE */
-}; /* end of CRAlnum */
+/* 'NEWLINE' */
+static const OnigCodePoint CR_NEWLINE[] = {
+ 1,
+ 0x000a, 0x000a
+}; /* CR_NEWLINE */
-static const OnigCodePoint CRAlpha[] = {
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- 396,
-#else
- 8,
-#endif
+/* 'Alpha': [[:Alpha:]] */
+static const OnigCodePoint CR_Alpha[] = {
+ 418,
0x0041, 0x005a,
0x0061, 0x007a,
0x00aa, 0x00aa,
@@ -503,15 +87,12 @@ static const OnigCodePoint CRAlpha[] = {
0x00ba, 0x00ba,
0x00c0, 0x00d6,
0x00d8, 0x00f6,
- 0x00f8, 0x0236
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- ,
+ 0x00f8, 0x0241,
0x0250, 0x02c1,
0x02c6, 0x02d1,
0x02e0, 0x02e4,
0x02ee, 0x02ee,
- 0x0300, 0x0357,
- 0x035d, 0x036f,
+ 0x0300, 0x036f,
0x037a, 0x037a,
0x0386, 0x0386,
0x0388, 0x038a,
@@ -519,27 +100,25 @@ static const OnigCodePoint CRAlpha[] = {
0x038e, 0x03a1,
0x03a3, 0x03ce,
0x03d0, 0x03f5,
- 0x03f7, 0x03fb,
- 0x0400, 0x0481,
+ 0x03f7, 0x0481,
0x0483, 0x0486,
0x0488, 0x04ce,
- 0x04d0, 0x04f5,
- 0x04f8, 0x04f9,
+ 0x04d0, 0x04f9,
0x0500, 0x050f,
0x0531, 0x0556,
0x0559, 0x0559,
0x0561, 0x0587,
- 0x0591, 0x05a1,
- 0x05a3, 0x05b9,
+ 0x0591, 0x05b9,
0x05bb, 0x05bd,
0x05bf, 0x05bf,
0x05c1, 0x05c2,
- 0x05c4, 0x05c4,
+ 0x05c4, 0x05c5,
+ 0x05c7, 0x05c7,
0x05d0, 0x05ea,
0x05f0, 0x05f2,
0x0610, 0x0615,
0x0621, 0x063a,
- 0x0640, 0x0658,
+ 0x0640, 0x065e,
0x066e, 0x06d3,
0x06d5, 0x06dc,
0x06de, 0x06e8,
@@ -547,12 +126,13 @@ static const OnigCodePoint CRAlpha[] = {
0x06fa, 0x06fc,
0x06ff, 0x06ff,
0x0710, 0x074a,
- 0x074d, 0x074f,
+ 0x074d, 0x076d,
0x0780, 0x07b1,
0x0901, 0x0939,
0x093c, 0x094d,
0x0950, 0x0954,
0x0958, 0x0963,
+ 0x097d, 0x097d,
0x0981, 0x0983,
0x0985, 0x098c,
0x098f, 0x0990,
@@ -562,7 +142,7 @@ static const OnigCodePoint CRAlpha[] = {
0x09b6, 0x09b9,
0x09bc, 0x09c4,
0x09c7, 0x09c8,
- 0x09cb, 0x09cd,
+ 0x09cb, 0x09ce,
0x09d7, 0x09d7,
0x09dc, 0x09dd,
0x09df, 0x09e3,
@@ -617,8 +197,7 @@ static const OnigCodePoint CRAlpha[] = {
0x0b9e, 0x0b9f,
0x0ba3, 0x0ba4,
0x0ba8, 0x0baa,
- 0x0bae, 0x0bb5,
- 0x0bb7, 0x0bb9,
+ 0x0bae, 0x0bb9,
0x0bbe, 0x0bc2,
0x0bc6, 0x0bc8,
0x0bca, 0x0bcd,
@@ -705,35 +284,29 @@ static const OnigCodePoint CRAlpha[] = {
0x1036, 0x1039,
0x1050, 0x1059,
0x10a0, 0x10c5,
- 0x10d0, 0x10f8,
+ 0x10d0, 0x10fa,
+ 0x10fc, 0x10fc,
0x1100, 0x1159,
0x115f, 0x11a2,
0x11a8, 0x11f9,
- 0x1200, 0x1206,
- 0x1208, 0x1246,
- 0x1248, 0x1248,
+ 0x1200, 0x1248,
0x124a, 0x124d,
0x1250, 0x1256,
0x1258, 0x1258,
0x125a, 0x125d,
- 0x1260, 0x1286,
- 0x1288, 0x1288,
+ 0x1260, 0x1288,
0x128a, 0x128d,
- 0x1290, 0x12ae,
- 0x12b0, 0x12b0,
+ 0x1290, 0x12b0,
0x12b2, 0x12b5,
0x12b8, 0x12be,
0x12c0, 0x12c0,
0x12c2, 0x12c5,
- 0x12c8, 0x12ce,
- 0x12d0, 0x12d6,
- 0x12d8, 0x12ee,
- 0x12f0, 0x130e,
- 0x1310, 0x1310,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
0x1312, 0x1315,
- 0x1318, 0x131e,
- 0x1320, 0x1346,
- 0x1348, 0x135a,
+ 0x1318, 0x135a,
+ 0x135f, 0x135f,
+ 0x1380, 0x138f,
0x13a0, 0x13f4,
0x1401, 0x166c,
0x166f, 0x1676,
@@ -758,7 +331,10 @@ static const OnigCodePoint CRAlpha[] = {
0x1930, 0x193b,
0x1950, 0x196d,
0x1970, 0x1974,
- 0x1d00, 0x1d6b,
+ 0x1980, 0x19a9,
+ 0x19b0, 0x19c9,
+ 0x1a00, 0x1a1b,
+ 0x1d00, 0x1dc3,
0x1e00, 0x1e9b,
0x1ea0, 0x1ef9,
0x1f00, 0x1f15,
@@ -782,7 +358,8 @@ static const OnigCodePoint CRAlpha[] = {
0x1ff6, 0x1ffc,
0x2071, 0x2071,
0x207f, 0x207f,
- 0x20d0, 0x20ea,
+ 0x2090, 0x2094,
+ 0x20d0, 0x20eb,
0x2102, 0x2102,
0x2107, 0x2107,
0x210a, 0x2113,
@@ -794,8 +371,23 @@ static const OnigCodePoint CRAlpha[] = {
0x212a, 0x212d,
0x212f, 0x2131,
0x2133, 0x2139,
- 0x213d, 0x213f,
+ 0x213c, 0x213f,
0x2145, 0x2149,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c80, 0x2ce4,
+ 0x2d00, 0x2d25,
+ 0x2d30, 0x2d65,
+ 0x2d6f, 0x2d6f,
+ 0x2d80, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
0x3005, 0x3006,
0x302a, 0x302f,
0x3031, 0x3035,
@@ -810,11 +402,13 @@ static const OnigCodePoint CRAlpha[] = {
0x31a0, 0x31b7,
0x31f0, 0x31ff,
0x3400, 0x4db5,
- 0x4e00, 0x9fa5,
+ 0x4e00, 0x9fbb,
0xa000, 0xa48c,
+ 0xa800, 0xa827,
0xac00, 0xd7a3,
0xf900, 0xfa2d,
0xfa30, 0xfa6a,
+ 0xfa70, 0xfad9,
0xfb00, 0xfb06,
0xfb13, 0xfb17,
0xfb1d, 0xfb28,
@@ -849,6 +443,8 @@ static const OnigCodePoint CRAlpha[] = {
0x10300, 0x1031e,
0x10330, 0x10349,
0x10380, 0x1039d,
+ 0x103a0, 0x103c3,
+ 0x103c8, 0x103cf,
0x10400, 0x1049d,
0x10800, 0x10805,
0x10808, 0x10808,
@@ -856,11 +452,19 @@ static const OnigCodePoint CRAlpha[] = {
0x10837, 0x10838,
0x1083c, 0x1083c,
0x1083f, 0x1083f,
+ 0x10a00, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a33,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a3f,
0x1d165, 0x1d169,
0x1d16d, 0x1d172,
0x1d17b, 0x1d182,
0x1d185, 0x1d18b,
0x1d1aa, 0x1d1ad,
+ 0x1d242, 0x1d244,
0x1d400, 0x1d454,
0x1d456, 0x1d49c,
0x1d49e, 0x1d49f,
@@ -879,7 +483,7 @@ static const OnigCodePoint CRAlpha[] = {
0x1d540, 0x1d544,
0x1d546, 0x1d546,
0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a3,
+ 0x1d552, 0x1d6a5,
0x1d6a8, 0x1d6c0,
0x1d6c2, 0x1d6da,
0x1d6dc, 0x1d6fa,
@@ -894,40 +498,28 @@ static const OnigCodePoint CRAlpha[] = {
0x20000, 0x2a6d6,
0x2f800, 0x2fa1d,
0xe0100, 0xe01ef
-#endif /* USE_UNICODE_FULL_RANGE_CTYPE */
-}; /* end of CRAlpha */
+}; /* CR_Alpha */
-static const OnigCodePoint CRBlank[] = {
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
+/* 'Blank': [[:Blank:]] */
+static const OnigCodePoint CR_Blank[] = {
9,
-#else
- 3,
-#endif
0x0009, 0x0009,
0x0020, 0x0020,
- 0x00a0, 0x00a0
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- ,
+ 0x00a0, 0x00a0,
0x1680, 0x1680,
0x180e, 0x180e,
0x2000, 0x200a,
0x202f, 0x202f,
0x205f, 0x205f,
0x3000, 0x3000
-#endif /* USE_UNICODE_FULL_RANGE_CTYPE */
-}; /* end of CRBlank */
+}; /* CR_Blank */
-static const OnigCodePoint CRCntrl[] = {
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
+/* 'Cntrl': [[:Cntrl:]] */
+static const OnigCodePoint CR_Cntrl[] = {
19,
-#else
- 3,
-#endif
0x0000, 0x001f,
0x007f, 0x009f,
- 0x00ad, 0x00ad
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- ,
+ 0x00ad, 0x00ad,
0x0600, 0x0603,
0x06dd, 0x06dd,
0x070f, 0x070f,
@@ -944,18 +536,12 @@ static const OnigCodePoint CRCntrl[] = {
0xe0020, 0xe007f,
0xf0000, 0xffffd,
0x100000, 0x10fffd
-#endif /* USE_UNICODE_FULL_RANGE_CTYPE */
-}; /* end of CRCntrl */
+}; /* CR_Cntrl */
-static const OnigCodePoint CRDigit[] = {
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
+/* 'Digit': [[:Digit:]] */
+static const OnigCodePoint CR_Digit[] = {
23,
-#else
- 1,
-#endif
- 0x0030, 0x0039
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- ,
+ 0x0030, 0x0039,
0x0660, 0x0669,
0x06f0, 0x06f9,
0x0966, 0x096f,
@@ -963,7 +549,7 @@ static const OnigCodePoint CRDigit[] = {
0x0a66, 0x0a6f,
0x0ae6, 0x0aef,
0x0b66, 0x0b6f,
- 0x0be7, 0x0bef,
+ 0x0be6, 0x0bef,
0x0c66, 0x0c6f,
0x0ce6, 0x0cef,
0x0d66, 0x0d6f,
@@ -971,28 +557,21 @@ static const OnigCodePoint CRDigit[] = {
0x0ed0, 0x0ed9,
0x0f20, 0x0f29,
0x1040, 0x1049,
- 0x1369, 0x1371,
0x17e0, 0x17e9,
0x1810, 0x1819,
0x1946, 0x194f,
+ 0x19d0, 0x19d9,
0xff10, 0xff19,
0x104a0, 0x104a9,
0x1d7ce, 0x1d7ff
-#endif /* USE_UNICODE_FULL_RANGE_CTYPE */
-}; /* end of CRDigit */
+}; /* CR_Digit */
-static const OnigCodePoint CRGraph[] = {
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- 405,
-#else
- 2,
-#endif
+/* 'Graph': [[:Graph:]] */
+static const OnigCodePoint CR_Graph[] = {
+ 424,
0x0021, 0x007e,
- 0x00a1, 0x0236
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- ,
- 0x0250, 0x0357,
- 0x035d, 0x036f,
+ 0x00a1, 0x0241,
+ 0x0250, 0x036f,
0x0374, 0x0375,
0x037a, 0x037a,
0x037e, 0x037e,
@@ -1000,35 +579,33 @@ static const OnigCodePoint CRGraph[] = {
0x038c, 0x038c,
0x038e, 0x03a1,
0x03a3, 0x03ce,
- 0x03d0, 0x03fb,
- 0x0400, 0x0486,
+ 0x03d0, 0x0486,
0x0488, 0x04ce,
- 0x04d0, 0x04f5,
- 0x04f8, 0x04f9,
+ 0x04d0, 0x04f9,
0x0500, 0x050f,
0x0531, 0x0556,
0x0559, 0x055f,
0x0561, 0x0587,
0x0589, 0x058a,
- 0x0591, 0x05a1,
- 0x05a3, 0x05b9,
- 0x05bb, 0x05c4,
+ 0x0591, 0x05b9,
+ 0x05bb, 0x05c7,
0x05d0, 0x05ea,
0x05f0, 0x05f4,
0x0600, 0x0603,
- 0x060c, 0x0615,
+ 0x060b, 0x0615,
0x061b, 0x061b,
- 0x061f, 0x061f,
+ 0x061e, 0x061f,
0x0621, 0x063a,
- 0x0640, 0x0658,
+ 0x0640, 0x065e,
0x0660, 0x070d,
0x070f, 0x074a,
- 0x074d, 0x074f,
+ 0x074d, 0x076d,
0x0780, 0x07b1,
0x0901, 0x0939,
0x093c, 0x094d,
0x0950, 0x0954,
0x0958, 0x0970,
+ 0x097d, 0x097d,
0x0981, 0x0983,
0x0985, 0x098c,
0x098f, 0x0990,
@@ -1038,7 +615,7 @@ static const OnigCodePoint CRGraph[] = {
0x09b6, 0x09b9,
0x09bc, 0x09c4,
0x09c7, 0x09c8,
- 0x09cb, 0x09cd,
+ 0x09cb, 0x09ce,
0x09d7, 0x09d7,
0x09dc, 0x09dd,
0x09df, 0x09e3,
@@ -1095,13 +672,12 @@ static const OnigCodePoint CRGraph[] = {
0x0b9e, 0x0b9f,
0x0ba3, 0x0ba4,
0x0ba8, 0x0baa,
- 0x0bae, 0x0bb5,
- 0x0bb7, 0x0bb9,
+ 0x0bae, 0x0bb9,
0x0bbe, 0x0bc2,
0x0bc6, 0x0bc8,
0x0bca, 0x0bcd,
0x0bd7, 0x0bd7,
- 0x0be7, 0x0bfa,
+ 0x0be6, 0x0bfa,
0x0c01, 0x0c03,
0x0c05, 0x0c0c,
0x0c0e, 0x0c10,
@@ -1175,7 +751,7 @@ static const OnigCodePoint CRGraph[] = {
0x0f90, 0x0f97,
0x0f99, 0x0fbc,
0x0fbe, 0x0fcc,
- 0x0fcf, 0x0fcf,
+ 0x0fcf, 0x0fd1,
0x1000, 0x1021,
0x1023, 0x1027,
0x1029, 0x102a,
@@ -1183,37 +759,28 @@ static const OnigCodePoint CRGraph[] = {
0x1036, 0x1039,
0x1040, 0x1059,
0x10a0, 0x10c5,
- 0x10d0, 0x10f8,
- 0x10fb, 0x10fb,
+ 0x10d0, 0x10fc,
0x1100, 0x1159,
0x115f, 0x11a2,
0x11a8, 0x11f9,
- 0x1200, 0x1206,
- 0x1208, 0x1246,
- 0x1248, 0x1248,
+ 0x1200, 0x1248,
0x124a, 0x124d,
0x1250, 0x1256,
0x1258, 0x1258,
0x125a, 0x125d,
- 0x1260, 0x1286,
- 0x1288, 0x1288,
+ 0x1260, 0x1288,
0x128a, 0x128d,
- 0x1290, 0x12ae,
- 0x12b0, 0x12b0,
+ 0x1290, 0x12b0,
0x12b2, 0x12b5,
0x12b8, 0x12be,
0x12c0, 0x12c0,
0x12c2, 0x12c5,
- 0x12c8, 0x12ce,
- 0x12d0, 0x12d6,
- 0x12d8, 0x12ee,
- 0x12f0, 0x130e,
- 0x1310, 0x1310,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
0x1312, 0x1315,
- 0x1318, 0x131e,
- 0x1320, 0x1346,
- 0x1348, 0x135a,
- 0x1361, 0x137c,
+ 0x1318, 0x135a,
+ 0x135f, 0x137c,
+ 0x1380, 0x1399,
0x13a0, 0x13f4,
0x1401, 0x1676,
0x1681, 0x169c,
@@ -1238,8 +805,12 @@ static const OnigCodePoint CRGraph[] = {
0x1940, 0x1940,
0x1944, 0x196d,
0x1970, 0x1974,
- 0x19e0, 0x19ff,
- 0x1d00, 0x1d6b,
+ 0x1980, 0x19a9,
+ 0x19b0, 0x19c9,
+ 0x19d0, 0x19d9,
+ 0x19de, 0x1a1b,
+ 0x1a1e, 0x1a1f,
+ 0x1d00, 0x1dc3,
0x1e00, 0x1e9b,
0x1ea0, 0x1ef9,
0x1f00, 0x1f15,
@@ -1260,23 +831,20 @@ static const OnigCodePoint CRGraph[] = {
0x1ff6, 0x1ffe,
0x200b, 0x2027,
0x202a, 0x202e,
- 0x2030, 0x2054,
- 0x2057, 0x2057,
+ 0x2030, 0x205e,
0x2060, 0x2063,
0x206a, 0x2071,
0x2074, 0x208e,
- 0x20a0, 0x20b1,
- 0x20d0, 0x20ea,
- 0x2100, 0x213b,
- 0x213d, 0x214b,
+ 0x2090, 0x2094,
+ 0x20a0, 0x20b5,
+ 0x20d0, 0x20eb,
+ 0x2100, 0x214c,
0x2153, 0x2183,
- 0x2190, 0x23d0,
+ 0x2190, 0x23db,
0x2400, 0x2426,
0x2440, 0x244a,
- 0x2460, 0x2617,
- 0x2619, 0x267d,
- 0x2680, 0x2691,
- 0x26a0, 0x26a1,
+ 0x2460, 0x269c,
+ 0x26a0, 0x26b1,
0x2701, 0x2704,
0x2706, 0x2709,
0x270c, 0x2727,
@@ -1288,8 +856,26 @@ static const OnigCodePoint CRGraph[] = {
0x2761, 0x2794,
0x2798, 0x27af,
0x27b1, 0x27be,
+ 0x27c0, 0x27c6,
0x27d0, 0x27eb,
- 0x27f0, 0x2b0d,
+ 0x27f0, 0x2b13,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c80, 0x2cea,
+ 0x2cf9, 0x2d25,
+ 0x2d30, 0x2d65,
+ 0x2d6f, 0x2d6f,
+ 0x2d80, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x2e00, 0x2e17,
+ 0x2e1c, 0x2e1d,
0x2e80, 0x2e99,
0x2e9b, 0x2ef3,
0x2f00, 0x2fd5,
@@ -1300,17 +886,20 @@ static const OnigCodePoint CRGraph[] = {
0x3105, 0x312c,
0x3131, 0x318e,
0x3190, 0x31b7,
+ 0x31c0, 0x31cf,
0x31f0, 0x321e,
0x3220, 0x3243,
- 0x3250, 0x327d,
- 0x327f, 0x32fe,
+ 0x3250, 0x32fe,
0x3300, 0x4db5,
- 0x4dc0, 0x9fa5,
+ 0x4dc0, 0x9fbb,
0xa000, 0xa48c,
0xa490, 0xa4c6,
+ 0xa700, 0xa716,
+ 0xa800, 0xa82b,
0xac00, 0xd7a3,
0xe000, 0xfa2d,
0xfa30, 0xfa6a,
+ 0xfa70, 0xfad9,
0xfb00, 0xfb06,
0xfb13, 0xfb17,
0xfb1d, 0xfb36,
@@ -1323,7 +912,7 @@ static const OnigCodePoint CRGraph[] = {
0xfd50, 0xfd8f,
0xfd92, 0xfdc7,
0xfdf0, 0xfdfd,
- 0xfe00, 0xfe0f,
+ 0xfe00, 0xfe19,
0xfe20, 0xfe23,
0xfe30, 0xfe52,
0xfe54, 0xfe66,
@@ -1348,12 +937,13 @@ static const OnigCodePoint CRGraph[] = {
0x10080, 0x100fa,
0x10100, 0x10102,
0x10107, 0x10133,
- 0x10137, 0x1013f,
+ 0x10137, 0x1018a,
0x10300, 0x1031e,
0x10320, 0x10323,
0x10330, 0x1034a,
0x10380, 0x1039d,
- 0x1039f, 0x1039f,
+ 0x1039f, 0x103c3,
+ 0x103c8, 0x103d5,
0x10400, 0x1049d,
0x104a0, 0x104a9,
0x10800, 0x10805,
@@ -1362,9 +952,18 @@ static const OnigCodePoint CRGraph[] = {
0x10837, 0x10838,
0x1083c, 0x1083c,
0x1083f, 0x1083f,
+ 0x10a00, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a33,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a47,
+ 0x10a50, 0x10a58,
0x1d000, 0x1d0f5,
0x1d100, 0x1d126,
0x1d12a, 0x1d1dd,
+ 0x1d200, 0x1d245,
0x1d300, 0x1d356,
0x1d400, 0x1d454,
0x1d456, 0x1d49c,
@@ -1384,7 +983,7 @@ static const OnigCodePoint CRGraph[] = {
0x1d540, 0x1d544,
0x1d546, 0x1d546,
0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a3,
+ 0x1d552, 0x1d6a5,
0x1d6a8, 0x1d7c9,
0x1d7ce, 0x1d7ff,
0x20000, 0x2a6d6,
@@ -1394,23 +993,17 @@ static const OnigCodePoint CRGraph[] = {
0xe0100, 0xe01ef,
0xf0000, 0xffffd,
0x100000, 0x10fffd
-#endif /* USE_UNICODE_FULL_RANGE_CTYPE */
-}; /* end of CRGraph */
+}; /* CR_Graph */
-static const OnigCodePoint CRLower[] = {
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- 424,
-#else
- 6,
-#endif
+/* 'Lower': [[:Lower:]] */
+static const OnigCodePoint CR_Lower[] = {
+ 480,
0x0061, 0x007a,
0x00aa, 0x00aa,
0x00b5, 0x00b5,
0x00ba, 0x00ba,
0x00df, 0x00f6,
- 0x00f8, 0x00ff
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- ,
+ 0x00f8, 0x00ff,
0x0101, 0x0101,
0x0103, 0x0103,
0x0105, 0x0105,
@@ -1543,7 +1136,9 @@ static const OnigCodePoint CRLower[] = {
0x022d, 0x022d,
0x022f, 0x022f,
0x0231, 0x0231,
- 0x0233, 0x0236,
+ 0x0233, 0x0239,
+ 0x023c, 0x023c,
+ 0x023f, 0x0240,
0x0250, 0x02af,
0x0390, 0x0390,
0x03ac, 0x03ce,
@@ -1563,7 +1158,7 @@ static const OnigCodePoint CRLower[] = {
0x03ef, 0x03f3,
0x03f5, 0x03f5,
0x03f8, 0x03f8,
- 0x03fb, 0x03fb,
+ 0x03fb, 0x03fc,
0x0430, 0x045f,
0x0461, 0x0461,
0x0463, 0x0463,
@@ -1635,6 +1230,7 @@ static const OnigCodePoint CRLower[] = {
0x04f1, 0x04f1,
0x04f3, 0x04f3,
0x04f5, 0x04f5,
+ 0x04f7, 0x04f7,
0x04f9, 0x04f9,
0x0501, 0x0501,
0x0503, 0x0503,
@@ -1646,7 +1242,8 @@ static const OnigCodePoint CRLower[] = {
0x050f, 0x050f,
0x0561, 0x0587,
0x1d00, 0x1d2b,
- 0x1d62, 0x1d6b,
+ 0x1d62, 0x1d77,
+ 0x1d79, 0x1d9a,
0x1e01, 0x1e01,
0x1e03, 0x1e03,
0x1e05, 0x1e05,
@@ -1796,8 +1393,60 @@ static const OnigCodePoint CRLower[] = {
0x212f, 0x212f,
0x2134, 0x2134,
0x2139, 0x2139,
- 0x213d, 0x213d,
+ 0x213c, 0x213d,
0x2146, 0x2149,
+ 0x2c30, 0x2c5e,
+ 0x2c81, 0x2c81,
+ 0x2c83, 0x2c83,
+ 0x2c85, 0x2c85,
+ 0x2c87, 0x2c87,
+ 0x2c89, 0x2c89,
+ 0x2c8b, 0x2c8b,
+ 0x2c8d, 0x2c8d,
+ 0x2c8f, 0x2c8f,
+ 0x2c91, 0x2c91,
+ 0x2c93, 0x2c93,
+ 0x2c95, 0x2c95,
+ 0x2c97, 0x2c97,
+ 0x2c99, 0x2c99,
+ 0x2c9b, 0x2c9b,
+ 0x2c9d, 0x2c9d,
+ 0x2c9f, 0x2c9f,
+ 0x2ca1, 0x2ca1,
+ 0x2ca3, 0x2ca3,
+ 0x2ca5, 0x2ca5,
+ 0x2ca7, 0x2ca7,
+ 0x2ca9, 0x2ca9,
+ 0x2cab, 0x2cab,
+ 0x2cad, 0x2cad,
+ 0x2caf, 0x2caf,
+ 0x2cb1, 0x2cb1,
+ 0x2cb3, 0x2cb3,
+ 0x2cb5, 0x2cb5,
+ 0x2cb7, 0x2cb7,
+ 0x2cb9, 0x2cb9,
+ 0x2cbb, 0x2cbb,
+ 0x2cbd, 0x2cbd,
+ 0x2cbf, 0x2cbf,
+ 0x2cc1, 0x2cc1,
+ 0x2cc3, 0x2cc3,
+ 0x2cc5, 0x2cc5,
+ 0x2cc7, 0x2cc7,
+ 0x2cc9, 0x2cc9,
+ 0x2ccb, 0x2ccb,
+ 0x2ccd, 0x2ccd,
+ 0x2ccf, 0x2ccf,
+ 0x2cd1, 0x2cd1,
+ 0x2cd3, 0x2cd3,
+ 0x2cd5, 0x2cd5,
+ 0x2cd7, 0x2cd7,
+ 0x2cd9, 0x2cd9,
+ 0x2cdb, 0x2cdb,
+ 0x2cdd, 0x2cdd,
+ 0x2cdf, 0x2cdf,
+ 0x2ce1, 0x2ce1,
+ 0x2ce3, 0x2ce4,
+ 0x2d00, 0x2d25,
0xfb00, 0xfb06,
0xfb13, 0xfb17,
0xff41, 0xff5a,
@@ -1818,7 +1467,7 @@ static const OnigCodePoint CRLower[] = {
0x1d5ee, 0x1d607,
0x1d622, 0x1d63b,
0x1d656, 0x1d66f,
- 0x1d68a, 0x1d6a3,
+ 0x1d68a, 0x1d6a5,
0x1d6c2, 0x1d6da,
0x1d6dc, 0x1d6e1,
0x1d6fc, 0x1d714,
@@ -1829,23 +1478,16 @@ static const OnigCodePoint CRLower[] = {
0x1d78a, 0x1d78f,
0x1d7aa, 0x1d7c2,
0x1d7c4, 0x1d7c9
-#endif /* USE_UNICODE_FULL_RANGE_CTYPE */
-}; /* end of CRLower */
+}; /* CR_Lower */
-static const OnigCodePoint CRPrint[] = {
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- 405,
-#else
- 4,
-#endif
+/* 'Print': [[:Print:]] */
+static const OnigCodePoint CR_Print[] = {
+ 423,
0x0009, 0x000d,
0x0020, 0x007e,
0x0085, 0x0085,
- 0x00a0, 0x0236
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- ,
- 0x0250, 0x0357,
- 0x035d, 0x036f,
+ 0x00a0, 0x0241,
+ 0x0250, 0x036f,
0x0374, 0x0375,
0x037a, 0x037a,
0x037e, 0x037e,
@@ -1853,35 +1495,33 @@ static const OnigCodePoint CRPrint[] = {
0x038c, 0x038c,
0x038e, 0x03a1,
0x03a3, 0x03ce,
- 0x03d0, 0x03fb,
- 0x0400, 0x0486,
+ 0x03d0, 0x0486,
0x0488, 0x04ce,
- 0x04d0, 0x04f5,
- 0x04f8, 0x04f9,
+ 0x04d0, 0x04f9,
0x0500, 0x050f,
0x0531, 0x0556,
0x0559, 0x055f,
0x0561, 0x0587,
0x0589, 0x058a,
- 0x0591, 0x05a1,
- 0x05a3, 0x05b9,
- 0x05bb, 0x05c4,
+ 0x0591, 0x05b9,
+ 0x05bb, 0x05c7,
0x05d0, 0x05ea,
0x05f0, 0x05f4,
0x0600, 0x0603,
- 0x060c, 0x0615,
+ 0x060b, 0x0615,
0x061b, 0x061b,
- 0x061f, 0x061f,
+ 0x061e, 0x061f,
0x0621, 0x063a,
- 0x0640, 0x0658,
+ 0x0640, 0x065e,
0x0660, 0x070d,
0x070f, 0x074a,
- 0x074d, 0x074f,
+ 0x074d, 0x076d,
0x0780, 0x07b1,
0x0901, 0x0939,
0x093c, 0x094d,
0x0950, 0x0954,
0x0958, 0x0970,
+ 0x097d, 0x097d,
0x0981, 0x0983,
0x0985, 0x098c,
0x098f, 0x0990,
@@ -1891,7 +1531,7 @@ static const OnigCodePoint CRPrint[] = {
0x09b6, 0x09b9,
0x09bc, 0x09c4,
0x09c7, 0x09c8,
- 0x09cb, 0x09cd,
+ 0x09cb, 0x09ce,
0x09d7, 0x09d7,
0x09dc, 0x09dd,
0x09df, 0x09e3,
@@ -1948,13 +1588,12 @@ static const OnigCodePoint CRPrint[] = {
0x0b9e, 0x0b9f,
0x0ba3, 0x0ba4,
0x0ba8, 0x0baa,
- 0x0bae, 0x0bb5,
- 0x0bb7, 0x0bb9,
+ 0x0bae, 0x0bb9,
0x0bbe, 0x0bc2,
0x0bc6, 0x0bc8,
0x0bca, 0x0bcd,
0x0bd7, 0x0bd7,
- 0x0be7, 0x0bfa,
+ 0x0be6, 0x0bfa,
0x0c01, 0x0c03,
0x0c05, 0x0c0c,
0x0c0e, 0x0c10,
@@ -2028,7 +1667,7 @@ static const OnigCodePoint CRPrint[] = {
0x0f90, 0x0f97,
0x0f99, 0x0fbc,
0x0fbe, 0x0fcc,
- 0x0fcf, 0x0fcf,
+ 0x0fcf, 0x0fd1,
0x1000, 0x1021,
0x1023, 0x1027,
0x1029, 0x102a,
@@ -2036,37 +1675,28 @@ static const OnigCodePoint CRPrint[] = {
0x1036, 0x1039,
0x1040, 0x1059,
0x10a0, 0x10c5,
- 0x10d0, 0x10f8,
- 0x10fb, 0x10fb,
+ 0x10d0, 0x10fc,
0x1100, 0x1159,
0x115f, 0x11a2,
0x11a8, 0x11f9,
- 0x1200, 0x1206,
- 0x1208, 0x1246,
- 0x1248, 0x1248,
+ 0x1200, 0x1248,
0x124a, 0x124d,
0x1250, 0x1256,
0x1258, 0x1258,
0x125a, 0x125d,
- 0x1260, 0x1286,
- 0x1288, 0x1288,
+ 0x1260, 0x1288,
0x128a, 0x128d,
- 0x1290, 0x12ae,
- 0x12b0, 0x12b0,
+ 0x1290, 0x12b0,
0x12b2, 0x12b5,
0x12b8, 0x12be,
0x12c0, 0x12c0,
0x12c2, 0x12c5,
- 0x12c8, 0x12ce,
- 0x12d0, 0x12d6,
- 0x12d8, 0x12ee,
- 0x12f0, 0x130e,
- 0x1310, 0x1310,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
0x1312, 0x1315,
- 0x1318, 0x131e,
- 0x1320, 0x1346,
- 0x1348, 0x135a,
- 0x1361, 0x137c,
+ 0x1318, 0x135a,
+ 0x135f, 0x137c,
+ 0x1380, 0x1399,
0x13a0, 0x13f4,
0x1401, 0x1676,
0x1680, 0x169c,
@@ -2091,8 +1721,12 @@ static const OnigCodePoint CRPrint[] = {
0x1940, 0x1940,
0x1944, 0x196d,
0x1970, 0x1974,
- 0x19e0, 0x19ff,
- 0x1d00, 0x1d6b,
+ 0x1980, 0x19a9,
+ 0x19b0, 0x19c9,
+ 0x19d0, 0x19d9,
+ 0x19de, 0x1a1b,
+ 0x1a1e, 0x1a1f,
+ 0x1d00, 0x1dc3,
0x1e00, 0x1e9b,
0x1ea0, 0x1ef9,
0x1f00, 0x1f15,
@@ -2111,23 +1745,19 @@ static const OnigCodePoint CRPrint[] = {
0x1fdd, 0x1fef,
0x1ff2, 0x1ff4,
0x1ff6, 0x1ffe,
- 0x2000, 0x2054,
- 0x2057, 0x2057,
- 0x205f, 0x2063,
+ 0x2000, 0x2063,
0x206a, 0x2071,
0x2074, 0x208e,
- 0x20a0, 0x20b1,
- 0x20d0, 0x20ea,
- 0x2100, 0x213b,
- 0x213d, 0x214b,
+ 0x2090, 0x2094,
+ 0x20a0, 0x20b5,
+ 0x20d0, 0x20eb,
+ 0x2100, 0x214c,
0x2153, 0x2183,
- 0x2190, 0x23d0,
+ 0x2190, 0x23db,
0x2400, 0x2426,
0x2440, 0x244a,
- 0x2460, 0x2617,
- 0x2619, 0x267d,
- 0x2680, 0x2691,
- 0x26a0, 0x26a1,
+ 0x2460, 0x269c,
+ 0x26a0, 0x26b1,
0x2701, 0x2704,
0x2706, 0x2709,
0x270c, 0x2727,
@@ -2139,8 +1769,26 @@ static const OnigCodePoint CRPrint[] = {
0x2761, 0x2794,
0x2798, 0x27af,
0x27b1, 0x27be,
+ 0x27c0, 0x27c6,
0x27d0, 0x27eb,
- 0x27f0, 0x2b0d,
+ 0x27f0, 0x2b13,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c80, 0x2cea,
+ 0x2cf9, 0x2d25,
+ 0x2d30, 0x2d65,
+ 0x2d6f, 0x2d6f,
+ 0x2d80, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x2e00, 0x2e17,
+ 0x2e1c, 0x2e1d,
0x2e80, 0x2e99,
0x2e9b, 0x2ef3,
0x2f00, 0x2fd5,
@@ -2151,17 +1799,20 @@ static const OnigCodePoint CRPrint[] = {
0x3105, 0x312c,
0x3131, 0x318e,
0x3190, 0x31b7,
+ 0x31c0, 0x31cf,
0x31f0, 0x321e,
0x3220, 0x3243,
- 0x3250, 0x327d,
- 0x327f, 0x32fe,
+ 0x3250, 0x32fe,
0x3300, 0x4db5,
- 0x4dc0, 0x9fa5,
+ 0x4dc0, 0x9fbb,
0xa000, 0xa48c,
0xa490, 0xa4c6,
+ 0xa700, 0xa716,
+ 0xa800, 0xa82b,
0xac00, 0xd7a3,
0xe000, 0xfa2d,
0xfa30, 0xfa6a,
+ 0xfa70, 0xfad9,
0xfb00, 0xfb06,
0xfb13, 0xfb17,
0xfb1d, 0xfb36,
@@ -2174,7 +1825,7 @@ static const OnigCodePoint CRPrint[] = {
0xfd50, 0xfd8f,
0xfd92, 0xfdc7,
0xfdf0, 0xfdfd,
- 0xfe00, 0xfe0f,
+ 0xfe00, 0xfe19,
0xfe20, 0xfe23,
0xfe30, 0xfe52,
0xfe54, 0xfe66,
@@ -2199,12 +1850,13 @@ static const OnigCodePoint CRPrint[] = {
0x10080, 0x100fa,
0x10100, 0x10102,
0x10107, 0x10133,
- 0x10137, 0x1013f,
+ 0x10137, 0x1018a,
0x10300, 0x1031e,
0x10320, 0x10323,
0x10330, 0x1034a,
0x10380, 0x1039d,
- 0x1039f, 0x1039f,
+ 0x1039f, 0x103c3,
+ 0x103c8, 0x103d5,
0x10400, 0x1049d,
0x104a0, 0x104a9,
0x10800, 0x10805,
@@ -2213,9 +1865,18 @@ static const OnigCodePoint CRPrint[] = {
0x10837, 0x10838,
0x1083c, 0x1083c,
0x1083f, 0x1083f,
+ 0x10a00, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a33,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a47,
+ 0x10a50, 0x10a58,
0x1d000, 0x1d0f5,
0x1d100, 0x1d126,
0x1d12a, 0x1d1dd,
+ 0x1d200, 0x1d245,
0x1d300, 0x1d356,
0x1d400, 0x1d454,
0x1d456, 0x1d49c,
@@ -2235,7 +1896,7 @@ static const OnigCodePoint CRPrint[] = {
0x1d540, 0x1d544,
0x1d546, 0x1d546,
0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a3,
+ 0x1d552, 0x1d6a5,
0x1d6a8, 0x1d7c9,
0x1d7ce, 0x1d7ff,
0x20000, 0x2a6d6,
@@ -2245,15 +1906,11 @@ static const OnigCodePoint CRPrint[] = {
0xe0100, 0xe01ef,
0xf0000, 0xffffd,
0x100000, 0x10fffd
-#endif /* USE_UNICODE_FULL_RANGE_CTYPE */
-}; /* end of CRPrint */
+}; /* CR_Print */
-static const OnigCodePoint CRPunct[] = {
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- 86,
-#else
- 14,
-#endif
+/* 'Punct': [[:Punct:]] */
+static const OnigCodePoint CR_Punct[] = {
+ 96,
0x0021, 0x0023,
0x0025, 0x002a,
0x002c, 0x002f,
@@ -2267,9 +1924,7 @@ static const OnigCodePoint CRPunct[] = {
0x00ab, 0x00ab,
0x00b7, 0x00b7,
0x00bb, 0x00bb,
- 0x00bf, 0x00bf
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- ,
+ 0x00bf, 0x00bf,
0x037e, 0x037e,
0x0387, 0x0387,
0x055a, 0x055f,
@@ -2277,10 +1932,11 @@ static const OnigCodePoint CRPunct[] = {
0x05be, 0x05be,
0x05c0, 0x05c0,
0x05c3, 0x05c3,
+ 0x05c6, 0x05c6,
0x05f3, 0x05f4,
0x060c, 0x060d,
0x061b, 0x061b,
- 0x061f, 0x061f,
+ 0x061e, 0x061f,
0x066a, 0x066d,
0x06d4, 0x06d4,
0x0700, 0x070d,
@@ -2292,6 +1948,7 @@ static const OnigCodePoint CRPunct[] = {
0x0f04, 0x0f12,
0x0f3a, 0x0f3d,
0x0f85, 0x0f85,
+ 0x0fd0, 0x0fd1,
0x104a, 0x104f,
0x10fb, 0x10fb,
0x1361, 0x1368,
@@ -2303,20 +1960,26 @@ static const OnigCodePoint CRPunct[] = {
0x17d8, 0x17da,
0x1800, 0x180a,
0x1944, 0x1945,
+ 0x19de, 0x19df,
+ 0x1a1e, 0x1a1f,
0x2010, 0x2027,
0x2030, 0x2043,
0x2045, 0x2051,
- 0x2053, 0x2054,
- 0x2057, 0x2057,
+ 0x2053, 0x205e,
0x207d, 0x207e,
0x208d, 0x208e,
0x2329, 0x232a,
0x23b4, 0x23b6,
0x2768, 0x2775,
+ 0x27c5, 0x27c6,
0x27e6, 0x27eb,
0x2983, 0x2998,
0x29d8, 0x29db,
0x29fc, 0x29fd,
+ 0x2cf9, 0x2cfc,
+ 0x2cfe, 0x2cff,
+ 0x2e00, 0x2e17,
+ 0x2e1c, 0x2e1d,
0x3001, 0x3003,
0x3008, 0x3011,
0x3014, 0x301f,
@@ -2325,6 +1988,7 @@ static const OnigCodePoint CRPunct[] = {
0x30a0, 0x30a0,
0x30fb, 0x30fb,
0xfd3e, 0xfd3f,
+ 0xfe10, 0xfe19,
0xfe30, 0xfe52,
0xfe54, 0xfe61,
0xfe63, 0xfe63,
@@ -2341,22 +2005,17 @@ static const OnigCodePoint CRPunct[] = {
0xff5d, 0xff5d,
0xff5f, 0xff65,
0x10100, 0x10101,
- 0x1039f, 0x1039f
-#endif /* USE_UNICODE_FULL_RANGE_CTYPE */
-}; /* end of CRPunct */
+ 0x1039f, 0x1039f,
+ 0x10a50, 0x10a58
+}; /* CR_Punct */
-static const OnigCodePoint CRSpace[] = {
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
+/* 'Space': [[:Space:]] */
+static const OnigCodePoint CR_Space[] = {
11,
-#else
- 4,
-#endif
0x0009, 0x000d,
0x0020, 0x0020,
0x0085, 0x0085,
- 0x00a0, 0x00a0
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- ,
+ 0x00a0, 0x00a0,
0x1680, 0x1680,
0x180e, 0x180e,
0x2000, 0x200a,
@@ -2364,20 +2023,14 @@ static const OnigCodePoint CRSpace[] = {
0x202f, 0x202f,
0x205f, 0x205f,
0x3000, 0x3000
-#endif /* USE_UNICODE_FULL_RANGE_CTYPE */
-}; /* end of CRSpace */
+}; /* CR_Space */
-static const OnigCodePoint CRUpper[] = {
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- 421,
-#else
- 3,
-#endif
+/* 'Upper': [[:Upper:]] */
+static const OnigCodePoint CR_Upper[] = {
+ 476,
0x0041, 0x005a,
0x00c0, 0x00d6,
- 0x00d8, 0x00de
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- ,
+ 0x00d8, 0x00de,
0x0100, 0x0100,
0x0102, 0x0102,
0x0104, 0x0104,
@@ -2511,6 +2164,9 @@ static const OnigCodePoint CRUpper[] = {
0x022e, 0x022e,
0x0230, 0x0230,
0x0232, 0x0232,
+ 0x023a, 0x023b,
+ 0x023d, 0x023e,
+ 0x0241, 0x0241,
0x0386, 0x0386,
0x0388, 0x038a,
0x038c, 0x038c,
@@ -2533,7 +2189,7 @@ static const OnigCodePoint CRUpper[] = {
0x03f4, 0x03f4,
0x03f7, 0x03f7,
0x03f9, 0x03fa,
- 0x0400, 0x042f,
+ 0x03fd, 0x042f,
0x0460, 0x0460,
0x0462, 0x0462,
0x0464, 0x0464,
@@ -2604,6 +2260,7 @@ static const OnigCodePoint CRUpper[] = {
0x04f0, 0x04f0,
0x04f2, 0x04f2,
0x04f4, 0x04f4,
+ 0x04f6, 0x04f6,
0x04f8, 0x04f8,
0x0500, 0x0500,
0x0502, 0x0502,
@@ -2764,6 +2421,57 @@ static const OnigCodePoint CRUpper[] = {
0x2133, 0x2133,
0x213e, 0x213f,
0x2145, 0x2145,
+ 0x2c00, 0x2c2e,
+ 0x2c80, 0x2c80,
+ 0x2c82, 0x2c82,
+ 0x2c84, 0x2c84,
+ 0x2c86, 0x2c86,
+ 0x2c88, 0x2c88,
+ 0x2c8a, 0x2c8a,
+ 0x2c8c, 0x2c8c,
+ 0x2c8e, 0x2c8e,
+ 0x2c90, 0x2c90,
+ 0x2c92, 0x2c92,
+ 0x2c94, 0x2c94,
+ 0x2c96, 0x2c96,
+ 0x2c98, 0x2c98,
+ 0x2c9a, 0x2c9a,
+ 0x2c9c, 0x2c9c,
+ 0x2c9e, 0x2c9e,
+ 0x2ca0, 0x2ca0,
+ 0x2ca2, 0x2ca2,
+ 0x2ca4, 0x2ca4,
+ 0x2ca6, 0x2ca6,
+ 0x2ca8, 0x2ca8,
+ 0x2caa, 0x2caa,
+ 0x2cac, 0x2cac,
+ 0x2cae, 0x2cae,
+ 0x2cb0, 0x2cb0,
+ 0x2cb2, 0x2cb2,
+ 0x2cb4, 0x2cb4,
+ 0x2cb6, 0x2cb6,
+ 0x2cb8, 0x2cb8,
+ 0x2cba, 0x2cba,
+ 0x2cbc, 0x2cbc,
+ 0x2cbe, 0x2cbe,
+ 0x2cc0, 0x2cc0,
+ 0x2cc2, 0x2cc2,
+ 0x2cc4, 0x2cc4,
+ 0x2cc6, 0x2cc6,
+ 0x2cc8, 0x2cc8,
+ 0x2cca, 0x2cca,
+ 0x2ccc, 0x2ccc,
+ 0x2cce, 0x2cce,
+ 0x2cd0, 0x2cd0,
+ 0x2cd2, 0x2cd2,
+ 0x2cd4, 0x2cd4,
+ 0x2cd6, 0x2cd6,
+ 0x2cd8, 0x2cd8,
+ 0x2cda, 0x2cda,
+ 0x2cdc, 0x2cdc,
+ 0x2cde, 0x2cde,
+ 0x2ce0, 0x2ce0,
+ 0x2ce2, 0x2ce2,
0xff21, 0xff3a,
0x10400, 0x10427,
0x1d400, 0x1d419,
@@ -2796,35 +2504,19 @@ static const OnigCodePoint CRUpper[] = {
0x1d71c, 0x1d734,
0x1d756, 0x1d76e,
0x1d790, 0x1d7a8
-#endif /* USE_UNICODE_FULL_RANGE_CTYPE */
-}; /* end of CRUpper */
+}; /* CR_Upper */
-static const OnigCodePoint CRXDigit[] = {
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- 3,
-#else
+/* 'XDigit': [[:XDigit:]] */
+static const OnigCodePoint CR_XDigit[] = {
3,
-#endif
0x0030, 0x0039,
0x0041, 0x0046,
0x0061, 0x0066
-};
-
-static const OnigCodePoint CRASCII[] = {
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- 1,
-#else
- 1,
-#endif
- 0x0000, 0x007f
-};
+}; /* CR_XDigit */
-static const OnigCodePoint CRWord[] = {
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- 436,
-#else
- 12,
-#endif
+/* 'Word': [[:Word:]] */
+static const OnigCodePoint CR_Word[] = {
+ 464,
0x0030, 0x0039,
0x0041, 0x005a,
0x005f, 0x005f,
@@ -2836,16 +2528,12 @@ static const OnigCodePoint CRWord[] = {
0x00bc, 0x00be,
0x00c0, 0x00d6,
0x00d8, 0x00f6,
-#ifndef USE_UNICODE_FULL_RANGE_CTYPE
- 0x00f8, 0x7fffffff
-#else /* not USE_UNICODE_FULL_RANGE_CTYPE */
- 0x00f8, 0x0236,
+ 0x00f8, 0x0241,
0x0250, 0x02c1,
0x02c6, 0x02d1,
0x02e0, 0x02e4,
0x02ee, 0x02ee,
- 0x0300, 0x0357,
- 0x035d, 0x036f,
+ 0x0300, 0x036f,
0x037a, 0x037a,
0x0386, 0x0386,
0x0388, 0x038a,
@@ -2853,27 +2541,25 @@ static const OnigCodePoint CRWord[] = {
0x038e, 0x03a1,
0x03a3, 0x03ce,
0x03d0, 0x03f5,
- 0x03f7, 0x03fb,
- 0x0400, 0x0481,
+ 0x03f7, 0x0481,
0x0483, 0x0486,
0x0488, 0x04ce,
- 0x04d0, 0x04f5,
- 0x04f8, 0x04f9,
+ 0x04d0, 0x04f9,
0x0500, 0x050f,
0x0531, 0x0556,
0x0559, 0x0559,
0x0561, 0x0587,
- 0x0591, 0x05a1,
- 0x05a3, 0x05b9,
+ 0x0591, 0x05b9,
0x05bb, 0x05bd,
0x05bf, 0x05bf,
0x05c1, 0x05c2,
- 0x05c4, 0x05c4,
+ 0x05c4, 0x05c5,
+ 0x05c7, 0x05c7,
0x05d0, 0x05ea,
0x05f0, 0x05f2,
0x0610, 0x0615,
0x0621, 0x063a,
- 0x0640, 0x0658,
+ 0x0640, 0x065e,
0x0660, 0x0669,
0x066e, 0x06d3,
0x06d5, 0x06dc,
@@ -2881,13 +2567,14 @@ static const OnigCodePoint CRWord[] = {
0x06ea, 0x06fc,
0x06ff, 0x06ff,
0x0710, 0x074a,
- 0x074d, 0x074f,
+ 0x074d, 0x076d,
0x0780, 0x07b1,
0x0901, 0x0939,
0x093c, 0x094d,
0x0950, 0x0954,
0x0958, 0x0963,
0x0966, 0x096f,
+ 0x097d, 0x097d,
0x0981, 0x0983,
0x0985, 0x098c,
0x098f, 0x0990,
@@ -2897,7 +2584,7 @@ static const OnigCodePoint CRWord[] = {
0x09b6, 0x09b9,
0x09bc, 0x09c4,
0x09c7, 0x09c8,
- 0x09cb, 0x09cd,
+ 0x09cb, 0x09ce,
0x09d7, 0x09d7,
0x09dc, 0x09dd,
0x09df, 0x09e3,
@@ -2955,13 +2642,12 @@ static const OnigCodePoint CRWord[] = {
0x0b9e, 0x0b9f,
0x0ba3, 0x0ba4,
0x0ba8, 0x0baa,
- 0x0bae, 0x0bb5,
- 0x0bb7, 0x0bb9,
+ 0x0bae, 0x0bb9,
0x0bbe, 0x0bc2,
0x0bc6, 0x0bc8,
0x0bca, 0x0bcd,
0x0bd7, 0x0bd7,
- 0x0be7, 0x0bf2,
+ 0x0be6, 0x0bf2,
0x0c01, 0x0c03,
0x0c05, 0x0c0c,
0x0c0e, 0x0c10,
@@ -3051,36 +2737,30 @@ static const OnigCodePoint CRWord[] = {
0x1040, 0x1049,
0x1050, 0x1059,
0x10a0, 0x10c5,
- 0x10d0, 0x10f8,
+ 0x10d0, 0x10fa,
+ 0x10fc, 0x10fc,
0x1100, 0x1159,
0x115f, 0x11a2,
0x11a8, 0x11f9,
- 0x1200, 0x1206,
- 0x1208, 0x1246,
- 0x1248, 0x1248,
+ 0x1200, 0x1248,
0x124a, 0x124d,
0x1250, 0x1256,
0x1258, 0x1258,
0x125a, 0x125d,
- 0x1260, 0x1286,
- 0x1288, 0x1288,
+ 0x1260, 0x1288,
0x128a, 0x128d,
- 0x1290, 0x12ae,
- 0x12b0, 0x12b0,
+ 0x1290, 0x12b0,
0x12b2, 0x12b5,
0x12b8, 0x12be,
0x12c0, 0x12c0,
0x12c2, 0x12c5,
- 0x12c8, 0x12ce,
- 0x12d0, 0x12d6,
- 0x12d8, 0x12ee,
- 0x12f0, 0x130e,
- 0x1310, 0x1310,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
0x1312, 0x1315,
- 0x1318, 0x131e,
- 0x1320, 0x1346,
- 0x1348, 0x135a,
+ 0x1318, 0x135a,
+ 0x135f, 0x135f,
0x1369, 0x137c,
+ 0x1380, 0x138f,
0x13a0, 0x13f4,
0x1401, 0x166c,
0x166f, 0x1676,
@@ -3109,7 +2789,11 @@ static const OnigCodePoint CRWord[] = {
0x1930, 0x193b,
0x1946, 0x196d,
0x1970, 0x1974,
- 0x1d00, 0x1d6b,
+ 0x1980, 0x19a9,
+ 0x19b0, 0x19c9,
+ 0x19d0, 0x19d9,
+ 0x1a00, 0x1a1b,
+ 0x1d00, 0x1dc3,
0x1e00, 0x1e9b,
0x1ea0, 0x1ef9,
0x1f00, 0x1f15,
@@ -3136,7 +2820,8 @@ static const OnigCodePoint CRWord[] = {
0x2070, 0x2071,
0x2074, 0x2079,
0x207f, 0x2089,
- 0x20d0, 0x20ea,
+ 0x2090, 0x2094,
+ 0x20d0, 0x20eb,
0x2102, 0x2102,
0x2107, 0x2107,
0x210a, 0x2113,
@@ -3148,12 +2833,28 @@ static const OnigCodePoint CRWord[] = {
0x212a, 0x212d,
0x212f, 0x2131,
0x2133, 0x2139,
- 0x213d, 0x213f,
+ 0x213c, 0x213f,
0x2145, 0x2149,
0x2153, 0x2183,
0x2460, 0x249b,
0x24ea, 0x24ff,
0x2776, 0x2793,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c80, 0x2ce4,
+ 0x2cfd, 0x2cfd,
+ 0x2d00, 0x2d25,
+ 0x2d30, 0x2d65,
+ 0x2d6f, 0x2d6f,
+ 0x2d80, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
0x3005, 0x3007,
0x3021, 0x302f,
0x3031, 0x3035,
@@ -3161,7 +2862,8 @@ static const OnigCodePoint CRWord[] = {
0x3041, 0x3096,
0x3099, 0x309a,
0x309d, 0x309f,
- 0x30a1, 0x30ff,
+ 0x30a1, 0x30fa,
+ 0x30fc, 0x30ff,
0x3105, 0x312c,
0x3131, 0x318e,
0x3192, 0x3195,
@@ -3172,11 +2874,13 @@ static const OnigCodePoint CRWord[] = {
0x3280, 0x3289,
0x32b1, 0x32bf,
0x3400, 0x4db5,
- 0x4e00, 0x9fa5,
+ 0x4e00, 0x9fbb,
0xa000, 0xa48c,
+ 0xa800, 0xa827,
0xac00, 0xd7a3,
0xf900, 0xfa2d,
0xfa30, 0xfa6a,
+ 0xfa70, 0xfad9,
0xfb00, 0xfb06,
0xfb13, 0xfb17,
0xfb1d, 0xfb28,
@@ -3200,7 +2904,7 @@ static const OnigCodePoint CRWord[] = {
0xff21, 0xff3a,
0xff3f, 0xff3f,
0xff41, 0xff5a,
- 0xff65, 0xffbe,
+ 0xff66, 0xffbe,
0xffc2, 0xffc7,
0xffca, 0xffcf,
0xffd2, 0xffd7,
@@ -3213,10 +2917,15 @@ static const OnigCodePoint CRWord[] = {
0x10050, 0x1005d,
0x10080, 0x100fa,
0x10107, 0x10133,
+ 0x10140, 0x10178,
+ 0x1018a, 0x1018a,
0x10300, 0x1031e,
0x10320, 0x10323,
0x10330, 0x1034a,
0x10380, 0x1039d,
+ 0x103a0, 0x103c3,
+ 0x103c8, 0x103cf,
+ 0x103d1, 0x103d5,
0x10400, 0x1049d,
0x104a0, 0x104a9,
0x10800, 0x10805,
@@ -3225,11 +2934,19 @@ static const OnigCodePoint CRWord[] = {
0x10837, 0x10838,
0x1083c, 0x1083c,
0x1083f, 0x1083f,
+ 0x10a00, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a33,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a47,
0x1d165, 0x1d169,
0x1d16d, 0x1d172,
0x1d17b, 0x1d182,
0x1d185, 0x1d18b,
0x1d1aa, 0x1d1ad,
+ 0x1d242, 0x1d244,
0x1d400, 0x1d454,
0x1d456, 0x1d49c,
0x1d49e, 0x1d49f,
@@ -3248,7 +2965,7 @@ static const OnigCodePoint CRWord[] = {
0x1d540, 0x1d544,
0x1d546, 0x1d546,
0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a3,
+ 0x1d552, 0x1d6a5,
0x1d6a8, 0x1d6c0,
0x1d6c2, 0x1d6da,
0x1d6dc, 0x1d6fa,
@@ -3264,140 +2981,8376 @@ static const OnigCodePoint CRWord[] = {
0x20000, 0x2a6d6,
0x2f800, 0x2fa1d,
0xe0100, 0xe01ef
-#endif /* USE_UNICODE_FULL_RANGE_CTYPE */
-}; /* end of CRWord */
+}; /* CR_Word */
+
+/* 'Alnum': [[:Alnum:]] */
+static const OnigCodePoint CR_Alnum[] = {
+ 436,
+ 0x0030, 0x0039,
+ 0x0041, 0x005a,
+ 0x0061, 0x007a,
+ 0x00aa, 0x00aa,
+ 0x00b5, 0x00b5,
+ 0x00ba, 0x00ba,
+ 0x00c0, 0x00d6,
+ 0x00d8, 0x00f6,
+ 0x00f8, 0x0241,
+ 0x0250, 0x02c1,
+ 0x02c6, 0x02d1,
+ 0x02e0, 0x02e4,
+ 0x02ee, 0x02ee,
+ 0x0300, 0x036f,
+ 0x037a, 0x037a,
+ 0x0386, 0x0386,
+ 0x0388, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x03ce,
+ 0x03d0, 0x03f5,
+ 0x03f7, 0x0481,
+ 0x0483, 0x0486,
+ 0x0488, 0x04ce,
+ 0x04d0, 0x04f9,
+ 0x0500, 0x050f,
+ 0x0531, 0x0556,
+ 0x0559, 0x0559,
+ 0x0561, 0x0587,
+ 0x0591, 0x05b9,
+ 0x05bb, 0x05bd,
+ 0x05bf, 0x05bf,
+ 0x05c1, 0x05c2,
+ 0x05c4, 0x05c5,
+ 0x05c7, 0x05c7,
+ 0x05d0, 0x05ea,
+ 0x05f0, 0x05f2,
+ 0x0610, 0x0615,
+ 0x0621, 0x063a,
+ 0x0640, 0x065e,
+ 0x0660, 0x0669,
+ 0x066e, 0x06d3,
+ 0x06d5, 0x06dc,
+ 0x06de, 0x06e8,
+ 0x06ea, 0x06fc,
+ 0x06ff, 0x06ff,
+ 0x0710, 0x074a,
+ 0x074d, 0x076d,
+ 0x0780, 0x07b1,
+ 0x0901, 0x0939,
+ 0x093c, 0x094d,
+ 0x0950, 0x0954,
+ 0x0958, 0x0963,
+ 0x0966, 0x096f,
+ 0x097d, 0x097d,
+ 0x0981, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09ce,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09f1,
+ 0x0a01, 0x0a03,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a74,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abc, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae3,
+ 0x0ae6, 0x0aef,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3c, 0x0b43,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b61,
+ 0x0b66, 0x0b6f,
+ 0x0b71, 0x0b71,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd7, 0x0bd7,
+ 0x0be6, 0x0bef,
+ 0x0c01, 0x0c03,
+ 0x0c05, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c33,
+ 0x0c35, 0x0c39,
+ 0x0c3e, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c60, 0x0c61,
+ 0x0c66, 0x0c6f,
+ 0x0c82, 0x0c83,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbc, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce1,
+ 0x0ce6, 0x0cef,
+ 0x0d02, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d28,
+ 0x0d2a, 0x0d39,
+ 0x0d3e, 0x0d43,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4d,
+ 0x0d57, 0x0d57,
+ 0x0d60, 0x0d61,
+ 0x0d66, 0x0d6f,
+ 0x0d82, 0x0d83,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0df2, 0x0df3,
+ 0x0e01, 0x0e3a,
+ 0x0e40, 0x0e4e,
+ 0x0e50, 0x0e59,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e87, 0x0e88,
+ 0x0e8a, 0x0e8a,
+ 0x0e8d, 0x0e8d,
+ 0x0e94, 0x0e97,
+ 0x0e99, 0x0e9f,
+ 0x0ea1, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ea7,
+ 0x0eaa, 0x0eab,
+ 0x0ead, 0x0eb9,
+ 0x0ebb, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edd,
+ 0x0f00, 0x0f00,
+ 0x0f18, 0x0f19,
+ 0x0f20, 0x0f29,
+ 0x0f35, 0x0f35,
+ 0x0f37, 0x0f37,
+ 0x0f39, 0x0f39,
+ 0x0f3e, 0x0f47,
+ 0x0f49, 0x0f6a,
+ 0x0f71, 0x0f84,
+ 0x0f86, 0x0f8b,
+ 0x0f90, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fc6, 0x0fc6,
+ 0x1000, 0x1021,
+ 0x1023, 0x1027,
+ 0x1029, 0x102a,
+ 0x102c, 0x1032,
+ 0x1036, 0x1039,
+ 0x1040, 0x1049,
+ 0x1050, 0x1059,
+ 0x10a0, 0x10c5,
+ 0x10d0, 0x10fa,
+ 0x10fc, 0x10fc,
+ 0x1100, 0x1159,
+ 0x115f, 0x11a2,
+ 0x11a8, 0x11f9,
+ 0x1200, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x135f, 0x135f,
+ 0x1380, 0x138f,
+ 0x13a0, 0x13f4,
+ 0x1401, 0x166c,
+ 0x166f, 0x1676,
+ 0x1681, 0x169a,
+ 0x16a0, 0x16ea,
+ 0x1700, 0x170c,
+ 0x170e, 0x1714,
+ 0x1720, 0x1734,
+ 0x1740, 0x1753,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1772, 0x1773,
+ 0x1780, 0x17b3,
+ 0x17b6, 0x17d3,
+ 0x17d7, 0x17d7,
+ 0x17dc, 0x17dd,
+ 0x17e0, 0x17e9,
+ 0x180b, 0x180d,
+ 0x1810, 0x1819,
+ 0x1820, 0x1877,
+ 0x1880, 0x18a9,
+ 0x1900, 0x191c,
+ 0x1920, 0x192b,
+ 0x1930, 0x193b,
+ 0x1946, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19a9,
+ 0x19b0, 0x19c9,
+ 0x19d0, 0x19d9,
+ 0x1a00, 0x1a1b,
+ 0x1d00, 0x1dc3,
+ 0x1e00, 0x1e9b,
+ 0x1ea0, 0x1ef9,
+ 0x1f00, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fbc,
+ 0x1fbe, 0x1fbe,
+ 0x1fc2, 0x1fc4,
+ 0x1fc6, 0x1fcc,
+ 0x1fd0, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fe0, 0x1fec,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffc,
+ 0x2071, 0x2071,
+ 0x207f, 0x207f,
+ 0x2090, 0x2094,
+ 0x20d0, 0x20eb,
+ 0x2102, 0x2102,
+ 0x2107, 0x2107,
+ 0x210a, 0x2113,
+ 0x2115, 0x2115,
+ 0x2119, 0x211d,
+ 0x2124, 0x2124,
+ 0x2126, 0x2126,
+ 0x2128, 0x2128,
+ 0x212a, 0x212d,
+ 0x212f, 0x2131,
+ 0x2133, 0x2139,
+ 0x213c, 0x213f,
+ 0x2145, 0x2149,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c80, 0x2ce4,
+ 0x2d00, 0x2d25,
+ 0x2d30, 0x2d65,
+ 0x2d6f, 0x2d6f,
+ 0x2d80, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x3005, 0x3006,
+ 0x302a, 0x302f,
+ 0x3031, 0x3035,
+ 0x303b, 0x303c,
+ 0x3041, 0x3096,
+ 0x3099, 0x309a,
+ 0x309d, 0x309f,
+ 0x30a1, 0x30fa,
+ 0x30fc, 0x30ff,
+ 0x3105, 0x312c,
+ 0x3131, 0x318e,
+ 0x31a0, 0x31b7,
+ 0x31f0, 0x31ff,
+ 0x3400, 0x4db5,
+ 0x4e00, 0x9fbb,
+ 0xa000, 0xa48c,
+ 0xa800, 0xa827,
+ 0xac00, 0xd7a3,
+ 0xf900, 0xfa2d,
+ 0xfa30, 0xfa6a,
+ 0xfa70, 0xfad9,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb28,
+ 0xfb2a, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbb1,
+ 0xfbd3, 0xfd3d,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdf0, 0xfdfb,
+ 0xfe00, 0xfe0f,
+ 0xfe20, 0xfe23,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xff10, 0xff19,
+ 0xff21, 0xff3a,
+ 0xff41, 0xff5a,
+ 0xff66, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0x10000, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10300, 0x1031e,
+ 0x10330, 0x10349,
+ 0x10380, 0x1039d,
+ 0x103a0, 0x103c3,
+ 0x103c8, 0x103cf,
+ 0x10400, 0x1049d,
+ 0x104a0, 0x104a9,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x1083f,
+ 0x10a00, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a33,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a3f,
+ 0x1d165, 0x1d169,
+ 0x1d16d, 0x1d172,
+ 0x1d17b, 0x1d182,
+ 0x1d185, 0x1d18b,
+ 0x1d1aa, 0x1d1ad,
+ 0x1d242, 0x1d244,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d6c0,
+ 0x1d6c2, 0x1d6da,
+ 0x1d6dc, 0x1d6fa,
+ 0x1d6fc, 0x1d714,
+ 0x1d716, 0x1d734,
+ 0x1d736, 0x1d74e,
+ 0x1d750, 0x1d76e,
+ 0x1d770, 0x1d788,
+ 0x1d78a, 0x1d7a8,
+ 0x1d7aa, 0x1d7c2,
+ 0x1d7c4, 0x1d7c9,
+ 0x1d7ce, 0x1d7ff,
+ 0x20000, 0x2a6d6,
+ 0x2f800, 0x2fa1d,
+ 0xe0100, 0xe01ef
+}; /* CR_Alnum */
+
+/* 'ASCII': [[:ASCII:]] */
+static const OnigCodePoint CR_ASCII[] = {
+ 1,
+ 0x0000, 0x007f
+}; /* CR_ASCII */
+
+#ifdef USE_UNICODE_PROPERTIES
+
+/* 'Any': - */
+static const OnigCodePoint CR_Any[] = {
+ 1,
+ 0x0000, 0x10ffff
+}; /* CR_Any */
+
+/* 'Assigned': - */
+static const OnigCodePoint CR_Assigned[] = {
+ 420,
+ 0x0000, 0x0241,
+ 0x0250, 0x036f,
+ 0x0374, 0x0375,
+ 0x037a, 0x037a,
+ 0x037e, 0x037e,
+ 0x0384, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x03ce,
+ 0x03d0, 0x0486,
+ 0x0488, 0x04ce,
+ 0x04d0, 0x04f9,
+ 0x0500, 0x050f,
+ 0x0531, 0x0556,
+ 0x0559, 0x055f,
+ 0x0561, 0x0587,
+ 0x0589, 0x058a,
+ 0x0591, 0x05b9,
+ 0x05bb, 0x05c7,
+ 0x05d0, 0x05ea,
+ 0x05f0, 0x05f4,
+ 0x0600, 0x0603,
+ 0x060b, 0x0615,
+ 0x061b, 0x061b,
+ 0x061e, 0x061f,
+ 0x0621, 0x063a,
+ 0x0640, 0x065e,
+ 0x0660, 0x070d,
+ 0x070f, 0x074a,
+ 0x074d, 0x076d,
+ 0x0780, 0x07b1,
+ 0x0901, 0x0939,
+ 0x093c, 0x094d,
+ 0x0950, 0x0954,
+ 0x0958, 0x0970,
+ 0x097d, 0x097d,
+ 0x0981, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09ce,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09fa,
+ 0x0a01, 0x0a03,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a74,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abc, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae3,
+ 0x0ae6, 0x0aef,
+ 0x0af1, 0x0af1,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3c, 0x0b43,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b61,
+ 0x0b66, 0x0b71,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd7, 0x0bd7,
+ 0x0be6, 0x0bfa,
+ 0x0c01, 0x0c03,
+ 0x0c05, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c33,
+ 0x0c35, 0x0c39,
+ 0x0c3e, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c60, 0x0c61,
+ 0x0c66, 0x0c6f,
+ 0x0c82, 0x0c83,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbc, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce1,
+ 0x0ce6, 0x0cef,
+ 0x0d02, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d28,
+ 0x0d2a, 0x0d39,
+ 0x0d3e, 0x0d43,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4d,
+ 0x0d57, 0x0d57,
+ 0x0d60, 0x0d61,
+ 0x0d66, 0x0d6f,
+ 0x0d82, 0x0d83,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0df2, 0x0df4,
+ 0x0e01, 0x0e3a,
+ 0x0e3f, 0x0e5b,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e87, 0x0e88,
+ 0x0e8a, 0x0e8a,
+ 0x0e8d, 0x0e8d,
+ 0x0e94, 0x0e97,
+ 0x0e99, 0x0e9f,
+ 0x0ea1, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ea7,
+ 0x0eaa, 0x0eab,
+ 0x0ead, 0x0eb9,
+ 0x0ebb, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edd,
+ 0x0f00, 0x0f47,
+ 0x0f49, 0x0f6a,
+ 0x0f71, 0x0f8b,
+ 0x0f90, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fbe, 0x0fcc,
+ 0x0fcf, 0x0fd1,
+ 0x1000, 0x1021,
+ 0x1023, 0x1027,
+ 0x1029, 0x102a,
+ 0x102c, 0x1032,
+ 0x1036, 0x1039,
+ 0x1040, 0x1059,
+ 0x10a0, 0x10c5,
+ 0x10d0, 0x10fc,
+ 0x1100, 0x1159,
+ 0x115f, 0x11a2,
+ 0x11a8, 0x11f9,
+ 0x1200, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x135f, 0x137c,
+ 0x1380, 0x1399,
+ 0x13a0, 0x13f4,
+ 0x1401, 0x1676,
+ 0x1680, 0x169c,
+ 0x16a0, 0x16f0,
+ 0x1700, 0x170c,
+ 0x170e, 0x1714,
+ 0x1720, 0x1736,
+ 0x1740, 0x1753,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1772, 0x1773,
+ 0x1780, 0x17dd,
+ 0x17e0, 0x17e9,
+ 0x17f0, 0x17f9,
+ 0x1800, 0x180e,
+ 0x1810, 0x1819,
+ 0x1820, 0x1877,
+ 0x1880, 0x18a9,
+ 0x1900, 0x191c,
+ 0x1920, 0x192b,
+ 0x1930, 0x193b,
+ 0x1940, 0x1940,
+ 0x1944, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19a9,
+ 0x19b0, 0x19c9,
+ 0x19d0, 0x19d9,
+ 0x19de, 0x1a1b,
+ 0x1a1e, 0x1a1f,
+ 0x1d00, 0x1dc3,
+ 0x1e00, 0x1e9b,
+ 0x1ea0, 0x1ef9,
+ 0x1f00, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fc4,
+ 0x1fc6, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fdd, 0x1fef,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffe,
+ 0x2000, 0x2063,
+ 0x206a, 0x2071,
+ 0x2074, 0x208e,
+ 0x2090, 0x2094,
+ 0x20a0, 0x20b5,
+ 0x20d0, 0x20eb,
+ 0x2100, 0x214c,
+ 0x2153, 0x2183,
+ 0x2190, 0x23db,
+ 0x2400, 0x2426,
+ 0x2440, 0x244a,
+ 0x2460, 0x269c,
+ 0x26a0, 0x26b1,
+ 0x2701, 0x2704,
+ 0x2706, 0x2709,
+ 0x270c, 0x2727,
+ 0x2729, 0x274b,
+ 0x274d, 0x274d,
+ 0x274f, 0x2752,
+ 0x2756, 0x2756,
+ 0x2758, 0x275e,
+ 0x2761, 0x2794,
+ 0x2798, 0x27af,
+ 0x27b1, 0x27be,
+ 0x27c0, 0x27c6,
+ 0x27d0, 0x27eb,
+ 0x27f0, 0x2b13,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c80, 0x2cea,
+ 0x2cf9, 0x2d25,
+ 0x2d30, 0x2d65,
+ 0x2d6f, 0x2d6f,
+ 0x2d80, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x2e00, 0x2e17,
+ 0x2e1c, 0x2e1d,
+ 0x2e80, 0x2e99,
+ 0x2e9b, 0x2ef3,
+ 0x2f00, 0x2fd5,
+ 0x2ff0, 0x2ffb,
+ 0x3000, 0x303f,
+ 0x3041, 0x3096,
+ 0x3099, 0x30ff,
+ 0x3105, 0x312c,
+ 0x3131, 0x318e,
+ 0x3190, 0x31b7,
+ 0x31c0, 0x31cf,
+ 0x31f0, 0x321e,
+ 0x3220, 0x3243,
+ 0x3250, 0x32fe,
+ 0x3300, 0x4db5,
+ 0x4dc0, 0x9fbb,
+ 0xa000, 0xa48c,
+ 0xa490, 0xa4c6,
+ 0xa700, 0xa716,
+ 0xa800, 0xa82b,
+ 0xac00, 0xd7a3,
+ 0xd800, 0xfa2d,
+ 0xfa30, 0xfa6a,
+ 0xfa70, 0xfad9,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbb1,
+ 0xfbd3, 0xfd3f,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdf0, 0xfdfd,
+ 0xfe00, 0xfe19,
+ 0xfe20, 0xfe23,
+ 0xfe30, 0xfe52,
+ 0xfe54, 0xfe66,
+ 0xfe68, 0xfe6b,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xfeff, 0xfeff,
+ 0xff01, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0xffe0, 0xffe6,
+ 0xffe8, 0xffee,
+ 0xfff9, 0xfffd,
+ 0x10000, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10100, 0x10102,
+ 0x10107, 0x10133,
+ 0x10137, 0x1018a,
+ 0x10300, 0x1031e,
+ 0x10320, 0x10323,
+ 0x10330, 0x1034a,
+ 0x10380, 0x1039d,
+ 0x1039f, 0x103c3,
+ 0x103c8, 0x103d5,
+ 0x10400, 0x1049d,
+ 0x104a0, 0x104a9,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x1083f,
+ 0x10a00, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a33,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a47,
+ 0x10a50, 0x10a58,
+ 0x1d000, 0x1d0f5,
+ 0x1d100, 0x1d126,
+ 0x1d12a, 0x1d1dd,
+ 0x1d200, 0x1d245,
+ 0x1d300, 0x1d356,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d7c9,
+ 0x1d7ce, 0x1d7ff,
+ 0x20000, 0x2a6d6,
+ 0x2f800, 0x2fa1d,
+ 0xe0001, 0xe0001,
+ 0xe0020, 0xe007f,
+ 0xe0100, 0xe01ef,
+ 0xf0000, 0xffffd,
+ 0x100000, 0x10fffd
+}; /* CR_Assigned */
+
+/* 'C': Major Category */
+static const OnigCodePoint CR_C[] = {
+ 422,
+ 0x0000, 0x001f,
+ 0x007f, 0x009f,
+ 0x00ad, 0x00ad,
+ 0x0242, 0x024f,
+ 0x0370, 0x0373,
+ 0x0376, 0x0379,
+ 0x037b, 0x037d,
+ 0x037f, 0x0383,
+ 0x038b, 0x038b,
+ 0x038d, 0x038d,
+ 0x03a2, 0x03a2,
+ 0x03cf, 0x03cf,
+ 0x0487, 0x0487,
+ 0x04cf, 0x04cf,
+ 0x04fa, 0x04ff,
+ 0x0510, 0x0530,
+ 0x0557, 0x0558,
+ 0x0560, 0x0560,
+ 0x0588, 0x0588,
+ 0x058b, 0x0590,
+ 0x05ba, 0x05ba,
+ 0x05c8, 0x05cf,
+ 0x05eb, 0x05ef,
+ 0x05f5, 0x060a,
+ 0x0616, 0x061a,
+ 0x061c, 0x061d,
+ 0x0620, 0x0620,
+ 0x063b, 0x063f,
+ 0x065f, 0x065f,
+ 0x06dd, 0x06dd,
+ 0x070e, 0x070f,
+ 0x074b, 0x074c,
+ 0x076e, 0x077f,
+ 0x07b2, 0x0900,
+ 0x093a, 0x093b,
+ 0x094e, 0x094f,
+ 0x0955, 0x0957,
+ 0x0971, 0x097c,
+ 0x097e, 0x0980,
+ 0x0984, 0x0984,
+ 0x098d, 0x098e,
+ 0x0991, 0x0992,
+ 0x09a9, 0x09a9,
+ 0x09b1, 0x09b1,
+ 0x09b3, 0x09b5,
+ 0x09ba, 0x09bb,
+ 0x09c5, 0x09c6,
+ 0x09c9, 0x09ca,
+ 0x09cf, 0x09d6,
+ 0x09d8, 0x09db,
+ 0x09de, 0x09de,
+ 0x09e4, 0x09e5,
+ 0x09fb, 0x0a00,
+ 0x0a04, 0x0a04,
+ 0x0a0b, 0x0a0e,
+ 0x0a11, 0x0a12,
+ 0x0a29, 0x0a29,
+ 0x0a31, 0x0a31,
+ 0x0a34, 0x0a34,
+ 0x0a37, 0x0a37,
+ 0x0a3a, 0x0a3b,
+ 0x0a3d, 0x0a3d,
+ 0x0a43, 0x0a46,
+ 0x0a49, 0x0a4a,
+ 0x0a4e, 0x0a58,
+ 0x0a5d, 0x0a5d,
+ 0x0a5f, 0x0a65,
+ 0x0a75, 0x0a80,
+ 0x0a84, 0x0a84,
+ 0x0a8e, 0x0a8e,
+ 0x0a92, 0x0a92,
+ 0x0aa9, 0x0aa9,
+ 0x0ab1, 0x0ab1,
+ 0x0ab4, 0x0ab4,
+ 0x0aba, 0x0abb,
+ 0x0ac6, 0x0ac6,
+ 0x0aca, 0x0aca,
+ 0x0ace, 0x0acf,
+ 0x0ad1, 0x0adf,
+ 0x0ae4, 0x0ae5,
+ 0x0af0, 0x0af0,
+ 0x0af2, 0x0b00,
+ 0x0b04, 0x0b04,
+ 0x0b0d, 0x0b0e,
+ 0x0b11, 0x0b12,
+ 0x0b29, 0x0b29,
+ 0x0b31, 0x0b31,
+ 0x0b34, 0x0b34,
+ 0x0b3a, 0x0b3b,
+ 0x0b44, 0x0b46,
+ 0x0b49, 0x0b4a,
+ 0x0b4e, 0x0b55,
+ 0x0b58, 0x0b5b,
+ 0x0b5e, 0x0b5e,
+ 0x0b62, 0x0b65,
+ 0x0b72, 0x0b81,
+ 0x0b84, 0x0b84,
+ 0x0b8b, 0x0b8d,
+ 0x0b91, 0x0b91,
+ 0x0b96, 0x0b98,
+ 0x0b9b, 0x0b9b,
+ 0x0b9d, 0x0b9d,
+ 0x0ba0, 0x0ba2,
+ 0x0ba5, 0x0ba7,
+ 0x0bab, 0x0bad,
+ 0x0bba, 0x0bbd,
+ 0x0bc3, 0x0bc5,
+ 0x0bc9, 0x0bc9,
+ 0x0bce, 0x0bd6,
+ 0x0bd8, 0x0be5,
+ 0x0bfb, 0x0c00,
+ 0x0c04, 0x0c04,
+ 0x0c0d, 0x0c0d,
+ 0x0c11, 0x0c11,
+ 0x0c29, 0x0c29,
+ 0x0c34, 0x0c34,
+ 0x0c3a, 0x0c3d,
+ 0x0c45, 0x0c45,
+ 0x0c49, 0x0c49,
+ 0x0c4e, 0x0c54,
+ 0x0c57, 0x0c5f,
+ 0x0c62, 0x0c65,
+ 0x0c70, 0x0c81,
+ 0x0c84, 0x0c84,
+ 0x0c8d, 0x0c8d,
+ 0x0c91, 0x0c91,
+ 0x0ca9, 0x0ca9,
+ 0x0cb4, 0x0cb4,
+ 0x0cba, 0x0cbb,
+ 0x0cc5, 0x0cc5,
+ 0x0cc9, 0x0cc9,
+ 0x0cce, 0x0cd4,
+ 0x0cd7, 0x0cdd,
+ 0x0cdf, 0x0cdf,
+ 0x0ce2, 0x0ce5,
+ 0x0cf0, 0x0d01,
+ 0x0d04, 0x0d04,
+ 0x0d0d, 0x0d0d,
+ 0x0d11, 0x0d11,
+ 0x0d29, 0x0d29,
+ 0x0d3a, 0x0d3d,
+ 0x0d44, 0x0d45,
+ 0x0d49, 0x0d49,
+ 0x0d4e, 0x0d56,
+ 0x0d58, 0x0d5f,
+ 0x0d62, 0x0d65,
+ 0x0d70, 0x0d81,
+ 0x0d84, 0x0d84,
+ 0x0d97, 0x0d99,
+ 0x0db2, 0x0db2,
+ 0x0dbc, 0x0dbc,
+ 0x0dbe, 0x0dbf,
+ 0x0dc7, 0x0dc9,
+ 0x0dcb, 0x0dce,
+ 0x0dd5, 0x0dd5,
+ 0x0dd7, 0x0dd7,
+ 0x0de0, 0x0df1,
+ 0x0df5, 0x0e00,
+ 0x0e3b, 0x0e3e,
+ 0x0e5c, 0x0e80,
+ 0x0e83, 0x0e83,
+ 0x0e85, 0x0e86,
+ 0x0e89, 0x0e89,
+ 0x0e8b, 0x0e8c,
+ 0x0e8e, 0x0e93,
+ 0x0e98, 0x0e98,
+ 0x0ea0, 0x0ea0,
+ 0x0ea4, 0x0ea4,
+ 0x0ea6, 0x0ea6,
+ 0x0ea8, 0x0ea9,
+ 0x0eac, 0x0eac,
+ 0x0eba, 0x0eba,
+ 0x0ebe, 0x0ebf,
+ 0x0ec5, 0x0ec5,
+ 0x0ec7, 0x0ec7,
+ 0x0ece, 0x0ecf,
+ 0x0eda, 0x0edb,
+ 0x0ede, 0x0eff,
+ 0x0f48, 0x0f48,
+ 0x0f6b, 0x0f70,
+ 0x0f8c, 0x0f8f,
+ 0x0f98, 0x0f98,
+ 0x0fbd, 0x0fbd,
+ 0x0fcd, 0x0fce,
+ 0x0fd2, 0x0fff,
+ 0x1022, 0x1022,
+ 0x1028, 0x1028,
+ 0x102b, 0x102b,
+ 0x1033, 0x1035,
+ 0x103a, 0x103f,
+ 0x105a, 0x109f,
+ 0x10c6, 0x10cf,
+ 0x10fd, 0x10ff,
+ 0x115a, 0x115e,
+ 0x11a3, 0x11a7,
+ 0x11fa, 0x11ff,
+ 0x1249, 0x1249,
+ 0x124e, 0x124f,
+ 0x1257, 0x1257,
+ 0x1259, 0x1259,
+ 0x125e, 0x125f,
+ 0x1289, 0x1289,
+ 0x128e, 0x128f,
+ 0x12b1, 0x12b1,
+ 0x12b6, 0x12b7,
+ 0x12bf, 0x12bf,
+ 0x12c1, 0x12c1,
+ 0x12c6, 0x12c7,
+ 0x12d7, 0x12d7,
+ 0x1311, 0x1311,
+ 0x1316, 0x1317,
+ 0x135b, 0x135e,
+ 0x137d, 0x137f,
+ 0x139a, 0x139f,
+ 0x13f5, 0x1400,
+ 0x1677, 0x167f,
+ 0x169d, 0x169f,
+ 0x16f1, 0x16ff,
+ 0x170d, 0x170d,
+ 0x1715, 0x171f,
+ 0x1737, 0x173f,
+ 0x1754, 0x175f,
+ 0x176d, 0x176d,
+ 0x1771, 0x1771,
+ 0x1774, 0x177f,
+ 0x17b4, 0x17b5,
+ 0x17de, 0x17df,
+ 0x17ea, 0x17ef,
+ 0x17fa, 0x17ff,
+ 0x180f, 0x180f,
+ 0x181a, 0x181f,
+ 0x1878, 0x187f,
+ 0x18aa, 0x18ff,
+ 0x191d, 0x191f,
+ 0x192c, 0x192f,
+ 0x193c, 0x193f,
+ 0x1941, 0x1943,
+ 0x196e, 0x196f,
+ 0x1975, 0x197f,
+ 0x19aa, 0x19af,
+ 0x19ca, 0x19cf,
+ 0x19da, 0x19dd,
+ 0x1a1c, 0x1a1d,
+ 0x1a20, 0x1cff,
+ 0x1dc4, 0x1dff,
+ 0x1e9c, 0x1e9f,
+ 0x1efa, 0x1eff,
+ 0x1f16, 0x1f17,
+ 0x1f1e, 0x1f1f,
+ 0x1f46, 0x1f47,
+ 0x1f4e, 0x1f4f,
+ 0x1f58, 0x1f58,
+ 0x1f5a, 0x1f5a,
+ 0x1f5c, 0x1f5c,
+ 0x1f5e, 0x1f5e,
+ 0x1f7e, 0x1f7f,
+ 0x1fb5, 0x1fb5,
+ 0x1fc5, 0x1fc5,
+ 0x1fd4, 0x1fd5,
+ 0x1fdc, 0x1fdc,
+ 0x1ff0, 0x1ff1,
+ 0x1ff5, 0x1ff5,
+ 0x1fff, 0x1fff,
+ 0x200b, 0x200f,
+ 0x202a, 0x202e,
+ 0x2060, 0x206f,
+ 0x2072, 0x2073,
+ 0x208f, 0x208f,
+ 0x2095, 0x209f,
+ 0x20b6, 0x20cf,
+ 0x20ec, 0x20ff,
+ 0x214d, 0x2152,
+ 0x2184, 0x218f,
+ 0x23dc, 0x23ff,
+ 0x2427, 0x243f,
+ 0x244b, 0x245f,
+ 0x269d, 0x269f,
+ 0x26b2, 0x2700,
+ 0x2705, 0x2705,
+ 0x270a, 0x270b,
+ 0x2728, 0x2728,
+ 0x274c, 0x274c,
+ 0x274e, 0x274e,
+ 0x2753, 0x2755,
+ 0x2757, 0x2757,
+ 0x275f, 0x2760,
+ 0x2795, 0x2797,
+ 0x27b0, 0x27b0,
+ 0x27bf, 0x27bf,
+ 0x27c7, 0x27cf,
+ 0x27ec, 0x27ef,
+ 0x2b14, 0x2bff,
+ 0x2c2f, 0x2c2f,
+ 0x2c5f, 0x2c7f,
+ 0x2ceb, 0x2cf8,
+ 0x2d26, 0x2d2f,
+ 0x2d66, 0x2d6e,
+ 0x2d70, 0x2d7f,
+ 0x2d97, 0x2d9f,
+ 0x2da7, 0x2da7,
+ 0x2daf, 0x2daf,
+ 0x2db7, 0x2db7,
+ 0x2dbf, 0x2dbf,
+ 0x2dc7, 0x2dc7,
+ 0x2dcf, 0x2dcf,
+ 0x2dd7, 0x2dd7,
+ 0x2ddf, 0x2dff,
+ 0x2e18, 0x2e1b,
+ 0x2e1e, 0x2e7f,
+ 0x2e9a, 0x2e9a,
+ 0x2ef4, 0x2eff,
+ 0x2fd6, 0x2fef,
+ 0x2ffc, 0x2fff,
+ 0x3040, 0x3040,
+ 0x3097, 0x3098,
+ 0x3100, 0x3104,
+ 0x312d, 0x3130,
+ 0x318f, 0x318f,
+ 0x31b8, 0x31bf,
+ 0x31d0, 0x31ef,
+ 0x321f, 0x321f,
+ 0x3244, 0x324f,
+ 0x32ff, 0x32ff,
+ 0x4db6, 0x4dbf,
+ 0x9fbc, 0x9fff,
+ 0xa48d, 0xa48f,
+ 0xa4c7, 0xa6ff,
+ 0xa717, 0xa7ff,
+ 0xa82c, 0xabff,
+ 0xd7a4, 0xf8ff,
+ 0xfa2e, 0xfa2f,
+ 0xfa6b, 0xfa6f,
+ 0xfada, 0xfaff,
+ 0xfb07, 0xfb12,
+ 0xfb18, 0xfb1c,
+ 0xfb37, 0xfb37,
+ 0xfb3d, 0xfb3d,
+ 0xfb3f, 0xfb3f,
+ 0xfb42, 0xfb42,
+ 0xfb45, 0xfb45,
+ 0xfbb2, 0xfbd2,
+ 0xfd40, 0xfd4f,
+ 0xfd90, 0xfd91,
+ 0xfdc8, 0xfdef,
+ 0xfdfe, 0xfdff,
+ 0xfe1a, 0xfe1f,
+ 0xfe24, 0xfe2f,
+ 0xfe53, 0xfe53,
+ 0xfe67, 0xfe67,
+ 0xfe6c, 0xfe6f,
+ 0xfe75, 0xfe75,
+ 0xfefd, 0xff00,
+ 0xffbf, 0xffc1,
+ 0xffc8, 0xffc9,
+ 0xffd0, 0xffd1,
+ 0xffd8, 0xffd9,
+ 0xffdd, 0xffdf,
+ 0xffe7, 0xffe7,
+ 0xffef, 0xfffb,
+ 0xfffe, 0xffff,
+ 0x1000c, 0x1000c,
+ 0x10027, 0x10027,
+ 0x1003b, 0x1003b,
+ 0x1003e, 0x1003e,
+ 0x1004e, 0x1004f,
+ 0x1005e, 0x1007f,
+ 0x100fb, 0x100ff,
+ 0x10103, 0x10106,
+ 0x10134, 0x10136,
+ 0x1018b, 0x102ff,
+ 0x1031f, 0x1031f,
+ 0x10324, 0x1032f,
+ 0x1034b, 0x1037f,
+ 0x1039e, 0x1039e,
+ 0x103c4, 0x103c7,
+ 0x103d6, 0x103ff,
+ 0x1049e, 0x1049f,
+ 0x104aa, 0x107ff,
+ 0x10806, 0x10807,
+ 0x10809, 0x10809,
+ 0x10836, 0x10836,
+ 0x10839, 0x1083b,
+ 0x1083d, 0x1083e,
+ 0x10840, 0x109ff,
+ 0x10a04, 0x10a04,
+ 0x10a07, 0x10a0b,
+ 0x10a14, 0x10a14,
+ 0x10a18, 0x10a18,
+ 0x10a34, 0x10a37,
+ 0x10a3b, 0x10a3e,
+ 0x10a48, 0x10a4f,
+ 0x10a59, 0x1cfff,
+ 0x1d0f6, 0x1d0ff,
+ 0x1d127, 0x1d129,
+ 0x1d173, 0x1d17a,
+ 0x1d1de, 0x1d1ff,
+ 0x1d246, 0x1d2ff,
+ 0x1d357, 0x1d3ff,
+ 0x1d455, 0x1d455,
+ 0x1d49d, 0x1d49d,
+ 0x1d4a0, 0x1d4a1,
+ 0x1d4a3, 0x1d4a4,
+ 0x1d4a7, 0x1d4a8,
+ 0x1d4ad, 0x1d4ad,
+ 0x1d4ba, 0x1d4ba,
+ 0x1d4bc, 0x1d4bc,
+ 0x1d4c4, 0x1d4c4,
+ 0x1d506, 0x1d506,
+ 0x1d50b, 0x1d50c,
+ 0x1d515, 0x1d515,
+ 0x1d51d, 0x1d51d,
+ 0x1d53a, 0x1d53a,
+ 0x1d53f, 0x1d53f,
+ 0x1d545, 0x1d545,
+ 0x1d547, 0x1d549,
+ 0x1d551, 0x1d551,
+ 0x1d6a6, 0x1d6a7,
+ 0x1d7ca, 0x1d7cd,
+ 0x1d800, 0x1ffff,
+ 0x2a6d7, 0x2f7ff,
+ 0x2fa1e, 0xe00ff,
+ 0xe01f0, 0x10ffff
+}; /* CR_C */
+
+/* 'Cc': General Category */
+static const OnigCodePoint CR_Cc[] = {
+ 2,
+ 0x0000, 0x001f,
+ 0x007f, 0x009f
+}; /* CR_Cc */
+
+/* 'Cf': General Category */
+static const OnigCodePoint CR_Cf[] = {
+ 14,
+ 0x00ad, 0x00ad,
+ 0x0600, 0x0603,
+ 0x06dd, 0x06dd,
+ 0x070f, 0x070f,
+ 0x17b4, 0x17b5,
+ 0x200b, 0x200f,
+ 0x202a, 0x202e,
+ 0x2060, 0x2063,
+ 0x206a, 0x206f,
+ 0xfeff, 0xfeff,
+ 0xfff9, 0xfffb,
+ 0x1d173, 0x1d17a,
+ 0xe0001, 0xe0001,
+ 0xe0020, 0xe007f
+}; /* CR_Cf */
+
+/* 'Cn': General Category */
+static const OnigCodePoint CR_Cn[] = {
+ 420,
+ 0x0242, 0x024f,
+ 0x0370, 0x0373,
+ 0x0376, 0x0379,
+ 0x037b, 0x037d,
+ 0x037f, 0x0383,
+ 0x038b, 0x038b,
+ 0x038d, 0x038d,
+ 0x03a2, 0x03a2,
+ 0x03cf, 0x03cf,
+ 0x0487, 0x0487,
+ 0x04cf, 0x04cf,
+ 0x04fa, 0x04ff,
+ 0x0510, 0x0530,
+ 0x0557, 0x0558,
+ 0x0560, 0x0560,
+ 0x0588, 0x0588,
+ 0x058b, 0x0590,
+ 0x05ba, 0x05ba,
+ 0x05c8, 0x05cf,
+ 0x05eb, 0x05ef,
+ 0x05f5, 0x05ff,
+ 0x0604, 0x060a,
+ 0x0616, 0x061a,
+ 0x061c, 0x061d,
+ 0x0620, 0x0620,
+ 0x063b, 0x063f,
+ 0x065f, 0x065f,
+ 0x070e, 0x070e,
+ 0x074b, 0x074c,
+ 0x076e, 0x077f,
+ 0x07b2, 0x0900,
+ 0x093a, 0x093b,
+ 0x094e, 0x094f,
+ 0x0955, 0x0957,
+ 0x0971, 0x097c,
+ 0x097e, 0x0980,
+ 0x0984, 0x0984,
+ 0x098d, 0x098e,
+ 0x0991, 0x0992,
+ 0x09a9, 0x09a9,
+ 0x09b1, 0x09b1,
+ 0x09b3, 0x09b5,
+ 0x09ba, 0x09bb,
+ 0x09c5, 0x09c6,
+ 0x09c9, 0x09ca,
+ 0x09cf, 0x09d6,
+ 0x09d8, 0x09db,
+ 0x09de, 0x09de,
+ 0x09e4, 0x09e5,
+ 0x09fb, 0x0a00,
+ 0x0a04, 0x0a04,
+ 0x0a0b, 0x0a0e,
+ 0x0a11, 0x0a12,
+ 0x0a29, 0x0a29,
+ 0x0a31, 0x0a31,
+ 0x0a34, 0x0a34,
+ 0x0a37, 0x0a37,
+ 0x0a3a, 0x0a3b,
+ 0x0a3d, 0x0a3d,
+ 0x0a43, 0x0a46,
+ 0x0a49, 0x0a4a,
+ 0x0a4e, 0x0a58,
+ 0x0a5d, 0x0a5d,
+ 0x0a5f, 0x0a65,
+ 0x0a75, 0x0a80,
+ 0x0a84, 0x0a84,
+ 0x0a8e, 0x0a8e,
+ 0x0a92, 0x0a92,
+ 0x0aa9, 0x0aa9,
+ 0x0ab1, 0x0ab1,
+ 0x0ab4, 0x0ab4,
+ 0x0aba, 0x0abb,
+ 0x0ac6, 0x0ac6,
+ 0x0aca, 0x0aca,
+ 0x0ace, 0x0acf,
+ 0x0ad1, 0x0adf,
+ 0x0ae4, 0x0ae5,
+ 0x0af0, 0x0af0,
+ 0x0af2, 0x0b00,
+ 0x0b04, 0x0b04,
+ 0x0b0d, 0x0b0e,
+ 0x0b11, 0x0b12,
+ 0x0b29, 0x0b29,
+ 0x0b31, 0x0b31,
+ 0x0b34, 0x0b34,
+ 0x0b3a, 0x0b3b,
+ 0x0b44, 0x0b46,
+ 0x0b49, 0x0b4a,
+ 0x0b4e, 0x0b55,
+ 0x0b58, 0x0b5b,
+ 0x0b5e, 0x0b5e,
+ 0x0b62, 0x0b65,
+ 0x0b72, 0x0b81,
+ 0x0b84, 0x0b84,
+ 0x0b8b, 0x0b8d,
+ 0x0b91, 0x0b91,
+ 0x0b96, 0x0b98,
+ 0x0b9b, 0x0b9b,
+ 0x0b9d, 0x0b9d,
+ 0x0ba0, 0x0ba2,
+ 0x0ba5, 0x0ba7,
+ 0x0bab, 0x0bad,
+ 0x0bba, 0x0bbd,
+ 0x0bc3, 0x0bc5,
+ 0x0bc9, 0x0bc9,
+ 0x0bce, 0x0bd6,
+ 0x0bd8, 0x0be5,
+ 0x0bfb, 0x0c00,
+ 0x0c04, 0x0c04,
+ 0x0c0d, 0x0c0d,
+ 0x0c11, 0x0c11,
+ 0x0c29, 0x0c29,
+ 0x0c34, 0x0c34,
+ 0x0c3a, 0x0c3d,
+ 0x0c45, 0x0c45,
+ 0x0c49, 0x0c49,
+ 0x0c4e, 0x0c54,
+ 0x0c57, 0x0c5f,
+ 0x0c62, 0x0c65,
+ 0x0c70, 0x0c81,
+ 0x0c84, 0x0c84,
+ 0x0c8d, 0x0c8d,
+ 0x0c91, 0x0c91,
+ 0x0ca9, 0x0ca9,
+ 0x0cb4, 0x0cb4,
+ 0x0cba, 0x0cbb,
+ 0x0cc5, 0x0cc5,
+ 0x0cc9, 0x0cc9,
+ 0x0cce, 0x0cd4,
+ 0x0cd7, 0x0cdd,
+ 0x0cdf, 0x0cdf,
+ 0x0ce2, 0x0ce5,
+ 0x0cf0, 0x0d01,
+ 0x0d04, 0x0d04,
+ 0x0d0d, 0x0d0d,
+ 0x0d11, 0x0d11,
+ 0x0d29, 0x0d29,
+ 0x0d3a, 0x0d3d,
+ 0x0d44, 0x0d45,
+ 0x0d49, 0x0d49,
+ 0x0d4e, 0x0d56,
+ 0x0d58, 0x0d5f,
+ 0x0d62, 0x0d65,
+ 0x0d70, 0x0d81,
+ 0x0d84, 0x0d84,
+ 0x0d97, 0x0d99,
+ 0x0db2, 0x0db2,
+ 0x0dbc, 0x0dbc,
+ 0x0dbe, 0x0dbf,
+ 0x0dc7, 0x0dc9,
+ 0x0dcb, 0x0dce,
+ 0x0dd5, 0x0dd5,
+ 0x0dd7, 0x0dd7,
+ 0x0de0, 0x0df1,
+ 0x0df5, 0x0e00,
+ 0x0e3b, 0x0e3e,
+ 0x0e5c, 0x0e80,
+ 0x0e83, 0x0e83,
+ 0x0e85, 0x0e86,
+ 0x0e89, 0x0e89,
+ 0x0e8b, 0x0e8c,
+ 0x0e8e, 0x0e93,
+ 0x0e98, 0x0e98,
+ 0x0ea0, 0x0ea0,
+ 0x0ea4, 0x0ea4,
+ 0x0ea6, 0x0ea6,
+ 0x0ea8, 0x0ea9,
+ 0x0eac, 0x0eac,
+ 0x0eba, 0x0eba,
+ 0x0ebe, 0x0ebf,
+ 0x0ec5, 0x0ec5,
+ 0x0ec7, 0x0ec7,
+ 0x0ece, 0x0ecf,
+ 0x0eda, 0x0edb,
+ 0x0ede, 0x0eff,
+ 0x0f48, 0x0f48,
+ 0x0f6b, 0x0f70,
+ 0x0f8c, 0x0f8f,
+ 0x0f98, 0x0f98,
+ 0x0fbd, 0x0fbd,
+ 0x0fcd, 0x0fce,
+ 0x0fd2, 0x0fff,
+ 0x1022, 0x1022,
+ 0x1028, 0x1028,
+ 0x102b, 0x102b,
+ 0x1033, 0x1035,
+ 0x103a, 0x103f,
+ 0x105a, 0x109f,
+ 0x10c6, 0x10cf,
+ 0x10fd, 0x10ff,
+ 0x115a, 0x115e,
+ 0x11a3, 0x11a7,
+ 0x11fa, 0x11ff,
+ 0x1249, 0x1249,
+ 0x124e, 0x124f,
+ 0x1257, 0x1257,
+ 0x1259, 0x1259,
+ 0x125e, 0x125f,
+ 0x1289, 0x1289,
+ 0x128e, 0x128f,
+ 0x12b1, 0x12b1,
+ 0x12b6, 0x12b7,
+ 0x12bf, 0x12bf,
+ 0x12c1, 0x12c1,
+ 0x12c6, 0x12c7,
+ 0x12d7, 0x12d7,
+ 0x1311, 0x1311,
+ 0x1316, 0x1317,
+ 0x135b, 0x135e,
+ 0x137d, 0x137f,
+ 0x139a, 0x139f,
+ 0x13f5, 0x1400,
+ 0x1677, 0x167f,
+ 0x169d, 0x169f,
+ 0x16f1, 0x16ff,
+ 0x170d, 0x170d,
+ 0x1715, 0x171f,
+ 0x1737, 0x173f,
+ 0x1754, 0x175f,
+ 0x176d, 0x176d,
+ 0x1771, 0x1771,
+ 0x1774, 0x177f,
+ 0x17de, 0x17df,
+ 0x17ea, 0x17ef,
+ 0x17fa, 0x17ff,
+ 0x180f, 0x180f,
+ 0x181a, 0x181f,
+ 0x1878, 0x187f,
+ 0x18aa, 0x18ff,
+ 0x191d, 0x191f,
+ 0x192c, 0x192f,
+ 0x193c, 0x193f,
+ 0x1941, 0x1943,
+ 0x196e, 0x196f,
+ 0x1975, 0x197f,
+ 0x19aa, 0x19af,
+ 0x19ca, 0x19cf,
+ 0x19da, 0x19dd,
+ 0x1a1c, 0x1a1d,
+ 0x1a20, 0x1cff,
+ 0x1dc4, 0x1dff,
+ 0x1e9c, 0x1e9f,
+ 0x1efa, 0x1eff,
+ 0x1f16, 0x1f17,
+ 0x1f1e, 0x1f1f,
+ 0x1f46, 0x1f47,
+ 0x1f4e, 0x1f4f,
+ 0x1f58, 0x1f58,
+ 0x1f5a, 0x1f5a,
+ 0x1f5c, 0x1f5c,
+ 0x1f5e, 0x1f5e,
+ 0x1f7e, 0x1f7f,
+ 0x1fb5, 0x1fb5,
+ 0x1fc5, 0x1fc5,
+ 0x1fd4, 0x1fd5,
+ 0x1fdc, 0x1fdc,
+ 0x1ff0, 0x1ff1,
+ 0x1ff5, 0x1ff5,
+ 0x1fff, 0x1fff,
+ 0x2064, 0x2069,
+ 0x2072, 0x2073,
+ 0x208f, 0x208f,
+ 0x2095, 0x209f,
+ 0x20b6, 0x20cf,
+ 0x20ec, 0x20ff,
+ 0x214d, 0x2152,
+ 0x2184, 0x218f,
+ 0x23dc, 0x23ff,
+ 0x2427, 0x243f,
+ 0x244b, 0x245f,
+ 0x269d, 0x269f,
+ 0x26b2, 0x2700,
+ 0x2705, 0x2705,
+ 0x270a, 0x270b,
+ 0x2728, 0x2728,
+ 0x274c, 0x274c,
+ 0x274e, 0x274e,
+ 0x2753, 0x2755,
+ 0x2757, 0x2757,
+ 0x275f, 0x2760,
+ 0x2795, 0x2797,
+ 0x27b0, 0x27b0,
+ 0x27bf, 0x27bf,
+ 0x27c7, 0x27cf,
+ 0x27ec, 0x27ef,
+ 0x2b14, 0x2bff,
+ 0x2c2f, 0x2c2f,
+ 0x2c5f, 0x2c7f,
+ 0x2ceb, 0x2cf8,
+ 0x2d26, 0x2d2f,
+ 0x2d66, 0x2d6e,
+ 0x2d70, 0x2d7f,
+ 0x2d97, 0x2d9f,
+ 0x2da7, 0x2da7,
+ 0x2daf, 0x2daf,
+ 0x2db7, 0x2db7,
+ 0x2dbf, 0x2dbf,
+ 0x2dc7, 0x2dc7,
+ 0x2dcf, 0x2dcf,
+ 0x2dd7, 0x2dd7,
+ 0x2ddf, 0x2dff,
+ 0x2e18, 0x2e1b,
+ 0x2e1e, 0x2e7f,
+ 0x2e9a, 0x2e9a,
+ 0x2ef4, 0x2eff,
+ 0x2fd6, 0x2fef,
+ 0x2ffc, 0x2fff,
+ 0x3040, 0x3040,
+ 0x3097, 0x3098,
+ 0x3100, 0x3104,
+ 0x312d, 0x3130,
+ 0x318f, 0x318f,
+ 0x31b8, 0x31bf,
+ 0x31d0, 0x31ef,
+ 0x321f, 0x321f,
+ 0x3244, 0x324f,
+ 0x32ff, 0x32ff,
+ 0x4db6, 0x4dbf,
+ 0x9fbc, 0x9fff,
+ 0xa48d, 0xa48f,
+ 0xa4c7, 0xa6ff,
+ 0xa717, 0xa7ff,
+ 0xa82c, 0xabff,
+ 0xd7a4, 0xd7ff,
+ 0xfa2e, 0xfa2f,
+ 0xfa6b, 0xfa6f,
+ 0xfada, 0xfaff,
+ 0xfb07, 0xfb12,
+ 0xfb18, 0xfb1c,
+ 0xfb37, 0xfb37,
+ 0xfb3d, 0xfb3d,
+ 0xfb3f, 0xfb3f,
+ 0xfb42, 0xfb42,
+ 0xfb45, 0xfb45,
+ 0xfbb2, 0xfbd2,
+ 0xfd40, 0xfd4f,
+ 0xfd90, 0xfd91,
+ 0xfdc8, 0xfdef,
+ 0xfdfe, 0xfdff,
+ 0xfe1a, 0xfe1f,
+ 0xfe24, 0xfe2f,
+ 0xfe53, 0xfe53,
+ 0xfe67, 0xfe67,
+ 0xfe6c, 0xfe6f,
+ 0xfe75, 0xfe75,
+ 0xfefd, 0xfefe,
+ 0xff00, 0xff00,
+ 0xffbf, 0xffc1,
+ 0xffc8, 0xffc9,
+ 0xffd0, 0xffd1,
+ 0xffd8, 0xffd9,
+ 0xffdd, 0xffdf,
+ 0xffe7, 0xffe7,
+ 0xffef, 0xfff8,
+ 0xfffe, 0xffff,
+ 0x1000c, 0x1000c,
+ 0x10027, 0x10027,
+ 0x1003b, 0x1003b,
+ 0x1003e, 0x1003e,
+ 0x1004e, 0x1004f,
+ 0x1005e, 0x1007f,
+ 0x100fb, 0x100ff,
+ 0x10103, 0x10106,
+ 0x10134, 0x10136,
+ 0x1018b, 0x102ff,
+ 0x1031f, 0x1031f,
+ 0x10324, 0x1032f,
+ 0x1034b, 0x1037f,
+ 0x1039e, 0x1039e,
+ 0x103c4, 0x103c7,
+ 0x103d6, 0x103ff,
+ 0x1049e, 0x1049f,
+ 0x104aa, 0x107ff,
+ 0x10806, 0x10807,
+ 0x10809, 0x10809,
+ 0x10836, 0x10836,
+ 0x10839, 0x1083b,
+ 0x1083d, 0x1083e,
+ 0x10840, 0x109ff,
+ 0x10a04, 0x10a04,
+ 0x10a07, 0x10a0b,
+ 0x10a14, 0x10a14,
+ 0x10a18, 0x10a18,
+ 0x10a34, 0x10a37,
+ 0x10a3b, 0x10a3e,
+ 0x10a48, 0x10a4f,
+ 0x10a59, 0x1cfff,
+ 0x1d0f6, 0x1d0ff,
+ 0x1d127, 0x1d129,
+ 0x1d1de, 0x1d1ff,
+ 0x1d246, 0x1d2ff,
+ 0x1d357, 0x1d3ff,
+ 0x1d455, 0x1d455,
+ 0x1d49d, 0x1d49d,
+ 0x1d4a0, 0x1d4a1,
+ 0x1d4a3, 0x1d4a4,
+ 0x1d4a7, 0x1d4a8,
+ 0x1d4ad, 0x1d4ad,
+ 0x1d4ba, 0x1d4ba,
+ 0x1d4bc, 0x1d4bc,
+ 0x1d4c4, 0x1d4c4,
+ 0x1d506, 0x1d506,
+ 0x1d50b, 0x1d50c,
+ 0x1d515, 0x1d515,
+ 0x1d51d, 0x1d51d,
+ 0x1d53a, 0x1d53a,
+ 0x1d53f, 0x1d53f,
+ 0x1d545, 0x1d545,
+ 0x1d547, 0x1d549,
+ 0x1d551, 0x1d551,
+ 0x1d6a6, 0x1d6a7,
+ 0x1d7ca, 0x1d7cd,
+ 0x1d800, 0x1ffff,
+ 0x2a6d7, 0x2f7ff,
+ 0x2fa1e, 0xe0000,
+ 0xe0002, 0xe001f,
+ 0xe0080, 0xe00ff,
+ 0xe01f0, 0xeffff,
+ 0xffffe, 0xfffff,
+ 0x10fffe, 0x10ffff
+}; /* CR_Cn */
+
+/* 'Co': General Category */
+static const OnigCodePoint CR_Co[] = {
+ 3,
+ 0xe000, 0xf8ff,
+ 0xf0000, 0xffffd,
+ 0x100000, 0x10fffd
+}; /* CR_Co */
+/* 'Cs': General Category */
+static const OnigCodePoint CR_Cs[] = {
+ 1,
+ 0xd800, 0xdfff
+}; /* CR_Cs */
+
+/* 'L': Major Category */
+static const OnigCodePoint CR_L[] = {
+ 347,
+ 0x0041, 0x005a,
+ 0x0061, 0x007a,
+ 0x00aa, 0x00aa,
+ 0x00b5, 0x00b5,
+ 0x00ba, 0x00ba,
+ 0x00c0, 0x00d6,
+ 0x00d8, 0x00f6,
+ 0x00f8, 0x0241,
+ 0x0250, 0x02c1,
+ 0x02c6, 0x02d1,
+ 0x02e0, 0x02e4,
+ 0x02ee, 0x02ee,
+ 0x037a, 0x037a,
+ 0x0386, 0x0386,
+ 0x0388, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x03ce,
+ 0x03d0, 0x03f5,
+ 0x03f7, 0x0481,
+ 0x048a, 0x04ce,
+ 0x04d0, 0x04f9,
+ 0x0500, 0x050f,
+ 0x0531, 0x0556,
+ 0x0559, 0x0559,
+ 0x0561, 0x0587,
+ 0x05d0, 0x05ea,
+ 0x05f0, 0x05f2,
+ 0x0621, 0x063a,
+ 0x0640, 0x064a,
+ 0x066e, 0x066f,
+ 0x0671, 0x06d3,
+ 0x06d5, 0x06d5,
+ 0x06e5, 0x06e6,
+ 0x06ee, 0x06ef,
+ 0x06fa, 0x06fc,
+ 0x06ff, 0x06ff,
+ 0x0710, 0x0710,
+ 0x0712, 0x072f,
+ 0x074d, 0x076d,
+ 0x0780, 0x07a5,
+ 0x07b1, 0x07b1,
+ 0x0904, 0x0939,
+ 0x093d, 0x093d,
+ 0x0950, 0x0950,
+ 0x0958, 0x0961,
+ 0x097d, 0x097d,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bd, 0x09bd,
+ 0x09ce, 0x09ce,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e1,
+ 0x09f0, 0x09f1,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a72, 0x0a74,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abd, 0x0abd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae1,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3d, 0x0b3d,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b61,
+ 0x0b71, 0x0b71,
+ 0x0b83, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0c05, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c33,
+ 0x0c35, 0x0c39,
+ 0x0c60, 0x0c61,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbd, 0x0cbd,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce1,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d28,
+ 0x0d2a, 0x0d39,
+ 0x0d60, 0x0d61,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0e01, 0x0e30,
+ 0x0e32, 0x0e33,
+ 0x0e40, 0x0e46,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e87, 0x0e88,
+ 0x0e8a, 0x0e8a,
+ 0x0e8d, 0x0e8d,
+ 0x0e94, 0x0e97,
+ 0x0e99, 0x0e9f,
+ 0x0ea1, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ea7,
+ 0x0eaa, 0x0eab,
+ 0x0ead, 0x0eb0,
+ 0x0eb2, 0x0eb3,
+ 0x0ebd, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0edc, 0x0edd,
+ 0x0f00, 0x0f00,
+ 0x0f40, 0x0f47,
+ 0x0f49, 0x0f6a,
+ 0x0f88, 0x0f8b,
+ 0x1000, 0x1021,
+ 0x1023, 0x1027,
+ 0x1029, 0x102a,
+ 0x1050, 0x1055,
+ 0x10a0, 0x10c5,
+ 0x10d0, 0x10fa,
+ 0x10fc, 0x10fc,
+ 0x1100, 0x1159,
+ 0x115f, 0x11a2,
+ 0x11a8, 0x11f9,
+ 0x1200, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x1380, 0x138f,
+ 0x13a0, 0x13f4,
+ 0x1401, 0x166c,
+ 0x166f, 0x1676,
+ 0x1681, 0x169a,
+ 0x16a0, 0x16ea,
+ 0x1700, 0x170c,
+ 0x170e, 0x1711,
+ 0x1720, 0x1731,
+ 0x1740, 0x1751,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1780, 0x17b3,
+ 0x17d7, 0x17d7,
+ 0x17dc, 0x17dc,
+ 0x1820, 0x1877,
+ 0x1880, 0x18a8,
+ 0x1900, 0x191c,
+ 0x1950, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19a9,
+ 0x19c1, 0x19c7,
+ 0x1a00, 0x1a16,
+ 0x1d00, 0x1dbf,
+ 0x1e00, 0x1e9b,
+ 0x1ea0, 0x1ef9,
+ 0x1f00, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fbc,
+ 0x1fbe, 0x1fbe,
+ 0x1fc2, 0x1fc4,
+ 0x1fc6, 0x1fcc,
+ 0x1fd0, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fe0, 0x1fec,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffc,
+ 0x2071, 0x2071,
+ 0x207f, 0x207f,
+ 0x2090, 0x2094,
+ 0x2102, 0x2102,
+ 0x2107, 0x2107,
+ 0x210a, 0x2113,
+ 0x2115, 0x2115,
+ 0x2119, 0x211d,
+ 0x2124, 0x2124,
+ 0x2126, 0x2126,
+ 0x2128, 0x2128,
+ 0x212a, 0x212d,
+ 0x212f, 0x2131,
+ 0x2133, 0x2139,
+ 0x213c, 0x213f,
+ 0x2145, 0x2149,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e,
+ 0x2c80, 0x2ce4,
+ 0x2d00, 0x2d25,
+ 0x2d30, 0x2d65,
+ 0x2d6f, 0x2d6f,
+ 0x2d80, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x3005, 0x3006,
+ 0x3031, 0x3035,
+ 0x303b, 0x303c,
+ 0x3041, 0x3096,
+ 0x309d, 0x309f,
+ 0x30a1, 0x30fa,
+ 0x30fc, 0x30ff,
+ 0x3105, 0x312c,
+ 0x3131, 0x318e,
+ 0x31a0, 0x31b7,
+ 0x31f0, 0x31ff,
+ 0x3400, 0x4db5,
+ 0x4e00, 0x9fbb,
+ 0xa000, 0xa48c,
+ 0xa800, 0xa801,
+ 0xa803, 0xa805,
+ 0xa807, 0xa80a,
+ 0xa80c, 0xa822,
+ 0xac00, 0xd7a3,
+ 0xf900, 0xfa2d,
+ 0xfa30, 0xfa6a,
+ 0xfa70, 0xfad9,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xfb1d, 0xfb1d,
+ 0xfb1f, 0xfb28,
+ 0xfb2a, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbb1,
+ 0xfbd3, 0xfd3d,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdf0, 0xfdfb,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xff21, 0xff3a,
+ 0xff41, 0xff5a,
+ 0xff66, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0x10000, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10300, 0x1031e,
+ 0x10330, 0x10349,
+ 0x10380, 0x1039d,
+ 0x103a0, 0x103c3,
+ 0x103c8, 0x103cf,
+ 0x10400, 0x1049d,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x1083f,
+ 0x10a00, 0x10a00,
+ 0x10a10, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a33,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d6c0,
+ 0x1d6c2, 0x1d6da,
+ 0x1d6dc, 0x1d6fa,
+ 0x1d6fc, 0x1d714,
+ 0x1d716, 0x1d734,
+ 0x1d736, 0x1d74e,
+ 0x1d750, 0x1d76e,
+ 0x1d770, 0x1d788,
+ 0x1d78a, 0x1d7a8,
+ 0x1d7aa, 0x1d7c2,
+ 0x1d7c4, 0x1d7c9,
+ 0x20000, 0x2a6d6,
+ 0x2f800, 0x2fa1d
+}; /* CR_L */
+
+/* 'Ll': General Category */
+static const OnigCodePoint CR_Ll[] = {
+ 480,
+ 0x0061, 0x007a,
+ 0x00aa, 0x00aa,
+ 0x00b5, 0x00b5,
+ 0x00ba, 0x00ba,
+ 0x00df, 0x00f6,
+ 0x00f8, 0x00ff,
+ 0x0101, 0x0101,
+ 0x0103, 0x0103,
+ 0x0105, 0x0105,
+ 0x0107, 0x0107,
+ 0x0109, 0x0109,
+ 0x010b, 0x010b,
+ 0x010d, 0x010d,
+ 0x010f, 0x010f,
+ 0x0111, 0x0111,
+ 0x0113, 0x0113,
+ 0x0115, 0x0115,
+ 0x0117, 0x0117,
+ 0x0119, 0x0119,
+ 0x011b, 0x011b,
+ 0x011d, 0x011d,
+ 0x011f, 0x011f,
+ 0x0121, 0x0121,
+ 0x0123, 0x0123,
+ 0x0125, 0x0125,
+ 0x0127, 0x0127,
+ 0x0129, 0x0129,
+ 0x012b, 0x012b,
+ 0x012d, 0x012d,
+ 0x012f, 0x012f,
+ 0x0131, 0x0131,
+ 0x0133, 0x0133,
+ 0x0135, 0x0135,
+ 0x0137, 0x0138,
+ 0x013a, 0x013a,
+ 0x013c, 0x013c,
+ 0x013e, 0x013e,
+ 0x0140, 0x0140,
+ 0x0142, 0x0142,
+ 0x0144, 0x0144,
+ 0x0146, 0x0146,
+ 0x0148, 0x0149,
+ 0x014b, 0x014b,
+ 0x014d, 0x014d,
+ 0x014f, 0x014f,
+ 0x0151, 0x0151,
+ 0x0153, 0x0153,
+ 0x0155, 0x0155,
+ 0x0157, 0x0157,
+ 0x0159, 0x0159,
+ 0x015b, 0x015b,
+ 0x015d, 0x015d,
+ 0x015f, 0x015f,
+ 0x0161, 0x0161,
+ 0x0163, 0x0163,
+ 0x0165, 0x0165,
+ 0x0167, 0x0167,
+ 0x0169, 0x0169,
+ 0x016b, 0x016b,
+ 0x016d, 0x016d,
+ 0x016f, 0x016f,
+ 0x0171, 0x0171,
+ 0x0173, 0x0173,
+ 0x0175, 0x0175,
+ 0x0177, 0x0177,
+ 0x017a, 0x017a,
+ 0x017c, 0x017c,
+ 0x017e, 0x0180,
+ 0x0183, 0x0183,
+ 0x0185, 0x0185,
+ 0x0188, 0x0188,
+ 0x018c, 0x018d,
+ 0x0192, 0x0192,
+ 0x0195, 0x0195,
+ 0x0199, 0x019b,
+ 0x019e, 0x019e,
+ 0x01a1, 0x01a1,
+ 0x01a3, 0x01a3,
+ 0x01a5, 0x01a5,
+ 0x01a8, 0x01a8,
+ 0x01aa, 0x01ab,
+ 0x01ad, 0x01ad,
+ 0x01b0, 0x01b0,
+ 0x01b4, 0x01b4,
+ 0x01b6, 0x01b6,
+ 0x01b9, 0x01ba,
+ 0x01bd, 0x01bf,
+ 0x01c6, 0x01c6,
+ 0x01c9, 0x01c9,
+ 0x01cc, 0x01cc,
+ 0x01ce, 0x01ce,
+ 0x01d0, 0x01d0,
+ 0x01d2, 0x01d2,
+ 0x01d4, 0x01d4,
+ 0x01d6, 0x01d6,
+ 0x01d8, 0x01d8,
+ 0x01da, 0x01da,
+ 0x01dc, 0x01dd,
+ 0x01df, 0x01df,
+ 0x01e1, 0x01e1,
+ 0x01e3, 0x01e3,
+ 0x01e5, 0x01e5,
+ 0x01e7, 0x01e7,
+ 0x01e9, 0x01e9,
+ 0x01eb, 0x01eb,
+ 0x01ed, 0x01ed,
+ 0x01ef, 0x01f0,
+ 0x01f3, 0x01f3,
+ 0x01f5, 0x01f5,
+ 0x01f9, 0x01f9,
+ 0x01fb, 0x01fb,
+ 0x01fd, 0x01fd,
+ 0x01ff, 0x01ff,
+ 0x0201, 0x0201,
+ 0x0203, 0x0203,
+ 0x0205, 0x0205,
+ 0x0207, 0x0207,
+ 0x0209, 0x0209,
+ 0x020b, 0x020b,
+ 0x020d, 0x020d,
+ 0x020f, 0x020f,
+ 0x0211, 0x0211,
+ 0x0213, 0x0213,
+ 0x0215, 0x0215,
+ 0x0217, 0x0217,
+ 0x0219, 0x0219,
+ 0x021b, 0x021b,
+ 0x021d, 0x021d,
+ 0x021f, 0x021f,
+ 0x0221, 0x0221,
+ 0x0223, 0x0223,
+ 0x0225, 0x0225,
+ 0x0227, 0x0227,
+ 0x0229, 0x0229,
+ 0x022b, 0x022b,
+ 0x022d, 0x022d,
+ 0x022f, 0x022f,
+ 0x0231, 0x0231,
+ 0x0233, 0x0239,
+ 0x023c, 0x023c,
+ 0x023f, 0x0240,
+ 0x0250, 0x02af,
+ 0x0390, 0x0390,
+ 0x03ac, 0x03ce,
+ 0x03d0, 0x03d1,
+ 0x03d5, 0x03d7,
+ 0x03d9, 0x03d9,
+ 0x03db, 0x03db,
+ 0x03dd, 0x03dd,
+ 0x03df, 0x03df,
+ 0x03e1, 0x03e1,
+ 0x03e3, 0x03e3,
+ 0x03e5, 0x03e5,
+ 0x03e7, 0x03e7,
+ 0x03e9, 0x03e9,
+ 0x03eb, 0x03eb,
+ 0x03ed, 0x03ed,
+ 0x03ef, 0x03f3,
+ 0x03f5, 0x03f5,
+ 0x03f8, 0x03f8,
+ 0x03fb, 0x03fc,
+ 0x0430, 0x045f,
+ 0x0461, 0x0461,
+ 0x0463, 0x0463,
+ 0x0465, 0x0465,
+ 0x0467, 0x0467,
+ 0x0469, 0x0469,
+ 0x046b, 0x046b,
+ 0x046d, 0x046d,
+ 0x046f, 0x046f,
+ 0x0471, 0x0471,
+ 0x0473, 0x0473,
+ 0x0475, 0x0475,
+ 0x0477, 0x0477,
+ 0x0479, 0x0479,
+ 0x047b, 0x047b,
+ 0x047d, 0x047d,
+ 0x047f, 0x047f,
+ 0x0481, 0x0481,
+ 0x048b, 0x048b,
+ 0x048d, 0x048d,
+ 0x048f, 0x048f,
+ 0x0491, 0x0491,
+ 0x0493, 0x0493,
+ 0x0495, 0x0495,
+ 0x0497, 0x0497,
+ 0x0499, 0x0499,
+ 0x049b, 0x049b,
+ 0x049d, 0x049d,
+ 0x049f, 0x049f,
+ 0x04a1, 0x04a1,
+ 0x04a3, 0x04a3,
+ 0x04a5, 0x04a5,
+ 0x04a7, 0x04a7,
+ 0x04a9, 0x04a9,
+ 0x04ab, 0x04ab,
+ 0x04ad, 0x04ad,
+ 0x04af, 0x04af,
+ 0x04b1, 0x04b1,
+ 0x04b3, 0x04b3,
+ 0x04b5, 0x04b5,
+ 0x04b7, 0x04b7,
+ 0x04b9, 0x04b9,
+ 0x04bb, 0x04bb,
+ 0x04bd, 0x04bd,
+ 0x04bf, 0x04bf,
+ 0x04c2, 0x04c2,
+ 0x04c4, 0x04c4,
+ 0x04c6, 0x04c6,
+ 0x04c8, 0x04c8,
+ 0x04ca, 0x04ca,
+ 0x04cc, 0x04cc,
+ 0x04ce, 0x04ce,
+ 0x04d1, 0x04d1,
+ 0x04d3, 0x04d3,
+ 0x04d5, 0x04d5,
+ 0x04d7, 0x04d7,
+ 0x04d9, 0x04d9,
+ 0x04db, 0x04db,
+ 0x04dd, 0x04dd,
+ 0x04df, 0x04df,
+ 0x04e1, 0x04e1,
+ 0x04e3, 0x04e3,
+ 0x04e5, 0x04e5,
+ 0x04e7, 0x04e7,
+ 0x04e9, 0x04e9,
+ 0x04eb, 0x04eb,
+ 0x04ed, 0x04ed,
+ 0x04ef, 0x04ef,
+ 0x04f1, 0x04f1,
+ 0x04f3, 0x04f3,
+ 0x04f5, 0x04f5,
+ 0x04f7, 0x04f7,
+ 0x04f9, 0x04f9,
+ 0x0501, 0x0501,
+ 0x0503, 0x0503,
+ 0x0505, 0x0505,
+ 0x0507, 0x0507,
+ 0x0509, 0x0509,
+ 0x050b, 0x050b,
+ 0x050d, 0x050d,
+ 0x050f, 0x050f,
+ 0x0561, 0x0587,
+ 0x1d00, 0x1d2b,
+ 0x1d62, 0x1d77,
+ 0x1d79, 0x1d9a,
+ 0x1e01, 0x1e01,
+ 0x1e03, 0x1e03,
+ 0x1e05, 0x1e05,
+ 0x1e07, 0x1e07,
+ 0x1e09, 0x1e09,
+ 0x1e0b, 0x1e0b,
+ 0x1e0d, 0x1e0d,
+ 0x1e0f, 0x1e0f,
+ 0x1e11, 0x1e11,
+ 0x1e13, 0x1e13,
+ 0x1e15, 0x1e15,
+ 0x1e17, 0x1e17,
+ 0x1e19, 0x1e19,
+ 0x1e1b, 0x1e1b,
+ 0x1e1d, 0x1e1d,
+ 0x1e1f, 0x1e1f,
+ 0x1e21, 0x1e21,
+ 0x1e23, 0x1e23,
+ 0x1e25, 0x1e25,
+ 0x1e27, 0x1e27,
+ 0x1e29, 0x1e29,
+ 0x1e2b, 0x1e2b,
+ 0x1e2d, 0x1e2d,
+ 0x1e2f, 0x1e2f,
+ 0x1e31, 0x1e31,
+ 0x1e33, 0x1e33,
+ 0x1e35, 0x1e35,
+ 0x1e37, 0x1e37,
+ 0x1e39, 0x1e39,
+ 0x1e3b, 0x1e3b,
+ 0x1e3d, 0x1e3d,
+ 0x1e3f, 0x1e3f,
+ 0x1e41, 0x1e41,
+ 0x1e43, 0x1e43,
+ 0x1e45, 0x1e45,
+ 0x1e47, 0x1e47,
+ 0x1e49, 0x1e49,
+ 0x1e4b, 0x1e4b,
+ 0x1e4d, 0x1e4d,
+ 0x1e4f, 0x1e4f,
+ 0x1e51, 0x1e51,
+ 0x1e53, 0x1e53,
+ 0x1e55, 0x1e55,
+ 0x1e57, 0x1e57,
+ 0x1e59, 0x1e59,
+ 0x1e5b, 0x1e5b,
+ 0x1e5d, 0x1e5d,
+ 0x1e5f, 0x1e5f,
+ 0x1e61, 0x1e61,
+ 0x1e63, 0x1e63,
+ 0x1e65, 0x1e65,
+ 0x1e67, 0x1e67,
+ 0x1e69, 0x1e69,
+ 0x1e6b, 0x1e6b,
+ 0x1e6d, 0x1e6d,
+ 0x1e6f, 0x1e6f,
+ 0x1e71, 0x1e71,
+ 0x1e73, 0x1e73,
+ 0x1e75, 0x1e75,
+ 0x1e77, 0x1e77,
+ 0x1e79, 0x1e79,
+ 0x1e7b, 0x1e7b,
+ 0x1e7d, 0x1e7d,
+ 0x1e7f, 0x1e7f,
+ 0x1e81, 0x1e81,
+ 0x1e83, 0x1e83,
+ 0x1e85, 0x1e85,
+ 0x1e87, 0x1e87,
+ 0x1e89, 0x1e89,
+ 0x1e8b, 0x1e8b,
+ 0x1e8d, 0x1e8d,
+ 0x1e8f, 0x1e8f,
+ 0x1e91, 0x1e91,
+ 0x1e93, 0x1e93,
+ 0x1e95, 0x1e9b,
+ 0x1ea1, 0x1ea1,
+ 0x1ea3, 0x1ea3,
+ 0x1ea5, 0x1ea5,
+ 0x1ea7, 0x1ea7,
+ 0x1ea9, 0x1ea9,
+ 0x1eab, 0x1eab,
+ 0x1ead, 0x1ead,
+ 0x1eaf, 0x1eaf,
+ 0x1eb1, 0x1eb1,
+ 0x1eb3, 0x1eb3,
+ 0x1eb5, 0x1eb5,
+ 0x1eb7, 0x1eb7,
+ 0x1eb9, 0x1eb9,
+ 0x1ebb, 0x1ebb,
+ 0x1ebd, 0x1ebd,
+ 0x1ebf, 0x1ebf,
+ 0x1ec1, 0x1ec1,
+ 0x1ec3, 0x1ec3,
+ 0x1ec5, 0x1ec5,
+ 0x1ec7, 0x1ec7,
+ 0x1ec9, 0x1ec9,
+ 0x1ecb, 0x1ecb,
+ 0x1ecd, 0x1ecd,
+ 0x1ecf, 0x1ecf,
+ 0x1ed1, 0x1ed1,
+ 0x1ed3, 0x1ed3,
+ 0x1ed5, 0x1ed5,
+ 0x1ed7, 0x1ed7,
+ 0x1ed9, 0x1ed9,
+ 0x1edb, 0x1edb,
+ 0x1edd, 0x1edd,
+ 0x1edf, 0x1edf,
+ 0x1ee1, 0x1ee1,
+ 0x1ee3, 0x1ee3,
+ 0x1ee5, 0x1ee5,
+ 0x1ee7, 0x1ee7,
+ 0x1ee9, 0x1ee9,
+ 0x1eeb, 0x1eeb,
+ 0x1eed, 0x1eed,
+ 0x1eef, 0x1eef,
+ 0x1ef1, 0x1ef1,
+ 0x1ef3, 0x1ef3,
+ 0x1ef5, 0x1ef5,
+ 0x1ef7, 0x1ef7,
+ 0x1ef9, 0x1ef9,
+ 0x1f00, 0x1f07,
+ 0x1f10, 0x1f15,
+ 0x1f20, 0x1f27,
+ 0x1f30, 0x1f37,
+ 0x1f40, 0x1f45,
+ 0x1f50, 0x1f57,
+ 0x1f60, 0x1f67,
+ 0x1f70, 0x1f7d,
+ 0x1f80, 0x1f87,
+ 0x1f90, 0x1f97,
+ 0x1fa0, 0x1fa7,
+ 0x1fb0, 0x1fb4,
+ 0x1fb6, 0x1fb7,
+ 0x1fbe, 0x1fbe,
+ 0x1fc2, 0x1fc4,
+ 0x1fc6, 0x1fc7,
+ 0x1fd0, 0x1fd3,
+ 0x1fd6, 0x1fd7,
+ 0x1fe0, 0x1fe7,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ff7,
+ 0x2071, 0x2071,
+ 0x207f, 0x207f,
+ 0x210a, 0x210a,
+ 0x210e, 0x210f,
+ 0x2113, 0x2113,
+ 0x212f, 0x212f,
+ 0x2134, 0x2134,
+ 0x2139, 0x2139,
+ 0x213c, 0x213d,
+ 0x2146, 0x2149,
+ 0x2c30, 0x2c5e,
+ 0x2c81, 0x2c81,
+ 0x2c83, 0x2c83,
+ 0x2c85, 0x2c85,
+ 0x2c87, 0x2c87,
+ 0x2c89, 0x2c89,
+ 0x2c8b, 0x2c8b,
+ 0x2c8d, 0x2c8d,
+ 0x2c8f, 0x2c8f,
+ 0x2c91, 0x2c91,
+ 0x2c93, 0x2c93,
+ 0x2c95, 0x2c95,
+ 0x2c97, 0x2c97,
+ 0x2c99, 0x2c99,
+ 0x2c9b, 0x2c9b,
+ 0x2c9d, 0x2c9d,
+ 0x2c9f, 0x2c9f,
+ 0x2ca1, 0x2ca1,
+ 0x2ca3, 0x2ca3,
+ 0x2ca5, 0x2ca5,
+ 0x2ca7, 0x2ca7,
+ 0x2ca9, 0x2ca9,
+ 0x2cab, 0x2cab,
+ 0x2cad, 0x2cad,
+ 0x2caf, 0x2caf,
+ 0x2cb1, 0x2cb1,
+ 0x2cb3, 0x2cb3,
+ 0x2cb5, 0x2cb5,
+ 0x2cb7, 0x2cb7,
+ 0x2cb9, 0x2cb9,
+ 0x2cbb, 0x2cbb,
+ 0x2cbd, 0x2cbd,
+ 0x2cbf, 0x2cbf,
+ 0x2cc1, 0x2cc1,
+ 0x2cc3, 0x2cc3,
+ 0x2cc5, 0x2cc5,
+ 0x2cc7, 0x2cc7,
+ 0x2cc9, 0x2cc9,
+ 0x2ccb, 0x2ccb,
+ 0x2ccd, 0x2ccd,
+ 0x2ccf, 0x2ccf,
+ 0x2cd1, 0x2cd1,
+ 0x2cd3, 0x2cd3,
+ 0x2cd5, 0x2cd5,
+ 0x2cd7, 0x2cd7,
+ 0x2cd9, 0x2cd9,
+ 0x2cdb, 0x2cdb,
+ 0x2cdd, 0x2cdd,
+ 0x2cdf, 0x2cdf,
+ 0x2ce1, 0x2ce1,
+ 0x2ce3, 0x2ce4,
+ 0x2d00, 0x2d25,
+ 0xfb00, 0xfb06,
+ 0xfb13, 0xfb17,
+ 0xff41, 0xff5a,
+ 0x10428, 0x1044f,
+ 0x1d41a, 0x1d433,
+ 0x1d44e, 0x1d454,
+ 0x1d456, 0x1d467,
+ 0x1d482, 0x1d49b,
+ 0x1d4b6, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d4cf,
+ 0x1d4ea, 0x1d503,
+ 0x1d51e, 0x1d537,
+ 0x1d552, 0x1d56b,
+ 0x1d586, 0x1d59f,
+ 0x1d5ba, 0x1d5d3,
+ 0x1d5ee, 0x1d607,
+ 0x1d622, 0x1d63b,
+ 0x1d656, 0x1d66f,
+ 0x1d68a, 0x1d6a5,
+ 0x1d6c2, 0x1d6da,
+ 0x1d6dc, 0x1d6e1,
+ 0x1d6fc, 0x1d714,
+ 0x1d716, 0x1d71b,
+ 0x1d736, 0x1d74e,
+ 0x1d750, 0x1d755,
+ 0x1d770, 0x1d788,
+ 0x1d78a, 0x1d78f,
+ 0x1d7aa, 0x1d7c2,
+ 0x1d7c4, 0x1d7c9
+}; /* CR_Ll */
+
+/* 'Lm': General Category */
+static const OnigCodePoint CR_Lm[] = {
+ 26,
+ 0x02b0, 0x02c1,
+ 0x02c6, 0x02d1,
+ 0x02e0, 0x02e4,
+ 0x02ee, 0x02ee,
+ 0x037a, 0x037a,
+ 0x0559, 0x0559,
+ 0x0640, 0x0640,
+ 0x06e5, 0x06e6,
+ 0x0e46, 0x0e46,
+ 0x0ec6, 0x0ec6,
+ 0x10fc, 0x10fc,
+ 0x17d7, 0x17d7,
+ 0x1843, 0x1843,
+ 0x1d2c, 0x1d61,
+ 0x1d78, 0x1d78,
+ 0x1d9b, 0x1dbf,
+ 0x2090, 0x2094,
+ 0x2d6f, 0x2d6f,
+ 0x3005, 0x3005,
+ 0x3031, 0x3035,
+ 0x303b, 0x303b,
+ 0x309d, 0x309e,
+ 0x30fc, 0x30fe,
+ 0xa015, 0xa015,
+ 0xff70, 0xff70,
+ 0xff9e, 0xff9f
+}; /* CR_Lm */
+
+/* 'Lo': General Category */
+static const OnigCodePoint CR_Lo[] = {
+ 245,
+ 0x01bb, 0x01bb,
+ 0x01c0, 0x01c3,
+ 0x05d0, 0x05ea,
+ 0x05f0, 0x05f2,
+ 0x0621, 0x063a,
+ 0x0641, 0x064a,
+ 0x066e, 0x066f,
+ 0x0671, 0x06d3,
+ 0x06d5, 0x06d5,
+ 0x06ee, 0x06ef,
+ 0x06fa, 0x06fc,
+ 0x06ff, 0x06ff,
+ 0x0710, 0x0710,
+ 0x0712, 0x072f,
+ 0x074d, 0x076d,
+ 0x0780, 0x07a5,
+ 0x07b1, 0x07b1,
+ 0x0904, 0x0939,
+ 0x093d, 0x093d,
+ 0x0950, 0x0950,
+ 0x0958, 0x0961,
+ 0x097d, 0x097d,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bd, 0x09bd,
+ 0x09ce, 0x09ce,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e1,
+ 0x09f0, 0x09f1,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a72, 0x0a74,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abd, 0x0abd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae1,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3d, 0x0b3d,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b61,
+ 0x0b71, 0x0b71,
+ 0x0b83, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0c05, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c33,
+ 0x0c35, 0x0c39,
+ 0x0c60, 0x0c61,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbd, 0x0cbd,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce1,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d28,
+ 0x0d2a, 0x0d39,
+ 0x0d60, 0x0d61,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0e01, 0x0e30,
+ 0x0e32, 0x0e33,
+ 0x0e40, 0x0e45,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e87, 0x0e88,
+ 0x0e8a, 0x0e8a,
+ 0x0e8d, 0x0e8d,
+ 0x0e94, 0x0e97,
+ 0x0e99, 0x0e9f,
+ 0x0ea1, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ea7,
+ 0x0eaa, 0x0eab,
+ 0x0ead, 0x0eb0,
+ 0x0eb2, 0x0eb3,
+ 0x0ebd, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0edc, 0x0edd,
+ 0x0f00, 0x0f00,
+ 0x0f40, 0x0f47,
+ 0x0f49, 0x0f6a,
+ 0x0f88, 0x0f8b,
+ 0x1000, 0x1021,
+ 0x1023, 0x1027,
+ 0x1029, 0x102a,
+ 0x1050, 0x1055,
+ 0x10d0, 0x10fa,
+ 0x1100, 0x1159,
+ 0x115f, 0x11a2,
+ 0x11a8, 0x11f9,
+ 0x1200, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x1380, 0x138f,
+ 0x13a0, 0x13f4,
+ 0x1401, 0x166c,
+ 0x166f, 0x1676,
+ 0x1681, 0x169a,
+ 0x16a0, 0x16ea,
+ 0x1700, 0x170c,
+ 0x170e, 0x1711,
+ 0x1720, 0x1731,
+ 0x1740, 0x1751,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1780, 0x17b3,
+ 0x17dc, 0x17dc,
+ 0x1820, 0x1842,
+ 0x1844, 0x1877,
+ 0x1880, 0x18a8,
+ 0x1900, 0x191c,
+ 0x1950, 0x196d,
+ 0x1970, 0x1974,
+ 0x1980, 0x19a9,
+ 0x19c1, 0x19c7,
+ 0x1a00, 0x1a16,
+ 0x2135, 0x2138,
+ 0x2d30, 0x2d65,
+ 0x2d80, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde,
+ 0x3006, 0x3006,
+ 0x303c, 0x303c,
+ 0x3041, 0x3096,
+ 0x309f, 0x309f,
+ 0x30a1, 0x30fa,
+ 0x30ff, 0x30ff,
+ 0x3105, 0x312c,
+ 0x3131, 0x318e,
+ 0x31a0, 0x31b7,
+ 0x31f0, 0x31ff,
+ 0x3400, 0x4db5,
+ 0x4e00, 0x9fbb,
+ 0xa000, 0xa014,
+ 0xa016, 0xa48c,
+ 0xa800, 0xa801,
+ 0xa803, 0xa805,
+ 0xa807, 0xa80a,
+ 0xa80c, 0xa822,
+ 0xac00, 0xd7a3,
+ 0xf900, 0xfa2d,
+ 0xfa30, 0xfa6a,
+ 0xfa70, 0xfad9,
+ 0xfb1d, 0xfb1d,
+ 0xfb1f, 0xfb28,
+ 0xfb2a, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfbb1,
+ 0xfbd3, 0xfd3d,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdf0, 0xfdfb,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc,
+ 0xff66, 0xff6f,
+ 0xff71, 0xff9d,
+ 0xffa0, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc,
+ 0x10000, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa,
+ 0x10300, 0x1031e,
+ 0x10330, 0x10349,
+ 0x10380, 0x1039d,
+ 0x103a0, 0x103c3,
+ 0x103c8, 0x103cf,
+ 0x10450, 0x1049d,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x1083f,
+ 0x10a00, 0x10a00,
+ 0x10a10, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a33,
+ 0x20000, 0x2a6d6,
+ 0x2f800, 0x2fa1d
+}; /* CR_Lo */
+
+/* 'Lt': General Category */
+static const OnigCodePoint CR_Lt[] = {
+ 10,
+ 0x01c5, 0x01c5,
+ 0x01c8, 0x01c8,
+ 0x01cb, 0x01cb,
+ 0x01f2, 0x01f2,
+ 0x1f88, 0x1f8f,
+ 0x1f98, 0x1f9f,
+ 0x1fa8, 0x1faf,
+ 0x1fbc, 0x1fbc,
+ 0x1fcc, 0x1fcc,
+ 0x1ffc, 0x1ffc
+}; /* CR_Lt */
+
+/* 'Lu': General Category */
+static const OnigCodePoint CR_Lu[] = {
+ 476,
+ 0x0041, 0x005a,
+ 0x00c0, 0x00d6,
+ 0x00d8, 0x00de,
+ 0x0100, 0x0100,
+ 0x0102, 0x0102,
+ 0x0104, 0x0104,
+ 0x0106, 0x0106,
+ 0x0108, 0x0108,
+ 0x010a, 0x010a,
+ 0x010c, 0x010c,
+ 0x010e, 0x010e,
+ 0x0110, 0x0110,
+ 0x0112, 0x0112,
+ 0x0114, 0x0114,
+ 0x0116, 0x0116,
+ 0x0118, 0x0118,
+ 0x011a, 0x011a,
+ 0x011c, 0x011c,
+ 0x011e, 0x011e,
+ 0x0120, 0x0120,
+ 0x0122, 0x0122,
+ 0x0124, 0x0124,
+ 0x0126, 0x0126,
+ 0x0128, 0x0128,
+ 0x012a, 0x012a,
+ 0x012c, 0x012c,
+ 0x012e, 0x012e,
+ 0x0130, 0x0130,
+ 0x0132, 0x0132,
+ 0x0134, 0x0134,
+ 0x0136, 0x0136,
+ 0x0139, 0x0139,
+ 0x013b, 0x013b,
+ 0x013d, 0x013d,
+ 0x013f, 0x013f,
+ 0x0141, 0x0141,
+ 0x0143, 0x0143,
+ 0x0145, 0x0145,
+ 0x0147, 0x0147,
+ 0x014a, 0x014a,
+ 0x014c, 0x014c,
+ 0x014e, 0x014e,
+ 0x0150, 0x0150,
+ 0x0152, 0x0152,
+ 0x0154, 0x0154,
+ 0x0156, 0x0156,
+ 0x0158, 0x0158,
+ 0x015a, 0x015a,
+ 0x015c, 0x015c,
+ 0x015e, 0x015e,
+ 0x0160, 0x0160,
+ 0x0162, 0x0162,
+ 0x0164, 0x0164,
+ 0x0166, 0x0166,
+ 0x0168, 0x0168,
+ 0x016a, 0x016a,
+ 0x016c, 0x016c,
+ 0x016e, 0x016e,
+ 0x0170, 0x0170,
+ 0x0172, 0x0172,
+ 0x0174, 0x0174,
+ 0x0176, 0x0176,
+ 0x0178, 0x0179,
+ 0x017b, 0x017b,
+ 0x017d, 0x017d,
+ 0x0181, 0x0182,
+ 0x0184, 0x0184,
+ 0x0186, 0x0187,
+ 0x0189, 0x018b,
+ 0x018e, 0x0191,
+ 0x0193, 0x0194,
+ 0x0196, 0x0198,
+ 0x019c, 0x019d,
+ 0x019f, 0x01a0,
+ 0x01a2, 0x01a2,
+ 0x01a4, 0x01a4,
+ 0x01a6, 0x01a7,
+ 0x01a9, 0x01a9,
+ 0x01ac, 0x01ac,
+ 0x01ae, 0x01af,
+ 0x01b1, 0x01b3,
+ 0x01b5, 0x01b5,
+ 0x01b7, 0x01b8,
+ 0x01bc, 0x01bc,
+ 0x01c4, 0x01c4,
+ 0x01c7, 0x01c7,
+ 0x01ca, 0x01ca,
+ 0x01cd, 0x01cd,
+ 0x01cf, 0x01cf,
+ 0x01d1, 0x01d1,
+ 0x01d3, 0x01d3,
+ 0x01d5, 0x01d5,
+ 0x01d7, 0x01d7,
+ 0x01d9, 0x01d9,
+ 0x01db, 0x01db,
+ 0x01de, 0x01de,
+ 0x01e0, 0x01e0,
+ 0x01e2, 0x01e2,
+ 0x01e4, 0x01e4,
+ 0x01e6, 0x01e6,
+ 0x01e8, 0x01e8,
+ 0x01ea, 0x01ea,
+ 0x01ec, 0x01ec,
+ 0x01ee, 0x01ee,
+ 0x01f1, 0x01f1,
+ 0x01f4, 0x01f4,
+ 0x01f6, 0x01f8,
+ 0x01fa, 0x01fa,
+ 0x01fc, 0x01fc,
+ 0x01fe, 0x01fe,
+ 0x0200, 0x0200,
+ 0x0202, 0x0202,
+ 0x0204, 0x0204,
+ 0x0206, 0x0206,
+ 0x0208, 0x0208,
+ 0x020a, 0x020a,
+ 0x020c, 0x020c,
+ 0x020e, 0x020e,
+ 0x0210, 0x0210,
+ 0x0212, 0x0212,
+ 0x0214, 0x0214,
+ 0x0216, 0x0216,
+ 0x0218, 0x0218,
+ 0x021a, 0x021a,
+ 0x021c, 0x021c,
+ 0x021e, 0x021e,
+ 0x0220, 0x0220,
+ 0x0222, 0x0222,
+ 0x0224, 0x0224,
+ 0x0226, 0x0226,
+ 0x0228, 0x0228,
+ 0x022a, 0x022a,
+ 0x022c, 0x022c,
+ 0x022e, 0x022e,
+ 0x0230, 0x0230,
+ 0x0232, 0x0232,
+ 0x023a, 0x023b,
+ 0x023d, 0x023e,
+ 0x0241, 0x0241,
+ 0x0386, 0x0386,
+ 0x0388, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x038f,
+ 0x0391, 0x03a1,
+ 0x03a3, 0x03ab,
+ 0x03d2, 0x03d4,
+ 0x03d8, 0x03d8,
+ 0x03da, 0x03da,
+ 0x03dc, 0x03dc,
+ 0x03de, 0x03de,
+ 0x03e0, 0x03e0,
+ 0x03e2, 0x03e2,
+ 0x03e4, 0x03e4,
+ 0x03e6, 0x03e6,
+ 0x03e8, 0x03e8,
+ 0x03ea, 0x03ea,
+ 0x03ec, 0x03ec,
+ 0x03ee, 0x03ee,
+ 0x03f4, 0x03f4,
+ 0x03f7, 0x03f7,
+ 0x03f9, 0x03fa,
+ 0x03fd, 0x042f,
+ 0x0460, 0x0460,
+ 0x0462, 0x0462,
+ 0x0464, 0x0464,
+ 0x0466, 0x0466,
+ 0x0468, 0x0468,
+ 0x046a, 0x046a,
+ 0x046c, 0x046c,
+ 0x046e, 0x046e,
+ 0x0470, 0x0470,
+ 0x0472, 0x0472,
+ 0x0474, 0x0474,
+ 0x0476, 0x0476,
+ 0x0478, 0x0478,
+ 0x047a, 0x047a,
+ 0x047c, 0x047c,
+ 0x047e, 0x047e,
+ 0x0480, 0x0480,
+ 0x048a, 0x048a,
+ 0x048c, 0x048c,
+ 0x048e, 0x048e,
+ 0x0490, 0x0490,
+ 0x0492, 0x0492,
+ 0x0494, 0x0494,
+ 0x0496, 0x0496,
+ 0x0498, 0x0498,
+ 0x049a, 0x049a,
+ 0x049c, 0x049c,
+ 0x049e, 0x049e,
+ 0x04a0, 0x04a0,
+ 0x04a2, 0x04a2,
+ 0x04a4, 0x04a4,
+ 0x04a6, 0x04a6,
+ 0x04a8, 0x04a8,
+ 0x04aa, 0x04aa,
+ 0x04ac, 0x04ac,
+ 0x04ae, 0x04ae,
+ 0x04b0, 0x04b0,
+ 0x04b2, 0x04b2,
+ 0x04b4, 0x04b4,
+ 0x04b6, 0x04b6,
+ 0x04b8, 0x04b8,
+ 0x04ba, 0x04ba,
+ 0x04bc, 0x04bc,
+ 0x04be, 0x04be,
+ 0x04c0, 0x04c1,
+ 0x04c3, 0x04c3,
+ 0x04c5, 0x04c5,
+ 0x04c7, 0x04c7,
+ 0x04c9, 0x04c9,
+ 0x04cb, 0x04cb,
+ 0x04cd, 0x04cd,
+ 0x04d0, 0x04d0,
+ 0x04d2, 0x04d2,
+ 0x04d4, 0x04d4,
+ 0x04d6, 0x04d6,
+ 0x04d8, 0x04d8,
+ 0x04da, 0x04da,
+ 0x04dc, 0x04dc,
+ 0x04de, 0x04de,
+ 0x04e0, 0x04e0,
+ 0x04e2, 0x04e2,
+ 0x04e4, 0x04e4,
+ 0x04e6, 0x04e6,
+ 0x04e8, 0x04e8,
+ 0x04ea, 0x04ea,
+ 0x04ec, 0x04ec,
+ 0x04ee, 0x04ee,
+ 0x04f0, 0x04f0,
+ 0x04f2, 0x04f2,
+ 0x04f4, 0x04f4,
+ 0x04f6, 0x04f6,
+ 0x04f8, 0x04f8,
+ 0x0500, 0x0500,
+ 0x0502, 0x0502,
+ 0x0504, 0x0504,
+ 0x0506, 0x0506,
+ 0x0508, 0x0508,
+ 0x050a, 0x050a,
+ 0x050c, 0x050c,
+ 0x050e, 0x050e,
+ 0x0531, 0x0556,
+ 0x10a0, 0x10c5,
+ 0x1e00, 0x1e00,
+ 0x1e02, 0x1e02,
+ 0x1e04, 0x1e04,
+ 0x1e06, 0x1e06,
+ 0x1e08, 0x1e08,
+ 0x1e0a, 0x1e0a,
+ 0x1e0c, 0x1e0c,
+ 0x1e0e, 0x1e0e,
+ 0x1e10, 0x1e10,
+ 0x1e12, 0x1e12,
+ 0x1e14, 0x1e14,
+ 0x1e16, 0x1e16,
+ 0x1e18, 0x1e18,
+ 0x1e1a, 0x1e1a,
+ 0x1e1c, 0x1e1c,
+ 0x1e1e, 0x1e1e,
+ 0x1e20, 0x1e20,
+ 0x1e22, 0x1e22,
+ 0x1e24, 0x1e24,
+ 0x1e26, 0x1e26,
+ 0x1e28, 0x1e28,
+ 0x1e2a, 0x1e2a,
+ 0x1e2c, 0x1e2c,
+ 0x1e2e, 0x1e2e,
+ 0x1e30, 0x1e30,
+ 0x1e32, 0x1e32,
+ 0x1e34, 0x1e34,
+ 0x1e36, 0x1e36,
+ 0x1e38, 0x1e38,
+ 0x1e3a, 0x1e3a,
+ 0x1e3c, 0x1e3c,
+ 0x1e3e, 0x1e3e,
+ 0x1e40, 0x1e40,
+ 0x1e42, 0x1e42,
+ 0x1e44, 0x1e44,
+ 0x1e46, 0x1e46,
+ 0x1e48, 0x1e48,
+ 0x1e4a, 0x1e4a,
+ 0x1e4c, 0x1e4c,
+ 0x1e4e, 0x1e4e,
+ 0x1e50, 0x1e50,
+ 0x1e52, 0x1e52,
+ 0x1e54, 0x1e54,
+ 0x1e56, 0x1e56,
+ 0x1e58, 0x1e58,
+ 0x1e5a, 0x1e5a,
+ 0x1e5c, 0x1e5c,
+ 0x1e5e, 0x1e5e,
+ 0x1e60, 0x1e60,
+ 0x1e62, 0x1e62,
+ 0x1e64, 0x1e64,
+ 0x1e66, 0x1e66,
+ 0x1e68, 0x1e68,
+ 0x1e6a, 0x1e6a,
+ 0x1e6c, 0x1e6c,
+ 0x1e6e, 0x1e6e,
+ 0x1e70, 0x1e70,
+ 0x1e72, 0x1e72,
+ 0x1e74, 0x1e74,
+ 0x1e76, 0x1e76,
+ 0x1e78, 0x1e78,
+ 0x1e7a, 0x1e7a,
+ 0x1e7c, 0x1e7c,
+ 0x1e7e, 0x1e7e,
+ 0x1e80, 0x1e80,
+ 0x1e82, 0x1e82,
+ 0x1e84, 0x1e84,
+ 0x1e86, 0x1e86,
+ 0x1e88, 0x1e88,
+ 0x1e8a, 0x1e8a,
+ 0x1e8c, 0x1e8c,
+ 0x1e8e, 0x1e8e,
+ 0x1e90, 0x1e90,
+ 0x1e92, 0x1e92,
+ 0x1e94, 0x1e94,
+ 0x1ea0, 0x1ea0,
+ 0x1ea2, 0x1ea2,
+ 0x1ea4, 0x1ea4,
+ 0x1ea6, 0x1ea6,
+ 0x1ea8, 0x1ea8,
+ 0x1eaa, 0x1eaa,
+ 0x1eac, 0x1eac,
+ 0x1eae, 0x1eae,
+ 0x1eb0, 0x1eb0,
+ 0x1eb2, 0x1eb2,
+ 0x1eb4, 0x1eb4,
+ 0x1eb6, 0x1eb6,
+ 0x1eb8, 0x1eb8,
+ 0x1eba, 0x1eba,
+ 0x1ebc, 0x1ebc,
+ 0x1ebe, 0x1ebe,
+ 0x1ec0, 0x1ec0,
+ 0x1ec2, 0x1ec2,
+ 0x1ec4, 0x1ec4,
+ 0x1ec6, 0x1ec6,
+ 0x1ec8, 0x1ec8,
+ 0x1eca, 0x1eca,
+ 0x1ecc, 0x1ecc,
+ 0x1ece, 0x1ece,
+ 0x1ed0, 0x1ed0,
+ 0x1ed2, 0x1ed2,
+ 0x1ed4, 0x1ed4,
+ 0x1ed6, 0x1ed6,
+ 0x1ed8, 0x1ed8,
+ 0x1eda, 0x1eda,
+ 0x1edc, 0x1edc,
+ 0x1ede, 0x1ede,
+ 0x1ee0, 0x1ee0,
+ 0x1ee2, 0x1ee2,
+ 0x1ee4, 0x1ee4,
+ 0x1ee6, 0x1ee6,
+ 0x1ee8, 0x1ee8,
+ 0x1eea, 0x1eea,
+ 0x1eec, 0x1eec,
+ 0x1eee, 0x1eee,
+ 0x1ef0, 0x1ef0,
+ 0x1ef2, 0x1ef2,
+ 0x1ef4, 0x1ef4,
+ 0x1ef6, 0x1ef6,
+ 0x1ef8, 0x1ef8,
+ 0x1f08, 0x1f0f,
+ 0x1f18, 0x1f1d,
+ 0x1f28, 0x1f2f,
+ 0x1f38, 0x1f3f,
+ 0x1f48, 0x1f4d,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f5f,
+ 0x1f68, 0x1f6f,
+ 0x1fb8, 0x1fbb,
+ 0x1fc8, 0x1fcb,
+ 0x1fd8, 0x1fdb,
+ 0x1fe8, 0x1fec,
+ 0x1ff8, 0x1ffb,
+ 0x2102, 0x2102,
+ 0x2107, 0x2107,
+ 0x210b, 0x210d,
+ 0x2110, 0x2112,
+ 0x2115, 0x2115,
+ 0x2119, 0x211d,
+ 0x2124, 0x2124,
+ 0x2126, 0x2126,
+ 0x2128, 0x2128,
+ 0x212a, 0x212d,
+ 0x2130, 0x2131,
+ 0x2133, 0x2133,
+ 0x213e, 0x213f,
+ 0x2145, 0x2145,
+ 0x2c00, 0x2c2e,
+ 0x2c80, 0x2c80,
+ 0x2c82, 0x2c82,
+ 0x2c84, 0x2c84,
+ 0x2c86, 0x2c86,
+ 0x2c88, 0x2c88,
+ 0x2c8a, 0x2c8a,
+ 0x2c8c, 0x2c8c,
+ 0x2c8e, 0x2c8e,
+ 0x2c90, 0x2c90,
+ 0x2c92, 0x2c92,
+ 0x2c94, 0x2c94,
+ 0x2c96, 0x2c96,
+ 0x2c98, 0x2c98,
+ 0x2c9a, 0x2c9a,
+ 0x2c9c, 0x2c9c,
+ 0x2c9e, 0x2c9e,
+ 0x2ca0, 0x2ca0,
+ 0x2ca2, 0x2ca2,
+ 0x2ca4, 0x2ca4,
+ 0x2ca6, 0x2ca6,
+ 0x2ca8, 0x2ca8,
+ 0x2caa, 0x2caa,
+ 0x2cac, 0x2cac,
+ 0x2cae, 0x2cae,
+ 0x2cb0, 0x2cb0,
+ 0x2cb2, 0x2cb2,
+ 0x2cb4, 0x2cb4,
+ 0x2cb6, 0x2cb6,
+ 0x2cb8, 0x2cb8,
+ 0x2cba, 0x2cba,
+ 0x2cbc, 0x2cbc,
+ 0x2cbe, 0x2cbe,
+ 0x2cc0, 0x2cc0,
+ 0x2cc2, 0x2cc2,
+ 0x2cc4, 0x2cc4,
+ 0x2cc6, 0x2cc6,
+ 0x2cc8, 0x2cc8,
+ 0x2cca, 0x2cca,
+ 0x2ccc, 0x2ccc,
+ 0x2cce, 0x2cce,
+ 0x2cd0, 0x2cd0,
+ 0x2cd2, 0x2cd2,
+ 0x2cd4, 0x2cd4,
+ 0x2cd6, 0x2cd6,
+ 0x2cd8, 0x2cd8,
+ 0x2cda, 0x2cda,
+ 0x2cdc, 0x2cdc,
+ 0x2cde, 0x2cde,
+ 0x2ce0, 0x2ce0,
+ 0x2ce2, 0x2ce2,
+ 0xff21, 0xff3a,
+ 0x10400, 0x10427,
+ 0x1d400, 0x1d419,
+ 0x1d434, 0x1d44d,
+ 0x1d468, 0x1d481,
+ 0x1d49c, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b5,
+ 0x1d4d0, 0x1d4e9,
+ 0x1d504, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d538, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d56c, 0x1d585,
+ 0x1d5a0, 0x1d5b9,
+ 0x1d5d4, 0x1d5ed,
+ 0x1d608, 0x1d621,
+ 0x1d63c, 0x1d655,
+ 0x1d670, 0x1d689,
+ 0x1d6a8, 0x1d6c0,
+ 0x1d6e2, 0x1d6fa,
+ 0x1d71c, 0x1d734,
+ 0x1d756, 0x1d76e,
+ 0x1d790, 0x1d7a8
+}; /* CR_Lu */
+
+/* 'M': Major Category */
+static const OnigCodePoint CR_M[] = {
+ 133,
+ 0x0300, 0x036f,
+ 0x0483, 0x0486,
+ 0x0488, 0x0489,
+ 0x0591, 0x05b9,
+ 0x05bb, 0x05bd,
+ 0x05bf, 0x05bf,
+ 0x05c1, 0x05c2,
+ 0x05c4, 0x05c5,
+ 0x05c7, 0x05c7,
+ 0x0610, 0x0615,
+ 0x064b, 0x065e,
+ 0x0670, 0x0670,
+ 0x06d6, 0x06dc,
+ 0x06de, 0x06e4,
+ 0x06e7, 0x06e8,
+ 0x06ea, 0x06ed,
+ 0x0711, 0x0711,
+ 0x0730, 0x074a,
+ 0x07a6, 0x07b0,
+ 0x0901, 0x0903,
+ 0x093c, 0x093c,
+ 0x093e, 0x094d,
+ 0x0951, 0x0954,
+ 0x0962, 0x0963,
+ 0x0981, 0x0983,
+ 0x09bc, 0x09bc,
+ 0x09be, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09cd,
+ 0x09d7, 0x09d7,
+ 0x09e2, 0x09e3,
+ 0x0a01, 0x0a03,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a70, 0x0a71,
+ 0x0a81, 0x0a83,
+ 0x0abc, 0x0abc,
+ 0x0abe, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ae2, 0x0ae3,
+ 0x0b01, 0x0b03,
+ 0x0b3c, 0x0b3c,
+ 0x0b3e, 0x0b43,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b82, 0x0b82,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd7, 0x0bd7,
+ 0x0c01, 0x0c03,
+ 0x0c3e, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c82, 0x0c83,
+ 0x0cbc, 0x0cbc,
+ 0x0cbe, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0d02, 0x0d03,
+ 0x0d3e, 0x0d43,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4d,
+ 0x0d57, 0x0d57,
+ 0x0d82, 0x0d83,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0df2, 0x0df3,
+ 0x0e31, 0x0e31,
+ 0x0e34, 0x0e3a,
+ 0x0e47, 0x0e4e,
+ 0x0eb1, 0x0eb1,
+ 0x0eb4, 0x0eb9,
+ 0x0ebb, 0x0ebc,
+ 0x0ec8, 0x0ecd,
+ 0x0f18, 0x0f19,
+ 0x0f35, 0x0f35,
+ 0x0f37, 0x0f37,
+ 0x0f39, 0x0f39,
+ 0x0f3e, 0x0f3f,
+ 0x0f71, 0x0f84,
+ 0x0f86, 0x0f87,
+ 0x0f90, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fc6, 0x0fc6,
+ 0x102c, 0x1032,
+ 0x1036, 0x1039,
+ 0x1056, 0x1059,
+ 0x135f, 0x135f,
+ 0x1712, 0x1714,
+ 0x1732, 0x1734,
+ 0x1752, 0x1753,
+ 0x1772, 0x1773,
+ 0x17b6, 0x17d3,
+ 0x17dd, 0x17dd,
+ 0x180b, 0x180d,
+ 0x18a9, 0x18a9,
+ 0x1920, 0x192b,
+ 0x1930, 0x193b,
+ 0x19b0, 0x19c0,
+ 0x19c8, 0x19c9,
+ 0x1a17, 0x1a1b,
+ 0x1dc0, 0x1dc3,
+ 0x20d0, 0x20eb,
+ 0x302a, 0x302f,
+ 0x3099, 0x309a,
+ 0xa802, 0xa802,
+ 0xa806, 0xa806,
+ 0xa80b, 0xa80b,
+ 0xa823, 0xa827,
+ 0xfb1e, 0xfb1e,
+ 0xfe00, 0xfe0f,
+ 0xfe20, 0xfe23,
+ 0x10a01, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a0f,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a3f,
+ 0x1d165, 0x1d169,
+ 0x1d16d, 0x1d172,
+ 0x1d17b, 0x1d182,
+ 0x1d185, 0x1d18b,
+ 0x1d1aa, 0x1d1ad,
+ 0x1d242, 0x1d244,
+ 0xe0100, 0xe01ef
+}; /* CR_M */
+
+/* 'Mc': General Category */
+static const OnigCodePoint CR_Mc[] = {
+ 63,
+ 0x0903, 0x0903,
+ 0x093e, 0x0940,
+ 0x0949, 0x094c,
+ 0x0982, 0x0983,
+ 0x09be, 0x09c0,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09cc,
+ 0x09d7, 0x09d7,
+ 0x0a03, 0x0a03,
+ 0x0a3e, 0x0a40,
+ 0x0a83, 0x0a83,
+ 0x0abe, 0x0ac0,
+ 0x0ac9, 0x0ac9,
+ 0x0acb, 0x0acc,
+ 0x0b02, 0x0b03,
+ 0x0b3e, 0x0b3e,
+ 0x0b40, 0x0b40,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4c,
+ 0x0b57, 0x0b57,
+ 0x0bbe, 0x0bbf,
+ 0x0bc1, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcc,
+ 0x0bd7, 0x0bd7,
+ 0x0c01, 0x0c03,
+ 0x0c41, 0x0c44,
+ 0x0c82, 0x0c83,
+ 0x0cbe, 0x0cbe,
+ 0x0cc0, 0x0cc4,
+ 0x0cc7, 0x0cc8,
+ 0x0cca, 0x0ccb,
+ 0x0cd5, 0x0cd6,
+ 0x0d02, 0x0d03,
+ 0x0d3e, 0x0d40,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4c,
+ 0x0d57, 0x0d57,
+ 0x0d82, 0x0d83,
+ 0x0dcf, 0x0dd1,
+ 0x0dd8, 0x0ddf,
+ 0x0df2, 0x0df3,
+ 0x0f3e, 0x0f3f,
+ 0x0f7f, 0x0f7f,
+ 0x102c, 0x102c,
+ 0x1031, 0x1031,
+ 0x1038, 0x1038,
+ 0x1056, 0x1057,
+ 0x17b6, 0x17b6,
+ 0x17be, 0x17c5,
+ 0x17c7, 0x17c8,
+ 0x1923, 0x1926,
+ 0x1929, 0x192b,
+ 0x1930, 0x1931,
+ 0x1933, 0x1938,
+ 0x19b0, 0x19c0,
+ 0x19c8, 0x19c9,
+ 0x1a19, 0x1a1b,
+ 0xa802, 0xa802,
+ 0xa823, 0xa824,
+ 0xa827, 0xa827,
+ 0x1d165, 0x1d166,
+ 0x1d16d, 0x1d172
+}; /* CR_Mc */
+
+/* 'Me': General Category */
+static const OnigCodePoint CR_Me[] = {
+ 4,
+ 0x0488, 0x0489,
+ 0x06de, 0x06de,
+ 0x20dd, 0x20e0,
+ 0x20e2, 0x20e4
+}; /* CR_Me */
+
+/* 'Mn': General Category */
+static const OnigCodePoint CR_Mn[] = {
+ 124,
+ 0x0300, 0x036f,
+ 0x0483, 0x0486,
+ 0x0591, 0x05b9,
+ 0x05bb, 0x05bd,
+ 0x05bf, 0x05bf,
+ 0x05c1, 0x05c2,
+ 0x05c4, 0x05c5,
+ 0x05c7, 0x05c7,
+ 0x0610, 0x0615,
+ 0x064b, 0x065e,
+ 0x0670, 0x0670,
+ 0x06d6, 0x06dc,
+ 0x06df, 0x06e4,
+ 0x06e7, 0x06e8,
+ 0x06ea, 0x06ed,
+ 0x0711, 0x0711,
+ 0x0730, 0x074a,
+ 0x07a6, 0x07b0,
+ 0x0901, 0x0902,
+ 0x093c, 0x093c,
+ 0x0941, 0x0948,
+ 0x094d, 0x094d,
+ 0x0951, 0x0954,
+ 0x0962, 0x0963,
+ 0x0981, 0x0981,
+ 0x09bc, 0x09bc,
+ 0x09c1, 0x09c4,
+ 0x09cd, 0x09cd,
+ 0x09e2, 0x09e3,
+ 0x0a01, 0x0a02,
+ 0x0a3c, 0x0a3c,
+ 0x0a41, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a70, 0x0a71,
+ 0x0a81, 0x0a82,
+ 0x0abc, 0x0abc,
+ 0x0ac1, 0x0ac5,
+ 0x0ac7, 0x0ac8,
+ 0x0acd, 0x0acd,
+ 0x0ae2, 0x0ae3,
+ 0x0b01, 0x0b01,
+ 0x0b3c, 0x0b3c,
+ 0x0b3f, 0x0b3f,
+ 0x0b41, 0x0b43,
+ 0x0b4d, 0x0b4d,
+ 0x0b56, 0x0b56,
+ 0x0b82, 0x0b82,
+ 0x0bc0, 0x0bc0,
+ 0x0bcd, 0x0bcd,
+ 0x0c3e, 0x0c40,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0cbc, 0x0cbc,
+ 0x0cbf, 0x0cbf,
+ 0x0cc6, 0x0cc6,
+ 0x0ccc, 0x0ccd,
+ 0x0d41, 0x0d43,
+ 0x0d4d, 0x0d4d,
+ 0x0dca, 0x0dca,
+ 0x0dd2, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0e31, 0x0e31,
+ 0x0e34, 0x0e3a,
+ 0x0e47, 0x0e4e,
+ 0x0eb1, 0x0eb1,
+ 0x0eb4, 0x0eb9,
+ 0x0ebb, 0x0ebc,
+ 0x0ec8, 0x0ecd,
+ 0x0f18, 0x0f19,
+ 0x0f35, 0x0f35,
+ 0x0f37, 0x0f37,
+ 0x0f39, 0x0f39,
+ 0x0f71, 0x0f7e,
+ 0x0f80, 0x0f84,
+ 0x0f86, 0x0f87,
+ 0x0f90, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fc6, 0x0fc6,
+ 0x102d, 0x1030,
+ 0x1032, 0x1032,
+ 0x1036, 0x1037,
+ 0x1039, 0x1039,
+ 0x1058, 0x1059,
+ 0x135f, 0x135f,
+ 0x1712, 0x1714,
+ 0x1732, 0x1734,
+ 0x1752, 0x1753,
+ 0x1772, 0x1773,
+ 0x17b7, 0x17bd,
+ 0x17c6, 0x17c6,
+ 0x17c9, 0x17d3,
+ 0x17dd, 0x17dd,
+ 0x180b, 0x180d,
+ 0x18a9, 0x18a9,
+ 0x1920, 0x1922,
+ 0x1927, 0x1928,
+ 0x1932, 0x1932,
+ 0x1939, 0x193b,
+ 0x1a17, 0x1a18,
+ 0x1dc0, 0x1dc3,
+ 0x20d0, 0x20dc,
+ 0x20e1, 0x20e1,
+ 0x20e5, 0x20eb,
+ 0x302a, 0x302f,
+ 0x3099, 0x309a,
+ 0xa806, 0xa806,
+ 0xa80b, 0xa80b,
+ 0xa825, 0xa826,
+ 0xfb1e, 0xfb1e,
+ 0xfe00, 0xfe0f,
+ 0xfe20, 0xfe23,
+ 0x10a01, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a0f,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a3f,
+ 0x1d167, 0x1d169,
+ 0x1d17b, 0x1d182,
+ 0x1d185, 0x1d18b,
+ 0x1d1aa, 0x1d1ad,
+ 0x1d242, 0x1d244,
+ 0xe0100, 0xe01ef
+}; /* CR_Mn */
+
+/* 'N': Major Category */
+static const OnigCodePoint CR_N[] = {
+ 53,
+ 0x0030, 0x0039,
+ 0x00b2, 0x00b3,
+ 0x00b9, 0x00b9,
+ 0x00bc, 0x00be,
+ 0x0660, 0x0669,
+ 0x06f0, 0x06f9,
+ 0x0966, 0x096f,
+ 0x09e6, 0x09ef,
+ 0x09f4, 0x09f9,
+ 0x0a66, 0x0a6f,
+ 0x0ae6, 0x0aef,
+ 0x0b66, 0x0b6f,
+ 0x0be6, 0x0bf2,
+ 0x0c66, 0x0c6f,
+ 0x0ce6, 0x0cef,
+ 0x0d66, 0x0d6f,
+ 0x0e50, 0x0e59,
+ 0x0ed0, 0x0ed9,
+ 0x0f20, 0x0f33,
+ 0x1040, 0x1049,
+ 0x1369, 0x137c,
+ 0x16ee, 0x16f0,
+ 0x17e0, 0x17e9,
+ 0x17f0, 0x17f9,
+ 0x1810, 0x1819,
+ 0x1946, 0x194f,
+ 0x19d0, 0x19d9,
+ 0x2070, 0x2070,
+ 0x2074, 0x2079,
+ 0x2080, 0x2089,
+ 0x2153, 0x2183,
+ 0x2460, 0x249b,
+ 0x24ea, 0x24ff,
+ 0x2776, 0x2793,
+ 0x2cfd, 0x2cfd,
+ 0x3007, 0x3007,
+ 0x3021, 0x3029,
+ 0x3038, 0x303a,
+ 0x3192, 0x3195,
+ 0x3220, 0x3229,
+ 0x3251, 0x325f,
+ 0x3280, 0x3289,
+ 0x32b1, 0x32bf,
+ 0xff10, 0xff19,
+ 0x10107, 0x10133,
+ 0x10140, 0x10178,
+ 0x1018a, 0x1018a,
+ 0x10320, 0x10323,
+ 0x1034a, 0x1034a,
+ 0x103d1, 0x103d5,
+ 0x104a0, 0x104a9,
+ 0x10a40, 0x10a47,
+ 0x1d7ce, 0x1d7ff
+}; /* CR_N */
+
+/* 'Nd': General Category */
+static const OnigCodePoint CR_Nd[] = {
+ 23,
+ 0x0030, 0x0039,
+ 0x0660, 0x0669,
+ 0x06f0, 0x06f9,
+ 0x0966, 0x096f,
+ 0x09e6, 0x09ef,
+ 0x0a66, 0x0a6f,
+ 0x0ae6, 0x0aef,
+ 0x0b66, 0x0b6f,
+ 0x0be6, 0x0bef,
+ 0x0c66, 0x0c6f,
+ 0x0ce6, 0x0cef,
+ 0x0d66, 0x0d6f,
+ 0x0e50, 0x0e59,
+ 0x0ed0, 0x0ed9,
+ 0x0f20, 0x0f29,
+ 0x1040, 0x1049,
+ 0x17e0, 0x17e9,
+ 0x1810, 0x1819,
+ 0x1946, 0x194f,
+ 0x19d0, 0x19d9,
+ 0xff10, 0xff19,
+ 0x104a0, 0x104a9,
+ 0x1d7ce, 0x1d7ff
+}; /* CR_Nd */
+
+/* 'Nl': General Category */
+static const OnigCodePoint CR_Nl[] = {
+ 8,
+ 0x16ee, 0x16f0,
+ 0x2160, 0x2183,
+ 0x3007, 0x3007,
+ 0x3021, 0x3029,
+ 0x3038, 0x303a,
+ 0x10140, 0x10174,
+ 0x1034a, 0x1034a,
+ 0x103d1, 0x103d5
+}; /* CR_Nl */
+
+/* 'No': General Category */
+static const OnigCodePoint CR_No[] = {
+ 26,
+ 0x00b2, 0x00b3,
+ 0x00b9, 0x00b9,
+ 0x00bc, 0x00be,
+ 0x09f4, 0x09f9,
+ 0x0bf0, 0x0bf2,
+ 0x0f2a, 0x0f33,
+ 0x1369, 0x137c,
+ 0x17f0, 0x17f9,
+ 0x2070, 0x2070,
+ 0x2074, 0x2079,
+ 0x2080, 0x2089,
+ 0x2153, 0x215f,
+ 0x2460, 0x249b,
+ 0x24ea, 0x24ff,
+ 0x2776, 0x2793,
+ 0x2cfd, 0x2cfd,
+ 0x3192, 0x3195,
+ 0x3220, 0x3229,
+ 0x3251, 0x325f,
+ 0x3280, 0x3289,
+ 0x32b1, 0x32bf,
+ 0x10107, 0x10133,
+ 0x10175, 0x10178,
+ 0x1018a, 0x1018a,
+ 0x10320, 0x10323,
+ 0x10a40, 0x10a47
+}; /* CR_No */
+
+/* 'P': Major Category */
+static const OnigCodePoint CR_P[] = {
+ 96,
+ 0x0021, 0x0023,
+ 0x0025, 0x002a,
+ 0x002c, 0x002f,
+ 0x003a, 0x003b,
+ 0x003f, 0x0040,
+ 0x005b, 0x005d,
+ 0x005f, 0x005f,
+ 0x007b, 0x007b,
+ 0x007d, 0x007d,
+ 0x00a1, 0x00a1,
+ 0x00ab, 0x00ab,
+ 0x00b7, 0x00b7,
+ 0x00bb, 0x00bb,
+ 0x00bf, 0x00bf,
+ 0x037e, 0x037e,
+ 0x0387, 0x0387,
+ 0x055a, 0x055f,
+ 0x0589, 0x058a,
+ 0x05be, 0x05be,
+ 0x05c0, 0x05c0,
+ 0x05c3, 0x05c3,
+ 0x05c6, 0x05c6,
+ 0x05f3, 0x05f4,
+ 0x060c, 0x060d,
+ 0x061b, 0x061b,
+ 0x061e, 0x061f,
+ 0x066a, 0x066d,
+ 0x06d4, 0x06d4,
+ 0x0700, 0x070d,
+ 0x0964, 0x0965,
+ 0x0970, 0x0970,
+ 0x0df4, 0x0df4,
+ 0x0e4f, 0x0e4f,
+ 0x0e5a, 0x0e5b,
+ 0x0f04, 0x0f12,
+ 0x0f3a, 0x0f3d,
+ 0x0f85, 0x0f85,
+ 0x0fd0, 0x0fd1,
+ 0x104a, 0x104f,
+ 0x10fb, 0x10fb,
+ 0x1361, 0x1368,
+ 0x166d, 0x166e,
+ 0x169b, 0x169c,
+ 0x16eb, 0x16ed,
+ 0x1735, 0x1736,
+ 0x17d4, 0x17d6,
+ 0x17d8, 0x17da,
+ 0x1800, 0x180a,
+ 0x1944, 0x1945,
+ 0x19de, 0x19df,
+ 0x1a1e, 0x1a1f,
+ 0x2010, 0x2027,
+ 0x2030, 0x2043,
+ 0x2045, 0x2051,
+ 0x2053, 0x205e,
+ 0x207d, 0x207e,
+ 0x208d, 0x208e,
+ 0x2329, 0x232a,
+ 0x23b4, 0x23b6,
+ 0x2768, 0x2775,
+ 0x27c5, 0x27c6,
+ 0x27e6, 0x27eb,
+ 0x2983, 0x2998,
+ 0x29d8, 0x29db,
+ 0x29fc, 0x29fd,
+ 0x2cf9, 0x2cfc,
+ 0x2cfe, 0x2cff,
+ 0x2e00, 0x2e17,
+ 0x2e1c, 0x2e1d,
+ 0x3001, 0x3003,
+ 0x3008, 0x3011,
+ 0x3014, 0x301f,
+ 0x3030, 0x3030,
+ 0x303d, 0x303d,
+ 0x30a0, 0x30a0,
+ 0x30fb, 0x30fb,
+ 0xfd3e, 0xfd3f,
+ 0xfe10, 0xfe19,
+ 0xfe30, 0xfe52,
+ 0xfe54, 0xfe61,
+ 0xfe63, 0xfe63,
+ 0xfe68, 0xfe68,
+ 0xfe6a, 0xfe6b,
+ 0xff01, 0xff03,
+ 0xff05, 0xff0a,
+ 0xff0c, 0xff0f,
+ 0xff1a, 0xff1b,
+ 0xff1f, 0xff20,
+ 0xff3b, 0xff3d,
+ 0xff3f, 0xff3f,
+ 0xff5b, 0xff5b,
+ 0xff5d, 0xff5d,
+ 0xff5f, 0xff65,
+ 0x10100, 0x10101,
+ 0x1039f, 0x1039f,
+ 0x10a50, 0x10a58
+}; /* CR_P */
+
+/* 'Pc': General Category */
+static const OnigCodePoint CR_Pc[] = {
+ 6,
+ 0x005f, 0x005f,
+ 0x203f, 0x2040,
+ 0x2054, 0x2054,
+ 0xfe33, 0xfe34,
+ 0xfe4d, 0xfe4f,
+ 0xff3f, 0xff3f
+}; /* CR_Pc */
+
+/* 'Pd': General Category */
+static const OnigCodePoint CR_Pd[] = {
+ 12,
+ 0x002d, 0x002d,
+ 0x058a, 0x058a,
+ 0x1806, 0x1806,
+ 0x2010, 0x2015,
+ 0x2e17, 0x2e17,
+ 0x301c, 0x301c,
+ 0x3030, 0x3030,
+ 0x30a0, 0x30a0,
+ 0xfe31, 0xfe32,
+ 0xfe58, 0xfe58,
+ 0xfe63, 0xfe63,
+ 0xff0d, 0xff0d
+}; /* CR_Pd */
+
+/* 'Pe': General Category */
+static const OnigCodePoint CR_Pe[] = {
+ 65,
+ 0x0029, 0x0029,
+ 0x005d, 0x005d,
+ 0x007d, 0x007d,
+ 0x0f3b, 0x0f3b,
+ 0x0f3d, 0x0f3d,
+ 0x169c, 0x169c,
+ 0x2046, 0x2046,
+ 0x207e, 0x207e,
+ 0x208e, 0x208e,
+ 0x232a, 0x232a,
+ 0x23b5, 0x23b5,
+ 0x2769, 0x2769,
+ 0x276b, 0x276b,
+ 0x276d, 0x276d,
+ 0x276f, 0x276f,
+ 0x2771, 0x2771,
+ 0x2773, 0x2773,
+ 0x2775, 0x2775,
+ 0x27c6, 0x27c6,
+ 0x27e7, 0x27e7,
+ 0x27e9, 0x27e9,
+ 0x27eb, 0x27eb,
+ 0x2984, 0x2984,
+ 0x2986, 0x2986,
+ 0x2988, 0x2988,
+ 0x298a, 0x298a,
+ 0x298c, 0x298c,
+ 0x298e, 0x298e,
+ 0x2990, 0x2990,
+ 0x2992, 0x2992,
+ 0x2994, 0x2994,
+ 0x2996, 0x2996,
+ 0x2998, 0x2998,
+ 0x29d9, 0x29d9,
+ 0x29db, 0x29db,
+ 0x29fd, 0x29fd,
+ 0x3009, 0x3009,
+ 0x300b, 0x300b,
+ 0x300d, 0x300d,
+ 0x300f, 0x300f,
+ 0x3011, 0x3011,
+ 0x3015, 0x3015,
+ 0x3017, 0x3017,
+ 0x3019, 0x3019,
+ 0x301b, 0x301b,
+ 0x301e, 0x301f,
+ 0xfd3f, 0xfd3f,
+ 0xfe18, 0xfe18,
+ 0xfe36, 0xfe36,
+ 0xfe38, 0xfe38,
+ 0xfe3a, 0xfe3a,
+ 0xfe3c, 0xfe3c,
+ 0xfe3e, 0xfe3e,
+ 0xfe40, 0xfe40,
+ 0xfe42, 0xfe42,
+ 0xfe44, 0xfe44,
+ 0xfe48, 0xfe48,
+ 0xfe5a, 0xfe5a,
+ 0xfe5c, 0xfe5c,
+ 0xfe5e, 0xfe5e,
+ 0xff09, 0xff09,
+ 0xff3d, 0xff3d,
+ 0xff5d, 0xff5d,
+ 0xff60, 0xff60,
+ 0xff63, 0xff63
+}; /* CR_Pe */
+
+/* 'Pf': General Category */
+static const OnigCodePoint CR_Pf[] = {
+ 9,
+ 0x00bb, 0x00bb,
+ 0x2019, 0x2019,
+ 0x201d, 0x201d,
+ 0x203a, 0x203a,
+ 0x2e03, 0x2e03,
+ 0x2e05, 0x2e05,
+ 0x2e0a, 0x2e0a,
+ 0x2e0d, 0x2e0d,
+ 0x2e1d, 0x2e1d
+}; /* CR_Pf */
+
+/* 'Pi': General Category */
+static const OnigCodePoint CR_Pi[] = {
+ 10,
+ 0x00ab, 0x00ab,
+ 0x2018, 0x2018,
+ 0x201b, 0x201c,
+ 0x201f, 0x201f,
+ 0x2039, 0x2039,
+ 0x2e02, 0x2e02,
+ 0x2e04, 0x2e04,
+ 0x2e09, 0x2e09,
+ 0x2e0c, 0x2e0c,
+ 0x2e1c, 0x2e1c
+}; /* CR_Pi */
+
+/* 'Po': General Category */
+static const OnigCodePoint CR_Po[] = {
+ 88,
+ 0x0021, 0x0023,
+ 0x0025, 0x0027,
+ 0x002a, 0x002a,
+ 0x002c, 0x002c,
+ 0x002e, 0x002f,
+ 0x003a, 0x003b,
+ 0x003f, 0x0040,
+ 0x005c, 0x005c,
+ 0x00a1, 0x00a1,
+ 0x00b7, 0x00b7,
+ 0x00bf, 0x00bf,
+ 0x037e, 0x037e,
+ 0x0387, 0x0387,
+ 0x055a, 0x055f,
+ 0x0589, 0x0589,
+ 0x05be, 0x05be,
+ 0x05c0, 0x05c0,
+ 0x05c3, 0x05c3,
+ 0x05c6, 0x05c6,
+ 0x05f3, 0x05f4,
+ 0x060c, 0x060d,
+ 0x061b, 0x061b,
+ 0x061e, 0x061f,
+ 0x066a, 0x066d,
+ 0x06d4, 0x06d4,
+ 0x0700, 0x070d,
+ 0x0964, 0x0965,
+ 0x0970, 0x0970,
+ 0x0df4, 0x0df4,
+ 0x0e4f, 0x0e4f,
+ 0x0e5a, 0x0e5b,
+ 0x0f04, 0x0f12,
+ 0x0f85, 0x0f85,
+ 0x0fd0, 0x0fd1,
+ 0x104a, 0x104f,
+ 0x10fb, 0x10fb,
+ 0x1361, 0x1368,
+ 0x166d, 0x166e,
+ 0x16eb, 0x16ed,
+ 0x1735, 0x1736,
+ 0x17d4, 0x17d6,
+ 0x17d8, 0x17da,
+ 0x1800, 0x1805,
+ 0x1807, 0x180a,
+ 0x1944, 0x1945,
+ 0x19de, 0x19df,
+ 0x1a1e, 0x1a1f,
+ 0x2016, 0x2017,
+ 0x2020, 0x2027,
+ 0x2030, 0x2038,
+ 0x203b, 0x203e,
+ 0x2041, 0x2043,
+ 0x2047, 0x2051,
+ 0x2053, 0x2053,
+ 0x2055, 0x205e,
+ 0x23b6, 0x23b6,
+ 0x2cf9, 0x2cfc,
+ 0x2cfe, 0x2cff,
+ 0x2e00, 0x2e01,
+ 0x2e06, 0x2e08,
+ 0x2e0b, 0x2e0b,
+ 0x2e0e, 0x2e16,
+ 0x3001, 0x3003,
+ 0x303d, 0x303d,
+ 0x30fb, 0x30fb,
+ 0xfe10, 0xfe16,
+ 0xfe19, 0xfe19,
+ 0xfe30, 0xfe30,
+ 0xfe45, 0xfe46,
+ 0xfe49, 0xfe4c,
+ 0xfe50, 0xfe52,
+ 0xfe54, 0xfe57,
+ 0xfe5f, 0xfe61,
+ 0xfe68, 0xfe68,
+ 0xfe6a, 0xfe6b,
+ 0xff01, 0xff03,
+ 0xff05, 0xff07,
+ 0xff0a, 0xff0a,
+ 0xff0c, 0xff0c,
+ 0xff0e, 0xff0f,
+ 0xff1a, 0xff1b,
+ 0xff1f, 0xff20,
+ 0xff3c, 0xff3c,
+ 0xff61, 0xff61,
+ 0xff64, 0xff65,
+ 0x10100, 0x10101,
+ 0x1039f, 0x1039f,
+ 0x10a50, 0x10a58
+}; /* CR_Po */
+
+/* 'Ps': General Category */
+static const OnigCodePoint CR_Ps[] = {
+ 67,
+ 0x0028, 0x0028,
+ 0x005b, 0x005b,
+ 0x007b, 0x007b,
+ 0x0f3a, 0x0f3a,
+ 0x0f3c, 0x0f3c,
+ 0x169b, 0x169b,
+ 0x201a, 0x201a,
+ 0x201e, 0x201e,
+ 0x2045, 0x2045,
+ 0x207d, 0x207d,
+ 0x208d, 0x208d,
+ 0x2329, 0x2329,
+ 0x23b4, 0x23b4,
+ 0x2768, 0x2768,
+ 0x276a, 0x276a,
+ 0x276c, 0x276c,
+ 0x276e, 0x276e,
+ 0x2770, 0x2770,
+ 0x2772, 0x2772,
+ 0x2774, 0x2774,
+ 0x27c5, 0x27c5,
+ 0x27e6, 0x27e6,
+ 0x27e8, 0x27e8,
+ 0x27ea, 0x27ea,
+ 0x2983, 0x2983,
+ 0x2985, 0x2985,
+ 0x2987, 0x2987,
+ 0x2989, 0x2989,
+ 0x298b, 0x298b,
+ 0x298d, 0x298d,
+ 0x298f, 0x298f,
+ 0x2991, 0x2991,
+ 0x2993, 0x2993,
+ 0x2995, 0x2995,
+ 0x2997, 0x2997,
+ 0x29d8, 0x29d8,
+ 0x29da, 0x29da,
+ 0x29fc, 0x29fc,
+ 0x3008, 0x3008,
+ 0x300a, 0x300a,
+ 0x300c, 0x300c,
+ 0x300e, 0x300e,
+ 0x3010, 0x3010,
+ 0x3014, 0x3014,
+ 0x3016, 0x3016,
+ 0x3018, 0x3018,
+ 0x301a, 0x301a,
+ 0x301d, 0x301d,
+ 0xfd3e, 0xfd3e,
+ 0xfe17, 0xfe17,
+ 0xfe35, 0xfe35,
+ 0xfe37, 0xfe37,
+ 0xfe39, 0xfe39,
+ 0xfe3b, 0xfe3b,
+ 0xfe3d, 0xfe3d,
+ 0xfe3f, 0xfe3f,
+ 0xfe41, 0xfe41,
+ 0xfe43, 0xfe43,
+ 0xfe47, 0xfe47,
+ 0xfe59, 0xfe59,
+ 0xfe5b, 0xfe5b,
+ 0xfe5d, 0xfe5d,
+ 0xff08, 0xff08,
+ 0xff3b, 0xff3b,
+ 0xff5b, 0xff5b,
+ 0xff5f, 0xff5f,
+ 0xff62, 0xff62
+}; /* CR_Ps */
+
+/* 'S': Major Category */
+static const OnigCodePoint CR_S[] = {
+ 162,
+ 0x0024, 0x0024,
+ 0x002b, 0x002b,
+ 0x003c, 0x003e,
+ 0x005e, 0x005e,
+ 0x0060, 0x0060,
+ 0x007c, 0x007c,
+ 0x007e, 0x007e,
+ 0x00a2, 0x00a9,
+ 0x00ac, 0x00ac,
+ 0x00ae, 0x00b1,
+ 0x00b4, 0x00b4,
+ 0x00b6, 0x00b6,
+ 0x00b8, 0x00b8,
+ 0x00d7, 0x00d7,
+ 0x00f7, 0x00f7,
+ 0x02c2, 0x02c5,
+ 0x02d2, 0x02df,
+ 0x02e5, 0x02ed,
+ 0x02ef, 0x02ff,
+ 0x0374, 0x0375,
+ 0x0384, 0x0385,
+ 0x03f6, 0x03f6,
+ 0x0482, 0x0482,
+ 0x060b, 0x060b,
+ 0x060e, 0x060f,
+ 0x06e9, 0x06e9,
+ 0x06fd, 0x06fe,
+ 0x09f2, 0x09f3,
+ 0x09fa, 0x09fa,
+ 0x0af1, 0x0af1,
+ 0x0b70, 0x0b70,
+ 0x0bf3, 0x0bfa,
+ 0x0e3f, 0x0e3f,
+ 0x0f01, 0x0f03,
+ 0x0f13, 0x0f17,
+ 0x0f1a, 0x0f1f,
+ 0x0f34, 0x0f34,
+ 0x0f36, 0x0f36,
+ 0x0f38, 0x0f38,
+ 0x0fbe, 0x0fc5,
+ 0x0fc7, 0x0fcc,
+ 0x0fcf, 0x0fcf,
+ 0x1360, 0x1360,
+ 0x1390, 0x1399,
+ 0x17db, 0x17db,
+ 0x1940, 0x1940,
+ 0x19e0, 0x19ff,
+ 0x1fbd, 0x1fbd,
+ 0x1fbf, 0x1fc1,
+ 0x1fcd, 0x1fcf,
+ 0x1fdd, 0x1fdf,
+ 0x1fed, 0x1fef,
+ 0x1ffd, 0x1ffe,
+ 0x2044, 0x2044,
+ 0x2052, 0x2052,
+ 0x207a, 0x207c,
+ 0x208a, 0x208c,
+ 0x20a0, 0x20b5,
+ 0x2100, 0x2101,
+ 0x2103, 0x2106,
+ 0x2108, 0x2109,
+ 0x2114, 0x2114,
+ 0x2116, 0x2118,
+ 0x211e, 0x2123,
+ 0x2125, 0x2125,
+ 0x2127, 0x2127,
+ 0x2129, 0x2129,
+ 0x212e, 0x212e,
+ 0x2132, 0x2132,
+ 0x213a, 0x213b,
+ 0x2140, 0x2144,
+ 0x214a, 0x214c,
+ 0x2190, 0x2328,
+ 0x232b, 0x23b3,
+ 0x23b7, 0x23db,
+ 0x2400, 0x2426,
+ 0x2440, 0x244a,
+ 0x249c, 0x24e9,
+ 0x2500, 0x269c,
+ 0x26a0, 0x26b1,
+ 0x2701, 0x2704,
+ 0x2706, 0x2709,
+ 0x270c, 0x2727,
+ 0x2729, 0x274b,
+ 0x274d, 0x274d,
+ 0x274f, 0x2752,
+ 0x2756, 0x2756,
+ 0x2758, 0x275e,
+ 0x2761, 0x2767,
+ 0x2794, 0x2794,
+ 0x2798, 0x27af,
+ 0x27b1, 0x27be,
+ 0x27c0, 0x27c4,
+ 0x27d0, 0x27e5,
+ 0x27f0, 0x2982,
+ 0x2999, 0x29d7,
+ 0x29dc, 0x29fb,
+ 0x29fe, 0x2b13,
+ 0x2ce5, 0x2cea,
+ 0x2e80, 0x2e99,
+ 0x2e9b, 0x2ef3,
+ 0x2f00, 0x2fd5,
+ 0x2ff0, 0x2ffb,
+ 0x3004, 0x3004,
+ 0x3012, 0x3013,
+ 0x3020, 0x3020,
+ 0x3036, 0x3037,
+ 0x303e, 0x303f,
+ 0x309b, 0x309c,
+ 0x3190, 0x3191,
+ 0x3196, 0x319f,
+ 0x31c0, 0x31cf,
+ 0x3200, 0x321e,
+ 0x322a, 0x3243,
+ 0x3250, 0x3250,
+ 0x3260, 0x327f,
+ 0x328a, 0x32b0,
+ 0x32c0, 0x32fe,
+ 0x3300, 0x33ff,
+ 0x4dc0, 0x4dff,
+ 0xa490, 0xa4c6,
+ 0xa700, 0xa716,
+ 0xa828, 0xa82b,
+ 0xfb29, 0xfb29,
+ 0xfdfc, 0xfdfd,
+ 0xfe62, 0xfe62,
+ 0xfe64, 0xfe66,
+ 0xfe69, 0xfe69,
+ 0xff04, 0xff04,
+ 0xff0b, 0xff0b,
+ 0xff1c, 0xff1e,
+ 0xff3e, 0xff3e,
+ 0xff40, 0xff40,
+ 0xff5c, 0xff5c,
+ 0xff5e, 0xff5e,
+ 0xffe0, 0xffe6,
+ 0xffe8, 0xffee,
+ 0xfffc, 0xfffd,
+ 0x10102, 0x10102,
+ 0x10137, 0x1013f,
+ 0x10179, 0x10189,
+ 0x103d0, 0x103d0,
+ 0x1d000, 0x1d0f5,
+ 0x1d100, 0x1d126,
+ 0x1d12a, 0x1d164,
+ 0x1d16a, 0x1d16c,
+ 0x1d183, 0x1d184,
+ 0x1d18c, 0x1d1a9,
+ 0x1d1ae, 0x1d1dd,
+ 0x1d200, 0x1d241,
+ 0x1d245, 0x1d245,
+ 0x1d300, 0x1d356,
+ 0x1d6c1, 0x1d6c1,
+ 0x1d6db, 0x1d6db,
+ 0x1d6fb, 0x1d6fb,
+ 0x1d715, 0x1d715,
+ 0x1d735, 0x1d735,
+ 0x1d74f, 0x1d74f,
+ 0x1d76f, 0x1d76f,
+ 0x1d789, 0x1d789,
+ 0x1d7a9, 0x1d7a9,
+ 0x1d7c3, 0x1d7c3
+}; /* CR_S */
+
+/* 'Sc': General Category */
+static const OnigCodePoint CR_Sc[] = {
+ 14,
+ 0x0024, 0x0024,
+ 0x00a2, 0x00a5,
+ 0x060b, 0x060b,
+ 0x09f2, 0x09f3,
+ 0x0af1, 0x0af1,
+ 0x0bf9, 0x0bf9,
+ 0x0e3f, 0x0e3f,
+ 0x17db, 0x17db,
+ 0x20a0, 0x20b5,
+ 0xfdfc, 0xfdfc,
+ 0xfe69, 0xfe69,
+ 0xff04, 0xff04,
+ 0xffe0, 0xffe1,
+ 0xffe5, 0xffe6
+}; /* CR_Sc */
+
+/* 'Sk': General Category */
+static const OnigCodePoint CR_Sk[] = {
+ 23,
+ 0x005e, 0x005e,
+ 0x0060, 0x0060,
+ 0x00a8, 0x00a8,
+ 0x00af, 0x00af,
+ 0x00b4, 0x00b4,
+ 0x00b8, 0x00b8,
+ 0x02c2, 0x02c5,
+ 0x02d2, 0x02df,
+ 0x02e5, 0x02ed,
+ 0x02ef, 0x02ff,
+ 0x0374, 0x0375,
+ 0x0384, 0x0385,
+ 0x1fbd, 0x1fbd,
+ 0x1fbf, 0x1fc1,
+ 0x1fcd, 0x1fcf,
+ 0x1fdd, 0x1fdf,
+ 0x1fed, 0x1fef,
+ 0x1ffd, 0x1ffe,
+ 0x309b, 0x309c,
+ 0xa700, 0xa716,
+ 0xff3e, 0xff3e,
+ 0xff40, 0xff40,
+ 0xffe3, 0xffe3
+}; /* CR_Sk */
+
+/* 'Sm': General Category */
+static const OnigCodePoint CR_Sm[] = {
+ 59,
+ 0x002b, 0x002b,
+ 0x003c, 0x003e,
+ 0x007c, 0x007c,
+ 0x007e, 0x007e,
+ 0x00ac, 0x00ac,
+ 0x00b1, 0x00b1,
+ 0x00d7, 0x00d7,
+ 0x00f7, 0x00f7,
+ 0x03f6, 0x03f6,
+ 0x2044, 0x2044,
+ 0x2052, 0x2052,
+ 0x207a, 0x207c,
+ 0x208a, 0x208c,
+ 0x2140, 0x2144,
+ 0x214b, 0x214b,
+ 0x2190, 0x2194,
+ 0x219a, 0x219b,
+ 0x21a0, 0x21a0,
+ 0x21a3, 0x21a3,
+ 0x21a6, 0x21a6,
+ 0x21ae, 0x21ae,
+ 0x21ce, 0x21cf,
+ 0x21d2, 0x21d2,
+ 0x21d4, 0x21d4,
+ 0x21f4, 0x22ff,
+ 0x2308, 0x230b,
+ 0x2320, 0x2321,
+ 0x237c, 0x237c,
+ 0x239b, 0x23b3,
+ 0x25b7, 0x25b7,
+ 0x25c1, 0x25c1,
+ 0x25f8, 0x25ff,
+ 0x266f, 0x266f,
+ 0x27c0, 0x27c4,
+ 0x27d0, 0x27e5,
+ 0x27f0, 0x27ff,
+ 0x2900, 0x2982,
+ 0x2999, 0x29d7,
+ 0x29dc, 0x29fb,
+ 0x29fe, 0x2aff,
+ 0xfb29, 0xfb29,
+ 0xfe62, 0xfe62,
+ 0xfe64, 0xfe66,
+ 0xff0b, 0xff0b,
+ 0xff1c, 0xff1e,
+ 0xff5c, 0xff5c,
+ 0xff5e, 0xff5e,
+ 0xffe2, 0xffe2,
+ 0xffe9, 0xffec,
+ 0x1d6c1, 0x1d6c1,
+ 0x1d6db, 0x1d6db,
+ 0x1d6fb, 0x1d6fb,
+ 0x1d715, 0x1d715,
+ 0x1d735, 0x1d735,
+ 0x1d74f, 0x1d74f,
+ 0x1d76f, 0x1d76f,
+ 0x1d789, 0x1d789,
+ 0x1d7a9, 0x1d7a9,
+ 0x1d7c3, 0x1d7c3
+}; /* CR_Sm */
+
+/* 'So': General Category */
+static const OnigCodePoint CR_So[] = {
+ 120,
+ 0x00a6, 0x00a7,
+ 0x00a9, 0x00a9,
+ 0x00ae, 0x00ae,
+ 0x00b0, 0x00b0,
+ 0x00b6, 0x00b6,
+ 0x0482, 0x0482,
+ 0x060e, 0x060f,
+ 0x06e9, 0x06e9,
+ 0x06fd, 0x06fe,
+ 0x09fa, 0x09fa,
+ 0x0b70, 0x0b70,
+ 0x0bf3, 0x0bf8,
+ 0x0bfa, 0x0bfa,
+ 0x0f01, 0x0f03,
+ 0x0f13, 0x0f17,
+ 0x0f1a, 0x0f1f,
+ 0x0f34, 0x0f34,
+ 0x0f36, 0x0f36,
+ 0x0f38, 0x0f38,
+ 0x0fbe, 0x0fc5,
+ 0x0fc7, 0x0fcc,
+ 0x0fcf, 0x0fcf,
+ 0x1360, 0x1360,
+ 0x1390, 0x1399,
+ 0x1940, 0x1940,
+ 0x19e0, 0x19ff,
+ 0x2100, 0x2101,
+ 0x2103, 0x2106,
+ 0x2108, 0x2109,
+ 0x2114, 0x2114,
+ 0x2116, 0x2118,
+ 0x211e, 0x2123,
+ 0x2125, 0x2125,
+ 0x2127, 0x2127,
+ 0x2129, 0x2129,
+ 0x212e, 0x212e,
+ 0x2132, 0x2132,
+ 0x213a, 0x213b,
+ 0x214a, 0x214a,
+ 0x214c, 0x214c,
+ 0x2195, 0x2199,
+ 0x219c, 0x219f,
+ 0x21a1, 0x21a2,
+ 0x21a4, 0x21a5,
+ 0x21a7, 0x21ad,
+ 0x21af, 0x21cd,
+ 0x21d0, 0x21d1,
+ 0x21d3, 0x21d3,
+ 0x21d5, 0x21f3,
+ 0x2300, 0x2307,
+ 0x230c, 0x231f,
+ 0x2322, 0x2328,
+ 0x232b, 0x237b,
+ 0x237d, 0x239a,
+ 0x23b7, 0x23db,
+ 0x2400, 0x2426,
+ 0x2440, 0x244a,
+ 0x249c, 0x24e9,
+ 0x2500, 0x25b6,
+ 0x25b8, 0x25c0,
+ 0x25c2, 0x25f7,
+ 0x2600, 0x266e,
+ 0x2670, 0x269c,
+ 0x26a0, 0x26b1,
+ 0x2701, 0x2704,
+ 0x2706, 0x2709,
+ 0x270c, 0x2727,
+ 0x2729, 0x274b,
+ 0x274d, 0x274d,
+ 0x274f, 0x2752,
+ 0x2756, 0x2756,
+ 0x2758, 0x275e,
+ 0x2761, 0x2767,
+ 0x2794, 0x2794,
+ 0x2798, 0x27af,
+ 0x27b1, 0x27be,
+ 0x2800, 0x28ff,
+ 0x2b00, 0x2b13,
+ 0x2ce5, 0x2cea,
+ 0x2e80, 0x2e99,
+ 0x2e9b, 0x2ef3,
+ 0x2f00, 0x2fd5,
+ 0x2ff0, 0x2ffb,
+ 0x3004, 0x3004,
+ 0x3012, 0x3013,
+ 0x3020, 0x3020,
+ 0x3036, 0x3037,
+ 0x303e, 0x303f,
+ 0x3190, 0x3191,
+ 0x3196, 0x319f,
+ 0x31c0, 0x31cf,
+ 0x3200, 0x321e,
+ 0x322a, 0x3243,
+ 0x3250, 0x3250,
+ 0x3260, 0x327f,
+ 0x328a, 0x32b0,
+ 0x32c0, 0x32fe,
+ 0x3300, 0x33ff,
+ 0x4dc0, 0x4dff,
+ 0xa490, 0xa4c6,
+ 0xa828, 0xa82b,
+ 0xfdfd, 0xfdfd,
+ 0xffe4, 0xffe4,
+ 0xffe8, 0xffe8,
+ 0xffed, 0xffee,
+ 0xfffc, 0xfffd,
+ 0x10102, 0x10102,
+ 0x10137, 0x1013f,
+ 0x10179, 0x10189,
+ 0x103d0, 0x103d0,
+ 0x1d000, 0x1d0f5,
+ 0x1d100, 0x1d126,
+ 0x1d12a, 0x1d164,
+ 0x1d16a, 0x1d16c,
+ 0x1d183, 0x1d184,
+ 0x1d18c, 0x1d1a9,
+ 0x1d1ae, 0x1d1dd,
+ 0x1d200, 0x1d241,
+ 0x1d245, 0x1d245,
+ 0x1d300, 0x1d356
+}; /* CR_So */
+
+/* 'Z': Major Category */
+static const OnigCodePoint CR_Z[] = {
+ 9,
+ 0x0020, 0x0020,
+ 0x00a0, 0x00a0,
+ 0x1680, 0x1680,
+ 0x180e, 0x180e,
+ 0x2000, 0x200a,
+ 0x2028, 0x2029,
+ 0x202f, 0x202f,
+ 0x205f, 0x205f,
+ 0x3000, 0x3000
+}; /* CR_Z */
+
+/* 'Zl': General Category */
+static const OnigCodePoint CR_Zl[] = {
+ 1,
+ 0x2028, 0x2028
+}; /* CR_Zl */
+
+/* 'Zp': General Category */
+static const OnigCodePoint CR_Zp[] = {
+ 1,
+ 0x2029, 0x2029
+}; /* CR_Zp */
+
+/* 'Zs': General Category */
+static const OnigCodePoint CR_Zs[] = {
+ 8,
+ 0x0020, 0x0020,
+ 0x00a0, 0x00a0,
+ 0x1680, 0x1680,
+ 0x180e, 0x180e,
+ 0x2000, 0x200a,
+ 0x202f, 0x202f,
+ 0x205f, 0x205f,
+ 0x3000, 0x3000
+}; /* CR_Zs */
+
+/* 'Arabic': Script */
+static const OnigCodePoint CR_Arabic[] = {
+ 17,
+ 0x060b, 0x060b,
+ 0x060d, 0x0615,
+ 0x061e, 0x061e,
+ 0x0621, 0x063a,
+ 0x0641, 0x064a,
+ 0x0656, 0x065e,
+ 0x066a, 0x066f,
+ 0x0671, 0x06dc,
+ 0x06de, 0x06ff,
+ 0x0750, 0x076d,
+ 0xfb50, 0xfbb1,
+ 0xfbd3, 0xfd3d,
+ 0xfd50, 0xfd8f,
+ 0xfd92, 0xfdc7,
+ 0xfdf0, 0xfdfc,
+ 0xfe70, 0xfe74,
+ 0xfe76, 0xfefc
+}; /* CR_Arabic */
+
+/* 'Armenian': Script */
+static const OnigCodePoint CR_Armenian[] = {
+ 5,
+ 0x0531, 0x0556,
+ 0x0559, 0x055f,
+ 0x0561, 0x0587,
+ 0x058a, 0x058a,
+ 0xfb13, 0xfb17
+}; /* CR_Armenian */
+
+/* 'Bengali': Script */
+static const OnigCodePoint CR_Bengali[] = {
+ 14,
+ 0x0981, 0x0983,
+ 0x0985, 0x098c,
+ 0x098f, 0x0990,
+ 0x0993, 0x09a8,
+ 0x09aa, 0x09b0,
+ 0x09b2, 0x09b2,
+ 0x09b6, 0x09b9,
+ 0x09bc, 0x09c4,
+ 0x09c7, 0x09c8,
+ 0x09cb, 0x09ce,
+ 0x09d7, 0x09d7,
+ 0x09dc, 0x09dd,
+ 0x09df, 0x09e3,
+ 0x09e6, 0x09fa
+}; /* CR_Bengali */
+
+/* 'Bopomofo': Script */
+static const OnigCodePoint CR_Bopomofo[] = {
+ 2,
+ 0x3105, 0x312c,
+ 0x31a0, 0x31b7
+}; /* CR_Bopomofo */
+
+/* 'Braille': Script */
+static const OnigCodePoint CR_Braille[] = {
+ 1,
+ 0x2800, 0x28ff
+}; /* CR_Braille */
+
+/* 'Buginese': Script */
+static const OnigCodePoint CR_Buginese[] = {
+ 2,
+ 0x1a00, 0x1a1b,
+ 0x1a1e, 0x1a1f
+}; /* CR_Buginese */
+
+/* 'Buhid': Script */
+static const OnigCodePoint CR_Buhid[] = {
+ 1,
+ 0x1740, 0x1753
+}; /* CR_Buhid */
+
+/* 'Canadian_Aboriginal': Script */
+static const OnigCodePoint CR_Canadian_Aboriginal[] = {
+ 1,
+ 0x1401, 0x1676
+}; /* CR_Canadian_Aboriginal */
+
+/* 'Cherokee': Script */
+static const OnigCodePoint CR_Cherokee[] = {
+ 1,
+ 0x13a0, 0x13f4
+}; /* CR_Cherokee */
+
+/* 'Common': Script */
+static const OnigCodePoint CR_Common[] = {
+ 126,
+ 0x0000, 0x0040,
+ 0x005b, 0x0060,
+ 0x007b, 0x00a9,
+ 0x00ab, 0x00b9,
+ 0x00bb, 0x00bf,
+ 0x00d7, 0x00d7,
+ 0x00f7, 0x00f7,
+ 0x02b9, 0x02df,
+ 0x02e5, 0x02ff,
+ 0x037e, 0x037e,
+ 0x0387, 0x0387,
+ 0x0589, 0x0589,
+ 0x0600, 0x0603,
+ 0x060c, 0x060c,
+ 0x061b, 0x061b,
+ 0x061f, 0x061f,
+ 0x0640, 0x0640,
+ 0x0660, 0x0669,
+ 0x06dd, 0x06dd,
+ 0x0964, 0x0965,
+ 0x0970, 0x0970,
+ 0x0e3f, 0x0e3f,
+ 0x10fb, 0x10fb,
+ 0x16eb, 0x16ed,
+ 0x1735, 0x1736,
+ 0x2000, 0x200b,
+ 0x200e, 0x2063,
+ 0x206a, 0x2070,
+ 0x2074, 0x207e,
+ 0x2080, 0x208e,
+ 0x20a0, 0x20b5,
+ 0x2100, 0x2125,
+ 0x2127, 0x2129,
+ 0x212c, 0x214c,
+ 0x2153, 0x2183,
+ 0x2190, 0x23db,
+ 0x2400, 0x2426,
+ 0x2440, 0x244a,
+ 0x2460, 0x269c,
+ 0x26a0, 0x26b1,
+ 0x2701, 0x2704,
+ 0x2706, 0x2709,
+ 0x270c, 0x2727,
+ 0x2729, 0x274b,
+ 0x274d, 0x274d,
+ 0x274f, 0x2752,
+ 0x2756, 0x2756,
+ 0x2758, 0x275e,
+ 0x2761, 0x2794,
+ 0x2798, 0x27af,
+ 0x27b1, 0x27be,
+ 0x27c0, 0x27c6,
+ 0x27d0, 0x27eb,
+ 0x27f0, 0x27ff,
+ 0x2900, 0x2b13,
+ 0x2e00, 0x2e17,
+ 0x2e1c, 0x2e1d,
+ 0x2ff0, 0x2ffb,
+ 0x3000, 0x3004,
+ 0x3006, 0x3006,
+ 0x3008, 0x3020,
+ 0x3030, 0x3037,
+ 0x303c, 0x303f,
+ 0x309b, 0x309c,
+ 0x30a0, 0x30a0,
+ 0x30fb, 0x30fc,
+ 0x3190, 0x319f,
+ 0x31c0, 0x31cf,
+ 0x3220, 0x3243,
+ 0x3250, 0x325f,
+ 0x327e, 0x32fe,
+ 0x3300, 0x33ff,
+ 0x4dc0, 0x4dff,
+ 0xa700, 0xa716,
+ 0xe000, 0xf8ff,
+ 0xfd3e, 0xfd3f,
+ 0xfdfd, 0xfdfd,
+ 0xfe10, 0xfe19,
+ 0xfe30, 0xfe52,
+ 0xfe54, 0xfe66,
+ 0xfe68, 0xfe6b,
+ 0xfeff, 0xfeff,
+ 0xff01, 0xff20,
+ 0xff3b, 0xff40,
+ 0xff5b, 0xff65,
+ 0xff70, 0xff70,
+ 0xff9e, 0xff9f,
+ 0xffe0, 0xffe6,
+ 0xffe8, 0xffee,
+ 0xfff9, 0xfffd,
+ 0x10100, 0x10102,
+ 0x10107, 0x10133,
+ 0x10137, 0x1013f,
+ 0x1d000, 0x1d0f5,
+ 0x1d100, 0x1d126,
+ 0x1d12a, 0x1d166,
+ 0x1d16a, 0x1d17a,
+ 0x1d183, 0x1d184,
+ 0x1d18c, 0x1d1a9,
+ 0x1d1ae, 0x1d1dd,
+ 0x1d300, 0x1d356,
+ 0x1d400, 0x1d454,
+ 0x1d456, 0x1d49c,
+ 0x1d49e, 0x1d49f,
+ 0x1d4a2, 0x1d4a2,
+ 0x1d4a5, 0x1d4a6,
+ 0x1d4a9, 0x1d4ac,
+ 0x1d4ae, 0x1d4b9,
+ 0x1d4bb, 0x1d4bb,
+ 0x1d4bd, 0x1d4c3,
+ 0x1d4c5, 0x1d505,
+ 0x1d507, 0x1d50a,
+ 0x1d50d, 0x1d514,
+ 0x1d516, 0x1d51c,
+ 0x1d51e, 0x1d539,
+ 0x1d53b, 0x1d53e,
+ 0x1d540, 0x1d544,
+ 0x1d546, 0x1d546,
+ 0x1d54a, 0x1d550,
+ 0x1d552, 0x1d6a5,
+ 0x1d6a8, 0x1d7c9,
+ 0x1d7ce, 0x1d7ff,
+ 0xe0001, 0xe0001,
+ 0xe0020, 0xe007f,
+ 0xf0000, 0xffffd,
+ 0x100000, 0x10fffd
+}; /* CR_Common */
+
+/* 'Coptic': Script */
+static const OnigCodePoint CR_Coptic[] = {
+ 3,
+ 0x03e2, 0x03ef,
+ 0x2c80, 0x2cea,
+ 0x2cf9, 0x2cff
+}; /* CR_Coptic */
+
+/* 'Cypriot': Script */
+static const OnigCodePoint CR_Cypriot[] = {
+ 6,
+ 0x10800, 0x10805,
+ 0x10808, 0x10808,
+ 0x1080a, 0x10835,
+ 0x10837, 0x10838,
+ 0x1083c, 0x1083c,
+ 0x1083f, 0x1083f
+}; /* CR_Cypriot */
+
+/* 'Cyrillic': Script */
+static const OnigCodePoint CR_Cyrillic[] = {
+ 6,
+ 0x0400, 0x0486,
+ 0x0488, 0x04ce,
+ 0x04d0, 0x04f9,
+ 0x0500, 0x050f,
+ 0x1d2b, 0x1d2b,
+ 0x1d78, 0x1d78
+}; /* CR_Cyrillic */
+
+/* 'Deseret': Script */
+static const OnigCodePoint CR_Deseret[] = {
+ 1,
+ 0x10400, 0x1044f
+}; /* CR_Deseret */
+
+/* 'Devanagari': Script */
+static const OnigCodePoint CR_Devanagari[] = {
+ 6,
+ 0x0901, 0x0939,
+ 0x093c, 0x094d,
+ 0x0950, 0x0954,
+ 0x0958, 0x0963,
+ 0x0966, 0x096f,
+ 0x097d, 0x097d
+}; /* CR_Devanagari */
+
+/* 'Ethiopic': Script */
+static const OnigCodePoint CR_Ethiopic[] = {
+ 27,
+ 0x1200, 0x1248,
+ 0x124a, 0x124d,
+ 0x1250, 0x1256,
+ 0x1258, 0x1258,
+ 0x125a, 0x125d,
+ 0x1260, 0x1288,
+ 0x128a, 0x128d,
+ 0x1290, 0x12b0,
+ 0x12b2, 0x12b5,
+ 0x12b8, 0x12be,
+ 0x12c0, 0x12c0,
+ 0x12c2, 0x12c5,
+ 0x12c8, 0x12d6,
+ 0x12d8, 0x1310,
+ 0x1312, 0x1315,
+ 0x1318, 0x135a,
+ 0x135f, 0x137c,
+ 0x1380, 0x1399,
+ 0x2d80, 0x2d96,
+ 0x2da0, 0x2da6,
+ 0x2da8, 0x2dae,
+ 0x2db0, 0x2db6,
+ 0x2db8, 0x2dbe,
+ 0x2dc0, 0x2dc6,
+ 0x2dc8, 0x2dce,
+ 0x2dd0, 0x2dd6,
+ 0x2dd8, 0x2dde
+}; /* CR_Ethiopic */
+
+/* 'Georgian': Script */
+static const OnigCodePoint CR_Georgian[] = {
+ 4,
+ 0x10a0, 0x10c5,
+ 0x10d0, 0x10fa,
+ 0x10fc, 0x10fc,
+ 0x2d00, 0x2d25
+}; /* CR_Georgian */
+
+/* 'Glagolitic': Script */
+static const OnigCodePoint CR_Glagolitic[] = {
+ 2,
+ 0x2c00, 0x2c2e,
+ 0x2c30, 0x2c5e
+}; /* CR_Glagolitic */
+
+/* 'Gothic': Script */
+static const OnigCodePoint CR_Gothic[] = {
+ 1,
+ 0x10330, 0x1034a
+}; /* CR_Gothic */
+
+/* 'Greek': Script */
+static const OnigCodePoint CR_Greek[] = {
+ 31,
+ 0x0374, 0x0375,
+ 0x037a, 0x037a,
+ 0x0384, 0x0386,
+ 0x0388, 0x038a,
+ 0x038c, 0x038c,
+ 0x038e, 0x03a1,
+ 0x03a3, 0x03ce,
+ 0x03d0, 0x03e1,
+ 0x03f0, 0x03ff,
+ 0x1d26, 0x1d2a,
+ 0x1d5d, 0x1d61,
+ 0x1d66, 0x1d6a,
+ 0x1f00, 0x1f15,
+ 0x1f18, 0x1f1d,
+ 0x1f20, 0x1f45,
+ 0x1f48, 0x1f4d,
+ 0x1f50, 0x1f57,
+ 0x1f59, 0x1f59,
+ 0x1f5b, 0x1f5b,
+ 0x1f5d, 0x1f5d,
+ 0x1f5f, 0x1f7d,
+ 0x1f80, 0x1fb4,
+ 0x1fb6, 0x1fc4,
+ 0x1fc6, 0x1fd3,
+ 0x1fd6, 0x1fdb,
+ 0x1fdd, 0x1fef,
+ 0x1ff2, 0x1ff4,
+ 0x1ff6, 0x1ffe,
+ 0x2126, 0x2126,
+ 0x10140, 0x1018a,
+ 0x1d200, 0x1d245
+}; /* CR_Greek */
+
+/* 'Gujarati': Script */
+static const OnigCodePoint CR_Gujarati[] = {
+ 14,
+ 0x0a81, 0x0a83,
+ 0x0a85, 0x0a8d,
+ 0x0a8f, 0x0a91,
+ 0x0a93, 0x0aa8,
+ 0x0aaa, 0x0ab0,
+ 0x0ab2, 0x0ab3,
+ 0x0ab5, 0x0ab9,
+ 0x0abc, 0x0ac5,
+ 0x0ac7, 0x0ac9,
+ 0x0acb, 0x0acd,
+ 0x0ad0, 0x0ad0,
+ 0x0ae0, 0x0ae3,
+ 0x0ae6, 0x0aef,
+ 0x0af1, 0x0af1
+}; /* CR_Gujarati */
+
+/* 'Gurmukhi': Script */
+static const OnigCodePoint CR_Gurmukhi[] = {
+ 15,
+ 0x0a01, 0x0a03,
+ 0x0a05, 0x0a0a,
+ 0x0a0f, 0x0a10,
+ 0x0a13, 0x0a28,
+ 0x0a2a, 0x0a30,
+ 0x0a32, 0x0a33,
+ 0x0a35, 0x0a36,
+ 0x0a38, 0x0a39,
+ 0x0a3c, 0x0a3c,
+ 0x0a3e, 0x0a42,
+ 0x0a47, 0x0a48,
+ 0x0a4b, 0x0a4d,
+ 0x0a59, 0x0a5c,
+ 0x0a5e, 0x0a5e,
+ 0x0a66, 0x0a74
+}; /* CR_Gurmukhi */
+
+/* 'Han': Script */
+static const OnigCodePoint CR_Han[] = {
+ 14,
+ 0x2e80, 0x2e99,
+ 0x2e9b, 0x2ef3,
+ 0x2f00, 0x2fd5,
+ 0x3005, 0x3005,
+ 0x3007, 0x3007,
+ 0x3021, 0x3029,
+ 0x3038, 0x303b,
+ 0x3400, 0x4db5,
+ 0x4e00, 0x9fbb,
+ 0xf900, 0xfa2d,
+ 0xfa30, 0xfa6a,
+ 0xfa70, 0xfad9,
+ 0x20000, 0x2a6d6,
+ 0x2f800, 0x2fa1d
+}; /* CR_Han */
+
+/* 'Hangul': Script */
+static const OnigCodePoint CR_Hangul[] = {
+ 12,
+ 0x1100, 0x1159,
+ 0x115f, 0x11a2,
+ 0x11a8, 0x11f9,
+ 0x3131, 0x318e,
+ 0x3200, 0x321e,
+ 0x3260, 0x327d,
+ 0xac00, 0xd7a3,
+ 0xffa0, 0xffbe,
+ 0xffc2, 0xffc7,
+ 0xffca, 0xffcf,
+ 0xffd2, 0xffd7,
+ 0xffda, 0xffdc
+}; /* CR_Hangul */
+
+/* 'Hanunoo': Script */
+static const OnigCodePoint CR_Hanunoo[] = {
+ 1,
+ 0x1720, 0x1734
+}; /* CR_Hanunoo */
+
+/* 'Hebrew': Script */
+static const OnigCodePoint CR_Hebrew[] = {
+ 10,
+ 0x0591, 0x05b9,
+ 0x05bb, 0x05c7,
+ 0x05d0, 0x05ea,
+ 0x05f0, 0x05f4,
+ 0xfb1d, 0xfb36,
+ 0xfb38, 0xfb3c,
+ 0xfb3e, 0xfb3e,
+ 0xfb40, 0xfb41,
+ 0xfb43, 0xfb44,
+ 0xfb46, 0xfb4f
+}; /* CR_Hebrew */
+
+/* 'Hiragana': Script */
+static const OnigCodePoint CR_Hiragana[] = {
+ 2,
+ 0x3041, 0x3096,
+ 0x309d, 0x309f
+}; /* CR_Hiragana */
+
+/* 'Inherited': Script */
+static const OnigCodePoint CR_Inherited[] = {
+ 15,
+ 0x0300, 0x036f,
+ 0x064b, 0x0655,
+ 0x0670, 0x0670,
+ 0x1dc0, 0x1dc3,
+ 0x200c, 0x200d,
+ 0x20d0, 0x20eb,
+ 0x302a, 0x302f,
+ 0x3099, 0x309a,
+ 0xfe00, 0xfe0f,
+ 0xfe20, 0xfe23,
+ 0x1d167, 0x1d169,
+ 0x1d17b, 0x1d182,
+ 0x1d185, 0x1d18b,
+ 0x1d1aa, 0x1d1ad,
+ 0xe0100, 0xe01ef
+}; /* CR_Inherited */
+
+/* 'Kannada': Script */
+static const OnigCodePoint CR_Kannada[] = {
+ 13,
+ 0x0c82, 0x0c83,
+ 0x0c85, 0x0c8c,
+ 0x0c8e, 0x0c90,
+ 0x0c92, 0x0ca8,
+ 0x0caa, 0x0cb3,
+ 0x0cb5, 0x0cb9,
+ 0x0cbc, 0x0cc4,
+ 0x0cc6, 0x0cc8,
+ 0x0cca, 0x0ccd,
+ 0x0cd5, 0x0cd6,
+ 0x0cde, 0x0cde,
+ 0x0ce0, 0x0ce1,
+ 0x0ce6, 0x0cef
+}; /* CR_Kannada */
+
+/* 'Katakana': Script */
+static const OnigCodePoint CR_Katakana[] = {
+ 5,
+ 0x30a1, 0x30fa,
+ 0x30fd, 0x30ff,
+ 0x31f0, 0x31ff,
+ 0xff66, 0xff6f,
+ 0xff71, 0xff9d
+}; /* CR_Katakana */
+
+/* 'Kharoshthi': Script */
+static const OnigCodePoint CR_Kharoshthi[] = {
+ 8,
+ 0x10a00, 0x10a03,
+ 0x10a05, 0x10a06,
+ 0x10a0c, 0x10a13,
+ 0x10a15, 0x10a17,
+ 0x10a19, 0x10a33,
+ 0x10a38, 0x10a3a,
+ 0x10a3f, 0x10a47,
+ 0x10a50, 0x10a58
+}; /* CR_Kharoshthi */
+
+/* 'Khmer': Script */
+static const OnigCodePoint CR_Khmer[] = {
+ 4,
+ 0x1780, 0x17dd,
+ 0x17e0, 0x17e9,
+ 0x17f0, 0x17f9,
+ 0x19e0, 0x19ff
+}; /* CR_Khmer */
+
+/* 'Lao': Script */
+static const OnigCodePoint CR_Lao[] = {
+ 18,
+ 0x0e81, 0x0e82,
+ 0x0e84, 0x0e84,
+ 0x0e87, 0x0e88,
+ 0x0e8a, 0x0e8a,
+ 0x0e8d, 0x0e8d,
+ 0x0e94, 0x0e97,
+ 0x0e99, 0x0e9f,
+ 0x0ea1, 0x0ea3,
+ 0x0ea5, 0x0ea5,
+ 0x0ea7, 0x0ea7,
+ 0x0eaa, 0x0eab,
+ 0x0ead, 0x0eb9,
+ 0x0ebb, 0x0ebd,
+ 0x0ec0, 0x0ec4,
+ 0x0ec6, 0x0ec6,
+ 0x0ec8, 0x0ecd,
+ 0x0ed0, 0x0ed9,
+ 0x0edc, 0x0edd
+}; /* CR_Lao */
+
+/* 'Latin': Script */
+static const OnigCodePoint CR_Latin[] = {
+ 23,
+ 0x0041, 0x005a,
+ 0x0061, 0x007a,
+ 0x00aa, 0x00aa,
+ 0x00ba, 0x00ba,
+ 0x00c0, 0x00d6,
+ 0x00d8, 0x00f6,
+ 0x00f8, 0x0241,
+ 0x0250, 0x02b8,
+ 0x02e0, 0x02e4,
+ 0x1d00, 0x1d25,
+ 0x1d2c, 0x1d5c,
+ 0x1d62, 0x1d65,
+ 0x1d6b, 0x1d77,
+ 0x1d79, 0x1dbf,
+ 0x1e00, 0x1e9b,
+ 0x1ea0, 0x1ef9,
+ 0x2071, 0x2071,
+ 0x207f, 0x207f,
+ 0x2090, 0x2094,
+ 0x212a, 0x212b,
+ 0xfb00, 0xfb06,
+ 0xff21, 0xff3a,
+ 0xff41, 0xff5a
+}; /* CR_Latin */
+
+/* 'Limbu': Script */
+static const OnigCodePoint CR_Limbu[] = {
+ 5,
+ 0x1900, 0x191c,
+ 0x1920, 0x192b,
+ 0x1930, 0x193b,
+ 0x1940, 0x1940,
+ 0x1944, 0x194f
+}; /* CR_Limbu */
+
+/* 'Linear_B': Script */
+static const OnigCodePoint CR_Linear_B[] = {
+ 7,
+ 0x10000, 0x1000b,
+ 0x1000d, 0x10026,
+ 0x10028, 0x1003a,
+ 0x1003c, 0x1003d,
+ 0x1003f, 0x1004d,
+ 0x10050, 0x1005d,
+ 0x10080, 0x100fa
+}; /* CR_Linear_B */
+
+/* 'Malayalam': Script */
+static const OnigCodePoint CR_Malayalam[] = {
+ 11,
+ 0x0d02, 0x0d03,
+ 0x0d05, 0x0d0c,
+ 0x0d0e, 0x0d10,
+ 0x0d12, 0x0d28,
+ 0x0d2a, 0x0d39,
+ 0x0d3e, 0x0d43,
+ 0x0d46, 0x0d48,
+ 0x0d4a, 0x0d4d,
+ 0x0d57, 0x0d57,
+ 0x0d60, 0x0d61,
+ 0x0d66, 0x0d6f
+}; /* CR_Malayalam */
+
+/* 'Mongolian': Script */
+static const OnigCodePoint CR_Mongolian[] = {
+ 4,
+ 0x1800, 0x180e,
+ 0x1810, 0x1819,
+ 0x1820, 0x1877,
+ 0x1880, 0x18a9
+}; /* CR_Mongolian */
+
+/* 'Myanmar': Script */
+static const OnigCodePoint CR_Myanmar[] = {
+ 6,
+ 0x1000, 0x1021,
+ 0x1023, 0x1027,
+ 0x1029, 0x102a,
+ 0x102c, 0x1032,
+ 0x1036, 0x1039,
+ 0x1040, 0x1059
+}; /* CR_Myanmar */
+
+/* 'New_Tai_Lue': Script */
+static const OnigCodePoint CR_New_Tai_Lue[] = {
+ 4,
+ 0x1980, 0x19a9,
+ 0x19b0, 0x19c9,
+ 0x19d0, 0x19d9,
+ 0x19de, 0x19df
+}; /* CR_New_Tai_Lue */
+
+/* 'Ogham': Script */
+static const OnigCodePoint CR_Ogham[] = {
+ 1,
+ 0x1680, 0x169c
+}; /* CR_Ogham */
+
+/* 'Old_Italic': Script */
+static const OnigCodePoint CR_Old_Italic[] = {
+ 2,
+ 0x10300, 0x1031e,
+ 0x10320, 0x10323
+}; /* CR_Old_Italic */
+
+/* 'Old_Persian': Script */
+static const OnigCodePoint CR_Old_Persian[] = {
+ 2,
+ 0x103a0, 0x103c3,
+ 0x103c8, 0x103d5
+}; /* CR_Old_Persian */
+
+/* 'Oriya': Script */
+static const OnigCodePoint CR_Oriya[] = {
+ 14,
+ 0x0b01, 0x0b03,
+ 0x0b05, 0x0b0c,
+ 0x0b0f, 0x0b10,
+ 0x0b13, 0x0b28,
+ 0x0b2a, 0x0b30,
+ 0x0b32, 0x0b33,
+ 0x0b35, 0x0b39,
+ 0x0b3c, 0x0b43,
+ 0x0b47, 0x0b48,
+ 0x0b4b, 0x0b4d,
+ 0x0b56, 0x0b57,
+ 0x0b5c, 0x0b5d,
+ 0x0b5f, 0x0b61,
+ 0x0b66, 0x0b71
+}; /* CR_Oriya */
+
+/* 'Osmanya': Script */
+static const OnigCodePoint CR_Osmanya[] = {
+ 2,
+ 0x10480, 0x1049d,
+ 0x104a0, 0x104a9
+}; /* CR_Osmanya */
+
+/* 'Runic': Script */
+static const OnigCodePoint CR_Runic[] = {
+ 2,
+ 0x16a0, 0x16ea,
+ 0x16ee, 0x16f0
+}; /* CR_Runic */
+
+/* 'Shavian': Script */
+static const OnigCodePoint CR_Shavian[] = {
+ 1,
+ 0x10450, 0x1047f
+}; /* CR_Shavian */
+
+/* 'Sinhala': Script */
+static const OnigCodePoint CR_Sinhala[] = {
+ 11,
+ 0x0d82, 0x0d83,
+ 0x0d85, 0x0d96,
+ 0x0d9a, 0x0db1,
+ 0x0db3, 0x0dbb,
+ 0x0dbd, 0x0dbd,
+ 0x0dc0, 0x0dc6,
+ 0x0dca, 0x0dca,
+ 0x0dcf, 0x0dd4,
+ 0x0dd6, 0x0dd6,
+ 0x0dd8, 0x0ddf,
+ 0x0df2, 0x0df4
+}; /* CR_Sinhala */
+
+/* 'Syloti_Nagri': Script */
+static const OnigCodePoint CR_Syloti_Nagri[] = {
+ 1,
+ 0xa800, 0xa82b
+}; /* CR_Syloti_Nagri */
+
+/* 'Syriac': Script */
+static const OnigCodePoint CR_Syriac[] = {
+ 3,
+ 0x0700, 0x070d,
+ 0x070f, 0x074a,
+ 0x074d, 0x074f
+}; /* CR_Syriac */
+
+/* 'Tagalog': Script */
+static const OnigCodePoint CR_Tagalog[] = {
+ 2,
+ 0x1700, 0x170c,
+ 0x170e, 0x1714
+}; /* CR_Tagalog */
+
+/* 'Tagbanwa': Script */
+static const OnigCodePoint CR_Tagbanwa[] = {
+ 3,
+ 0x1760, 0x176c,
+ 0x176e, 0x1770,
+ 0x1772, 0x1773
+}; /* CR_Tagbanwa */
+
+/* 'Tai_Le': Script */
+static const OnigCodePoint CR_Tai_Le[] = {
+ 2,
+ 0x1950, 0x196d,
+ 0x1970, 0x1974
+}; /* CR_Tai_Le */
+
+/* 'Tamil': Script */
+static const OnigCodePoint CR_Tamil[] = {
+ 15,
+ 0x0b82, 0x0b83,
+ 0x0b85, 0x0b8a,
+ 0x0b8e, 0x0b90,
+ 0x0b92, 0x0b95,
+ 0x0b99, 0x0b9a,
+ 0x0b9c, 0x0b9c,
+ 0x0b9e, 0x0b9f,
+ 0x0ba3, 0x0ba4,
+ 0x0ba8, 0x0baa,
+ 0x0bae, 0x0bb9,
+ 0x0bbe, 0x0bc2,
+ 0x0bc6, 0x0bc8,
+ 0x0bca, 0x0bcd,
+ 0x0bd7, 0x0bd7,
+ 0x0be6, 0x0bfa
+}; /* CR_Tamil */
+
+/* 'Telugu': Script */
+static const OnigCodePoint CR_Telugu[] = {
+ 12,
+ 0x0c01, 0x0c03,
+ 0x0c05, 0x0c0c,
+ 0x0c0e, 0x0c10,
+ 0x0c12, 0x0c28,
+ 0x0c2a, 0x0c33,
+ 0x0c35, 0x0c39,
+ 0x0c3e, 0x0c44,
+ 0x0c46, 0x0c48,
+ 0x0c4a, 0x0c4d,
+ 0x0c55, 0x0c56,
+ 0x0c60, 0x0c61,
+ 0x0c66, 0x0c6f
+}; /* CR_Telugu */
+
+/* 'Thaana': Script */
+static const OnigCodePoint CR_Thaana[] = {
+ 1,
+ 0x0780, 0x07b1
+}; /* CR_Thaana */
+
+/* 'Thai': Script */
+static const OnigCodePoint CR_Thai[] = {
+ 2,
+ 0x0e01, 0x0e3a,
+ 0x0e40, 0x0e5b
+}; /* CR_Thai */
+
+/* 'Tibetan': Script */
+static const OnigCodePoint CR_Tibetan[] = {
+ 7,
+ 0x0f00, 0x0f47,
+ 0x0f49, 0x0f6a,
+ 0x0f71, 0x0f8b,
+ 0x0f90, 0x0f97,
+ 0x0f99, 0x0fbc,
+ 0x0fbe, 0x0fcc,
+ 0x0fcf, 0x0fd1
+}; /* CR_Tibetan */
+
+/* 'Tifinagh': Script */
+static const OnigCodePoint CR_Tifinagh[] = {
+ 2,
+ 0x2d30, 0x2d65,
+ 0x2d6f, 0x2d6f
+}; /* CR_Tifinagh */
+
+/* 'Ugaritic': Script */
+static const OnigCodePoint CR_Ugaritic[] = {
+ 2,
+ 0x10380, 0x1039d,
+ 0x1039f, 0x1039f
+}; /* CR_Ugaritic */
+
+/* 'Yi': Script */
+static const OnigCodePoint CR_Yi[] = {
+ 2,
+ 0xa000, 0xa48c,
+ 0xa490, 0xa4c6
+}; /* CR_Yi */
+
+
+#endif /* USE_UNICODE_PROPERTIES */
+
+
+typedef struct {
+ int n;
+ OnigCodePoint code[3];
+} CodePointList3;
+
+typedef struct {
+ OnigCodePoint from;
+ CodePointList3 to;
+} CaseFold_11_Type;
+
+typedef struct {
+ OnigCodePoint from;
+ CodePointList3 to;
+} CaseUnfold_11_Type;
+
+typedef struct {
+ int n;
+ OnigCodePoint code[2];
+} CodePointList2;
+
+typedef struct {
+ OnigCodePoint from[2];
+ CodePointList2 to;
+} CaseUnfold_12_Type;
+
+typedef struct {
+ OnigCodePoint from[3];
+ CodePointList2 to;
+} CaseUnfold_13_Type;
+
+static const CaseFold_11_Type CaseFold[] = {
+ { 0x0041, {1, {0x0061}}},
+ { 0x0042, {1, {0x0062}}},
+ { 0x0043, {1, {0x0063}}},
+ { 0x0044, {1, {0x0064}}},
+ { 0x0045, {1, {0x0065}}},
+ { 0x0046, {1, {0x0066}}},
+ { 0x0047, {1, {0x0067}}},
+ { 0x0048, {1, {0x0068}}},
+ { 0x004a, {1, {0x006a}}},
+ { 0x004b, {1, {0x006b}}},
+ { 0x004c, {1, {0x006c}}},
+ { 0x004d, {1, {0x006d}}},
+ { 0x004e, {1, {0x006e}}},
+ { 0x004f, {1, {0x006f}}},
+ { 0x0050, {1, {0x0070}}},
+ { 0x0051, {1, {0x0071}}},
+ { 0x0052, {1, {0x0072}}},
+ { 0x0053, {1, {0x0073}}},
+ { 0x0054, {1, {0x0074}}},
+ { 0x0055, {1, {0x0075}}},
+ { 0x0056, {1, {0x0076}}},
+ { 0x0057, {1, {0x0077}}},
+ { 0x0058, {1, {0x0078}}},
+ { 0x0059, {1, {0x0079}}},
+ { 0x005a, {1, {0x007a}}},
+ { 0x00b5, {1, {0x03bc}}},
+ { 0x00c0, {1, {0x00e0}}},
+ { 0x00c1, {1, {0x00e1}}},
+ { 0x00c2, {1, {0x00e2}}},
+ { 0x00c3, {1, {0x00e3}}},
+ { 0x00c4, {1, {0x00e4}}},
+ { 0x00c5, {1, {0x00e5}}},
+ { 0x00c6, {1, {0x00e6}}},
+ { 0x00c7, {1, {0x00e7}}},
+ { 0x00c8, {1, {0x00e8}}},
+ { 0x00c9, {1, {0x00e9}}},
+ { 0x00ca, {1, {0x00ea}}},
+ { 0x00cb, {1, {0x00eb}}},
+ { 0x00cc, {1, {0x00ec}}},
+ { 0x00cd, {1, {0x00ed}}},
+ { 0x00ce, {1, {0x00ee}}},
+ { 0x00cf, {1, {0x00ef}}},
+ { 0x00d0, {1, {0x00f0}}},
+ { 0x00d1, {1, {0x00f1}}},
+ { 0x00d2, {1, {0x00f2}}},
+ { 0x00d3, {1, {0x00f3}}},
+ { 0x00d4, {1, {0x00f4}}},
+ { 0x00d5, {1, {0x00f5}}},
+ { 0x00d6, {1, {0x00f6}}},
+ { 0x00d8, {1, {0x00f8}}},
+ { 0x00d9, {1, {0x00f9}}},
+ { 0x00da, {1, {0x00fa}}},
+ { 0x00db, {1, {0x00fb}}},
+ { 0x00dc, {1, {0x00fc}}},
+ { 0x00dd, {1, {0x00fd}}},
+ { 0x00de, {1, {0x00fe}}},
+ { 0x00df, {2, {0x0073, 0x0073}}},
+ { 0x0100, {1, {0x0101}}},
+ { 0x0102, {1, {0x0103}}},
+ { 0x0104, {1, {0x0105}}},
+ { 0x0106, {1, {0x0107}}},
+ { 0x0108, {1, {0x0109}}},
+ { 0x010a, {1, {0x010b}}},
+ { 0x010c, {1, {0x010d}}},
+ { 0x010e, {1, {0x010f}}},
+ { 0x0110, {1, {0x0111}}},
+ { 0x0112, {1, {0x0113}}},
+ { 0x0114, {1, {0x0115}}},
+ { 0x0116, {1, {0x0117}}},
+ { 0x0118, {1, {0x0119}}},
+ { 0x011a, {1, {0x011b}}},
+ { 0x011c, {1, {0x011d}}},
+ { 0x011e, {1, {0x011f}}},
+ { 0x0120, {1, {0x0121}}},
+ { 0x0122, {1, {0x0123}}},
+ { 0x0124, {1, {0x0125}}},
+ { 0x0126, {1, {0x0127}}},
+ { 0x0128, {1, {0x0129}}},
+ { 0x012a, {1, {0x012b}}},
+ { 0x012c, {1, {0x012d}}},
+ { 0x012e, {1, {0x012f}}},
+ { 0x0132, {1, {0x0133}}},
+ { 0x0134, {1, {0x0135}}},
+ { 0x0136, {1, {0x0137}}},
+ { 0x0139, {1, {0x013a}}},
+ { 0x013b, {1, {0x013c}}},
+ { 0x013d, {1, {0x013e}}},
+ { 0x013f, {1, {0x0140}}},
+ { 0x0141, {1, {0x0142}}},
+ { 0x0143, {1, {0x0144}}},
+ { 0x0145, {1, {0x0146}}},
+ { 0x0147, {1, {0x0148}}},
+ { 0x0149, {2, {0x02bc, 0x006e}}},
+ { 0x014a, {1, {0x014b}}},
+ { 0x014c, {1, {0x014d}}},
+ { 0x014e, {1, {0x014f}}},
+ { 0x0150, {1, {0x0151}}},
+ { 0x0152, {1, {0x0153}}},
+ { 0x0154, {1, {0x0155}}},
+ { 0x0156, {1, {0x0157}}},
+ { 0x0158, {1, {0x0159}}},
+ { 0x015a, {1, {0x015b}}},
+ { 0x015c, {1, {0x015d}}},
+ { 0x015e, {1, {0x015f}}},
+ { 0x0160, {1, {0x0161}}},
+ { 0x0162, {1, {0x0163}}},
+ { 0x0164, {1, {0x0165}}},
+ { 0x0166, {1, {0x0167}}},
+ { 0x0168, {1, {0x0169}}},
+ { 0x016a, {1, {0x016b}}},
+ { 0x016c, {1, {0x016d}}},
+ { 0x016e, {1, {0x016f}}},
+ { 0x0170, {1, {0x0171}}},
+ { 0x0172, {1, {0x0173}}},
+ { 0x0174, {1, {0x0175}}},
+ { 0x0176, {1, {0x0177}}},
+ { 0x0178, {1, {0x00ff}}},
+ { 0x0179, {1, {0x017a}}},
+ { 0x017b, {1, {0x017c}}},
+ { 0x017d, {1, {0x017e}}},
+ { 0x017f, {1, {0x0073}}},
+ { 0x0181, {1, {0x0253}}},
+ { 0x0182, {1, {0x0183}}},
+ { 0x0184, {1, {0x0185}}},
+ { 0x0186, {1, {0x0254}}},
+ { 0x0187, {1, {0x0188}}},
+ { 0x0189, {1, {0x0256}}},
+ { 0x018a, {1, {0x0257}}},
+ { 0x018b, {1, {0x018c}}},
+ { 0x018e, {1, {0x01dd}}},
+ { 0x018f, {1, {0x0259}}},
+ { 0x0190, {1, {0x025b}}},
+ { 0x0191, {1, {0x0192}}},
+ { 0x0193, {1, {0x0260}}},
+ { 0x0194, {1, {0x0263}}},
+ { 0x0196, {1, {0x0269}}},
+ { 0x0197, {1, {0x0268}}},
+ { 0x0198, {1, {0x0199}}},
+ { 0x019c, {1, {0x026f}}},
+ { 0x019d, {1, {0x0272}}},
+ { 0x019f, {1, {0x0275}}},
+ { 0x01a0, {1, {0x01a1}}},
+ { 0x01a2, {1, {0x01a3}}},
+ { 0x01a4, {1, {0x01a5}}},
+ { 0x01a6, {1, {0x0280}}},
+ { 0x01a7, {1, {0x01a8}}},
+ { 0x01a9, {1, {0x0283}}},
+ { 0x01ac, {1, {0x01ad}}},
+ { 0x01ae, {1, {0x0288}}},
+ { 0x01af, {1, {0x01b0}}},
+ { 0x01b1, {1, {0x028a}}},
+ { 0x01b2, {1, {0x028b}}},
+ { 0x01b3, {1, {0x01b4}}},
+ { 0x01b5, {1, {0x01b6}}},
+ { 0x01b7, {1, {0x0292}}},
+ { 0x01b8, {1, {0x01b9}}},
+ { 0x01bc, {1, {0x01bd}}},
+ { 0x01c4, {1, {0x01c6}}},
+ { 0x01c5, {1, {0x01c6}}},
+ { 0x01c7, {1, {0x01c9}}},
+ { 0x01c8, {1, {0x01c9}}},
+ { 0x01ca, {1, {0x01cc}}},
+ { 0x01cb, {1, {0x01cc}}},
+ { 0x01cd, {1, {0x01ce}}},
+ { 0x01cf, {1, {0x01d0}}},
+ { 0x01d1, {1, {0x01d2}}},
+ { 0x01d3, {1, {0x01d4}}},
+ { 0x01d5, {1, {0x01d6}}},
+ { 0x01d7, {1, {0x01d8}}},
+ { 0x01d9, {1, {0x01da}}},
+ { 0x01db, {1, {0x01dc}}},
+ { 0x01de, {1, {0x01df}}},
+ { 0x01e0, {1, {0x01e1}}},
+ { 0x01e2, {1, {0x01e3}}},
+ { 0x01e4, {1, {0x01e5}}},
+ { 0x01e6, {1, {0x01e7}}},
+ { 0x01e8, {1, {0x01e9}}},
+ { 0x01ea, {1, {0x01eb}}},
+ { 0x01ec, {1, {0x01ed}}},
+ { 0x01ee, {1, {0x01ef}}},
+ { 0x01f0, {2, {0x006a, 0x030c}}},
+ { 0x01f1, {1, {0x01f3}}},
+ { 0x01f2, {1, {0x01f3}}},
+ { 0x01f4, {1, {0x01f5}}},
+ { 0x01f6, {1, {0x0195}}},
+ { 0x01f7, {1, {0x01bf}}},
+ { 0x01f8, {1, {0x01f9}}},
+ { 0x01fa, {1, {0x01fb}}},
+ { 0x01fc, {1, {0x01fd}}},
+ { 0x01fe, {1, {0x01ff}}},
+ { 0x0200, {1, {0x0201}}},
+ { 0x0202, {1, {0x0203}}},
+ { 0x0204, {1, {0x0205}}},
+ { 0x0206, {1, {0x0207}}},
+ { 0x0208, {1, {0x0209}}},
+ { 0x020a, {1, {0x020b}}},
+ { 0x020c, {1, {0x020d}}},
+ { 0x020e, {1, {0x020f}}},
+ { 0x0210, {1, {0x0211}}},
+ { 0x0212, {1, {0x0213}}},
+ { 0x0214, {1, {0x0215}}},
+ { 0x0216, {1, {0x0217}}},
+ { 0x0218, {1, {0x0219}}},
+ { 0x021a, {1, {0x021b}}},
+ { 0x021c, {1, {0x021d}}},
+ { 0x021e, {1, {0x021f}}},
+ { 0x0220, {1, {0x019e}}},
+ { 0x0222, {1, {0x0223}}},
+ { 0x0224, {1, {0x0225}}},
+ { 0x0226, {1, {0x0227}}},
+ { 0x0228, {1, {0x0229}}},
+ { 0x022a, {1, {0x022b}}},
+ { 0x022c, {1, {0x022d}}},
+ { 0x022e, {1, {0x022f}}},
+ { 0x0230, {1, {0x0231}}},
+ { 0x0232, {1, {0x0233}}},
+ { 0x023b, {1, {0x023c}}},
+ { 0x023d, {1, {0x019a}}},
+ { 0x0241, {1, {0x0294}}},
+ { 0x0345, {1, {0x03b9}}},
+ { 0x0386, {1, {0x03ac}}},
+ { 0x0388, {1, {0x03ad}}},
+ { 0x0389, {1, {0x03ae}}},
+ { 0x038a, {1, {0x03af}}},
+ { 0x038c, {1, {0x03cc}}},
+ { 0x038e, {1, {0x03cd}}},
+ { 0x038f, {1, {0x03ce}}},
+ { 0x0390, {3, {0x03b9, 0x0308, 0x0301}}},
+ { 0x0391, {1, {0x03b1}}},
+ { 0x0392, {1, {0x03b2}}},
+ { 0x0393, {1, {0x03b3}}},
+ { 0x0394, {1, {0x03b4}}},
+ { 0x0395, {1, {0x03b5}}},
+ { 0x0396, {1, {0x03b6}}},
+ { 0x0397, {1, {0x03b7}}},
+ { 0x0398, {1, {0x03b8}}},
+ { 0x0399, {1, {0x03b9}}},
+ { 0x039a, {1, {0x03ba}}},
+ { 0x039b, {1, {0x03bb}}},
+ { 0x039c, {1, {0x03bc}}},
+ { 0x039d, {1, {0x03bd}}},
+ { 0x039e, {1, {0x03be}}},
+ { 0x039f, {1, {0x03bf}}},
+ { 0x03a0, {1, {0x03c0}}},
+ { 0x03a1, {1, {0x03c1}}},
+ { 0x03a3, {1, {0x03c3}}},
+ { 0x03a4, {1, {0x03c4}}},
+ { 0x03a5, {1, {0x03c5}}},
+ { 0x03a6, {1, {0x03c6}}},
+ { 0x03a7, {1, {0x03c7}}},
+ { 0x03a8, {1, {0x03c8}}},
+ { 0x03a9, {1, {0x03c9}}},
+ { 0x03aa, {1, {0x03ca}}},
+ { 0x03ab, {1, {0x03cb}}},
+ { 0x03b0, {3, {0x03c5, 0x0308, 0x0301}}},
+ { 0x03c2, {1, {0x03c3}}},
+ { 0x03d0, {1, {0x03b2}}},
+ { 0x03d1, {1, {0x03b8}}},
+ { 0x03d5, {1, {0x03c6}}},
+ { 0x03d6, {1, {0x03c0}}},
+ { 0x03d8, {1, {0x03d9}}},
+ { 0x03da, {1, {0x03db}}},
+ { 0x03dc, {1, {0x03dd}}},
+ { 0x03de, {1, {0x03df}}},
+ { 0x03e0, {1, {0x03e1}}},
+ { 0x03e2, {1, {0x03e3}}},
+ { 0x03e4, {1, {0x03e5}}},
+ { 0x03e6, {1, {0x03e7}}},
+ { 0x03e8, {1, {0x03e9}}},
+ { 0x03ea, {1, {0x03eb}}},
+ { 0x03ec, {1, {0x03ed}}},
+ { 0x03ee, {1, {0x03ef}}},
+ { 0x03f0, {1, {0x03ba}}},
+ { 0x03f1, {1, {0x03c1}}},
+ { 0x03f4, {1, {0x03b8}}},
+ { 0x03f5, {1, {0x03b5}}},
+ { 0x03f7, {1, {0x03f8}}},
+ { 0x03f9, {1, {0x03f2}}},
+ { 0x03fa, {1, {0x03fb}}},
+ { 0x0400, {1, {0x0450}}},
+ { 0x0401, {1, {0x0451}}},
+ { 0x0402, {1, {0x0452}}},
+ { 0x0403, {1, {0x0453}}},
+ { 0x0404, {1, {0x0454}}},
+ { 0x0405, {1, {0x0455}}},
+ { 0x0406, {1, {0x0456}}},
+ { 0x0407, {1, {0x0457}}},
+ { 0x0408, {1, {0x0458}}},
+ { 0x0409, {1, {0x0459}}},
+ { 0x040a, {1, {0x045a}}},
+ { 0x040b, {1, {0x045b}}},
+ { 0x040c, {1, {0x045c}}},
+ { 0x040d, {1, {0x045d}}},
+ { 0x040e, {1, {0x045e}}},
+ { 0x040f, {1, {0x045f}}},
+ { 0x0410, {1, {0x0430}}},
+ { 0x0411, {1, {0x0431}}},
+ { 0x0412, {1, {0x0432}}},
+ { 0x0413, {1, {0x0433}}},
+ { 0x0414, {1, {0x0434}}},
+ { 0x0415, {1, {0x0435}}},
+ { 0x0416, {1, {0x0436}}},
+ { 0x0417, {1, {0x0437}}},
+ { 0x0418, {1, {0x0438}}},
+ { 0x0419, {1, {0x0439}}},
+ { 0x041a, {1, {0x043a}}},
+ { 0x041b, {1, {0x043b}}},
+ { 0x041c, {1, {0x043c}}},
+ { 0x041d, {1, {0x043d}}},
+ { 0x041e, {1, {0x043e}}},
+ { 0x041f, {1, {0x043f}}},
+ { 0x0420, {1, {0x0440}}},
+ { 0x0421, {1, {0x0441}}},
+ { 0x0422, {1, {0x0442}}},
+ { 0x0423, {1, {0x0443}}},
+ { 0x0424, {1, {0x0444}}},
+ { 0x0425, {1, {0x0445}}},
+ { 0x0426, {1, {0x0446}}},
+ { 0x0427, {1, {0x0447}}},
+ { 0x0428, {1, {0x0448}}},
+ { 0x0429, {1, {0x0449}}},
+ { 0x042a, {1, {0x044a}}},
+ { 0x042b, {1, {0x044b}}},
+ { 0x042c, {1, {0x044c}}},
+ { 0x042d, {1, {0x044d}}},
+ { 0x042e, {1, {0x044e}}},
+ { 0x042f, {1, {0x044f}}},
+ { 0x0460, {1, {0x0461}}},
+ { 0x0462, {1, {0x0463}}},
+ { 0x0464, {1, {0x0465}}},
+ { 0x0466, {1, {0x0467}}},
+ { 0x0468, {1, {0x0469}}},
+ { 0x046a, {1, {0x046b}}},
+ { 0x046c, {1, {0x046d}}},
+ { 0x046e, {1, {0x046f}}},
+ { 0x0470, {1, {0x0471}}},
+ { 0x0472, {1, {0x0473}}},
+ { 0x0474, {1, {0x0475}}},
+ { 0x0476, {1, {0x0477}}},
+ { 0x0478, {1, {0x0479}}},
+ { 0x047a, {1, {0x047b}}},
+ { 0x047c, {1, {0x047d}}},
+ { 0x047e, {1, {0x047f}}},
+ { 0x0480, {1, {0x0481}}},
+ { 0x048a, {1, {0x048b}}},
+ { 0x048c, {1, {0x048d}}},
+ { 0x048e, {1, {0x048f}}},
+ { 0x0490, {1, {0x0491}}},
+ { 0x0492, {1, {0x0493}}},
+ { 0x0494, {1, {0x0495}}},
+ { 0x0496, {1, {0x0497}}},
+ { 0x0498, {1, {0x0499}}},
+ { 0x049a, {1, {0x049b}}},
+ { 0x049c, {1, {0x049d}}},
+ { 0x049e, {1, {0x049f}}},
+ { 0x04a0, {1, {0x04a1}}},
+ { 0x04a2, {1, {0x04a3}}},
+ { 0x04a4, {1, {0x04a5}}},
+ { 0x04a6, {1, {0x04a7}}},
+ { 0x04a8, {1, {0x04a9}}},
+ { 0x04aa, {1, {0x04ab}}},
+ { 0x04ac, {1, {0x04ad}}},
+ { 0x04ae, {1, {0x04af}}},
+ { 0x04b0, {1, {0x04b1}}},
+ { 0x04b2, {1, {0x04b3}}},
+ { 0x04b4, {1, {0x04b5}}},
+ { 0x04b6, {1, {0x04b7}}},
+ { 0x04b8, {1, {0x04b9}}},
+ { 0x04ba, {1, {0x04bb}}},
+ { 0x04bc, {1, {0x04bd}}},
+ { 0x04be, {1, {0x04bf}}},
+ { 0x04c1, {1, {0x04c2}}},
+ { 0x04c3, {1, {0x04c4}}},
+ { 0x04c5, {1, {0x04c6}}},
+ { 0x04c7, {1, {0x04c8}}},
+ { 0x04c9, {1, {0x04ca}}},
+ { 0x04cb, {1, {0x04cc}}},
+ { 0x04cd, {1, {0x04ce}}},
+ { 0x04d0, {1, {0x04d1}}},
+ { 0x04d2, {1, {0x04d3}}},
+ { 0x04d4, {1, {0x04d5}}},
+ { 0x04d6, {1, {0x04d7}}},
+ { 0x04d8, {1, {0x04d9}}},
+ { 0x04da, {1, {0x04db}}},
+ { 0x04dc, {1, {0x04dd}}},
+ { 0x04de, {1, {0x04df}}},
+ { 0x04e0, {1, {0x04e1}}},
+ { 0x04e2, {1, {0x04e3}}},
+ { 0x04e4, {1, {0x04e5}}},
+ { 0x04e6, {1, {0x04e7}}},
+ { 0x04e8, {1, {0x04e9}}},
+ { 0x04ea, {1, {0x04eb}}},
+ { 0x04ec, {1, {0x04ed}}},
+ { 0x04ee, {1, {0x04ef}}},
+ { 0x04f0, {1, {0x04f1}}},
+ { 0x04f2, {1, {0x04f3}}},
+ { 0x04f4, {1, {0x04f5}}},
+ { 0x04f6, {1, {0x04f7}}},
+ { 0x04f8, {1, {0x04f9}}},
+ { 0x0500, {1, {0x0501}}},
+ { 0x0502, {1, {0x0503}}},
+ { 0x0504, {1, {0x0505}}},
+ { 0x0506, {1, {0x0507}}},
+ { 0x0508, {1, {0x0509}}},
+ { 0x050a, {1, {0x050b}}},
+ { 0x050c, {1, {0x050d}}},
+ { 0x050e, {1, {0x050f}}},
+ { 0x0531, {1, {0x0561}}},
+ { 0x0532, {1, {0x0562}}},
+ { 0x0533, {1, {0x0563}}},
+ { 0x0534, {1, {0x0564}}},
+ { 0x0535, {1, {0x0565}}},
+ { 0x0536, {1, {0x0566}}},
+ { 0x0537, {1, {0x0567}}},
+ { 0x0538, {1, {0x0568}}},
+ { 0x0539, {1, {0x0569}}},
+ { 0x053a, {1, {0x056a}}},
+ { 0x053b, {1, {0x056b}}},
+ { 0x053c, {1, {0x056c}}},
+ { 0x053d, {1, {0x056d}}},
+ { 0x053e, {1, {0x056e}}},
+ { 0x053f, {1, {0x056f}}},
+ { 0x0540, {1, {0x0570}}},
+ { 0x0541, {1, {0x0571}}},
+ { 0x0542, {1, {0x0572}}},
+ { 0x0543, {1, {0x0573}}},
+ { 0x0544, {1, {0x0574}}},
+ { 0x0545, {1, {0x0575}}},
+ { 0x0546, {1, {0x0576}}},
+ { 0x0547, {1, {0x0577}}},
+ { 0x0548, {1, {0x0578}}},
+ { 0x0549, {1, {0x0579}}},
+ { 0x054a, {1, {0x057a}}},
+ { 0x054b, {1, {0x057b}}},
+ { 0x054c, {1, {0x057c}}},
+ { 0x054d, {1, {0x057d}}},
+ { 0x054e, {1, {0x057e}}},
+ { 0x054f, {1, {0x057f}}},
+ { 0x0550, {1, {0x0580}}},
+ { 0x0551, {1, {0x0581}}},
+ { 0x0552, {1, {0x0582}}},
+ { 0x0553, {1, {0x0583}}},
+ { 0x0554, {1, {0x0584}}},
+ { 0x0555, {1, {0x0585}}},
+ { 0x0556, {1, {0x0586}}},
+ { 0x0587, {2, {0x0565, 0x0582}}},
+ { 0x10a0, {1, {0x2d00}}},
+ { 0x10a1, {1, {0x2d01}}},
+ { 0x10a2, {1, {0x2d02}}},
+ { 0x10a3, {1, {0x2d03}}},
+ { 0x10a4, {1, {0x2d04}}},
+ { 0x10a5, {1, {0x2d05}}},
+ { 0x10a6, {1, {0x2d06}}},
+ { 0x10a7, {1, {0x2d07}}},
+ { 0x10a8, {1, {0x2d08}}},
+ { 0x10a9, {1, {0x2d09}}},
+ { 0x10aa, {1, {0x2d0a}}},
+ { 0x10ab, {1, {0x2d0b}}},
+ { 0x10ac, {1, {0x2d0c}}},
+ { 0x10ad, {1, {0x2d0d}}},
+ { 0x10ae, {1, {0x2d0e}}},
+ { 0x10af, {1, {0x2d0f}}},
+ { 0x10b0, {1, {0x2d10}}},
+ { 0x10b1, {1, {0x2d11}}},
+ { 0x10b2, {1, {0x2d12}}},
+ { 0x10b3, {1, {0x2d13}}},
+ { 0x10b4, {1, {0x2d14}}},
+ { 0x10b5, {1, {0x2d15}}},
+ { 0x10b6, {1, {0x2d16}}},
+ { 0x10b7, {1, {0x2d17}}},
+ { 0x10b8, {1, {0x2d18}}},
+ { 0x10b9, {1, {0x2d19}}},
+ { 0x10ba, {1, {0x2d1a}}},
+ { 0x10bb, {1, {0x2d1b}}},
+ { 0x10bc, {1, {0x2d1c}}},
+ { 0x10bd, {1, {0x2d1d}}},
+ { 0x10be, {1, {0x2d1e}}},
+ { 0x10bf, {1, {0x2d1f}}},
+ { 0x10c0, {1, {0x2d20}}},
+ { 0x10c1, {1, {0x2d21}}},
+ { 0x10c2, {1, {0x2d22}}},
+ { 0x10c3, {1, {0x2d23}}},
+ { 0x10c4, {1, {0x2d24}}},
+ { 0x10c5, {1, {0x2d25}}},
+ { 0x1e00, {1, {0x1e01}}},
+ { 0x1e02, {1, {0x1e03}}},
+ { 0x1e04, {1, {0x1e05}}},
+ { 0x1e06, {1, {0x1e07}}},
+ { 0x1e08, {1, {0x1e09}}},
+ { 0x1e0a, {1, {0x1e0b}}},
+ { 0x1e0c, {1, {0x1e0d}}},
+ { 0x1e0e, {1, {0x1e0f}}},
+ { 0x1e10, {1, {0x1e11}}},
+ { 0x1e12, {1, {0x1e13}}},
+ { 0x1e14, {1, {0x1e15}}},
+ { 0x1e16, {1, {0x1e17}}},
+ { 0x1e18, {1, {0x1e19}}},
+ { 0x1e1a, {1, {0x1e1b}}},
+ { 0x1e1c, {1, {0x1e1d}}},
+ { 0x1e1e, {1, {0x1e1f}}},
+ { 0x1e20, {1, {0x1e21}}},
+ { 0x1e22, {1, {0x1e23}}},
+ { 0x1e24, {1, {0x1e25}}},
+ { 0x1e26, {1, {0x1e27}}},
+ { 0x1e28, {1, {0x1e29}}},
+ { 0x1e2a, {1, {0x1e2b}}},
+ { 0x1e2c, {1, {0x1e2d}}},
+ { 0x1e2e, {1, {0x1e2f}}},
+ { 0x1e30, {1, {0x1e31}}},
+ { 0x1e32, {1, {0x1e33}}},
+ { 0x1e34, {1, {0x1e35}}},
+ { 0x1e36, {1, {0x1e37}}},
+ { 0x1e38, {1, {0x1e39}}},
+ { 0x1e3a, {1, {0x1e3b}}},
+ { 0x1e3c, {1, {0x1e3d}}},
+ { 0x1e3e, {1, {0x1e3f}}},
+ { 0x1e40, {1, {0x1e41}}},
+ { 0x1e42, {1, {0x1e43}}},
+ { 0x1e44, {1, {0x1e45}}},
+ { 0x1e46, {1, {0x1e47}}},
+ { 0x1e48, {1, {0x1e49}}},
+ { 0x1e4a, {1, {0x1e4b}}},
+ { 0x1e4c, {1, {0x1e4d}}},
+ { 0x1e4e, {1, {0x1e4f}}},
+ { 0x1e50, {1, {0x1e51}}},
+ { 0x1e52, {1, {0x1e53}}},
+ { 0x1e54, {1, {0x1e55}}},
+ { 0x1e56, {1, {0x1e57}}},
+ { 0x1e58, {1, {0x1e59}}},
+ { 0x1e5a, {1, {0x1e5b}}},
+ { 0x1e5c, {1, {0x1e5d}}},
+ { 0x1e5e, {1, {0x1e5f}}},
+ { 0x1e60, {1, {0x1e61}}},
+ { 0x1e62, {1, {0x1e63}}},
+ { 0x1e64, {1, {0x1e65}}},
+ { 0x1e66, {1, {0x1e67}}},
+ { 0x1e68, {1, {0x1e69}}},
+ { 0x1e6a, {1, {0x1e6b}}},
+ { 0x1e6c, {1, {0x1e6d}}},
+ { 0x1e6e, {1, {0x1e6f}}},
+ { 0x1e70, {1, {0x1e71}}},
+ { 0x1e72, {1, {0x1e73}}},
+ { 0x1e74, {1, {0x1e75}}},
+ { 0x1e76, {1, {0x1e77}}},
+ { 0x1e78, {1, {0x1e79}}},
+ { 0x1e7a, {1, {0x1e7b}}},
+ { 0x1e7c, {1, {0x1e7d}}},
+ { 0x1e7e, {1, {0x1e7f}}},
+ { 0x1e80, {1, {0x1e81}}},
+ { 0x1e82, {1, {0x1e83}}},
+ { 0x1e84, {1, {0x1e85}}},
+ { 0x1e86, {1, {0x1e87}}},
+ { 0x1e88, {1, {0x1e89}}},
+ { 0x1e8a, {1, {0x1e8b}}},
+ { 0x1e8c, {1, {0x1e8d}}},
+ { 0x1e8e, {1, {0x1e8f}}},
+ { 0x1e90, {1, {0x1e91}}},
+ { 0x1e92, {1, {0x1e93}}},
+ { 0x1e94, {1, {0x1e95}}},
+ { 0x1e96, {2, {0x0068, 0x0331}}},
+ { 0x1e97, {2, {0x0074, 0x0308}}},
+ { 0x1e98, {2, {0x0077, 0x030a}}},
+ { 0x1e99, {2, {0x0079, 0x030a}}},
+ { 0x1e9a, {2, {0x0061, 0x02be}}},
+ { 0x1e9b, {1, {0x1e61}}},
+ { 0x1ea0, {1, {0x1ea1}}},
+ { 0x1ea2, {1, {0x1ea3}}},
+ { 0x1ea4, {1, {0x1ea5}}},
+ { 0x1ea6, {1, {0x1ea7}}},
+ { 0x1ea8, {1, {0x1ea9}}},
+ { 0x1eaa, {1, {0x1eab}}},
+ { 0x1eac, {1, {0x1ead}}},
+ { 0x1eae, {1, {0x1eaf}}},
+ { 0x1eb0, {1, {0x1eb1}}},
+ { 0x1eb2, {1, {0x1eb3}}},
+ { 0x1eb4, {1, {0x1eb5}}},
+ { 0x1eb6, {1, {0x1eb7}}},
+ { 0x1eb8, {1, {0x1eb9}}},
+ { 0x1eba, {1, {0x1ebb}}},
+ { 0x1ebc, {1, {0x1ebd}}},
+ { 0x1ebe, {1, {0x1ebf}}},
+ { 0x1ec0, {1, {0x1ec1}}},
+ { 0x1ec2, {1, {0x1ec3}}},
+ { 0x1ec4, {1, {0x1ec5}}},
+ { 0x1ec6, {1, {0x1ec7}}},
+ { 0x1ec8, {1, {0x1ec9}}},
+ { 0x1eca, {1, {0x1ecb}}},
+ { 0x1ecc, {1, {0x1ecd}}},
+ { 0x1ece, {1, {0x1ecf}}},
+ { 0x1ed0, {1, {0x1ed1}}},
+ { 0x1ed2, {1, {0x1ed3}}},
+ { 0x1ed4, {1, {0x1ed5}}},
+ { 0x1ed6, {1, {0x1ed7}}},
+ { 0x1ed8, {1, {0x1ed9}}},
+ { 0x1eda, {1, {0x1edb}}},
+ { 0x1edc, {1, {0x1edd}}},
+ { 0x1ede, {1, {0x1edf}}},
+ { 0x1ee0, {1, {0x1ee1}}},
+ { 0x1ee2, {1, {0x1ee3}}},
+ { 0x1ee4, {1, {0x1ee5}}},
+ { 0x1ee6, {1, {0x1ee7}}},
+ { 0x1ee8, {1, {0x1ee9}}},
+ { 0x1eea, {1, {0x1eeb}}},
+ { 0x1eec, {1, {0x1eed}}},
+ { 0x1eee, {1, {0x1eef}}},
+ { 0x1ef0, {1, {0x1ef1}}},
+ { 0x1ef2, {1, {0x1ef3}}},
+ { 0x1ef4, {1, {0x1ef5}}},
+ { 0x1ef6, {1, {0x1ef7}}},
+ { 0x1ef8, {1, {0x1ef9}}},
+ { 0x1f08, {1, {0x1f00}}},
+ { 0x1f09, {1, {0x1f01}}},
+ { 0x1f0a, {1, {0x1f02}}},
+ { 0x1f0b, {1, {0x1f03}}},
+ { 0x1f0c, {1, {0x1f04}}},
+ { 0x1f0d, {1, {0x1f05}}},
+ { 0x1f0e, {1, {0x1f06}}},
+ { 0x1f0f, {1, {0x1f07}}},
+ { 0x1f18, {1, {0x1f10}}},
+ { 0x1f19, {1, {0x1f11}}},
+ { 0x1f1a, {1, {0x1f12}}},
+ { 0x1f1b, {1, {0x1f13}}},
+ { 0x1f1c, {1, {0x1f14}}},
+ { 0x1f1d, {1, {0x1f15}}},
+ { 0x1f28, {1, {0x1f20}}},
+ { 0x1f29, {1, {0x1f21}}},
+ { 0x1f2a, {1, {0x1f22}}},
+ { 0x1f2b, {1, {0x1f23}}},
+ { 0x1f2c, {1, {0x1f24}}},
+ { 0x1f2d, {1, {0x1f25}}},
+ { 0x1f2e, {1, {0x1f26}}},
+ { 0x1f2f, {1, {0x1f27}}},
+ { 0x1f38, {1, {0x1f30}}},
+ { 0x1f39, {1, {0x1f31}}},
+ { 0x1f3a, {1, {0x1f32}}},
+ { 0x1f3b, {1, {0x1f33}}},
+ { 0x1f3c, {1, {0x1f34}}},
+ { 0x1f3d, {1, {0x1f35}}},
+ { 0x1f3e, {1, {0x1f36}}},
+ { 0x1f3f, {1, {0x1f37}}},
+ { 0x1f48, {1, {0x1f40}}},
+ { 0x1f49, {1, {0x1f41}}},
+ { 0x1f4a, {1, {0x1f42}}},
+ { 0x1f4b, {1, {0x1f43}}},
+ { 0x1f4c, {1, {0x1f44}}},
+ { 0x1f4d, {1, {0x1f45}}},
+ { 0x1f50, {2, {0x03c5, 0x0313}}},
+ { 0x1f52, {3, {0x03c5, 0x0313, 0x0300}}},
+ { 0x1f54, {3, {0x03c5, 0x0313, 0x0301}}},
+ { 0x1f56, {3, {0x03c5, 0x0313, 0x0342}}},
+ { 0x1f59, {1, {0x1f51}}},
+ { 0x1f5b, {1, {0x1f53}}},
+ { 0x1f5d, {1, {0x1f55}}},
+ { 0x1f5f, {1, {0x1f57}}},
+ { 0x1f68, {1, {0x1f60}}},
+ { 0x1f69, {1, {0x1f61}}},
+ { 0x1f6a, {1, {0x1f62}}},
+ { 0x1f6b, {1, {0x1f63}}},
+ { 0x1f6c, {1, {0x1f64}}},
+ { 0x1f6d, {1, {0x1f65}}},
+ { 0x1f6e, {1, {0x1f66}}},
+ { 0x1f6f, {1, {0x1f67}}},
+ { 0x1f80, {2, {0x1f00, 0x03b9}}},
+ { 0x1f81, {2, {0x1f01, 0x03b9}}},
+ { 0x1f82, {2, {0x1f02, 0x03b9}}},
+ { 0x1f83, {2, {0x1f03, 0x03b9}}},
+ { 0x1f84, {2, {0x1f04, 0x03b9}}},
+ { 0x1f85, {2, {0x1f05, 0x03b9}}},
+ { 0x1f86, {2, {0x1f06, 0x03b9}}},
+ { 0x1f87, {2, {0x1f07, 0x03b9}}},
+ { 0x1f88, {2, {0x1f00, 0x03b9}}},
+ { 0x1f89, {2, {0x1f01, 0x03b9}}},
+ { 0x1f8a, {2, {0x1f02, 0x03b9}}},
+ { 0x1f8b, {2, {0x1f03, 0x03b9}}},
+ { 0x1f8c, {2, {0x1f04, 0x03b9}}},
+ { 0x1f8d, {2, {0x1f05, 0x03b9}}},
+ { 0x1f8e, {2, {0x1f06, 0x03b9}}},
+ { 0x1f8f, {2, {0x1f07, 0x03b9}}},
+ { 0x1f90, {2, {0x1f20, 0x03b9}}},
+ { 0x1f91, {2, {0x1f21, 0x03b9}}},
+ { 0x1f92, {2, {0x1f22, 0x03b9}}},
+ { 0x1f93, {2, {0x1f23, 0x03b9}}},
+ { 0x1f94, {2, {0x1f24, 0x03b9}}},
+ { 0x1f95, {2, {0x1f25, 0x03b9}}},
+ { 0x1f96, {2, {0x1f26, 0x03b9}}},
+ { 0x1f97, {2, {0x1f27, 0x03b9}}},
+ { 0x1f98, {2, {0x1f20, 0x03b9}}},
+ { 0x1f99, {2, {0x1f21, 0x03b9}}},
+ { 0x1f9a, {2, {0x1f22, 0x03b9}}},
+ { 0x1f9b, {2, {0x1f23, 0x03b9}}},
+ { 0x1f9c, {2, {0x1f24, 0x03b9}}},
+ { 0x1f9d, {2, {0x1f25, 0x03b9}}},
+ { 0x1f9e, {2, {0x1f26, 0x03b9}}},
+ { 0x1f9f, {2, {0x1f27, 0x03b9}}},
+ { 0x1fa0, {2, {0x1f60, 0x03b9}}},
+ { 0x1fa1, {2, {0x1f61, 0x03b9}}},
+ { 0x1fa2, {2, {0x1f62, 0x03b9}}},
+ { 0x1fa3, {2, {0x1f63, 0x03b9}}},
+ { 0x1fa4, {2, {0x1f64, 0x03b9}}},
+ { 0x1fa5, {2, {0x1f65, 0x03b9}}},
+ { 0x1fa6, {2, {0x1f66, 0x03b9}}},
+ { 0x1fa7, {2, {0x1f67, 0x03b9}}},
+ { 0x1fa8, {2, {0x1f60, 0x03b9}}},
+ { 0x1fa9, {2, {0x1f61, 0x03b9}}},
+ { 0x1faa, {2, {0x1f62, 0x03b9}}},
+ { 0x1fab, {2, {0x1f63, 0x03b9}}},
+ { 0x1fac, {2, {0x1f64, 0x03b9}}},
+ { 0x1fad, {2, {0x1f65, 0x03b9}}},
+ { 0x1fae, {2, {0x1f66, 0x03b9}}},
+ { 0x1faf, {2, {0x1f67, 0x03b9}}},
+ { 0x1fb2, {2, {0x1f70, 0x03b9}}},
+ { 0x1fb3, {2, {0x03b1, 0x03b9}}},
+ { 0x1fb4, {2, {0x03ac, 0x03b9}}},
+ { 0x1fb6, {2, {0x03b1, 0x0342}}},
+ { 0x1fb7, {3, {0x03b1, 0x0342, 0x03b9}}},
+ { 0x1fb8, {1, {0x1fb0}}},
+ { 0x1fb9, {1, {0x1fb1}}},
+ { 0x1fba, {1, {0x1f70}}},
+ { 0x1fbb, {1, {0x1f71}}},
+ { 0x1fbc, {2, {0x03b1, 0x03b9}}},
+ { 0x1fbe, {1, {0x03b9}}},
+ { 0x1fc2, {2, {0x1f74, 0x03b9}}},
+ { 0x1fc3, {2, {0x03b7, 0x03b9}}},
+ { 0x1fc4, {2, {0x03ae, 0x03b9}}},
+ { 0x1fc6, {2, {0x03b7, 0x0342}}},
+ { 0x1fc7, {3, {0x03b7, 0x0342, 0x03b9}}},
+ { 0x1fc8, {1, {0x1f72}}},
+ { 0x1fc9, {1, {0x1f73}}},
+ { 0x1fca, {1, {0x1f74}}},
+ { 0x1fcb, {1, {0x1f75}}},
+ { 0x1fcc, {2, {0x03b7, 0x03b9}}},
+ { 0x1fd2, {3, {0x03b9, 0x0308, 0x0300}}},
+ { 0x1fd3, {3, {0x03b9, 0x0308, 0x0301}}},
+ { 0x1fd6, {2, {0x03b9, 0x0342}}},
+ { 0x1fd7, {3, {0x03b9, 0x0308, 0x0342}}},
+ { 0x1fd8, {1, {0x1fd0}}},
+ { 0x1fd9, {1, {0x1fd1}}},
+ { 0x1fda, {1, {0x1f76}}},
+ { 0x1fdb, {1, {0x1f77}}},
+ { 0x1fe2, {3, {0x03c5, 0x0308, 0x0300}}},
+ { 0x1fe3, {3, {0x03c5, 0x0308, 0x0301}}},
+ { 0x1fe4, {2, {0x03c1, 0x0313}}},
+ { 0x1fe6, {2, {0x03c5, 0x0342}}},
+ { 0x1fe7, {3, {0x03c5, 0x0308, 0x0342}}},
+ { 0x1fe8, {1, {0x1fe0}}},
+ { 0x1fe9, {1, {0x1fe1}}},
+ { 0x1fea, {1, {0x1f7a}}},
+ { 0x1feb, {1, {0x1f7b}}},
+ { 0x1fec, {1, {0x1fe5}}},
+ { 0x1ff2, {2, {0x1f7c, 0x03b9}}},
+ { 0x1ff3, {2, {0x03c9, 0x03b9}}},
+ { 0x1ff4, {2, {0x03ce, 0x03b9}}},
+ { 0x1ff6, {2, {0x03c9, 0x0342}}},
+ { 0x1ff7, {3, {0x03c9, 0x0342, 0x03b9}}},
+ { 0x1ff8, {1, {0x1f78}}},
+ { 0x1ff9, {1, {0x1f79}}},
+ { 0x1ffa, {1, {0x1f7c}}},
+ { 0x1ffb, {1, {0x1f7d}}},
+ { 0x1ffc, {2, {0x03c9, 0x03b9}}},
+ { 0x2126, {1, {0x03c9}}},
+ { 0x212a, {1, {0x006b}}},
+ { 0x212b, {1, {0x00e5}}},
+ { 0x2160, {1, {0x2170}}},
+ { 0x2161, {1, {0x2171}}},
+ { 0x2162, {1, {0x2172}}},
+ { 0x2163, {1, {0x2173}}},
+ { 0x2164, {1, {0x2174}}},
+ { 0x2165, {1, {0x2175}}},
+ { 0x2166, {1, {0x2176}}},
+ { 0x2167, {1, {0x2177}}},
+ { 0x2168, {1, {0x2178}}},
+ { 0x2169, {1, {0x2179}}},
+ { 0x216a, {1, {0x217a}}},
+ { 0x216b, {1, {0x217b}}},
+ { 0x216c, {1, {0x217c}}},
+ { 0x216d, {1, {0x217d}}},
+ { 0x216e, {1, {0x217e}}},
+ { 0x216f, {1, {0x217f}}},
+ { 0x24b6, {1, {0x24d0}}},
+ { 0x24b7, {1, {0x24d1}}},
+ { 0x24b8, {1, {0x24d2}}},
+ { 0x24b9, {1, {0x24d3}}},
+ { 0x24ba, {1, {0x24d4}}},
+ { 0x24bb, {1, {0x24d5}}},
+ { 0x24bc, {1, {0x24d6}}},
+ { 0x24bd, {1, {0x24d7}}},
+ { 0x24be, {1, {0x24d8}}},
+ { 0x24bf, {1, {0x24d9}}},
+ { 0x24c0, {1, {0x24da}}},
+ { 0x24c1, {1, {0x24db}}},
+ { 0x24c2, {1, {0x24dc}}},
+ { 0x24c3, {1, {0x24dd}}},
+ { 0x24c4, {1, {0x24de}}},
+ { 0x24c5, {1, {0x24df}}},
+ { 0x24c6, {1, {0x24e0}}},
+ { 0x24c7, {1, {0x24e1}}},
+ { 0x24c8, {1, {0x24e2}}},
+ { 0x24c9, {1, {0x24e3}}},
+ { 0x24ca, {1, {0x24e4}}},
+ { 0x24cb, {1, {0x24e5}}},
+ { 0x24cc, {1, {0x24e6}}},
+ { 0x24cd, {1, {0x24e7}}},
+ { 0x24ce, {1, {0x24e8}}},
+ { 0x24cf, {1, {0x24e9}}},
+ { 0x2c00, {1, {0x2c30}}},
+ { 0x2c01, {1, {0x2c31}}},
+ { 0x2c02, {1, {0x2c32}}},
+ { 0x2c03, {1, {0x2c33}}},
+ { 0x2c04, {1, {0x2c34}}},
+ { 0x2c05, {1, {0x2c35}}},
+ { 0x2c06, {1, {0x2c36}}},
+ { 0x2c07, {1, {0x2c37}}},
+ { 0x2c08, {1, {0x2c38}}},
+ { 0x2c09, {1, {0x2c39}}},
+ { 0x2c0a, {1, {0x2c3a}}},
+ { 0x2c0b, {1, {0x2c3b}}},
+ { 0x2c0c, {1, {0x2c3c}}},
+ { 0x2c0d, {1, {0x2c3d}}},
+ { 0x2c0e, {1, {0x2c3e}}},
+ { 0x2c0f, {1, {0x2c3f}}},
+ { 0x2c10, {1, {0x2c40}}},
+ { 0x2c11, {1, {0x2c41}}},
+ { 0x2c12, {1, {0x2c42}}},
+ { 0x2c13, {1, {0x2c43}}},
+ { 0x2c14, {1, {0x2c44}}},
+ { 0x2c15, {1, {0x2c45}}},
+ { 0x2c16, {1, {0x2c46}}},
+ { 0x2c17, {1, {0x2c47}}},
+ { 0x2c18, {1, {0x2c48}}},
+ { 0x2c19, {1, {0x2c49}}},
+ { 0x2c1a, {1, {0x2c4a}}},
+ { 0x2c1b, {1, {0x2c4b}}},
+ { 0x2c1c, {1, {0x2c4c}}},
+ { 0x2c1d, {1, {0x2c4d}}},
+ { 0x2c1e, {1, {0x2c4e}}},
+ { 0x2c1f, {1, {0x2c4f}}},
+ { 0x2c20, {1, {0x2c50}}},
+ { 0x2c21, {1, {0x2c51}}},
+ { 0x2c22, {1, {0x2c52}}},
+ { 0x2c23, {1, {0x2c53}}},
+ { 0x2c24, {1, {0x2c54}}},
+ { 0x2c25, {1, {0x2c55}}},
+ { 0x2c26, {1, {0x2c56}}},
+ { 0x2c27, {1, {0x2c57}}},
+ { 0x2c28, {1, {0x2c58}}},
+ { 0x2c29, {1, {0x2c59}}},
+ { 0x2c2a, {1, {0x2c5a}}},
+ { 0x2c2b, {1, {0x2c5b}}},
+ { 0x2c2c, {1, {0x2c5c}}},
+ { 0x2c2d, {1, {0x2c5d}}},
+ { 0x2c2e, {1, {0x2c5e}}},
+ { 0x2c80, {1, {0x2c81}}},
+ { 0x2c82, {1, {0x2c83}}},
+ { 0x2c84, {1, {0x2c85}}},
+ { 0x2c86, {1, {0x2c87}}},
+ { 0x2c88, {1, {0x2c89}}},
+ { 0x2c8a, {1, {0x2c8b}}},
+ { 0x2c8c, {1, {0x2c8d}}},
+ { 0x2c8e, {1, {0x2c8f}}},
+ { 0x2c90, {1, {0x2c91}}},
+ { 0x2c92, {1, {0x2c93}}},
+ { 0x2c94, {1, {0x2c95}}},
+ { 0x2c96, {1, {0x2c97}}},
+ { 0x2c98, {1, {0x2c99}}},
+ { 0x2c9a, {1, {0x2c9b}}},
+ { 0x2c9c, {1, {0x2c9d}}},
+ { 0x2c9e, {1, {0x2c9f}}},
+ { 0x2ca0, {1, {0x2ca1}}},
+ { 0x2ca2, {1, {0x2ca3}}},
+ { 0x2ca4, {1, {0x2ca5}}},
+ { 0x2ca6, {1, {0x2ca7}}},
+ { 0x2ca8, {1, {0x2ca9}}},
+ { 0x2caa, {1, {0x2cab}}},
+ { 0x2cac, {1, {0x2cad}}},
+ { 0x2cae, {1, {0x2caf}}},
+ { 0x2cb0, {1, {0x2cb1}}},
+ { 0x2cb2, {1, {0x2cb3}}},
+ { 0x2cb4, {1, {0x2cb5}}},
+ { 0x2cb6, {1, {0x2cb7}}},
+ { 0x2cb8, {1, {0x2cb9}}},
+ { 0x2cba, {1, {0x2cbb}}},
+ { 0x2cbc, {1, {0x2cbd}}},
+ { 0x2cbe, {1, {0x2cbf}}},
+ { 0x2cc0, {1, {0x2cc1}}},
+ { 0x2cc2, {1, {0x2cc3}}},
+ { 0x2cc4, {1, {0x2cc5}}},
+ { 0x2cc6, {1, {0x2cc7}}},
+ { 0x2cc8, {1, {0x2cc9}}},
+ { 0x2cca, {1, {0x2ccb}}},
+ { 0x2ccc, {1, {0x2ccd}}},
+ { 0x2cce, {1, {0x2ccf}}},
+ { 0x2cd0, {1, {0x2cd1}}},
+ { 0x2cd2, {1, {0x2cd3}}},
+ { 0x2cd4, {1, {0x2cd5}}},
+ { 0x2cd6, {1, {0x2cd7}}},
+ { 0x2cd8, {1, {0x2cd9}}},
+ { 0x2cda, {1, {0x2cdb}}},
+ { 0x2cdc, {1, {0x2cdd}}},
+ { 0x2cde, {1, {0x2cdf}}},
+ { 0x2ce0, {1, {0x2ce1}}},
+ { 0x2ce2, {1, {0x2ce3}}},
+ { 0xfb00, {2, {0x0066, 0x0066}}},
+ { 0xfb01, {2, {0x0066, 0x0069}}},
+ { 0xfb02, {2, {0x0066, 0x006c}}},
+ { 0xfb03, {3, {0x0066, 0x0066, 0x0069}}},
+ { 0xfb04, {3, {0x0066, 0x0066, 0x006c}}},
+ { 0xfb05, {2, {0x0073, 0x0074}}},
+ { 0xfb06, {2, {0x0073, 0x0074}}},
+ { 0xfb13, {2, {0x0574, 0x0576}}},
+ { 0xfb14, {2, {0x0574, 0x0565}}},
+ { 0xfb15, {2, {0x0574, 0x056b}}},
+ { 0xfb16, {2, {0x057e, 0x0576}}},
+ { 0xfb17, {2, {0x0574, 0x056d}}},
+ { 0xff21, {1, {0xff41}}},
+ { 0xff22, {1, {0xff42}}},
+ { 0xff23, {1, {0xff43}}},
+ { 0xff24, {1, {0xff44}}},
+ { 0xff25, {1, {0xff45}}},
+ { 0xff26, {1, {0xff46}}},
+ { 0xff27, {1, {0xff47}}},
+ { 0xff28, {1, {0xff48}}},
+ { 0xff29, {1, {0xff49}}},
+ { 0xff2a, {1, {0xff4a}}},
+ { 0xff2b, {1, {0xff4b}}},
+ { 0xff2c, {1, {0xff4c}}},
+ { 0xff2d, {1, {0xff4d}}},
+ { 0xff2e, {1, {0xff4e}}},
+ { 0xff2f, {1, {0xff4f}}},
+ { 0xff30, {1, {0xff50}}},
+ { 0xff31, {1, {0xff51}}},
+ { 0xff32, {1, {0xff52}}},
+ { 0xff33, {1, {0xff53}}},
+ { 0xff34, {1, {0xff54}}},
+ { 0xff35, {1, {0xff55}}},
+ { 0xff36, {1, {0xff56}}},
+ { 0xff37, {1, {0xff57}}},
+ { 0xff38, {1, {0xff58}}},
+ { 0xff39, {1, {0xff59}}},
+ { 0xff3a, {1, {0xff5a}}},
+ { 0x10400, {1, {0x10428}}},
+ { 0x10401, {1, {0x10429}}},
+ { 0x10402, {1, {0x1042a}}},
+ { 0x10403, {1, {0x1042b}}},
+ { 0x10404, {1, {0x1042c}}},
+ { 0x10405, {1, {0x1042d}}},
+ { 0x10406, {1, {0x1042e}}},
+ { 0x10407, {1, {0x1042f}}},
+ { 0x10408, {1, {0x10430}}},
+ { 0x10409, {1, {0x10431}}},
+ { 0x1040a, {1, {0x10432}}},
+ { 0x1040b, {1, {0x10433}}},
+ { 0x1040c, {1, {0x10434}}},
+ { 0x1040d, {1, {0x10435}}},
+ { 0x1040e, {1, {0x10436}}},
+ { 0x1040f, {1, {0x10437}}},
+ { 0x10410, {1, {0x10438}}},
+ { 0x10411, {1, {0x10439}}},
+ { 0x10412, {1, {0x1043a}}},
+ { 0x10413, {1, {0x1043b}}},
+ { 0x10414, {1, {0x1043c}}},
+ { 0x10415, {1, {0x1043d}}},
+ { 0x10416, {1, {0x1043e}}},
+ { 0x10417, {1, {0x1043f}}},
+ { 0x10418, {1, {0x10440}}},
+ { 0x10419, {1, {0x10441}}},
+ { 0x1041a, {1, {0x10442}}},
+ { 0x1041b, {1, {0x10443}}},
+ { 0x1041c, {1, {0x10444}}},
+ { 0x1041d, {1, {0x10445}}},
+ { 0x1041e, {1, {0x10446}}},
+ { 0x1041f, {1, {0x10447}}},
+ { 0x10420, {1, {0x10448}}},
+ { 0x10421, {1, {0x10449}}},
+ { 0x10422, {1, {0x1044a}}},
+ { 0x10423, {1, {0x1044b}}},
+ { 0x10424, {1, {0x1044c}}},
+ { 0x10425, {1, {0x1044d}}},
+ { 0x10426, {1, {0x1044e}}},
+ { 0x10427, {1, {0x1044f}}}
+};
+
+static const CaseFold_11_Type CaseFold_Locale[] = {
+ { 0x0049, {1, {0x0069}}},
+ { 0x0130, {2, {0x0069, 0x0307}}}
+};
+
+static const CaseUnfold_11_Type CaseUnfold_11[] = {
+ { 0x0061, {1, {0x0041 }}},
+ { 0x0062, {1, {0x0042 }}},
+ { 0x0063, {1, {0x0043 }}},
+ { 0x0064, {1, {0x0044 }}},
+ { 0x0065, {1, {0x0045 }}},
+ { 0x0066, {1, {0x0046 }}},
+ { 0x0067, {1, {0x0047 }}},
+ { 0x0068, {1, {0x0048 }}},
+ { 0x006a, {1, {0x004a }}},
+ { 0x006b, {2, {0x212a, 0x004b }}},
+ { 0x006c, {1, {0x004c }}},
+ { 0x006d, {1, {0x004d }}},
+ { 0x006e, {1, {0x004e }}},
+ { 0x006f, {1, {0x004f }}},
+ { 0x0070, {1, {0x0050 }}},
+ { 0x0071, {1, {0x0051 }}},
+ { 0x0072, {1, {0x0052 }}},
+ { 0x0073, {2, {0x0053, 0x017f }}},
+ { 0x0074, {1, {0x0054 }}},
+ { 0x0075, {1, {0x0055 }}},
+ { 0x0076, {1, {0x0056 }}},
+ { 0x0077, {1, {0x0057 }}},
+ { 0x0078, {1, {0x0058 }}},
+ { 0x0079, {1, {0x0059 }}},
+ { 0x007a, {1, {0x005a }}},
+ { 0x00e0, {1, {0x00c0 }}},
+ { 0x00e1, {1, {0x00c1 }}},
+ { 0x00e2, {1, {0x00c2 }}},
+ { 0x00e3, {1, {0x00c3 }}},
+ { 0x00e4, {1, {0x00c4 }}},
+ { 0x00e5, {2, {0x212b, 0x00c5 }}},
+ { 0x00e6, {1, {0x00c6 }}},
+ { 0x00e7, {1, {0x00c7 }}},
+ { 0x00e8, {1, {0x00c8 }}},
+ { 0x00e9, {1, {0x00c9 }}},
+ { 0x00ea, {1, {0x00ca }}},
+ { 0x00eb, {1, {0x00cb }}},
+ { 0x00ec, {1, {0x00cc }}},
+ { 0x00ed, {1, {0x00cd }}},
+ { 0x00ee, {1, {0x00ce }}},
+ { 0x00ef, {1, {0x00cf }}},
+ { 0x00f0, {1, {0x00d0 }}},
+ { 0x00f1, {1, {0x00d1 }}},
+ { 0x00f2, {1, {0x00d2 }}},
+ { 0x00f3, {1, {0x00d3 }}},
+ { 0x00f4, {1, {0x00d4 }}},
+ { 0x00f5, {1, {0x00d5 }}},
+ { 0x00f6, {1, {0x00d6 }}},
+ { 0x00f8, {1, {0x00d8 }}},
+ { 0x00f9, {1, {0x00d9 }}},
+ { 0x00fa, {1, {0x00da }}},
+ { 0x00fb, {1, {0x00db }}},
+ { 0x00fc, {1, {0x00dc }}},
+ { 0x00fd, {1, {0x00dd }}},
+ { 0x00fe, {1, {0x00de }}},
+ { 0x00ff, {1, {0x0178 }}},
+ { 0x0101, {1, {0x0100 }}},
+ { 0x0103, {1, {0x0102 }}},
+ { 0x0105, {1, {0x0104 }}},
+ { 0x0107, {1, {0x0106 }}},
+ { 0x0109, {1, {0x0108 }}},
+ { 0x010b, {1, {0x010a }}},
+ { 0x010d, {1, {0x010c }}},
+ { 0x010f, {1, {0x010e }}},
+ { 0x0111, {1, {0x0110 }}},
+ { 0x0113, {1, {0x0112 }}},
+ { 0x0115, {1, {0x0114 }}},
+ { 0x0117, {1, {0x0116 }}},
+ { 0x0119, {1, {0x0118 }}},
+ { 0x011b, {1, {0x011a }}},
+ { 0x011d, {1, {0x011c }}},
+ { 0x011f, {1, {0x011e }}},
+ { 0x0121, {1, {0x0120 }}},
+ { 0x0123, {1, {0x0122 }}},
+ { 0x0125, {1, {0x0124 }}},
+ { 0x0127, {1, {0x0126 }}},
+ { 0x0129, {1, {0x0128 }}},
+ { 0x012b, {1, {0x012a }}},
+ { 0x012d, {1, {0x012c }}},
+ { 0x012f, {1, {0x012e }}},
+ { 0x0133, {1, {0x0132 }}},
+ { 0x0135, {1, {0x0134 }}},
+ { 0x0137, {1, {0x0136 }}},
+ { 0x013a, {1, {0x0139 }}},
+ { 0x013c, {1, {0x013b }}},
+ { 0x013e, {1, {0x013d }}},
+ { 0x0140, {1, {0x013f }}},
+ { 0x0142, {1, {0x0141 }}},
+ { 0x0144, {1, {0x0143 }}},
+ { 0x0146, {1, {0x0145 }}},
+ { 0x0148, {1, {0x0147 }}},
+ { 0x014b, {1, {0x014a }}},
+ { 0x014d, {1, {0x014c }}},
+ { 0x014f, {1, {0x014e }}},
+ { 0x0151, {1, {0x0150 }}},
+ { 0x0153, {1, {0x0152 }}},
+ { 0x0155, {1, {0x0154 }}},
+ { 0x0157, {1, {0x0156 }}},
+ { 0x0159, {1, {0x0158 }}},
+ { 0x015b, {1, {0x015a }}},
+ { 0x015d, {1, {0x015c }}},
+ { 0x015f, {1, {0x015e }}},
+ { 0x0161, {1, {0x0160 }}},
+ { 0x0163, {1, {0x0162 }}},
+ { 0x0165, {1, {0x0164 }}},
+ { 0x0167, {1, {0x0166 }}},
+ { 0x0169, {1, {0x0168 }}},
+ { 0x016b, {1, {0x016a }}},
+ { 0x016d, {1, {0x016c }}},
+ { 0x016f, {1, {0x016e }}},
+ { 0x0171, {1, {0x0170 }}},
+ { 0x0173, {1, {0x0172 }}},
+ { 0x0175, {1, {0x0174 }}},
+ { 0x0177, {1, {0x0176 }}},
+ { 0x017a, {1, {0x0179 }}},
+ { 0x017c, {1, {0x017b }}},
+ { 0x017e, {1, {0x017d }}},
+ { 0x0183, {1, {0x0182 }}},
+ { 0x0185, {1, {0x0184 }}},
+ { 0x0188, {1, {0x0187 }}},
+ { 0x018c, {1, {0x018b }}},
+ { 0x0192, {1, {0x0191 }}},
+ { 0x0195, {1, {0x01f6 }}},
+ { 0x0199, {1, {0x0198 }}},
+ { 0x019a, {1, {0x023d }}},
+ { 0x019e, {1, {0x0220 }}},
+ { 0x01a1, {1, {0x01a0 }}},
+ { 0x01a3, {1, {0x01a2 }}},
+ { 0x01a5, {1, {0x01a4 }}},
+ { 0x01a8, {1, {0x01a7 }}},
+ { 0x01ad, {1, {0x01ac }}},
+ { 0x01b0, {1, {0x01af }}},
+ { 0x01b4, {1, {0x01b3 }}},
+ { 0x01b6, {1, {0x01b5 }}},
+ { 0x01b9, {1, {0x01b8 }}},
+ { 0x01bd, {1, {0x01bc }}},
+ { 0x01bf, {1, {0x01f7 }}},
+ { 0x01c6, {2, {0x01c4, 0x01c5 }}},
+ { 0x01c9, {2, {0x01c7, 0x01c8 }}},
+ { 0x01cc, {2, {0x01ca, 0x01cb }}},
+ { 0x01ce, {1, {0x01cd }}},
+ { 0x01d0, {1, {0x01cf }}},
+ { 0x01d2, {1, {0x01d1 }}},
+ { 0x01d4, {1, {0x01d3 }}},
+ { 0x01d6, {1, {0x01d5 }}},
+ { 0x01d8, {1, {0x01d7 }}},
+ { 0x01da, {1, {0x01d9 }}},
+ { 0x01dc, {1, {0x01db }}},
+ { 0x01dd, {1, {0x018e }}},
+ { 0x01df, {1, {0x01de }}},
+ { 0x01e1, {1, {0x01e0 }}},
+ { 0x01e3, {1, {0x01e2 }}},
+ { 0x01e5, {1, {0x01e4 }}},
+ { 0x01e7, {1, {0x01e6 }}},
+ { 0x01e9, {1, {0x01e8 }}},
+ { 0x01eb, {1, {0x01ea }}},
+ { 0x01ed, {1, {0x01ec }}},
+ { 0x01ef, {1, {0x01ee }}},
+ { 0x01f3, {2, {0x01f1, 0x01f2 }}},
+ { 0x01f5, {1, {0x01f4 }}},
+ { 0x01f9, {1, {0x01f8 }}},
+ { 0x01fb, {1, {0x01fa }}},
+ { 0x01fd, {1, {0x01fc }}},
+ { 0x01ff, {1, {0x01fe }}},
+ { 0x0201, {1, {0x0200 }}},
+ { 0x0203, {1, {0x0202 }}},
+ { 0x0205, {1, {0x0204 }}},
+ { 0x0207, {1, {0x0206 }}},
+ { 0x0209, {1, {0x0208 }}},
+ { 0x020b, {1, {0x020a }}},
+ { 0x020d, {1, {0x020c }}},
+ { 0x020f, {1, {0x020e }}},
+ { 0x0211, {1, {0x0210 }}},
+ { 0x0213, {1, {0x0212 }}},
+ { 0x0215, {1, {0x0214 }}},
+ { 0x0217, {1, {0x0216 }}},
+ { 0x0219, {1, {0x0218 }}},
+ { 0x021b, {1, {0x021a }}},
+ { 0x021d, {1, {0x021c }}},
+ { 0x021f, {1, {0x021e }}},
+ { 0x0223, {1, {0x0222 }}},
+ { 0x0225, {1, {0x0224 }}},
+ { 0x0227, {1, {0x0226 }}},
+ { 0x0229, {1, {0x0228 }}},
+ { 0x022b, {1, {0x022a }}},
+ { 0x022d, {1, {0x022c }}},
+ { 0x022f, {1, {0x022e }}},
+ { 0x0231, {1, {0x0230 }}},
+ { 0x0233, {1, {0x0232 }}},
+ { 0x023c, {1, {0x023b }}},
+ { 0x0253, {1, {0x0181 }}},
+ { 0x0254, {1, {0x0186 }}},
+ { 0x0256, {1, {0x0189 }}},
+ { 0x0257, {1, {0x018a }}},
+ { 0x0259, {1, {0x018f }}},
+ { 0x025b, {1, {0x0190 }}},
+ { 0x0260, {1, {0x0193 }}},
+ { 0x0263, {1, {0x0194 }}},
+ { 0x0268, {1, {0x0197 }}},
+ { 0x0269, {1, {0x0196 }}},
+ { 0x026f, {1, {0x019c }}},
+ { 0x0272, {1, {0x019d }}},
+ { 0x0275, {1, {0x019f }}},
+ { 0x0280, {1, {0x01a6 }}},
+ { 0x0283, {1, {0x01a9 }}},
+ { 0x0288, {1, {0x01ae }}},
+ { 0x028a, {1, {0x01b1 }}},
+ { 0x028b, {1, {0x01b2 }}},
+ { 0x0292, {1, {0x01b7 }}},
+ { 0x0294, {1, {0x0241 }}},
+ { 0x03ac, {1, {0x0386 }}},
+ { 0x03ad, {1, {0x0388 }}},
+ { 0x03ae, {1, {0x0389 }}},
+ { 0x03af, {1, {0x038a }}},
+ { 0x03b1, {1, {0x0391 }}},
+ { 0x03b2, {2, {0x0392, 0x03d0 }}},
+ { 0x03b3, {1, {0x0393 }}},
+ { 0x03b4, {1, {0x0394 }}},
+ { 0x03b5, {2, {0x03f5, 0x0395 }}},
+ { 0x03b6, {1, {0x0396 }}},
+ { 0x03b7, {1, {0x0397 }}},
+ { 0x03b8, {3, {0x03f4, 0x0398, 0x03d1 }}},
+ { 0x03b9, {3, {0x1fbe, 0x0399, 0x0345 }}},
+ { 0x03ba, {2, {0x03f0, 0x039a }}},
+ { 0x03bb, {1, {0x039b }}},
+ { 0x03bc, {2, {0x00b5, 0x039c }}},
+ { 0x03bd, {1, {0x039d }}},
+ { 0x03be, {1, {0x039e }}},
+ { 0x03bf, {1, {0x039f }}},
+ { 0x03c0, {2, {0x03a0, 0x03d6 }}},
+ { 0x03c1, {2, {0x03f1, 0x03a1 }}},
+ { 0x03c3, {2, {0x03a3, 0x03c2 }}},
+ { 0x03c4, {1, {0x03a4 }}},
+ { 0x03c5, {1, {0x03a5 }}},
+ { 0x03c6, {2, {0x03a6, 0x03d5 }}},
+ { 0x03c7, {1, {0x03a7 }}},
+ { 0x03c8, {1, {0x03a8 }}},
+ { 0x03c9, {2, {0x03a9, 0x2126 }}},
+ { 0x03ca, {1, {0x03aa }}},
+ { 0x03cb, {1, {0x03ab }}},
+ { 0x03cc, {1, {0x038c }}},
+ { 0x03cd, {1, {0x038e }}},
+ { 0x03ce, {1, {0x038f }}},
+ { 0x03d9, {1, {0x03d8 }}},
+ { 0x03db, {1, {0x03da }}},
+ { 0x03dd, {1, {0x03dc }}},
+ { 0x03df, {1, {0x03de }}},
+ { 0x03e1, {1, {0x03e0 }}},
+ { 0x03e3, {1, {0x03e2 }}},
+ { 0x03e5, {1, {0x03e4 }}},
+ { 0x03e7, {1, {0x03e6 }}},
+ { 0x03e9, {1, {0x03e8 }}},
+ { 0x03eb, {1, {0x03ea }}},
+ { 0x03ed, {1, {0x03ec }}},
+ { 0x03ef, {1, {0x03ee }}},
+ { 0x03f2, {1, {0x03f9 }}},
+ { 0x03f8, {1, {0x03f7 }}},
+ { 0x03fb, {1, {0x03fa }}},
+ { 0x0430, {1, {0x0410 }}},
+ { 0x0431, {1, {0x0411 }}},
+ { 0x0432, {1, {0x0412 }}},
+ { 0x0433, {1, {0x0413 }}},
+ { 0x0434, {1, {0x0414 }}},
+ { 0x0435, {1, {0x0415 }}},
+ { 0x0436, {1, {0x0416 }}},
+ { 0x0437, {1, {0x0417 }}},
+ { 0x0438, {1, {0x0418 }}},
+ { 0x0439, {1, {0x0419 }}},
+ { 0x043a, {1, {0x041a }}},
+ { 0x043b, {1, {0x041b }}},
+ { 0x043c, {1, {0x041c }}},
+ { 0x043d, {1, {0x041d }}},
+ { 0x043e, {1, {0x041e }}},
+ { 0x043f, {1, {0x041f }}},
+ { 0x0440, {1, {0x0420 }}},
+ { 0x0441, {1, {0x0421 }}},
+ { 0x0442, {1, {0x0422 }}},
+ { 0x0443, {1, {0x0423 }}},
+ { 0x0444, {1, {0x0424 }}},
+ { 0x0445, {1, {0x0425 }}},
+ { 0x0446, {1, {0x0426 }}},
+ { 0x0447, {1, {0x0427 }}},
+ { 0x0448, {1, {0x0428 }}},
+ { 0x0449, {1, {0x0429 }}},
+ { 0x044a, {1, {0x042a }}},
+ { 0x044b, {1, {0x042b }}},
+ { 0x044c, {1, {0x042c }}},
+ { 0x044d, {1, {0x042d }}},
+ { 0x044e, {1, {0x042e }}},
+ { 0x044f, {1, {0x042f }}},
+ { 0x0450, {1, {0x0400 }}},
+ { 0x0451, {1, {0x0401 }}},
+ { 0x0452, {1, {0x0402 }}},
+ { 0x0453, {1, {0x0403 }}},
+ { 0x0454, {1, {0x0404 }}},
+ { 0x0455, {1, {0x0405 }}},
+ { 0x0456, {1, {0x0406 }}},
+ { 0x0457, {1, {0x0407 }}},
+ { 0x0458, {1, {0x0408 }}},
+ { 0x0459, {1, {0x0409 }}},
+ { 0x045a, {1, {0x040a }}},
+ { 0x045b, {1, {0x040b }}},
+ { 0x045c, {1, {0x040c }}},
+ { 0x045d, {1, {0x040d }}},
+ { 0x045e, {1, {0x040e }}},
+ { 0x045f, {1, {0x040f }}},
+ { 0x0461, {1, {0x0460 }}},
+ { 0x0463, {1, {0x0462 }}},
+ { 0x0465, {1, {0x0464 }}},
+ { 0x0467, {1, {0x0466 }}},
+ { 0x0469, {1, {0x0468 }}},
+ { 0x046b, {1, {0x046a }}},
+ { 0x046d, {1, {0x046c }}},
+ { 0x046f, {1, {0x046e }}},
+ { 0x0471, {1, {0x0470 }}},
+ { 0x0473, {1, {0x0472 }}},
+ { 0x0475, {1, {0x0474 }}},
+ { 0x0477, {1, {0x0476 }}},
+ { 0x0479, {1, {0x0478 }}},
+ { 0x047b, {1, {0x047a }}},
+ { 0x047d, {1, {0x047c }}},
+ { 0x047f, {1, {0x047e }}},
+ { 0x0481, {1, {0x0480 }}},
+ { 0x048b, {1, {0x048a }}},
+ { 0x048d, {1, {0x048c }}},
+ { 0x048f, {1, {0x048e }}},
+ { 0x0491, {1, {0x0490 }}},
+ { 0x0493, {1, {0x0492 }}},
+ { 0x0495, {1, {0x0494 }}},
+ { 0x0497, {1, {0x0496 }}},
+ { 0x0499, {1, {0x0498 }}},
+ { 0x049b, {1, {0x049a }}},
+ { 0x049d, {1, {0x049c }}},
+ { 0x049f, {1, {0x049e }}},
+ { 0x04a1, {1, {0x04a0 }}},
+ { 0x04a3, {1, {0x04a2 }}},
+ { 0x04a5, {1, {0x04a4 }}},
+ { 0x04a7, {1, {0x04a6 }}},
+ { 0x04a9, {1, {0x04a8 }}},
+ { 0x04ab, {1, {0x04aa }}},
+ { 0x04ad, {1, {0x04ac }}},
+ { 0x04af, {1, {0x04ae }}},
+ { 0x04b1, {1, {0x04b0 }}},
+ { 0x04b3, {1, {0x04b2 }}},
+ { 0x04b5, {1, {0x04b4 }}},
+ { 0x04b7, {1, {0x04b6 }}},
+ { 0x04b9, {1, {0x04b8 }}},
+ { 0x04bb, {1, {0x04ba }}},
+ { 0x04bd, {1, {0x04bc }}},
+ { 0x04bf, {1, {0x04be }}},
+ { 0x04c2, {1, {0x04c1 }}},
+ { 0x04c4, {1, {0x04c3 }}},
+ { 0x04c6, {1, {0x04c5 }}},
+ { 0x04c8, {1, {0x04c7 }}},
+ { 0x04ca, {1, {0x04c9 }}},
+ { 0x04cc, {1, {0x04cb }}},
+ { 0x04ce, {1, {0x04cd }}},
+ { 0x04d1, {1, {0x04d0 }}},
+ { 0x04d3, {1, {0x04d2 }}},
+ { 0x04d5, {1, {0x04d4 }}},
+ { 0x04d7, {1, {0x04d6 }}},
+ { 0x04d9, {1, {0x04d8 }}},
+ { 0x04db, {1, {0x04da }}},
+ { 0x04dd, {1, {0x04dc }}},
+ { 0x04df, {1, {0x04de }}},
+ { 0x04e1, {1, {0x04e0 }}},
+ { 0x04e3, {1, {0x04e2 }}},
+ { 0x04e5, {1, {0x04e4 }}},
+ { 0x04e7, {1, {0x04e6 }}},
+ { 0x04e9, {1, {0x04e8 }}},
+ { 0x04eb, {1, {0x04ea }}},
+ { 0x04ed, {1, {0x04ec }}},
+ { 0x04ef, {1, {0x04ee }}},
+ { 0x04f1, {1, {0x04f0 }}},
+ { 0x04f3, {1, {0x04f2 }}},
+ { 0x04f5, {1, {0x04f4 }}},
+ { 0x04f7, {1, {0x04f6 }}},
+ { 0x04f9, {1, {0x04f8 }}},
+ { 0x0501, {1, {0x0500 }}},
+ { 0x0503, {1, {0x0502 }}},
+ { 0x0505, {1, {0x0504 }}},
+ { 0x0507, {1, {0x0506 }}},
+ { 0x0509, {1, {0x0508 }}},
+ { 0x050b, {1, {0x050a }}},
+ { 0x050d, {1, {0x050c }}},
+ { 0x050f, {1, {0x050e }}},
+ { 0x0561, {1, {0x0531 }}},
+ { 0x0562, {1, {0x0532 }}},
+ { 0x0563, {1, {0x0533 }}},
+ { 0x0564, {1, {0x0534 }}},
+ { 0x0565, {1, {0x0535 }}},
+ { 0x0566, {1, {0x0536 }}},
+ { 0x0567, {1, {0x0537 }}},
+ { 0x0568, {1, {0x0538 }}},
+ { 0x0569, {1, {0x0539 }}},
+ { 0x056a, {1, {0x053a }}},
+ { 0x056b, {1, {0x053b }}},
+ { 0x056c, {1, {0x053c }}},
+ { 0x056d, {1, {0x053d }}},
+ { 0x056e, {1, {0x053e }}},
+ { 0x056f, {1, {0x053f }}},
+ { 0x0570, {1, {0x0540 }}},
+ { 0x0571, {1, {0x0541 }}},
+ { 0x0572, {1, {0x0542 }}},
+ { 0x0573, {1, {0x0543 }}},
+ { 0x0574, {1, {0x0544 }}},
+ { 0x0575, {1, {0x0545 }}},
+ { 0x0576, {1, {0x0546 }}},
+ { 0x0577, {1, {0x0547 }}},
+ { 0x0578, {1, {0x0548 }}},
+ { 0x0579, {1, {0x0549 }}},
+ { 0x057a, {1, {0x054a }}},
+ { 0x057b, {1, {0x054b }}},
+ { 0x057c, {1, {0x054c }}},
+ { 0x057d, {1, {0x054d }}},
+ { 0x057e, {1, {0x054e }}},
+ { 0x057f, {1, {0x054f }}},
+ { 0x0580, {1, {0x0550 }}},
+ { 0x0581, {1, {0x0551 }}},
+ { 0x0582, {1, {0x0552 }}},
+ { 0x0583, {1, {0x0553 }}},
+ { 0x0584, {1, {0x0554 }}},
+ { 0x0585, {1, {0x0555 }}},
+ { 0x0586, {1, {0x0556 }}},
+ { 0x1e01, {1, {0x1e00 }}},
+ { 0x1e03, {1, {0x1e02 }}},
+ { 0x1e05, {1, {0x1e04 }}},
+ { 0x1e07, {1, {0x1e06 }}},
+ { 0x1e09, {1, {0x1e08 }}},
+ { 0x1e0b, {1, {0x1e0a }}},
+ { 0x1e0d, {1, {0x1e0c }}},
+ { 0x1e0f, {1, {0x1e0e }}},
+ { 0x1e11, {1, {0x1e10 }}},
+ { 0x1e13, {1, {0x1e12 }}},
+ { 0x1e15, {1, {0x1e14 }}},
+ { 0x1e17, {1, {0x1e16 }}},
+ { 0x1e19, {1, {0x1e18 }}},
+ { 0x1e1b, {1, {0x1e1a }}},
+ { 0x1e1d, {1, {0x1e1c }}},
+ { 0x1e1f, {1, {0x1e1e }}},
+ { 0x1e21, {1, {0x1e20 }}},
+ { 0x1e23, {1, {0x1e22 }}},
+ { 0x1e25, {1, {0x1e24 }}},
+ { 0x1e27, {1, {0x1e26 }}},
+ { 0x1e29, {1, {0x1e28 }}},
+ { 0x1e2b, {1, {0x1e2a }}},
+ { 0x1e2d, {1, {0x1e2c }}},
+ { 0x1e2f, {1, {0x1e2e }}},
+ { 0x1e31, {1, {0x1e30 }}},
+ { 0x1e33, {1, {0x1e32 }}},
+ { 0x1e35, {1, {0x1e34 }}},
+ { 0x1e37, {1, {0x1e36 }}},
+ { 0x1e39, {1, {0x1e38 }}},
+ { 0x1e3b, {1, {0x1e3a }}},
+ { 0x1e3d, {1, {0x1e3c }}},
+ { 0x1e3f, {1, {0x1e3e }}},
+ { 0x1e41, {1, {0x1e40 }}},
+ { 0x1e43, {1, {0x1e42 }}},
+ { 0x1e45, {1, {0x1e44 }}},
+ { 0x1e47, {1, {0x1e46 }}},
+ { 0x1e49, {1, {0x1e48 }}},
+ { 0x1e4b, {1, {0x1e4a }}},
+ { 0x1e4d, {1, {0x1e4c }}},
+ { 0x1e4f, {1, {0x1e4e }}},
+ { 0x1e51, {1, {0x1e50 }}},
+ { 0x1e53, {1, {0x1e52 }}},
+ { 0x1e55, {1, {0x1e54 }}},
+ { 0x1e57, {1, {0x1e56 }}},
+ { 0x1e59, {1, {0x1e58 }}},
+ { 0x1e5b, {1, {0x1e5a }}},
+ { 0x1e5d, {1, {0x1e5c }}},
+ { 0x1e5f, {1, {0x1e5e }}},
+ { 0x1e61, {2, {0x1e9b, 0x1e60 }}},
+ { 0x1e63, {1, {0x1e62 }}},
+ { 0x1e65, {1, {0x1e64 }}},
+ { 0x1e67, {1, {0x1e66 }}},
+ { 0x1e69, {1, {0x1e68 }}},
+ { 0x1e6b, {1, {0x1e6a }}},
+ { 0x1e6d, {1, {0x1e6c }}},
+ { 0x1e6f, {1, {0x1e6e }}},
+ { 0x1e71, {1, {0x1e70 }}},
+ { 0x1e73, {1, {0x1e72 }}},
+ { 0x1e75, {1, {0x1e74 }}},
+ { 0x1e77, {1, {0x1e76 }}},
+ { 0x1e79, {1, {0x1e78 }}},
+ { 0x1e7b, {1, {0x1e7a }}},
+ { 0x1e7d, {1, {0x1e7c }}},
+ { 0x1e7f, {1, {0x1e7e }}},
+ { 0x1e81, {1, {0x1e80 }}},
+ { 0x1e83, {1, {0x1e82 }}},
+ { 0x1e85, {1, {0x1e84 }}},
+ { 0x1e87, {1, {0x1e86 }}},
+ { 0x1e89, {1, {0x1e88 }}},
+ { 0x1e8b, {1, {0x1e8a }}},
+ { 0x1e8d, {1, {0x1e8c }}},
+ { 0x1e8f, {1, {0x1e8e }}},
+ { 0x1e91, {1, {0x1e90 }}},
+ { 0x1e93, {1, {0x1e92 }}},
+ { 0x1e95, {1, {0x1e94 }}},
+ { 0x1ea1, {1, {0x1ea0 }}},
+ { 0x1ea3, {1, {0x1ea2 }}},
+ { 0x1ea5, {1, {0x1ea4 }}},
+ { 0x1ea7, {1, {0x1ea6 }}},
+ { 0x1ea9, {1, {0x1ea8 }}},
+ { 0x1eab, {1, {0x1eaa }}},
+ { 0x1ead, {1, {0x1eac }}},
+ { 0x1eaf, {1, {0x1eae }}},
+ { 0x1eb1, {1, {0x1eb0 }}},
+ { 0x1eb3, {1, {0x1eb2 }}},
+ { 0x1eb5, {1, {0x1eb4 }}},
+ { 0x1eb7, {1, {0x1eb6 }}},
+ { 0x1eb9, {1, {0x1eb8 }}},
+ { 0x1ebb, {1, {0x1eba }}},
+ { 0x1ebd, {1, {0x1ebc }}},
+ { 0x1ebf, {1, {0x1ebe }}},
+ { 0x1ec1, {1, {0x1ec0 }}},
+ { 0x1ec3, {1, {0x1ec2 }}},
+ { 0x1ec5, {1, {0x1ec4 }}},
+ { 0x1ec7, {1, {0x1ec6 }}},
+ { 0x1ec9, {1, {0x1ec8 }}},
+ { 0x1ecb, {1, {0x1eca }}},
+ { 0x1ecd, {1, {0x1ecc }}},
+ { 0x1ecf, {1, {0x1ece }}},
+ { 0x1ed1, {1, {0x1ed0 }}},
+ { 0x1ed3, {1, {0x1ed2 }}},
+ { 0x1ed5, {1, {0x1ed4 }}},
+ { 0x1ed7, {1, {0x1ed6 }}},
+ { 0x1ed9, {1, {0x1ed8 }}},
+ { 0x1edb, {1, {0x1eda }}},
+ { 0x1edd, {1, {0x1edc }}},
+ { 0x1edf, {1, {0x1ede }}},
+ { 0x1ee1, {1, {0x1ee0 }}},
+ { 0x1ee3, {1, {0x1ee2 }}},
+ { 0x1ee5, {1, {0x1ee4 }}},
+ { 0x1ee7, {1, {0x1ee6 }}},
+ { 0x1ee9, {1, {0x1ee8 }}},
+ { 0x1eeb, {1, {0x1eea }}},
+ { 0x1eed, {1, {0x1eec }}},
+ { 0x1eef, {1, {0x1eee }}},
+ { 0x1ef1, {1, {0x1ef0 }}},
+ { 0x1ef3, {1, {0x1ef2 }}},
+ { 0x1ef5, {1, {0x1ef4 }}},
+ { 0x1ef7, {1, {0x1ef6 }}},
+ { 0x1ef9, {1, {0x1ef8 }}},
+ { 0x1f00, {1, {0x1f08 }}},
+ { 0x1f01, {1, {0x1f09 }}},
+ { 0x1f02, {1, {0x1f0a }}},
+ { 0x1f03, {1, {0x1f0b }}},
+ { 0x1f04, {1, {0x1f0c }}},
+ { 0x1f05, {1, {0x1f0d }}},
+ { 0x1f06, {1, {0x1f0e }}},
+ { 0x1f07, {1, {0x1f0f }}},
+ { 0x1f10, {1, {0x1f18 }}},
+ { 0x1f11, {1, {0x1f19 }}},
+ { 0x1f12, {1, {0x1f1a }}},
+ { 0x1f13, {1, {0x1f1b }}},
+ { 0x1f14, {1, {0x1f1c }}},
+ { 0x1f15, {1, {0x1f1d }}},
+ { 0x1f20, {1, {0x1f28 }}},
+ { 0x1f21, {1, {0x1f29 }}},
+ { 0x1f22, {1, {0x1f2a }}},
+ { 0x1f23, {1, {0x1f2b }}},
+ { 0x1f24, {1, {0x1f2c }}},
+ { 0x1f25, {1, {0x1f2d }}},
+ { 0x1f26, {1, {0x1f2e }}},
+ { 0x1f27, {1, {0x1f2f }}},
+ { 0x1f30, {1, {0x1f38 }}},
+ { 0x1f31, {1, {0x1f39 }}},
+ { 0x1f32, {1, {0x1f3a }}},
+ { 0x1f33, {1, {0x1f3b }}},
+ { 0x1f34, {1, {0x1f3c }}},
+ { 0x1f35, {1, {0x1f3d }}},
+ { 0x1f36, {1, {0x1f3e }}},
+ { 0x1f37, {1, {0x1f3f }}},
+ { 0x1f40, {1, {0x1f48 }}},
+ { 0x1f41, {1, {0x1f49 }}},
+ { 0x1f42, {1, {0x1f4a }}},
+ { 0x1f43, {1, {0x1f4b }}},
+ { 0x1f44, {1, {0x1f4c }}},
+ { 0x1f45, {1, {0x1f4d }}},
+ { 0x1f51, {1, {0x1f59 }}},
+ { 0x1f53, {1, {0x1f5b }}},
+ { 0x1f55, {1, {0x1f5d }}},
+ { 0x1f57, {1, {0x1f5f }}},
+ { 0x1f60, {1, {0x1f68 }}},
+ { 0x1f61, {1, {0x1f69 }}},
+ { 0x1f62, {1, {0x1f6a }}},
+ { 0x1f63, {1, {0x1f6b }}},
+ { 0x1f64, {1, {0x1f6c }}},
+ { 0x1f65, {1, {0x1f6d }}},
+ { 0x1f66, {1, {0x1f6e }}},
+ { 0x1f67, {1, {0x1f6f }}},
+ { 0x1f70, {1, {0x1fba }}},
+ { 0x1f71, {1, {0x1fbb }}},
+ { 0x1f72, {1, {0x1fc8 }}},
+ { 0x1f73, {1, {0x1fc9 }}},
+ { 0x1f74, {1, {0x1fca }}},
+ { 0x1f75, {1, {0x1fcb }}},
+ { 0x1f76, {1, {0x1fda }}},
+ { 0x1f77, {1, {0x1fdb }}},
+ { 0x1f78, {1, {0x1ff8 }}},
+ { 0x1f79, {1, {0x1ff9 }}},
+ { 0x1f7a, {1, {0x1fea }}},
+ { 0x1f7b, {1, {0x1feb }}},
+ { 0x1f7c, {1, {0x1ffa }}},
+ { 0x1f7d, {1, {0x1ffb }}},
+ { 0x1fb0, {1, {0x1fb8 }}},
+ { 0x1fb1, {1, {0x1fb9 }}},
+ { 0x1fd0, {1, {0x1fd8 }}},
+ { 0x1fd1, {1, {0x1fd9 }}},
+ { 0x1fe0, {1, {0x1fe8 }}},
+ { 0x1fe1, {1, {0x1fe9 }}},
+ { 0x1fe5, {1, {0x1fec }}},
+ { 0x2170, {1, {0x2160 }}},
+ { 0x2171, {1, {0x2161 }}},
+ { 0x2172, {1, {0x2162 }}},
+ { 0x2173, {1, {0x2163 }}},
+ { 0x2174, {1, {0x2164 }}},
+ { 0x2175, {1, {0x2165 }}},
+ { 0x2176, {1, {0x2166 }}},
+ { 0x2177, {1, {0x2167 }}},
+ { 0x2178, {1, {0x2168 }}},
+ { 0x2179, {1, {0x2169 }}},
+ { 0x217a, {1, {0x216a }}},
+ { 0x217b, {1, {0x216b }}},
+ { 0x217c, {1, {0x216c }}},
+ { 0x217d, {1, {0x216d }}},
+ { 0x217e, {1, {0x216e }}},
+ { 0x217f, {1, {0x216f }}},
+ { 0x24d0, {1, {0x24b6 }}},
+ { 0x24d1, {1, {0x24b7 }}},
+ { 0x24d2, {1, {0x24b8 }}},
+ { 0x24d3, {1, {0x24b9 }}},
+ { 0x24d4, {1, {0x24ba }}},
+ { 0x24d5, {1, {0x24bb }}},
+ { 0x24d6, {1, {0x24bc }}},
+ { 0x24d7, {1, {0x24bd }}},
+ { 0x24d8, {1, {0x24be }}},
+ { 0x24d9, {1, {0x24bf }}},
+ { 0x24da, {1, {0x24c0 }}},
+ { 0x24db, {1, {0x24c1 }}},
+ { 0x24dc, {1, {0x24c2 }}},
+ { 0x24dd, {1, {0x24c3 }}},
+ { 0x24de, {1, {0x24c4 }}},
+ { 0x24df, {1, {0x24c5 }}},
+ { 0x24e0, {1, {0x24c6 }}},
+ { 0x24e1, {1, {0x24c7 }}},
+ { 0x24e2, {1, {0x24c8 }}},
+ { 0x24e3, {1, {0x24c9 }}},
+ { 0x24e4, {1, {0x24ca }}},
+ { 0x24e5, {1, {0x24cb }}},
+ { 0x24e6, {1, {0x24cc }}},
+ { 0x24e7, {1, {0x24cd }}},
+ { 0x24e8, {1, {0x24ce }}},
+ { 0x24e9, {1, {0x24cf }}},
+ { 0x2c30, {1, {0x2c00 }}},
+ { 0x2c31, {1, {0x2c01 }}},
+ { 0x2c32, {1, {0x2c02 }}},
+ { 0x2c33, {1, {0x2c03 }}},
+ { 0x2c34, {1, {0x2c04 }}},
+ { 0x2c35, {1, {0x2c05 }}},
+ { 0x2c36, {1, {0x2c06 }}},
+ { 0x2c37, {1, {0x2c07 }}},
+ { 0x2c38, {1, {0x2c08 }}},
+ { 0x2c39, {1, {0x2c09 }}},
+ { 0x2c3a, {1, {0x2c0a }}},
+ { 0x2c3b, {1, {0x2c0b }}},
+ { 0x2c3c, {1, {0x2c0c }}},
+ { 0x2c3d, {1, {0x2c0d }}},
+ { 0x2c3e, {1, {0x2c0e }}},
+ { 0x2c3f, {1, {0x2c0f }}},
+ { 0x2c40, {1, {0x2c10 }}},
+ { 0x2c41, {1, {0x2c11 }}},
+ { 0x2c42, {1, {0x2c12 }}},
+ { 0x2c43, {1, {0x2c13 }}},
+ { 0x2c44, {1, {0x2c14 }}},
+ { 0x2c45, {1, {0x2c15 }}},
+ { 0x2c46, {1, {0x2c16 }}},
+ { 0x2c47, {1, {0x2c17 }}},
+ { 0x2c48, {1, {0x2c18 }}},
+ { 0x2c49, {1, {0x2c19 }}},
+ { 0x2c4a, {1, {0x2c1a }}},
+ { 0x2c4b, {1, {0x2c1b }}},
+ { 0x2c4c, {1, {0x2c1c }}},
+ { 0x2c4d, {1, {0x2c1d }}},
+ { 0x2c4e, {1, {0x2c1e }}},
+ { 0x2c4f, {1, {0x2c1f }}},
+ { 0x2c50, {1, {0x2c20 }}},
+ { 0x2c51, {1, {0x2c21 }}},
+ { 0x2c52, {1, {0x2c22 }}},
+ { 0x2c53, {1, {0x2c23 }}},
+ { 0x2c54, {1, {0x2c24 }}},
+ { 0x2c55, {1, {0x2c25 }}},
+ { 0x2c56, {1, {0x2c26 }}},
+ { 0x2c57, {1, {0x2c27 }}},
+ { 0x2c58, {1, {0x2c28 }}},
+ { 0x2c59, {1, {0x2c29 }}},
+ { 0x2c5a, {1, {0x2c2a }}},
+ { 0x2c5b, {1, {0x2c2b }}},
+ { 0x2c5c, {1, {0x2c2c }}},
+ { 0x2c5d, {1, {0x2c2d }}},
+ { 0x2c5e, {1, {0x2c2e }}},
+ { 0x2c81, {1, {0x2c80 }}},
+ { 0x2c83, {1, {0x2c82 }}},
+ { 0x2c85, {1, {0x2c84 }}},
+ { 0x2c87, {1, {0x2c86 }}},
+ { 0x2c89, {1, {0x2c88 }}},
+ { 0x2c8b, {1, {0x2c8a }}},
+ { 0x2c8d, {1, {0x2c8c }}},
+ { 0x2c8f, {1, {0x2c8e }}},
+ { 0x2c91, {1, {0x2c90 }}},
+ { 0x2c93, {1, {0x2c92 }}},
+ { 0x2c95, {1, {0x2c94 }}},
+ { 0x2c97, {1, {0x2c96 }}},
+ { 0x2c99, {1, {0x2c98 }}},
+ { 0x2c9b, {1, {0x2c9a }}},
+ { 0x2c9d, {1, {0x2c9c }}},
+ { 0x2c9f, {1, {0x2c9e }}},
+ { 0x2ca1, {1, {0x2ca0 }}},
+ { 0x2ca3, {1, {0x2ca2 }}},
+ { 0x2ca5, {1, {0x2ca4 }}},
+ { 0x2ca7, {1, {0x2ca6 }}},
+ { 0x2ca9, {1, {0x2ca8 }}},
+ { 0x2cab, {1, {0x2caa }}},
+ { 0x2cad, {1, {0x2cac }}},
+ { 0x2caf, {1, {0x2cae }}},
+ { 0x2cb1, {1, {0x2cb0 }}},
+ { 0x2cb3, {1, {0x2cb2 }}},
+ { 0x2cb5, {1, {0x2cb4 }}},
+ { 0x2cb7, {1, {0x2cb6 }}},
+ { 0x2cb9, {1, {0x2cb8 }}},
+ { 0x2cbb, {1, {0x2cba }}},
+ { 0x2cbd, {1, {0x2cbc }}},
+ { 0x2cbf, {1, {0x2cbe }}},
+ { 0x2cc1, {1, {0x2cc0 }}},
+ { 0x2cc3, {1, {0x2cc2 }}},
+ { 0x2cc5, {1, {0x2cc4 }}},
+ { 0x2cc7, {1, {0x2cc6 }}},
+ { 0x2cc9, {1, {0x2cc8 }}},
+ { 0x2ccb, {1, {0x2cca }}},
+ { 0x2ccd, {1, {0x2ccc }}},
+ { 0x2ccf, {1, {0x2cce }}},
+ { 0x2cd1, {1, {0x2cd0 }}},
+ { 0x2cd3, {1, {0x2cd2 }}},
+ { 0x2cd5, {1, {0x2cd4 }}},
+ { 0x2cd7, {1, {0x2cd6 }}},
+ { 0x2cd9, {1, {0x2cd8 }}},
+ { 0x2cdb, {1, {0x2cda }}},
+ { 0x2cdd, {1, {0x2cdc }}},
+ { 0x2cdf, {1, {0x2cde }}},
+ { 0x2ce1, {1, {0x2ce0 }}},
+ { 0x2ce3, {1, {0x2ce2 }}},
+ { 0x2d00, {1, {0x10a0 }}},
+ { 0x2d01, {1, {0x10a1 }}},
+ { 0x2d02, {1, {0x10a2 }}},
+ { 0x2d03, {1, {0x10a3 }}},
+ { 0x2d04, {1, {0x10a4 }}},
+ { 0x2d05, {1, {0x10a5 }}},
+ { 0x2d06, {1, {0x10a6 }}},
+ { 0x2d07, {1, {0x10a7 }}},
+ { 0x2d08, {1, {0x10a8 }}},
+ { 0x2d09, {1, {0x10a9 }}},
+ { 0x2d0a, {1, {0x10aa }}},
+ { 0x2d0b, {1, {0x10ab }}},
+ { 0x2d0c, {1, {0x10ac }}},
+ { 0x2d0d, {1, {0x10ad }}},
+ { 0x2d0e, {1, {0x10ae }}},
+ { 0x2d0f, {1, {0x10af }}},
+ { 0x2d10, {1, {0x10b0 }}},
+ { 0x2d11, {1, {0x10b1 }}},
+ { 0x2d12, {1, {0x10b2 }}},
+ { 0x2d13, {1, {0x10b3 }}},
+ { 0x2d14, {1, {0x10b4 }}},
+ { 0x2d15, {1, {0x10b5 }}},
+ { 0x2d16, {1, {0x10b6 }}},
+ { 0x2d17, {1, {0x10b7 }}},
+ { 0x2d18, {1, {0x10b8 }}},
+ { 0x2d19, {1, {0x10b9 }}},
+ { 0x2d1a, {1, {0x10ba }}},
+ { 0x2d1b, {1, {0x10bb }}},
+ { 0x2d1c, {1, {0x10bc }}},
+ { 0x2d1d, {1, {0x10bd }}},
+ { 0x2d1e, {1, {0x10be }}},
+ { 0x2d1f, {1, {0x10bf }}},
+ { 0x2d20, {1, {0x10c0 }}},
+ { 0x2d21, {1, {0x10c1 }}},
+ { 0x2d22, {1, {0x10c2 }}},
+ { 0x2d23, {1, {0x10c3 }}},
+ { 0x2d24, {1, {0x10c4 }}},
+ { 0x2d25, {1, {0x10c5 }}},
+ { 0xff41, {1, {0xff21 }}},
+ { 0xff42, {1, {0xff22 }}},
+ { 0xff43, {1, {0xff23 }}},
+ { 0xff44, {1, {0xff24 }}},
+ { 0xff45, {1, {0xff25 }}},
+ { 0xff46, {1, {0xff26 }}},
+ { 0xff47, {1, {0xff27 }}},
+ { 0xff48, {1, {0xff28 }}},
+ { 0xff49, {1, {0xff29 }}},
+ { 0xff4a, {1, {0xff2a }}},
+ { 0xff4b, {1, {0xff2b }}},
+ { 0xff4c, {1, {0xff2c }}},
+ { 0xff4d, {1, {0xff2d }}},
+ { 0xff4e, {1, {0xff2e }}},
+ { 0xff4f, {1, {0xff2f }}},
+ { 0xff50, {1, {0xff30 }}},
+ { 0xff51, {1, {0xff31 }}},
+ { 0xff52, {1, {0xff32 }}},
+ { 0xff53, {1, {0xff33 }}},
+ { 0xff54, {1, {0xff34 }}},
+ { 0xff55, {1, {0xff35 }}},
+ { 0xff56, {1, {0xff36 }}},
+ { 0xff57, {1, {0xff37 }}},
+ { 0xff58, {1, {0xff38 }}},
+ { 0xff59, {1, {0xff39 }}},
+ { 0xff5a, {1, {0xff3a }}},
+ { 0x10428, {1, {0x10400 }}},
+ { 0x10429, {1, {0x10401 }}},
+ { 0x1042a, {1, {0x10402 }}},
+ { 0x1042b, {1, {0x10403 }}},
+ { 0x1042c, {1, {0x10404 }}},
+ { 0x1042d, {1, {0x10405 }}},
+ { 0x1042e, {1, {0x10406 }}},
+ { 0x1042f, {1, {0x10407 }}},
+ { 0x10430, {1, {0x10408 }}},
+ { 0x10431, {1, {0x10409 }}},
+ { 0x10432, {1, {0x1040a }}},
+ { 0x10433, {1, {0x1040b }}},
+ { 0x10434, {1, {0x1040c }}},
+ { 0x10435, {1, {0x1040d }}},
+ { 0x10436, {1, {0x1040e }}},
+ { 0x10437, {1, {0x1040f }}},
+ { 0x10438, {1, {0x10410 }}},
+ { 0x10439, {1, {0x10411 }}},
+ { 0x1043a, {1, {0x10412 }}},
+ { 0x1043b, {1, {0x10413 }}},
+ { 0x1043c, {1, {0x10414 }}},
+ { 0x1043d, {1, {0x10415 }}},
+ { 0x1043e, {1, {0x10416 }}},
+ { 0x1043f, {1, {0x10417 }}},
+ { 0x10440, {1, {0x10418 }}},
+ { 0x10441, {1, {0x10419 }}},
+ { 0x10442, {1, {0x1041a }}},
+ { 0x10443, {1, {0x1041b }}},
+ { 0x10444, {1, {0x1041c }}},
+ { 0x10445, {1, {0x1041d }}},
+ { 0x10446, {1, {0x1041e }}},
+ { 0x10447, {1, {0x1041f }}},
+ { 0x10448, {1, {0x10420 }}},
+ { 0x10449, {1, {0x10421 }}},
+ { 0x1044a, {1, {0x10422 }}},
+ { 0x1044b, {1, {0x10423 }}},
+ { 0x1044c, {1, {0x10424 }}},
+ { 0x1044d, {1, {0x10425 }}},
+ { 0x1044e, {1, {0x10426 }}},
+ { 0x1044f, {1, {0x10427 }}}
+};
+
+static const CaseUnfold_11_Type CaseUnfold_11_Locale[] = {
+ { 0x0069, {1, {0x0049 }}}
+};
+
+static const CaseUnfold_12_Type CaseUnfold_12[] = {
+ { {0x0061, 0x02be}, {1, {0x1e9a }}},
+ { {0x0066, 0x0066}, {1, {0xfb00 }}},
+ { {0x0066, 0x0069}, {1, {0xfb01 }}},
+ { {0x0066, 0x006c}, {1, {0xfb02 }}},
+ { {0x0068, 0x0331}, {1, {0x1e96 }}},
+ { {0x006a, 0x030c}, {1, {0x01f0 }}},
+ { {0x0073, 0x0073}, {1, {0x00df }}},
+ { {0x0073, 0x0074}, {2, {0xfb05, 0xfb06 }}},
+ { {0x0074, 0x0308}, {1, {0x1e97 }}},
+ { {0x0077, 0x030a}, {1, {0x1e98 }}},
+ { {0x0079, 0x030a}, {1, {0x1e99 }}},
+ { {0x02bc, 0x006e}, {1, {0x0149 }}},
+ { {0x03ac, 0x03b9}, {1, {0x1fb4 }}},
+ { {0x03ae, 0x03b9}, {1, {0x1fc4 }}},
+ { {0x03b1, 0x0342}, {1, {0x1fb6 }}},
+ { {0x03b1, 0x03b9}, {2, {0x1fb3, 0x1fbc }}},
+ { {0x03b7, 0x0342}, {1, {0x1fc6 }}},
+ { {0x03b7, 0x03b9}, {2, {0x1fc3, 0x1fcc }}},
+ { {0x03b9, 0x0342}, {1, {0x1fd6 }}},
+ { {0x03c1, 0x0313}, {1, {0x1fe4 }}},
+ { {0x03c5, 0x0313}, {1, {0x1f50 }}},
+ { {0x03c5, 0x0342}, {1, {0x1fe6 }}},
+ { {0x03c9, 0x0342}, {1, {0x1ff6 }}},
+ { {0x03c9, 0x03b9}, {2, {0x1ff3, 0x1ffc }}},
+ { {0x03ce, 0x03b9}, {1, {0x1ff4 }}},
+ { {0x0565, 0x0582}, {1, {0x0587 }}},
+ { {0x0574, 0x0565}, {1, {0xfb14 }}},
+ { {0x0574, 0x056b}, {1, {0xfb15 }}},
+ { {0x0574, 0x056d}, {1, {0xfb17 }}},
+ { {0x0574, 0x0576}, {1, {0xfb13 }}},
+ { {0x057e, 0x0576}, {1, {0xfb16 }}},
+ { {0x1f00, 0x03b9}, {2, {0x1f88, 0x1f80 }}},
+ { {0x1f01, 0x03b9}, {2, {0x1f81, 0x1f89 }}},
+ { {0x1f02, 0x03b9}, {2, {0x1f82, 0x1f8a }}},
+ { {0x1f03, 0x03b9}, {2, {0x1f83, 0x1f8b }}},
+ { {0x1f04, 0x03b9}, {2, {0x1f84, 0x1f8c }}},
+ { {0x1f05, 0x03b9}, {2, {0x1f85, 0x1f8d }}},
+ { {0x1f06, 0x03b9}, {2, {0x1f86, 0x1f8e }}},
+ { {0x1f07, 0x03b9}, {2, {0x1f87, 0x1f8f }}},
+ { {0x1f20, 0x03b9}, {2, {0x1f90, 0x1f98 }}},
+ { {0x1f21, 0x03b9}, {2, {0x1f91, 0x1f99 }}},
+ { {0x1f22, 0x03b9}, {2, {0x1f92, 0x1f9a }}},
+ { {0x1f23, 0x03b9}, {2, {0x1f93, 0x1f9b }}},
+ { {0x1f24, 0x03b9}, {2, {0x1f94, 0x1f9c }}},
+ { {0x1f25, 0x03b9}, {2, {0x1f95, 0x1f9d }}},
+ { {0x1f26, 0x03b9}, {2, {0x1f96, 0x1f9e }}},
+ { {0x1f27, 0x03b9}, {2, {0x1f97, 0x1f9f }}},
+ { {0x1f60, 0x03b9}, {2, {0x1fa0, 0x1fa8 }}},
+ { {0x1f61, 0x03b9}, {2, {0x1fa1, 0x1fa9 }}},
+ { {0x1f62, 0x03b9}, {2, {0x1fa2, 0x1faa }}},
+ { {0x1f63, 0x03b9}, {2, {0x1fa3, 0x1fab }}},
+ { {0x1f64, 0x03b9}, {2, {0x1fa4, 0x1fac }}},
+ { {0x1f65, 0x03b9}, {2, {0x1fa5, 0x1fad }}},
+ { {0x1f66, 0x03b9}, {2, {0x1fa6, 0x1fae }}},
+ { {0x1f67, 0x03b9}, {2, {0x1fa7, 0x1faf }}},
+ { {0x1f70, 0x03b9}, {1, {0x1fb2 }}},
+ { {0x1f74, 0x03b9}, {1, {0x1fc2 }}},
+ { {0x1f7c, 0x03b9}, {1, {0x1ff2 }}}
+};
+
+static const CaseUnfold_12_Type CaseUnfold_12_Locale[] = {
+ { {0x0069, 0x0307}, {1, {0x0130 }}}
+};
+
+static const CaseUnfold_13_Type CaseUnfold_13[] = {
+ { {0x0066, 0x0066, 0x0069}, {1, {0xfb03 }}},
+ { {0x0066, 0x0066, 0x006c}, {1, {0xfb04 }}},
+ { {0x03b1, 0x0342, 0x03b9}, {1, {0x1fb7 }}},
+ { {0x03b7, 0x0342, 0x03b9}, {1, {0x1fc7 }}},
+ { {0x03b9, 0x0308, 0x0300}, {1, {0x1fd2 }}},
+ { {0x03b9, 0x0308, 0x0301}, {2, {0x0390, 0x1fd3 }}},
+ { {0x03b9, 0x0308, 0x0342}, {1, {0x1fd7 }}},
+ { {0x03c5, 0x0308, 0x0300}, {1, {0x1fe2 }}},
+ { {0x03c5, 0x0308, 0x0301}, {2, {0x03b0, 0x1fe3 }}},
+ { {0x03c5, 0x0308, 0x0342}, {1, {0x1fe7 }}},
+ { {0x03c5, 0x0313, 0x0300}, {1, {0x1f52 }}},
+ { {0x03c5, 0x0313, 0x0301}, {1, {0x1f54 }}},
+ { {0x03c5, 0x0313, 0x0342}, {1, {0x1f56 }}},
+ { {0x03c9, 0x0342, 0x03b9}, {1, {0x1ff7 }}}
+};
+
+
+static PosixBracketEntryType HashEntryData[] = {
+ { (UChar* )"NEWLINE", 0, 7 },
+ { (UChar* )"Alpha", 1, 5 },
+ { (UChar* )"Blank", 2, 5 },
+ { (UChar* )"Cntrl", 3, 5 },
+ { (UChar* )"Digit", 4, 5 },
+ { (UChar* )"Graph", 5, 5 },
+ { (UChar* )"Lower", 6, 5 },
+ { (UChar* )"Print", 7, 5 },
+ { (UChar* )"Punct", 8, 5 },
+ { (UChar* )"Space", 9, 5 },
+ { (UChar* )"Upper", 10, 5 },
+ { (UChar* )"XDigit", 11, 6 },
+ { (UChar* )"Word", 12, 4 },
+ { (UChar* )"Alnum", 13, 5 },
+ { (UChar* )"ASCII", 14, 5 },
+
+#ifdef USE_UNICODE_PROPERTIES
+ { (UChar* )"Any", 15, 3 },
+ { (UChar* )"Assigned", 16, 8 },
+ { (UChar* )"C", 17, 1 },
+ { (UChar* )"Cc", 18, 2 },
+ { (UChar* )"Cf", 19, 2 },
+ { (UChar* )"Cn", 20, 2 },
+ { (UChar* )"Co", 21, 2 },
+ { (UChar* )"Cs", 22, 2 },
+ { (UChar* )"L", 23, 1 },
+ { (UChar* )"Ll", 24, 2 },
+ { (UChar* )"Lm", 25, 2 },
+ { (UChar* )"Lo", 26, 2 },
+ { (UChar* )"Lt", 27, 2 },
+ { (UChar* )"Lu", 28, 2 },
+ { (UChar* )"M", 29, 1 },
+ { (UChar* )"Mc", 30, 2 },
+ { (UChar* )"Me", 31, 2 },
+ { (UChar* )"Mn", 32, 2 },
+ { (UChar* )"N", 33, 1 },
+ { (UChar* )"Nd", 34, 2 },
+ { (UChar* )"Nl", 35, 2 },
+ { (UChar* )"No", 36, 2 },
+ { (UChar* )"P", 37, 1 },
+ { (UChar* )"Pc", 38, 2 },
+ { (UChar* )"Pd", 39, 2 },
+ { (UChar* )"Pe", 40, 2 },
+ { (UChar* )"Pf", 41, 2 },
+ { (UChar* )"Pi", 42, 2 },
+ { (UChar* )"Po", 43, 2 },
+ { (UChar* )"Ps", 44, 2 },
+ { (UChar* )"S", 45, 1 },
+ { (UChar* )"Sc", 46, 2 },
+ { (UChar* )"Sk", 47, 2 },
+ { (UChar* )"Sm", 48, 2 },
+ { (UChar* )"So", 49, 2 },
+ { (UChar* )"Z", 50, 1 },
+ { (UChar* )"Zl", 51, 2 },
+ { (UChar* )"Zp", 52, 2 },
+ { (UChar* )"Zs", 53, 2 },
+ { (UChar* )"Arabic", 54, 6 },
+ { (UChar* )"Armenian", 55, 8 },
+ { (UChar* )"Bengali", 56, 7 },
+ { (UChar* )"Bopomofo", 57, 8 },
+ { (UChar* )"Braille", 58, 7 },
+ { (UChar* )"Buginese", 59, 8 },
+ { (UChar* )"Buhid", 60, 5 },
+ { (UChar* )"Canadian_Aboriginal", 61, 19 },
+ { (UChar* )"Cherokee", 62, 8 },
+ { (UChar* )"Common", 63, 6 },
+ { (UChar* )"Coptic", 64, 6 },
+ { (UChar* )"Cypriot", 65, 7 },
+ { (UChar* )"Cyrillic", 66, 8 },
+ { (UChar* )"Deseret", 67, 7 },
+ { (UChar* )"Devanagari", 68, 10 },
+ { (UChar* )"Ethiopic", 69, 8 },
+ { (UChar* )"Georgian", 70, 8 },
+ { (UChar* )"Glagolitic", 71, 10 },
+ { (UChar* )"Gothic", 72, 6 },
+ { (UChar* )"Greek", 73, 5 },
+ { (UChar* )"Gujarati", 74, 8 },
+ { (UChar* )"Gurmukhi", 75, 8 },
+ { (UChar* )"Han", 76, 3 },
+ { (UChar* )"Hangul", 77, 6 },
+ { (UChar* )"Hanunoo", 78, 7 },
+ { (UChar* )"Hebrew", 79, 6 },
+ { (UChar* )"Hiragana", 80, 8 },
+ { (UChar* )"Inherited", 81, 9 },
+ { (UChar* )"Kannada", 82, 7 },
+ { (UChar* )"Katakana", 83, 8 },
+ { (UChar* )"Kharoshthi", 84, 10 },
+ { (UChar* )"Khmer", 85, 5 },
+ { (UChar* )"Lao", 86, 3 },
+ { (UChar* )"Latin", 87, 5 },
+ { (UChar* )"Limbu", 88, 5 },
+ { (UChar* )"Linear_B", 89, 8 },
+ { (UChar* )"Malayalam", 90, 9 },
+ { (UChar* )"Mongolian", 91, 9 },
+ { (UChar* )"Myanmar", 92, 7 },
+ { (UChar* )"New_Tai_Lue", 93, 11 },
+ { (UChar* )"Ogham", 94, 5 },
+ { (UChar* )"Old_Italic", 95, 10 },
+ { (UChar* )"Old_Persian", 96, 11 },
+ { (UChar* )"Oriya", 97, 5 },
+ { (UChar* )"Osmanya", 98, 7 },
+ { (UChar* )"Runic", 99, 5 },
+ { (UChar* )"Shavian", 100, 7 },
+ { (UChar* )"Sinhala", 101, 7 },
+ { (UChar* )"Syloti_Nagri", 102, 12 },
+ { (UChar* )"Syriac", 103, 6 },
+ { (UChar* )"Tagalog", 104, 7 },
+ { (UChar* )"Tagbanwa", 105, 8 },
+ { (UChar* )"Tai_Le", 106, 6 },
+ { (UChar* )"Tamil", 107, 5 },
+ { (UChar* )"Telugu", 108, 6 },
+ { (UChar* )"Thaana", 109, 6 },
+ { (UChar* )"Thai", 110, 4 },
+ { (UChar* )"Tibetan", 111, 7 },
+ { (UChar* )"Tifinagh", 112, 8 },
+ { (UChar* )"Ugaritic", 113, 8 },
+ { (UChar* )"Yi", 114, 2 },
+#endif /* USE_UNICODE_PROPERTIES */
+ { (UChar* )NULL, -1, 0 }
+};
+
+#ifdef USE_UNICODE_PROPERTIES
+#define CODE_RANGES_NUM 115
+#else
+#define CODE_RANGES_NUM 15
+#endif
+
+static const OnigCodePoint* CodeRanges[CODE_RANGES_NUM];
+static int CodeRangeTableInited = 0;
+
+static void init_code_range_array(void) {
+ THREAD_ATOMIC_START;
+
+ CodeRanges[0] = CR_NEWLINE;
+ CodeRanges[1] = CR_Alpha;
+ CodeRanges[2] = CR_Blank;
+ CodeRanges[3] = CR_Cntrl;
+ CodeRanges[4] = CR_Digit;
+ CodeRanges[5] = CR_Graph;
+ CodeRanges[6] = CR_Lower;
+ CodeRanges[7] = CR_Print;
+ CodeRanges[8] = CR_Punct;
+ CodeRanges[9] = CR_Space;
+ CodeRanges[10] = CR_Upper;
+ CodeRanges[11] = CR_XDigit;
+ CodeRanges[12] = CR_Word;
+ CodeRanges[13] = CR_Alnum;
+ CodeRanges[14] = CR_ASCII;
+
+#ifdef USE_UNICODE_PROPERTIES
+ CodeRanges[15] = CR_Any;
+ CodeRanges[16] = CR_Assigned;
+ CodeRanges[17] = CR_C;
+ CodeRanges[18] = CR_Cc;
+ CodeRanges[19] = CR_Cf;
+ CodeRanges[20] = CR_Cn;
+ CodeRanges[21] = CR_Co;
+ CodeRanges[22] = CR_Cs;
+ CodeRanges[23] = CR_L;
+ CodeRanges[24] = CR_Ll;
+ CodeRanges[25] = CR_Lm;
+ CodeRanges[26] = CR_Lo;
+ CodeRanges[27] = CR_Lt;
+ CodeRanges[28] = CR_Lu;
+ CodeRanges[29] = CR_M;
+ CodeRanges[30] = CR_Mc;
+ CodeRanges[31] = CR_Me;
+ CodeRanges[32] = CR_Mn;
+ CodeRanges[33] = CR_N;
+ CodeRanges[34] = CR_Nd;
+ CodeRanges[35] = CR_Nl;
+ CodeRanges[36] = CR_No;
+ CodeRanges[37] = CR_P;
+ CodeRanges[38] = CR_Pc;
+ CodeRanges[39] = CR_Pd;
+ CodeRanges[40] = CR_Pe;
+ CodeRanges[41] = CR_Pf;
+ CodeRanges[42] = CR_Pi;
+ CodeRanges[43] = CR_Po;
+ CodeRanges[44] = CR_Ps;
+ CodeRanges[45] = CR_S;
+ CodeRanges[46] = CR_Sc;
+ CodeRanges[47] = CR_Sk;
+ CodeRanges[48] = CR_Sm;
+ CodeRanges[49] = CR_So;
+ CodeRanges[50] = CR_Z;
+ CodeRanges[51] = CR_Zl;
+ CodeRanges[52] = CR_Zp;
+ CodeRanges[53] = CR_Zs;
+ CodeRanges[54] = CR_Arabic;
+ CodeRanges[55] = CR_Armenian;
+ CodeRanges[56] = CR_Bengali;
+ CodeRanges[57] = CR_Bopomofo;
+ CodeRanges[58] = CR_Braille;
+ CodeRanges[59] = CR_Buginese;
+ CodeRanges[60] = CR_Buhid;
+ CodeRanges[61] = CR_Canadian_Aboriginal;
+ CodeRanges[62] = CR_Cherokee;
+ CodeRanges[63] = CR_Common;
+ CodeRanges[64] = CR_Coptic;
+ CodeRanges[65] = CR_Cypriot;
+ CodeRanges[66] = CR_Cyrillic;
+ CodeRanges[67] = CR_Deseret;
+ CodeRanges[68] = CR_Devanagari;
+ CodeRanges[69] = CR_Ethiopic;
+ CodeRanges[70] = CR_Georgian;
+ CodeRanges[71] = CR_Glagolitic;
+ CodeRanges[72] = CR_Gothic;
+ CodeRanges[73] = CR_Greek;
+ CodeRanges[74] = CR_Gujarati;
+ CodeRanges[75] = CR_Gurmukhi;
+ CodeRanges[76] = CR_Han;
+ CodeRanges[77] = CR_Hangul;
+ CodeRanges[78] = CR_Hanunoo;
+ CodeRanges[79] = CR_Hebrew;
+ CodeRanges[80] = CR_Hiragana;
+ CodeRanges[81] = CR_Inherited;
+ CodeRanges[82] = CR_Kannada;
+ CodeRanges[83] = CR_Katakana;
+ CodeRanges[84] = CR_Kharoshthi;
+ CodeRanges[85] = CR_Khmer;
+ CodeRanges[86] = CR_Lao;
+ CodeRanges[87] = CR_Latin;
+ CodeRanges[88] = CR_Limbu;
+ CodeRanges[89] = CR_Linear_B;
+ CodeRanges[90] = CR_Malayalam;
+ CodeRanges[91] = CR_Mongolian;
+ CodeRanges[92] = CR_Myanmar;
+ CodeRanges[93] = CR_New_Tai_Lue;
+ CodeRanges[94] = CR_Ogham;
+ CodeRanges[95] = CR_Old_Italic;
+ CodeRanges[96] = CR_Old_Persian;
+ CodeRanges[97] = CR_Oriya;
+ CodeRanges[98] = CR_Osmanya;
+ CodeRanges[99] = CR_Runic;
+ CodeRanges[100] = CR_Shavian;
+ CodeRanges[101] = CR_Sinhala;
+ CodeRanges[102] = CR_Syloti_Nagri;
+ CodeRanges[103] = CR_Syriac;
+ CodeRanges[104] = CR_Tagalog;
+ CodeRanges[105] = CR_Tagbanwa;
+ CodeRanges[106] = CR_Tai_Le;
+ CodeRanges[107] = CR_Tamil;
+ CodeRanges[108] = CR_Telugu;
+ CodeRanges[109] = CR_Thaana;
+ CodeRanges[110] = CR_Thai;
+ CodeRanges[111] = CR_Tibetan;
+ CodeRanges[112] = CR_Tifinagh;
+ CodeRanges[113] = CR_Ugaritic;
+ CodeRanges[114] = CR_Yi;
+#endif /* USE_UNICODE_PROPERTIES */
+
+ CodeRangeTableInited = 1;
+ THREAD_ATOMIC_END;
+}
extern int
onigenc_unicode_is_code_ctype(OnigCodePoint code, unsigned int ctype)
{
- if (code < 256) {
+ if (
+#ifdef USE_UNICODE_PROPERTIES
+ ctype <= ONIGENC_MAX_STD_CTYPE &&
+#endif
+ code < 256) {
return ONIGENC_IS_UNICODE_ISO_8859_1_CTYPE(code, ctype);
}
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
-
- switch (ctype) {
- case ONIGENC_CTYPE_ALPHA:
- return onig_is_in_code_range((UChar* )CRAlpha, code);
- break;
- case ONIGENC_CTYPE_BLANK:
- return onig_is_in_code_range((UChar* )CRBlank, code);
- break;
- case ONIGENC_CTYPE_CNTRL:
- return onig_is_in_code_range((UChar* )CRCntrl, code);
- break;
- case ONIGENC_CTYPE_DIGIT:
- return onig_is_in_code_range((UChar* )CRDigit, code);
- break;
- case ONIGENC_CTYPE_GRAPH:
- return onig_is_in_code_range((UChar* )CRGraph, code);
- break;
- case ONIGENC_CTYPE_LOWER:
- return onig_is_in_code_range((UChar* )CRLower, code);
- break;
- case ONIGENC_CTYPE_PRINT:
- return onig_is_in_code_range((UChar* )CRPrint, code);
- break;
- case ONIGENC_CTYPE_PUNCT:
- return onig_is_in_code_range((UChar* )CRPunct, code);
- break;
- case ONIGENC_CTYPE_SPACE:
- return onig_is_in_code_range((UChar* )CRSpace, code);
- break;
- case ONIGENC_CTYPE_UPPER:
- return onig_is_in_code_range((UChar* )CRUpper, code);
- break;
- case ONIGENC_CTYPE_XDIGIT:
- return FALSE;
- break;
- case ONIGENC_CTYPE_WORD:
- return onig_is_in_code_range((UChar* )CRWord, code);
- break;
- case ONIGENC_CTYPE_ASCII:
- return FALSE;
- break;
- case ONIGENC_CTYPE_ALNUM:
- return onig_is_in_code_range((UChar* )CRAlnum, code);
- break;
- case ONIGENC_CTYPE_NEWLINE:
- return FALSE;
- break;
-
- default:
- return ONIGENCERR_TYPE_BUG;
- break;
+ if (ctype >= CODE_RANGES_NUM) {
+ return ONIGERR_TYPE_BUG;
+ }
+
+ if (CodeRangeTableInited == 0) init_code_range_array();
+
+ return onig_is_in_code_range((UChar* )CodeRanges[ctype], code);
+}
+
+
+extern int
+onigenc_unicode_ctype_code_range(int ctype, const OnigCodePoint* ranges[])
+{
+ if (ctype >= CODE_RANGES_NUM) {
+ return ONIGERR_TYPE_BUG;
}
+ if (CodeRangeTableInited == 0) init_code_range_array();
+
+ *ranges = CodeRanges[ctype];
+
+ return 0;
+}
+
+extern int
+onigenc_utf16_32_get_ctype_code_range(OnigCtype ctype, OnigCodePoint* sb_out,
+ const OnigCodePoint* ranges[])
+{
+ *sb_out = 0x00;
+ return onigenc_unicode_ctype_code_range(ctype, ranges);
+}
+
+#include "st.h"
+
+#define PROPERTY_NAME_MAX_SIZE 20
+
+static st_table* NameCtypeTable;
+static int NameTableInited = 0;
+
+static int init_name_ctype_table(void)
+{
+ PosixBracketEntryType *pb;
+
+ THREAD_ATOMIC_START;
+
+ NameCtypeTable = onig_st_init_strend_table_with_size(100);
+ if (ONIG_IS_NULL(NameCtypeTable)) return ONIGERR_MEMORY;
+
+ for (pb = HashEntryData; ONIG_IS_NOT_NULL(pb->name); pb++) {
+ onig_st_insert_strend(NameCtypeTable, pb->name, pb->name + pb->len,
+ (st_data_t )pb->ctype);
+ }
+
+ NameTableInited = 1;
+ THREAD_ATOMIC_END;
+ return 0;
+}
+
+extern int
+onigenc_unicode_property_name_to_ctype(OnigEncoding enc, UChar* name, UChar* end)
+{
+ int len;
+ hash_data_type ctype;
+ UChar buf[PROPERTY_NAME_MAX_SIZE];
+ UChar *p;
+ OnigCodePoint code;
+
+ p = name;
+ len = 0;
+ while (p < end) {
+ code = ONIGENC_MBC_TO_CODE(enc, p, end);
+ if (code >= 0x80)
+ return ONIGERR_INVALID_CHAR_PROPERTY_NAME;
+
+ buf[len++] = (UChar )code;
+ if (len >= PROPERTY_NAME_MAX_SIZE)
+ return ONIGERR_INVALID_CHAR_PROPERTY_NAME;
+
+ p += enclen(enc, p);
+ }
+
+ buf[len] = 0;
+
+ if (NameTableInited == 0) init_name_ctype_table();
+
+ if (onig_st_lookup_strend(NameCtypeTable, buf, buf + len, &ctype) == 0) {
+ return ONIGERR_INVALID_CHAR_PROPERTY_NAME;
+ }
+
+ return (int )ctype;
+}
+
+
+static int
+code2_cmp(OnigCodePoint* x, OnigCodePoint* y)
+{
+ if (x[0] == y[0] && x[1] == y[1]) return 0;
+ return 1;
+}
+
+static int
+code2_hash(OnigCodePoint* x)
+{
+ return (int )(x[0] + x[1]);
+}
+
+static struct st_hash_type type_code2_hash = {
+ code2_cmp,
+ code2_hash,
+};
+
+static int
+code3_cmp(OnigCodePoint* x, OnigCodePoint* y)
+{
+ if (x[0] == y[0] && x[1] == y[1] && x[2] == y[2]) return 0;
+ return 1;
+}
+
+static int
+code3_hash(OnigCodePoint* x)
+{
+ return (int )(x[0] + x[1] + x[2]);
+}
+
+static struct st_hash_type type_code3_hash = {
+ code3_cmp,
+ code3_hash,
+};
+
+
+static st_table* FoldTable; /* fold-1, fold-2, fold-3 */
+static st_table* Unfold1Table;
+static st_table* Unfold2Table;
+static st_table* Unfold3Table;
+static int CaseFoldInited = 0;
+
+static int init_case_fold_table(void)
+{
+ const CaseFold_11_Type *p;
+ const CaseUnfold_11_Type *p1;
+ const CaseUnfold_12_Type *p2;
+ const CaseUnfold_13_Type *p3;
+ int i;
+
+ THREAD_ATOMIC_START;
+
+ FoldTable = st_init_numtable_with_size(1200);
+ if (ONIG_IS_NULL(FoldTable)) return ONIGERR_MEMORY;
+ for (i = 0; i < (int )(sizeof(CaseFold)/sizeof(CaseFold_11_Type)); i++) {
+ p = &CaseFold[i];
+ st_add_direct(FoldTable, (st_data_t )p->from, (st_data_t )&(p->to));
+ }
+ for (i = 0; i < (int )(sizeof(CaseFold_Locale)/sizeof(CaseFold_11_Type));
+ i++) {
+ p = &CaseFold_Locale[i];
+ st_add_direct(FoldTable, (st_data_t )p->from, (st_data_t )&(p->to));
+ }
+
+ Unfold1Table = st_init_numtable_with_size(1000);
+ if (ONIG_IS_NULL(Unfold1Table)) return ONIGERR_MEMORY;
+
+ for (i = 0; i < (int )(sizeof(CaseUnfold_11)/sizeof(CaseUnfold_11_Type));
+ i++) {
+ p1 = &CaseUnfold_11[i];
+ st_add_direct(Unfold1Table, (st_data_t )p1->from, (st_data_t )&(p1->to));
+ }
+ for (i = 0;
+ i < (int )(sizeof(CaseUnfold_11_Locale)/sizeof(CaseUnfold_11_Type));
+ i++) {
+ p1 = &CaseUnfold_11_Locale[i];
+ st_add_direct(Unfold1Table, (st_data_t )p1->from, (st_data_t )&(p1->to));
+ }
+
+ Unfold2Table = st_init_table_with_size(&type_code2_hash, 200);
+ if (ONIG_IS_NULL(Unfold2Table)) return ONIGERR_MEMORY;
+
+ for (i = 0; i < (int )(sizeof(CaseUnfold_12)/sizeof(CaseUnfold_12_Type));
+ i++) {
+ p2 = &CaseUnfold_12[i];
+ st_add_direct(Unfold2Table, (st_data_t )p2->from, (st_data_t )(&p2->to));
+ }
+ for (i = 0;
+ i < (int )(sizeof(CaseUnfold_12_Locale)/sizeof(CaseUnfold_12_Type));
+ i++) {
+ p2 = &CaseUnfold_12_Locale[i];
+ st_add_direct(Unfold2Table, (st_data_t )p2->from, (st_data_t )(&p2->to));
+ }
+
+ Unfold3Table = st_init_table_with_size(&type_code3_hash, 30);
+ if (ONIG_IS_NULL(Unfold3Table)) return ONIGERR_MEMORY;
+
+ for (i = 0; i < (int )(sizeof(CaseUnfold_13)/sizeof(CaseUnfold_13_Type));
+ i++) {
+ p3 = &CaseUnfold_13[i];
+ st_add_direct(Unfold3Table, (st_data_t )p3->from, (st_data_t )(&p3->to));
+ }
+
+ CaseFoldInited = 1;
+ THREAD_ATOMIC_END;
+ return 0;
+}
+
+extern int
+onigenc_unicode_mbc_case_fold(OnigEncoding enc,
+ OnigCaseFoldType flag ARG_UNUSED, const UChar** pp, const UChar* end,
+ UChar* fold)
+{
+ CodePointList3 *to;
+ OnigCodePoint code;
+ int i, len, rlen;
+ const UChar *p = *pp;
+
+ if (CaseFoldInited == 0) init_case_fold_table();
+
+ code = ONIGENC_MBC_TO_CODE(enc, p, end);
+ len = enclen(enc, p);
+ *pp += len;
+
+#ifdef USE_UNICODE_CASE_FOLD_TURKISH_AZERI
+ if ((flag & ONIGENC_CASE_FOLD_TURKISH_AZERI) != 0) {
+ if (code == 0x0049) {
+ return ONIGENC_CODE_TO_MBC(enc, 0x0131, fold);
+ }
+ else if (code == 0x0130) {
+ return ONIGENC_CODE_TO_MBC(enc, 0x0069, fold);
+ }
+ }
+#endif
+
+ if (onig_st_lookup(FoldTable, (st_data_t )code, (void* )&to) != 0) {
+ if (to->n == 1) {
+ return ONIGENC_CODE_TO_MBC(enc, to->code[0], fold);
+ }
+#if 0
+ /* NO NEEDS TO CHECK */
+ else if ((flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
#else
+ else {
+#endif
+ rlen = 0;
+ for (i = 0; i < to->n; i++) {
+ len = ONIGENC_CODE_TO_MBC(enc, to->code[i], fold);
+ fold += len;
+ rlen += len;
+ }
+ return rlen;
+ }
+ }
- if ((ctype & ONIGENC_CTYPE_WORD) != 0) {
- return TRUE;
+ for (i = 0; i < len; i++) {
+ *fold++ = *p++;
}
- return FALSE;
-#endif /* USE_UNICODE_FULL_RANGE_CTYPE */
+ return len;
}
extern int
-onigenc_unicode_get_ctype_code_range(int ctype,
- const OnigCodePoint* sbr[], const OnigCodePoint* mbr[])
+onigenc_unicode_apply_all_case_fold(OnigCaseFoldType flag,
+ OnigApplyAllCaseFoldFunc f, void* arg)
{
- static const OnigCodePoint EmptyRange[] = { 0 };
-
-#define CR_SET(list) do { \
- *mbr = list; \
-} while (0)
-
- *sbr = EmptyRange;
-
- switch (ctype) {
- case ONIGENC_CTYPE_ALPHA:
- CR_SET(CRAlpha);
- break;
- case ONIGENC_CTYPE_BLANK:
- CR_SET(CRBlank);
- break;
- case ONIGENC_CTYPE_CNTRL:
- CR_SET(CRCntrl);
- break;
- case ONIGENC_CTYPE_DIGIT:
- CR_SET(CRDigit);
- break;
- case ONIGENC_CTYPE_GRAPH:
- CR_SET(CRGraph);
- break;
- case ONIGENC_CTYPE_LOWER:
- CR_SET(CRLower);
- break;
- case ONIGENC_CTYPE_PRINT:
- CR_SET(CRPrint);
- break;
- case ONIGENC_CTYPE_PUNCT:
- CR_SET(CRPunct);
- break;
- case ONIGENC_CTYPE_SPACE:
- CR_SET(CRSpace);
- break;
- case ONIGENC_CTYPE_UPPER:
- CR_SET(CRUpper);
- break;
- case ONIGENC_CTYPE_XDIGIT:
- CR_SET(CRXDigit);
- break;
- case ONIGENC_CTYPE_WORD:
- CR_SET(CRWord);
- break;
- case ONIGENC_CTYPE_ASCII:
- CR_SET(CRASCII);
- break;
- case ONIGENC_CTYPE_ALNUM:
- CR_SET(CRAlnum);
- break;
-
- default:
- return ONIGENCERR_TYPE_BUG;
- break;
+ const CaseUnfold_11_Type* p11;
+ OnigCodePoint code;
+ int i, j, k, r;
+
+ /* if (CaseFoldInited == 0) init_case_fold_table(); */
+
+ for (i = 0; i < (int )(sizeof(CaseUnfold_11)/sizeof(CaseUnfold_11_Type));
+ i++) {
+ p11 = &CaseUnfold_11[i];
+ for (j = 0; j < p11->to.n; j++) {
+ code = p11->from;
+ r = (*f)(p11->to.code[j], &code, 1, arg);
+ if (r != 0) return r;
+
+ code = p11->to.code[j];
+ r = (*f)(p11->from, &code, 1, arg);
+ if (r != 0) return r;
+
+ for (k = 0; k < j; k++) {
+ r = (*f)(p11->to.code[j], (OnigCodePoint* )(&p11->to.code[k]), 1, arg);
+ if (r != 0) return r;
+
+ r = (*f)(p11->to.code[k], (OnigCodePoint* )(&p11->to.code[j]), 1, arg);
+ if (r != 0) return r;
+ }
+ }
+ }
+
+#ifdef USE_UNICODE_CASE_FOLD_TURKISH_AZERI
+ if ((flag & ONIGENC_CASE_FOLD_TURKISH_AZERI) != 0) {
+ code = 0x0131;
+ r = (*f)(0x0049, &code, 1, arg);
+ if (r != 0) return r;
+ code = 0x0049;
+ r = (*f)(0x0131, &code, 1, arg);
+ if (r != 0) return r;
+
+ code = 0x0130;
+ r = (*f)(0x0069, &code, 1, arg);
+ if (r != 0) return r;
+ code = 0x0069;
+ r = (*f)(0x0130, &code, 1, arg);
+ if (r != 0) return r;
+ }
+ else {
+#endif
+ for (i = 0;
+ i < (int )(sizeof(CaseUnfold_11_Locale)/sizeof(CaseUnfold_11_Type));
+ i++) {
+ p11 = &CaseUnfold_11_Locale[i];
+ for (j = 0; j < p11->to.n; j++) {
+ code = p11->from;
+ r = (*f)(p11->to.code[j], &code, 1, arg);
+ if (r != 0) return r;
+
+ code = p11->to.code[j];
+ r = (*f)(p11->from, &code, 1, arg);
+ if (r != 0) return r;
+
+ for (k = 0; k < j; k++) {
+ r = (*f)(p11->to.code[j], (OnigCodePoint* )(&p11->to.code[k]),
+ 1, arg);
+ if (r != 0) return r;
+
+ r = (*f)(p11->to.code[k], (OnigCodePoint* )(&p11->to.code[j]),
+ 1, arg);
+ if (r != 0) return r;
+ }
+ }
+ }
+#ifdef USE_UNICODE_CASE_FOLD_TURKISH_AZERI
+ }
+#endif
+
+ if ((flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
+ for (i = 0; i < (int )(sizeof(CaseUnfold_12)/sizeof(CaseUnfold_12_Type));
+ i++) {
+ for (j = 0; j < CaseUnfold_12[i].to.n; j++) {
+ r = (*f)(CaseUnfold_12[i].to.code[j],
+ (OnigCodePoint* )CaseUnfold_12[i].from, 2, arg);
+ if (r != 0) return r;
+
+ for (k = 0; k < CaseUnfold_12[i].to.n; k++) {
+ if (k == j) continue;
+
+ r = (*f)(CaseUnfold_12[i].to.code[j],
+ (OnigCodePoint* )(&CaseUnfold_12[i].to.code[k]), 1, arg);
+ if (r != 0) return r;
+ }
+ }
+ }
+
+#ifdef USE_UNICODE_CASE_FOLD_TURKISH_AZERI
+ if ((flag & ONIGENC_CASE_FOLD_TURKISH_AZERI) == 0) {
+#endif
+ for (i = 0;
+ i < (int )(sizeof(CaseUnfold_12_Locale)/sizeof(CaseUnfold_12_Type));
+ i++) {
+ for (j = 0; j < CaseUnfold_12_Locale[i].to.n; j++) {
+ r = (*f)(CaseUnfold_12_Locale[i].to.code[j],
+ (OnigCodePoint* )CaseUnfold_12_Locale[i].from, 2, arg);
+ if (r != 0) return r;
+
+ for (k = 0; k < CaseUnfold_12_Locale[i].to.n; k++) {
+ if (k == j) continue;
+
+ r = (*f)(CaseUnfold_12_Locale[i].to.code[j],
+ (OnigCodePoint* )(&CaseUnfold_12_Locale[i].to.code[k]),
+ 1, arg);
+ if (r != 0) return r;
+ }
+ }
+ }
+#ifdef USE_UNICODE_CASE_FOLD_TURKISH_AZERI
+ }
+#endif
+
+ for (i = 0; i < (int )(sizeof(CaseUnfold_13)/sizeof(CaseUnfold_13_Type));
+ i++) {
+ for (j = 0; j < CaseUnfold_13[i].to.n; j++) {
+ r = (*f)(CaseUnfold_13[i].to.code[j],
+ (OnigCodePoint* )CaseUnfold_13[i].from, 3, arg);
+ if (r != 0) return r;
+
+ for (k = 0; k < CaseUnfold_13[i].to.n; k++) {
+ if (k == j) continue;
+
+ r = (*f)(CaseUnfold_13[i].to.code[j],
+ (OnigCodePoint* )(&CaseUnfold_13[i].to.code[k]), 1, arg);
+ if (r != 0) return r;
+ }
+ }
+ }
}
return 0;
}
+
+extern int
+onigenc_unicode_get_case_fold_codes_by_str(OnigEncoding enc,
+ OnigCaseFoldType flag, const OnigUChar* p, const OnigUChar* end,
+ OnigCaseFoldCodeItem items[])
+{
+ int n, i, j, k, len;
+ OnigCodePoint code, codes[3];
+ CodePointList3 *to, *z3;
+ CodePointList2 *z2;
+
+ if (CaseFoldInited == 0) init_case_fold_table();
+
+ n = 0;
+
+ code = ONIGENC_MBC_TO_CODE(enc, p, end);
+ len = enclen(enc, p);
+
+#ifdef USE_UNICODE_CASE_FOLD_TURKISH_AZERI
+ if ((flag & ONIGENC_CASE_FOLD_TURKISH_AZERI) != 0) {
+ if (code == 0x0049) {
+ items[0].byte_len = len;
+ items[0].code_len = 1;
+ items[0].code[0] = 0x0131;
+ return 1;
+ }
+ else if (code == 0x0130) {
+ items[0].byte_len = len;
+ items[0].code_len = 1;
+ items[0].code[0] = 0x0069;
+ return 1;
+ }
+ else if (code == 0x0131) {
+ items[0].byte_len = len;
+ items[0].code_len = 1;
+ items[0].code[0] = 0x0049;
+ return 1;
+ }
+ else if (code == 0x0069) {
+ items[0].byte_len = len;
+ items[0].code_len = 1;
+ items[0].code[0] = 0x0130;
+ return 1;
+ }
+ }
+#endif
+
+ if (onig_st_lookup(FoldTable, (st_data_t )code, (void* )&to) != 0) {
+ if (to->n == 1) {
+ OnigCodePoint orig_code = code;
+
+ items[0].byte_len = len;
+ items[0].code_len = 1;
+ items[0].code[0] = to->code[0];
+ n++;
+
+ code = to->code[0];
+ if (onig_st_lookup(Unfold1Table, (st_data_t )code, (void* )&to) != 0) {
+ for (i = 0; i < to->n; i++) {
+ if (to->code[i] != orig_code) {
+ items[n].byte_len = len;
+ items[n].code_len = 1;
+ items[n].code[0] = to->code[i];
+ n++;
+ }
+ }
+ }
+ }
+ else if ((flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
+ OnigCodePoint cs[3][4];
+ int fn, ncs[3];
+
+ for (fn = 0; fn < to->n; fn++) {
+ cs[fn][0] = to->code[fn];
+ if (onig_st_lookup(Unfold1Table, (st_data_t )cs[fn][0],
+ (void* )&z3) != 0) {
+ for (i = 0; i < z3->n; i++) {
+ cs[fn][i+1] = z3->code[i];
+ }
+ ncs[fn] = z3->n + 1;
+ }
+ else
+ ncs[fn] = 1;
+ }
+
+ if (fn == 2) {
+ for (i = 0; i < ncs[0]; i++) {
+ for (j = 0; j < ncs[1]; j++) {
+ items[n].byte_len = len;
+ items[n].code_len = 2;
+ items[n].code[0] = cs[0][i];
+ items[n].code[1] = cs[1][j];
+ n++;
+ }
+ }
+
+ if (onig_st_lookup(Unfold2Table, (st_data_t )to->code,
+ (void* )&z2) != 0) {
+ for (i = 0; i < z2->n; i++) {
+ if (z2->code[i] == code) continue;
+
+ items[n].byte_len = len;
+ items[n].code_len = 1;
+ items[n].code[0] = z2->code[i];
+ n++;
+ }
+ }
+ }
+ else {
+ for (i = 0; i < ncs[0]; i++) {
+ for (j = 0; j < ncs[1]; j++) {
+ for (k = 0; k < ncs[2]; k++) {
+ items[n].byte_len = len;
+ items[n].code_len = 3;
+ items[n].code[0] = cs[0][i];
+ items[n].code[1] = cs[1][j];
+ items[n].code[2] = cs[2][k];
+ n++;
+ }
+ }
+ }
+
+ if (onig_st_lookup(Unfold3Table, (st_data_t )to->code,
+ (void* )&z2) != 0) {
+ for (i = 0; i < z2->n; i++) {
+ if (z2->code[i] == code) continue;
+
+ items[n].byte_len = len;
+ items[n].code_len = 1;
+ items[n].code[0] = z2->code[i];
+ n++;
+ }
+ }
+ }
+
+ /* multi char folded code is not head of another folded multi char */
+ flag = 0; /* DISABLE_CASE_FOLD_MULTI_CHAR(flag); */
+ }
+ }
+ else {
+ if (onig_st_lookup(Unfold1Table, (st_data_t )code, (void* )&to) != 0) {
+ for (i = 0; i < to->n; i++) {
+ items[n].byte_len = len;
+ items[n].code_len = 1;
+ items[n].code[0] = to->code[i];
+ n++;
+ }
+ }
+ }
+
+
+ if ((flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
+ p += len;
+ if (p < end) {
+ int clen;
+
+ codes[0] = code;
+ code = ONIGENC_MBC_TO_CODE(enc, p, end);
+ if (onig_st_lookup(FoldTable, (st_data_t )code, (void* )&to) != 0
+ && to->n == 1) {
+ codes[1] = to->code[0];
+ }
+ else
+ codes[1] = code;
+
+ clen = enclen(enc, p);
+ len += clen;
+ if (onig_st_lookup(Unfold2Table, (st_data_t )codes, (void* )&z2) != 0) {
+ for (i = 0; i < z2->n; i++) {
+ items[n].byte_len = len;
+ items[n].code_len = 1;
+ items[n].code[0] = z2->code[i];
+ n++;
+ }
+ }
+
+ p += clen;
+ if (p < end) {
+ code = ONIGENC_MBC_TO_CODE(enc, p, end);
+ if (onig_st_lookup(FoldTable, (st_data_t )code, (void* )&to) != 0
+ && to->n == 1) {
+ codes[2] = to->code[0];
+ }
+ else
+ codes[2] = code;
+
+ clen = enclen(enc, p);
+ len += clen;
+ if (onig_st_lookup(Unfold3Table, (st_data_t )codes,
+ (void* )&z2) != 0) {
+ for (i = 0; i < z2->n; i++) {
+ items[n].byte_len = len;
+ items[n].code_len = 1;
+ items[n].code[0] = z2->code[i];
+ n++;
+ }
+ }
+ }
+ }
+ }
+
+ return n;
+}
diff --git a/ext/mbstring/oniguruma/enc/utf16_be.c b/ext/mbstring/oniguruma/enc/utf16_be.c
index 6ab80a6c1c..1e909ebbf2 100644
--- a/ext/mbstring/oniguruma/enc/utf16_be.c
+++ b/ext/mbstring/oniguruma/enc/utf16_be.c
@@ -2,7 +2,7 @@
utf16_be.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2006 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2008 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -29,9 +29,6 @@
#include "regenc.h"
-#define UTF16_IS_SURROGATE_FIRST(c) (c >= 0xd8 && c <= 0xdb)
-#define UTF16_IS_SURROGATE_SECOND(c) (c >= 0xdc && c <= 0xdf)
-
static const int EncLen_UTF16[] = {
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -64,7 +61,11 @@ utf16be_is_mbc_newline(const UChar* p, const UChar* end)
if (*(p+1) == 0x0a && *p == 0x00)
return 1;
#ifdef USE_UNICODE_ALL_LINE_TERMINATORS
- if ((*(p+1) == 0x0d || *(p+1) == 0x85) && *p == 0x00)
+ if ((
+#ifndef USE_CRNL_AS_LINE_TERMINATOR
+ *(p+1) == 0x0d ||
+#endif
+ *(p+1) == 0x85) && *p == 0x00)
return 1;
if (*p == 0x20 && (*(p+1) == 0x29 || *(p+1) == 0x28))
return 1;
@@ -74,7 +75,7 @@ utf16be_is_mbc_newline(const UChar* p, const UChar* end)
}
static OnigCodePoint
-utf16be_mbc_to_code(const UChar* p, const UChar* end)
+utf16be_mbc_to_code(const UChar* p, const UChar* end ARG_UNUSED)
{
OnigCodePoint code;
@@ -103,11 +104,11 @@ utf16be_code_to_mbc(OnigCodePoint code, UChar *buf)
if (code > 0xffff) {
unsigned int plane, high;
- plane = code >> 16;
+ plane = (code >> 16) - 1;
*p++ = (plane >> 2) + 0xd8;
high = (code & 0xff00) >> 8;
*p++ = ((plane & 0x03) << 6) + (high >> 2);
- *p++ = (high & 0x02) + 0xdc;
+ *p++ = (high & 0x03) + 0xdc;
*p = (UChar )(code & 0xff);
return 4;
}
@@ -119,43 +120,37 @@ utf16be_code_to_mbc(OnigCodePoint code, UChar *buf)
}
static int
-utf16be_mbc_to_normalize(OnigAmbigType flag, const UChar** pp, const UChar* end,
- UChar* lower)
+utf16be_mbc_case_fold(OnigCaseFoldType flag,
+ const UChar** pp, const UChar* end, UChar* fold)
{
const UChar* p = *pp;
- if (*p == 0) {
+ if (ONIGENC_IS_ASCII_CODE(*(p+1)) && *p == 0) {
p++;
- *lower++ = '\0';
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- *lower = ONIGENC_ISO_8859_1_TO_LOWER_CASE(*p);
- }
- else {
- *lower = *p;
- }
-
- (*pp) += 2;
- return 2; /* return byte length of converted char to lower */
- }
- else {
- int len;
- len = EncLen_UTF16[*p];
- if (lower != p) {
- int i;
- for (i = 0; i < len; i++) {
- *lower++ = *p++;
+#ifdef USE_UNICODE_CASE_FOLD_TURKISH_AZERI
+ if ((flag & ONIGENC_CASE_FOLD_TURKISH_AZERI) != 0) {
+ if (*p == 0x49) {
+ *fold++ = 0x01;
+ *fold = 0x31;
+ (*pp) += 2;
+ return 2;
}
}
- (*pp) += len;
- return len; /* return byte length of converted char to lower */
+#endif
+
+ *fold++ = 0;
+ *fold = ONIGENC_ASCII_CODE_TO_LOWER_CASE(*p);
+ *pp += 2;
+ return 2;
}
+ else
+ return onigenc_unicode_mbc_case_fold(ONIG_ENCODING_UTF16_BE, flag,
+ pp, end, fold);
}
+#if 0
static int
-utf16be_is_mbc_ambiguous(OnigAmbigType flag, const UChar** pp, const UChar* end)
+utf16be_is_mbc_ambiguous(OnigCaseFoldType flag, const UChar** pp, const UChar* end)
{
const UChar* p = *pp;
@@ -165,27 +160,27 @@ utf16be_is_mbc_ambiguous(OnigAmbigType flag, const UChar** pp, const UChar* end)
int c, v;
p++;
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- c = *p;
- v = ONIGENC_IS_UNICODE_ISO_8859_1_CTYPE(c,
- (ONIGENC_CTYPE_UPPER | ONIGENC_CTYPE_LOWER));
-
- if ((v | ONIGENC_CTYPE_LOWER) != 0) {
- /* 0xaa, 0xb5, 0xba are lower case letter, but can't convert. */
- if (c >= 0xaa && c <= 0xba)
- return FALSE;
- else
- return TRUE;
- }
- return (v != 0 ? TRUE : FALSE);
+ if (*p == 0xdf && (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
+ return TRUE;
+ }
+
+ c = *p;
+ v = ONIGENC_IS_UNICODE_ISO_8859_1_BIT_CTYPE(c,
+ (BIT_CTYPE_UPPER | BIT_CTYPE_LOWER));
+
+ if ((v | BIT_CTYPE_LOWER) != 0) {
+ /* 0xaa, 0xb5, 0xba are lower case letter, but can't convert. */
+ if (c >= 0xaa && c <= 0xba)
+ return FALSE;
+ else
+ return TRUE;
}
+ return (v != 0 ? TRUE : FALSE);
}
return FALSE;
}
+#endif
static UChar*
utf16be_left_adjust_char_head(const UChar* start, const UChar* s)
@@ -202,31 +197,29 @@ utf16be_left_adjust_char_head(const UChar* start, const UChar* s)
return (UChar* )s;
}
+static int
+utf16be_get_case_fold_codes_by_str(OnigCaseFoldType flag,
+ const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[])
+{
+ return onigenc_unicode_get_case_fold_codes_by_str(ONIG_ENCODING_UTF16_BE,
+ flag, p, end, items);
+}
+
OnigEncodingType OnigEncodingUTF16_BE = {
utf16be_mbc_enc_len,
"UTF-16BE", /* name */
4, /* max byte length */
2, /* min byte length */
- (ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE |
- ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE ),
- {
- (OnigCodePoint )'\\' /* esc */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
- },
utf16be_is_mbc_newline,
utf16be_mbc_to_code,
utf16be_code_to_mbclen,
utf16be_code_to_mbc,
- utf16be_mbc_to_normalize,
- utf16be_is_mbc_ambiguous,
- onigenc_iso_8859_1_get_all_pair_ambig_codes,
- onigenc_ess_tsett_get_all_comp_ambig_codes,
+ utf16be_mbc_case_fold,
+ onigenc_unicode_apply_all_case_fold,
+ utf16be_get_case_fold_codes_by_str,
+ onigenc_unicode_property_name_to_ctype,
onigenc_unicode_is_code_ctype,
- onigenc_unicode_get_ctype_code_range,
+ onigenc_utf16_32_get_ctype_code_range,
utf16be_left_adjust_char_head,
onigenc_always_false_is_allowed_reverse_match
};
diff --git a/ext/mbstring/oniguruma/enc/utf16_le.c b/ext/mbstring/oniguruma/enc/utf16_le.c
index 2248e4910f..5cc0759117 100644
--- a/ext/mbstring/oniguruma/enc/utf16_le.c
+++ b/ext/mbstring/oniguruma/enc/utf16_le.c
@@ -2,7 +2,7 @@
utf16_le.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2006 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2008 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -29,9 +29,6 @@
#include "regenc.h"
-#define UTF16_IS_SURROGATE_FIRST(c) (c >= 0xd8 && c <= 0xdb)
-#define UTF16_IS_SURROGATE_SECOND(c) (c >= 0xdc && c <= 0xdf)
-
static const int EncLen_UTF16[] = {
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -70,7 +67,11 @@ utf16le_is_mbc_newline(const UChar* p, const UChar* end)
if (*p == 0x0a && *(p+1) == 0x00)
return 1;
#ifdef USE_UNICODE_ALL_LINE_TERMINATORS
- if ((*p == 0x0d || *p == 0x85) && *(p+1) == 0x00)
+ if ((
+#ifndef USE_CRNL_AS_LINE_TERMINATOR
+ *p == 0x0d ||
+#endif
+ *p == 0x85) && *(p+1) == 0x00)
return 1;
if (*(p+1) == 0x20 && (*p == 0x29 || *p == 0x28))
return 1;
@@ -80,7 +81,7 @@ utf16le_is_mbc_newline(const UChar* p, const UChar* end)
}
static OnigCodePoint
-utf16le_mbc_to_code(const UChar* p, const UChar* end)
+utf16le_mbc_to_code(const UChar* p, const UChar* end ARG_UNUSED)
{
OnigCodePoint code;
UChar c0 = *p;
@@ -105,13 +106,13 @@ utf16le_code_to_mbc(OnigCodePoint code, UChar *buf)
if (code > 0xffff) {
unsigned int plane, high;
- plane = code >> 16;
+ plane = (code >> 16) - 1;
high = (code & 0xff00) >> 8;
*p++ = ((plane & 0x03) << 6) + (high >> 2);
*p++ = (plane >> 2) + 0xd8;
*p++ = (UChar )(code & 0xff);
- *p = (high & 0x02) + 0xdc;
+ *p = (high & 0x03) + 0xdc;
return 4;
}
else {
@@ -122,40 +123,37 @@ utf16le_code_to_mbc(OnigCodePoint code, UChar *buf)
}
static int
-utf16le_mbc_to_normalize(OnigAmbigType flag, const UChar** pp, const UChar* end,
- UChar* lower)
+utf16le_mbc_case_fold(OnigCaseFoldType flag,
+ const UChar** pp, const UChar* end, UChar* fold)
{
const UChar* p = *pp;
- if (*(p+1) == 0) {
- *(lower+1) = '\0';
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- *lower = ONIGENC_ISO_8859_1_TO_LOWER_CASE(*p);
- }
- else {
- *lower = *p;
- }
- (*pp) += 2;
- return 2; /* return byte length of converted char to lower */
- }
- else {
- int len = EncLen_UTF16[*(p+1)];
- if (lower != p) {
- int i;
- for (i = 0; i < len; i++) {
- *lower++ = *p++;
+ if (ONIGENC_IS_ASCII_CODE(*p) && *(p+1) == 0) {
+#ifdef USE_UNICODE_CASE_FOLD_TURKISH_AZERI
+ if ((flag & ONIGENC_CASE_FOLD_TURKISH_AZERI) != 0) {
+ if (*p == 0x49) {
+ *fold++ = 0x31;
+ *fold = 0x01;
+ (*pp) += 2;
+ return 2;
}
}
- (*pp) += len;
- return len; /* return byte length of converted char to lower */
+#endif
+
+ *fold++ = ONIGENC_ASCII_CODE_TO_LOWER_CASE(*p);
+ *fold = 0;
+ *pp += 2;
+ return 2;
}
+ else
+ return onigenc_unicode_mbc_case_fold(ONIG_ENCODING_UTF16_LE, flag, pp, end,
+ fold);
}
+#if 0
static int
-utf16le_is_mbc_ambiguous(OnigAmbigType flag, const UChar** pp, const UChar* end)
+utf16le_is_mbc_ambiguous(OnigCaseFoldType flag, const UChar** pp,
+ const UChar* end)
{
const UChar* p = *pp;
@@ -164,26 +162,26 @@ utf16le_is_mbc_ambiguous(OnigAmbigType flag, const UChar** pp, const UChar* end)
if (*(p+1) == 0) {
int c, v;
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- c = *p;
- v = ONIGENC_IS_UNICODE_ISO_8859_1_CTYPE(c,
- (ONIGENC_CTYPE_UPPER | ONIGENC_CTYPE_LOWER));
- if ((v | ONIGENC_CTYPE_LOWER) != 0) {
- /* 0xaa, 0xb5, 0xba are lower case letter, but can't convert. */
- if (c >= 0xaa && c <= 0xba)
- return FALSE;
- else
- return TRUE;
- }
- return (v != 0 ? TRUE : FALSE);
+ if (*p == 0xdf && (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
+ return TRUE;
}
+
+ c = *p;
+ v = ONIGENC_IS_UNICODE_ISO_8859_1_BIT_CTYPE(c,
+ (BIT_CTYPE_UPPER | BIT_CTYPE_LOWER));
+ if ((v | BIT_CTYPE_LOWER) != 0) {
+ /* 0xaa, 0xb5, 0xba are lower case letter, but can't convert. */
+ if (c >= 0xaa && c <= 0xba)
+ return FALSE;
+ else
+ return TRUE;
+ }
+ return (v != 0 ? TRUE : FALSE);
}
return FALSE;
}
+#endif
static UChar*
utf16le_left_adjust_char_head(const UChar* start, const UChar* s)
@@ -200,31 +198,29 @@ utf16le_left_adjust_char_head(const UChar* start, const UChar* s)
return (UChar* )s;
}
+static int
+utf16le_get_case_fold_codes_by_str(OnigCaseFoldType flag,
+ const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[])
+{
+ return onigenc_unicode_get_case_fold_codes_by_str(ONIG_ENCODING_UTF16_LE,
+ flag, p, end, items);
+}
+
OnigEncodingType OnigEncodingUTF16_LE = {
utf16le_mbc_enc_len,
"UTF-16LE", /* name */
4, /* max byte length */
2, /* min byte length */
- (ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE |
- ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE ),
- {
- (OnigCodePoint )'\\' /* esc */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
- },
utf16le_is_mbc_newline,
utf16le_mbc_to_code,
utf16le_code_to_mbclen,
utf16le_code_to_mbc,
- utf16le_mbc_to_normalize,
- utf16le_is_mbc_ambiguous,
- onigenc_iso_8859_1_get_all_pair_ambig_codes,
- onigenc_ess_tsett_get_all_comp_ambig_codes,
+ utf16le_mbc_case_fold,
+ onigenc_unicode_apply_all_case_fold,
+ utf16le_get_case_fold_codes_by_str,
+ onigenc_unicode_property_name_to_ctype,
onigenc_unicode_is_code_ctype,
- onigenc_unicode_get_ctype_code_range,
+ onigenc_utf16_32_get_ctype_code_range,
utf16le_left_adjust_char_head,
onigenc_always_false_is_allowed_reverse_match
};
diff --git a/ext/mbstring/oniguruma/enc/utf32_be.c b/ext/mbstring/oniguruma/enc/utf32_be.c
index 75133ca262..b4f822607c 100644
--- a/ext/mbstring/oniguruma/enc/utf32_be.c
+++ b/ext/mbstring/oniguruma/enc/utf32_be.c
@@ -2,7 +2,7 @@
utf32_be.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2006 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2007 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
#include "regenc.h"
static int
-utf32be_mbc_enc_len(const UChar* p)
+utf32be_mbc_enc_len(const UChar* p ARG_UNUSED)
{
return 4;
}
@@ -42,7 +42,11 @@ utf32be_is_mbc_newline(const UChar* p, const UChar* end)
if (*(p+3) == 0x0a && *(p+2) == 0 && *(p+1) == 0 && *p == 0)
return 1;
#ifdef USE_UNICODE_ALL_LINE_TERMINATORS
- if ((*(p+3) == 0x0d || *(p+3) == 0x85)
+ if ((
+#ifndef USE_CRNL_AS_LINE_TERMINATOR
+ *(p+3) == 0x0d ||
+#endif
+ *(p+3) == 0x85)
&& *(p+2) == 0 && *(p+1) == 0 && *p == 0x00)
return 1;
if (*(p+2) == 0x20 && (*(p+3) == 0x29 || *(p+3) == 0x28)
@@ -54,13 +58,13 @@ utf32be_is_mbc_newline(const UChar* p, const UChar* end)
}
static OnigCodePoint
-utf32be_mbc_to_code(const UChar* p, const UChar* end)
+utf32be_mbc_to_code(const UChar* p, const UChar* end ARG_UNUSED)
{
return (OnigCodePoint )(((p[0] * 256 + p[1]) * 256 + p[2]) * 256 + p[3]);
}
static int
-utf32be_code_to_mbclen(OnigCodePoint code)
+utf32be_code_to_mbclen(OnigCodePoint code ARG_UNUSED)
{
return 4;
}
@@ -78,44 +82,39 @@ utf32be_code_to_mbc(OnigCodePoint code, UChar *buf)
}
static int
-utf32be_mbc_to_normalize(OnigAmbigType flag, const UChar** pp, const UChar* end,
- UChar* lower)
+utf32be_mbc_case_fold(OnigCaseFoldType flag,
+ const UChar** pp, const UChar* end, UChar* fold)
{
const UChar* p = *pp;
- if (*(p+2) == 0 && *(p+1) == 0 && *p == 0) {
- p += 3;
- *lower++ = '\0';
- *lower++ = '\0';
- *lower++ = '\0';
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- *lower = ONIGENC_ISO_8859_1_TO_LOWER_CASE(*p);
- }
- else {
- *lower = *p;
- }
-
- (*pp) += 4;
- return 4; /* return byte length of converted char to lower */
- }
- else {
- int len = 4;
- if (lower != p) {
- int i;
- for (i = 0; i < len; i++) {
- *lower++ = *p++;
+ if (ONIGENC_IS_ASCII_CODE(*(p+3)) && *(p+2) == 0 && *(p+1) == 0 && *p == 0) {
+ *fold++ = 0;
+ *fold++ = 0;
+
+#ifdef USE_UNICODE_CASE_FOLD_TURKISH_AZERI
+ if ((flag & ONIGENC_CASE_FOLD_TURKISH_AZERI) != 0) {
+ if (*(p+3) == 0x49) {
+ *fold++ = 0x01;
+ *fold = 0x31;
+ (*pp) += 4;
+ return 4;
}
}
- (*pp) += len;
- return len; /* return byte length of converted char to lower */
+#endif
+
+ *fold++ = 0;
+ *fold = ONIGENC_ASCII_CODE_TO_LOWER_CASE(*(p+3));
+ *pp += 4;
+ return 4;
}
+ else
+ return onigenc_unicode_mbc_case_fold(ONIG_ENCODING_UTF32_BE, flag, pp, end,
+ fold);
}
+#if 0
static int
-utf32be_is_mbc_ambiguous(OnigAmbigType flag, const UChar** pp, const UChar* end)
+utf32be_is_mbc_ambiguous(OnigCaseFoldType flag, const UChar** pp, const UChar* end)
{
const UChar* p = *pp;
@@ -125,26 +124,26 @@ utf32be_is_mbc_ambiguous(OnigAmbigType flag, const UChar** pp, const UChar* end)
int c, v;
p += 3;
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- c = *p;
- v = ONIGENC_IS_UNICODE_ISO_8859_1_CTYPE(c,
- (ONIGENC_CTYPE_UPPER | ONIGENC_CTYPE_LOWER));
- if ((v | ONIGENC_CTYPE_LOWER) != 0) {
- /* 0xaa, 0xb5, 0xba are lower case letter, but can't convert. */
- if (c >= 0xaa && c <= 0xba)
- return FALSE;
- else
- return TRUE;
- }
- return (v != 0 ? TRUE : FALSE);
+ if (*p == 0xdf && (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
+ return TRUE;
+ }
+
+ c = *p;
+ v = ONIGENC_IS_UNICODE_ISO_8859_1_BIT_CTYPE(c,
+ (BIT_CTYPE_UPPER | BIT_CTYPE_LOWER));
+ if ((v | BIT_CTYPE_LOWER) != 0) {
+ /* 0xaa, 0xb5, 0xba are lower case letter, but can't convert. */
+ if (c >= 0xaa && c <= 0xba)
+ return FALSE;
+ else
+ return TRUE;
}
+ return (v != 0 ? TRUE : FALSE);
}
return FALSE;
}
+#endif
static UChar*
utf32be_left_adjust_char_head(const UChar* start, const UChar* s)
@@ -157,31 +156,29 @@ utf32be_left_adjust_char_head(const UChar* start, const UChar* s)
return (UChar* )(s - rem);
}
+static int
+utf32be_get_case_fold_codes_by_str(OnigCaseFoldType flag,
+ const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[])
+{
+ return onigenc_unicode_get_case_fold_codes_by_str(ONIG_ENCODING_UTF32_BE,
+ flag, p, end, items);
+}
+
OnigEncodingType OnigEncodingUTF32_BE = {
utf32be_mbc_enc_len,
"UTF-32BE", /* name */
4, /* max byte length */
4, /* min byte length */
- (ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE |
- ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE ),
- {
- (OnigCodePoint )'\\' /* esc */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
- },
utf32be_is_mbc_newline,
utf32be_mbc_to_code,
utf32be_code_to_mbclen,
utf32be_code_to_mbc,
- utf32be_mbc_to_normalize,
- utf32be_is_mbc_ambiguous,
- onigenc_iso_8859_1_get_all_pair_ambig_codes,
- onigenc_ess_tsett_get_all_comp_ambig_codes,
+ utf32be_mbc_case_fold,
+ onigenc_unicode_apply_all_case_fold,
+ utf32be_get_case_fold_codes_by_str,
+ onigenc_unicode_property_name_to_ctype,
onigenc_unicode_is_code_ctype,
- onigenc_unicode_get_ctype_code_range,
+ onigenc_utf16_32_get_ctype_code_range,
utf32be_left_adjust_char_head,
onigenc_always_false_is_allowed_reverse_match
};
diff --git a/ext/mbstring/oniguruma/enc/utf32_le.c b/ext/mbstring/oniguruma/enc/utf32_le.c
index 21dca10c11..8f413bfc74 100644
--- a/ext/mbstring/oniguruma/enc/utf32_le.c
+++ b/ext/mbstring/oniguruma/enc/utf32_le.c
@@ -2,7 +2,7 @@
utf32_le.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2006 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2007 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,7 +30,7 @@
#include "regenc.h"
static int
-utf32le_mbc_enc_len(const UChar* p)
+utf32le_mbc_enc_len(const UChar* p ARG_UNUSED)
{
return 4;
}
@@ -42,8 +42,12 @@ utf32le_is_mbc_newline(const UChar* p, const UChar* end)
if (*p == 0x0a && *(p+1) == 0 && *(p+2) == 0 && *(p+3) == 0)
return 1;
#ifdef USE_UNICODE_ALL_LINE_TERMINATORS
- if ((*p == 0x0d || *p == 0x85) && *(p+1) == 0x00
- && (p+2) == 0x00 && *(p+3) == 0x00)
+ if ((
+#ifndef USE_CRNL_AS_LINE_TERMINATOR
+ *p == 0x0d ||
+#endif
+ *p == 0x85)
+ && *(p+1) == 0x00 && (p+2) == 0x00 && *(p+3) == 0x00)
return 1;
if (*(p+1) == 0x20 && (*p == 0x29 || *p == 0x28)
&& *(p+2) == 0x00 && *(p+3) == 0x00)
@@ -54,13 +58,13 @@ utf32le_is_mbc_newline(const UChar* p, const UChar* end)
}
static OnigCodePoint
-utf32le_mbc_to_code(const UChar* p, const UChar* end)
+utf32le_mbc_to_code(const UChar* p, const UChar* end ARG_UNUSED)
{
return (OnigCodePoint )(((p[3] * 256 + p[2]) * 256 + p[1]) * 256 + p[0]);
}
static int
-utf32le_code_to_mbclen(OnigCodePoint code)
+utf32le_code_to_mbclen(OnigCodePoint code ARG_UNUSED)
{
return 4;
}
@@ -78,43 +82,40 @@ utf32le_code_to_mbc(OnigCodePoint code, UChar *buf)
}
static int
-utf32le_mbc_to_normalize(OnigAmbigType flag, const UChar** pp, const UChar* end,
- UChar* lower)
+utf32le_mbc_case_fold(OnigCaseFoldType flag,
+ const UChar** pp, const UChar* end, UChar* fold)
{
const UChar* p = *pp;
- if (*(p+1) == 0 && *(p+2) == 0 && *(p+3) == 0) {
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- *lower++ = ONIGENC_ISO_8859_1_TO_LOWER_CASE(*p);
+ if (ONIGENC_IS_ASCII_CODE(*p) && *(p+1) == 0 && *(p+2) == 0 && *(p+3) == 0) {
+#ifdef USE_UNICODE_CASE_FOLD_TURKISH_AZERI
+ if ((flag & ONIGENC_CASE_FOLD_TURKISH_AZERI) != 0) {
+ if (*p == 0x49) {
+ *fold++ = 0x31;
+ *fold++ = 0x01;
+ }
}
else {
- *lower++ = *p;
+#endif
+ *fold++ = ONIGENC_ASCII_CODE_TO_LOWER_CASE(*p);
+ *fold++ = 0;
+#ifdef USE_UNICODE_CASE_FOLD_TURKISH_AZERI
}
- *lower++ = '\0';
- *lower++ = '\0';
- *lower = '\0';
+#endif
- (*pp) += 4;
- return 4; /* return byte length of converted char to lower */
- }
- else {
- int len = 4;
- if (lower != p) {
- int i;
- for (i = 0; i < len; i++) {
- *lower++ = *p++;
- }
- }
- (*pp) += len;
- return len; /* return byte length of converted char to lower */
+ *fold++ = 0;
+ *fold = 0;
+ *pp += 4;
+ return 4;
}
+ else
+ return onigenc_unicode_mbc_case_fold(ONIG_ENCODING_UTF32_LE, flag, pp, end,
+ fold);
}
+#if 0
static int
-utf32le_is_mbc_ambiguous(OnigAmbigType flag, const UChar** pp, const UChar* end)
+utf32le_is_mbc_ambiguous(OnigCaseFoldType flag, const UChar** pp, const UChar* end)
{
const UChar* p = *pp;
@@ -123,26 +124,26 @@ utf32le_is_mbc_ambiguous(OnigAmbigType flag, const UChar** pp, const UChar* end)
if (*(p+1) == 0 && *(p+2) == 0 && *(p+3) == 0) {
int c, v;
- if (((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0 &&
- ONIGENC_IS_MBC_ASCII(p)) ||
- ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0 &&
- !ONIGENC_IS_MBC_ASCII(p))) {
- c = *p;
- v = ONIGENC_IS_UNICODE_ISO_8859_1_CTYPE(c,
- (ONIGENC_CTYPE_UPPER | ONIGENC_CTYPE_LOWER));
- if ((v | ONIGENC_CTYPE_LOWER) != 0) {
- /* 0xaa, 0xb5, 0xba are lower case letter, but can't convert. */
- if (c >= 0xaa && c <= 0xba)
- return FALSE;
- else
- return TRUE;
- }
- return (v != 0 ? TRUE : FALSE);
+ if (*p == 0xdf && (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
+ return TRUE;
+ }
+
+ c = *p;
+ v = ONIGENC_IS_UNICODE_ISO_8859_1_BIT_CTYPE(c,
+ (BIT_CTYPE_UPPER | BIT_CTYPE_LOWER));
+ if ((v | BIT_CTYPE_LOWER) != 0) {
+ /* 0xaa, 0xb5, 0xba are lower case letter, but can't convert. */
+ if (c >= 0xaa && c <= 0xba)
+ return FALSE;
+ else
+ return TRUE;
}
+ return (v != 0 ? TRUE : FALSE);
}
return FALSE;
}
+#endif
static UChar*
utf32le_left_adjust_char_head(const UChar* start, const UChar* s)
@@ -155,31 +156,29 @@ utf32le_left_adjust_char_head(const UChar* start, const UChar* s)
return (UChar* )(s - rem);
}
+static int
+utf32le_get_case_fold_codes_by_str(OnigCaseFoldType flag,
+ const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[])
+{
+ return onigenc_unicode_get_case_fold_codes_by_str(ONIG_ENCODING_UTF32_LE,
+ flag, p, end, items);
+}
+
OnigEncodingType OnigEncodingUTF32_LE = {
utf32le_mbc_enc_len,
"UTF-32LE", /* name */
4, /* max byte length */
4, /* min byte length */
- (ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE |
- ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE ),
- {
- (OnigCodePoint )'\\' /* esc */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
- },
utf32le_is_mbc_newline,
utf32le_mbc_to_code,
utf32le_code_to_mbclen,
utf32le_code_to_mbc,
- utf32le_mbc_to_normalize,
- utf32le_is_mbc_ambiguous,
- onigenc_iso_8859_1_get_all_pair_ambig_codes,
- onigenc_ess_tsett_get_all_comp_ambig_codes,
+ utf32le_mbc_case_fold,
+ onigenc_unicode_apply_all_case_fold,
+ utf32le_get_case_fold_codes_by_str,
+ onigenc_unicode_property_name_to_ctype,
onigenc_unicode_is_code_ctype,
- onigenc_unicode_get_ctype_code_range,
+ onigenc_utf16_32_get_ctype_code_range,
utf32le_left_adjust_char_head,
onigenc_always_false_is_allowed_reverse_match
};
diff --git a/ext/mbstring/oniguruma/enc/utf8.c b/ext/mbstring/oniguruma/enc/utf8.c
index c7481d7050..5e2c1721aa 100644
--- a/ext/mbstring/oniguruma/enc/utf8.c
+++ b/ext/mbstring/oniguruma/enc/utf8.c
@@ -2,7 +2,7 @@
utf8.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2006 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2007 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -60,19 +60,21 @@ static const int EncLen_UTF8[] = {
};
static int
-utf8_mbc_enc_len(const UChar* p)
+mbc_enc_len(const UChar* p)
{
return EncLen_UTF8[*p];
}
static int
-utf8_is_mbc_newline(const UChar* p, const UChar* end)
+is_mbc_newline(const UChar* p, const UChar* end)
{
if (p < end) {
if (*p == 0x0a) return 1;
#ifdef USE_UNICODE_ALL_LINE_TERMINATORS
+#ifndef USE_CRNL_AS_LINE_TERMINATOR
if (*p == 0x0d) return 1;
+#endif
if (p + 1 < end) {
if (*(p+1) == 0x85 && *p == 0xc2) /* U+0085 */
return 1;
@@ -89,12 +91,12 @@ utf8_is_mbc_newline(const UChar* p, const UChar* end)
}
static OnigCodePoint
-utf8_mbc_to_code(const UChar* p, const UChar* end)
+mbc_to_code(const UChar* p, const UChar* end ARG_UNUSED)
{
int c, len;
OnigCodePoint n;
- len = enc_len(ONIG_ENCODING_UTF8, p);
+ len = enclen(ONIG_ENCODING_UTF8, p);
c = *p++;
if (len > 1) {
len--;
@@ -116,14 +118,10 @@ utf8_mbc_to_code(const UChar* p, const UChar* end)
}
static int
-utf8_code_to_mbclen(OnigCodePoint code)
+code_to_mbclen(OnigCodePoint code)
{
if ((code & 0xffffff80) == 0) return 1;
- else if ((code & 0xfffff800) == 0) {
- if (code <= 0xff && code >= 0xfe)
- return 1;
- return 2;
- }
+ else if ((code & 0xfffff800) == 0) return 2;
else if ((code & 0xffff0000) == 0) return 3;
else if ((code & 0xffe00000) == 0) return 4;
else if ((code & 0xfc000000) == 0) return 5;
@@ -133,35 +131,11 @@ utf8_code_to_mbclen(OnigCodePoint code)
else if (code == INVALID_CODE_FF) return 1;
#endif
else
- return ONIGENCERR_TOO_BIG_WIDE_CHAR_VALUE;
-}
-
-#if 0
-static int
-utf8_code_to_mbc_first(OnigCodePoint code)
-{
- if ((code & 0xffffff80) == 0)
- return code;
- else {
- if ((code & 0xfffff800) == 0)
- return ((code>>6)& 0x1f) | 0xc0;
- else if ((code & 0xffff0000) == 0)
- return ((code>>12) & 0x0f) | 0xe0;
- else if ((code & 0xffe00000) == 0)
- return ((code>>18) & 0x07) | 0xf0;
- else if ((code & 0xfc000000) == 0)
- return ((code>>24) & 0x03) | 0xf8;
- else if ((code & 0x80000000) == 0)
- return ((code>>30) & 0x01) | 0xfc;
- else {
- return ONIGENCERR_TOO_BIG_WIDE_CHAR_VALUE;
- }
- }
+ return ONIGERR_INVALID_CODE_POINT_VALUE;
}
-#endif
static int
-utf8_code_to_mbc(OnigCodePoint code, UChar *buf)
+code_to_mbc(OnigCodePoint code, UChar *buf)
{
#define UTF8_TRAILS(code, shift) (UChar )((((code) >> (shift)) & 0x3f) | 0x80)
#define UTF8_TRAIL0(code) (UChar )(((code) & 0x3f) | 0x80)
@@ -209,7 +183,7 @@ utf8_code_to_mbc(OnigCodePoint code, UChar *buf)
}
#endif
else {
- return ONIGENCERR_TOO_BIG_WIDE_CHAR_VALUE;
+ return ONIGERR_TOO_BIG_WIDE_CHAR_VALUE;
}
*p++ = UTF8_TRAIL0(code);
@@ -218,76 +192,60 @@ utf8_code_to_mbc(OnigCodePoint code, UChar *buf)
}
static int
-utf8_mbc_to_normalize(OnigAmbigType flag, const UChar** pp, const UChar* end, UChar* lower)
+mbc_case_fold(OnigCaseFoldType flag, const UChar** pp,
+ const UChar* end, UChar* fold)
{
const UChar* p = *pp;
if (ONIGENC_IS_MBC_ASCII(p)) {
- if ((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0) {
- *lower = ONIGENC_ASCII_CODE_TO_LOWER_CASE(*p);
- }
- else {
- *lower = *p;
+#ifdef USE_UNICODE_CASE_FOLD_TURKISH_AZERI
+ if ((flag & ONIGENC_CASE_FOLD_TURKISH_AZERI) != 0) {
+ if (*p == 0x49) {
+ *fold++ = 0xc4;
+ *fold = 0xb1;
+ (*pp)++;
+ return 2;
+ }
}
+#endif
+
+ *fold = ONIGENC_ASCII_CODE_TO_LOWER_CASE(*p);
(*pp)++;
return 1; /* return byte length of converted char to lower */
}
else {
- int len;
-
- if (*p == 195) { /* 195 == '\303' */
- int c = *(p + 1);
- if (c >= 128) {
- if (c <= (UChar )'\236' && /* upper */
- (flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0) {
- if (c != (UChar )'\227') {
- *lower++ = *p;
- *lower = (UChar )(c + 32);
- (*pp) += 2;
- return 2;
- }
- }
- }
- }
-
- len = enc_len(ONIG_ENCODING_UTF8, p);
- if (lower != p) {
- int i;
- for (i = 0; i < len; i++) {
- *lower++ = *p++;
- }
- }
- (*pp) += len;
- return len; /* return byte length of converted char to lower */
+ return onigenc_unicode_mbc_case_fold(ONIG_ENCODING_UTF8, flag,
+ pp, end, fold);
}
}
+#if 0
static int
-utf8_is_mbc_ambiguous(OnigAmbigType flag, const UChar** pp, const UChar* end)
+is_mbc_ambiguous(OnigCaseFoldType flag, const UChar** pp, const UChar* end)
{
const UChar* p = *pp;
if (ONIGENC_IS_MBC_ASCII(p)) {
(*pp)++;
- if ((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0) {
- return ONIGENC_IS_ASCII_CODE_CASE_AMBIG(*p);
- }
+ return ONIGENC_IS_ASCII_CODE_CASE_AMBIG(*p);
}
else {
- (*pp) += enc_len(ONIG_ENCODING_UTF8, p);
+ (*pp) += enclen(ONIG_ENCODING_UTF8, p);
- if (*p == 195) { /* 195 == '\303' */
+ if (*p == 0xc3) {
int c = *(p + 1);
- if (c >= 128) {
- if ((flag & ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) != 0) {
- if (c <= (UChar )'\236') { /* upper */
- if (c == (UChar )'\227') return FALSE;
- return TRUE;
- }
- else if (c >= (UChar )'\240' && c <= (UChar )'\276') { /* lower */
- if (c == (UChar )'\267') return FALSE;
- return TRUE;
- }
+ if (c >= 0x80) {
+ if (c <= (UChar )0x9e) { /* upper */
+ if (c == (UChar )0x97) return FALSE;
+ return TRUE;
+ }
+ else if (c >= (UChar )0xa0 && c <= (UChar )0xbe) { /* lower */
+ if (c == (UChar )'\267') return FALSE;
+ return TRUE;
+ }
+ else if (c == (UChar )0x9f &&
+ (flag & INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR) != 0) {
+ return TRUE;
}
}
}
@@ -295,3401 +253,20 @@ utf8_is_mbc_ambiguous(OnigAmbigType flag, const UChar** pp, const UChar* end)
return FALSE;
}
-
-
-static const OnigCodePoint EmptyRange[] = { 0 };
-
-static const OnigCodePoint SBAlnum[] = {
- 3,
- 0x0030, 0x0039,
- 0x0041, 0x005a,
- 0x0061, 0x007a
-};
-
-static const OnigCodePoint MBAlnum[] = {
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- 411,
-#else
- 6,
-#endif
- 0x00aa, 0x00aa,
- 0x00b5, 0x00b5,
- 0x00ba, 0x00ba,
- 0x00c0, 0x00d6,
- 0x00d8, 0x00f6,
- 0x00f8, 0x0236
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- ,
- 0x0250, 0x02c1,
- 0x02c6, 0x02d1,
- 0x02e0, 0x02e4,
- 0x02ee, 0x02ee,
- 0x0300, 0x0357,
- 0x035d, 0x036f,
- 0x037a, 0x037a,
- 0x0386, 0x0386,
- 0x0388, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x03ce,
- 0x03d0, 0x03f5,
- 0x03f7, 0x03fb,
- 0x0400, 0x0481,
- 0x0483, 0x0486,
- 0x0488, 0x04ce,
- 0x04d0, 0x04f5,
- 0x04f8, 0x04f9,
- 0x0500, 0x050f,
- 0x0531, 0x0556,
- 0x0559, 0x0559,
- 0x0561, 0x0587,
- 0x0591, 0x05a1,
- 0x05a3, 0x05b9,
- 0x05bb, 0x05bd,
- 0x05bf, 0x05bf,
- 0x05c1, 0x05c2,
- 0x05c4, 0x05c4,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f2,
- 0x0610, 0x0615,
- 0x0621, 0x063a,
- 0x0640, 0x0658,
- 0x0660, 0x0669,
- 0x066e, 0x06d3,
- 0x06d5, 0x06dc,
- 0x06de, 0x06e8,
- 0x06ea, 0x06fc,
- 0x06ff, 0x06ff,
- 0x0710, 0x074a,
- 0x074d, 0x074f,
- 0x0780, 0x07b1,
- 0x0901, 0x0939,
- 0x093c, 0x094d,
- 0x0950, 0x0954,
- 0x0958, 0x0963,
- 0x0966, 0x096f,
- 0x0981, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09cd,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09e6, 0x09f1,
- 0x0a01, 0x0a03,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a74,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abc, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae3,
- 0x0ae6, 0x0aef,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3c, 0x0b43,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b61,
- 0x0b66, 0x0b6f,
- 0x0b71, 0x0b71,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb5,
- 0x0bb7, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd7, 0x0bd7,
- 0x0be7, 0x0bef,
- 0x0c01, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c33,
- 0x0c35, 0x0c39,
- 0x0c3e, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c60, 0x0c61,
- 0x0c66, 0x0c6f,
- 0x0c82, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbc, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce1,
- 0x0ce6, 0x0cef,
- 0x0d02, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d28,
- 0x0d2a, 0x0d39,
- 0x0d3e, 0x0d43,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4d,
- 0x0d57, 0x0d57,
- 0x0d60, 0x0d61,
- 0x0d66, 0x0d6f,
- 0x0d82, 0x0d83,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dca, 0x0dca,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0df2, 0x0df3,
- 0x0e01, 0x0e3a,
- 0x0e40, 0x0e4e,
- 0x0e50, 0x0e59,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edd,
- 0x0f00, 0x0f00,
- 0x0f18, 0x0f19,
- 0x0f20, 0x0f29,
- 0x0f35, 0x0f35,
- 0x0f37, 0x0f37,
- 0x0f39, 0x0f39,
- 0x0f3e, 0x0f47,
- 0x0f49, 0x0f6a,
- 0x0f71, 0x0f84,
- 0x0f86, 0x0f8b,
- 0x0f90, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fc6, 0x0fc6,
- 0x1000, 0x1021,
- 0x1023, 0x1027,
- 0x1029, 0x102a,
- 0x102c, 0x1032,
- 0x1036, 0x1039,
- 0x1040, 0x1049,
- 0x1050, 0x1059,
- 0x10a0, 0x10c5,
- 0x10d0, 0x10f8,
- 0x1100, 0x1159,
- 0x115f, 0x11a2,
- 0x11a8, 0x11f9,
- 0x1200, 0x1206,
- 0x1208, 0x1246,
- 0x1248, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1286,
- 0x1288, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12ae,
- 0x12b0, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12ce,
- 0x12d0, 0x12d6,
- 0x12d8, 0x12ee,
- 0x12f0, 0x130e,
- 0x1310, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x131e,
- 0x1320, 0x1346,
- 0x1348, 0x135a,
- 0x1369, 0x1371,
- 0x13a0, 0x13f4,
- 0x1401, 0x166c,
- 0x166f, 0x1676,
- 0x1681, 0x169a,
- 0x16a0, 0x16ea,
- 0x1700, 0x170c,
- 0x170e, 0x1714,
- 0x1720, 0x1734,
- 0x1740, 0x1753,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1772, 0x1773,
- 0x1780, 0x17b3,
- 0x17b6, 0x17d3,
- 0x17d7, 0x17d7,
- 0x17dc, 0x17dd,
- 0x17e0, 0x17e9,
- 0x180b, 0x180d,
- 0x1810, 0x1819,
- 0x1820, 0x1877,
- 0x1880, 0x18a9,
- 0x1900, 0x191c,
- 0x1920, 0x192b,
- 0x1930, 0x193b,
- 0x1946, 0x196d,
- 0x1970, 0x1974,
- 0x1d00, 0x1d6b,
- 0x1e00, 0x1e9b,
- 0x1ea0, 0x1ef9,
- 0x1f00, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fbc,
- 0x1fbe, 0x1fbe,
- 0x1fc2, 0x1fc4,
- 0x1fc6, 0x1fcc,
- 0x1fd0, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fe0, 0x1fec,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffc,
- 0x2071, 0x2071,
- 0x207f, 0x207f,
- 0x20d0, 0x20ea,
- 0x2102, 0x2102,
- 0x2107, 0x2107,
- 0x210a, 0x2113,
- 0x2115, 0x2115,
- 0x2119, 0x211d,
- 0x2124, 0x2124,
- 0x2126, 0x2126,
- 0x2128, 0x2128,
- 0x212a, 0x212d,
- 0x212f, 0x2131,
- 0x2133, 0x2139,
- 0x213d, 0x213f,
- 0x2145, 0x2149,
- 0x3005, 0x3006,
- 0x302a, 0x302f,
- 0x3031, 0x3035,
- 0x303b, 0x303c,
- 0x3041, 0x3096,
- 0x3099, 0x309a,
- 0x309d, 0x309f,
- 0x30a1, 0x30fa,
- 0x30fc, 0x30ff,
- 0x3105, 0x312c,
- 0x3131, 0x318e,
- 0x31a0, 0x31b7,
- 0x31f0, 0x31ff,
- 0x3400, 0x4db5,
- 0x4e00, 0x9fa5,
- 0xa000, 0xa48c,
- 0xac00, 0xd7a3,
- 0xf900, 0xfa2d,
- 0xfa30, 0xfa6a,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb28,
- 0xfb2a, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbb1,
- 0xfbd3, 0xfd3d,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdf0, 0xfdfb,
- 0xfe00, 0xfe0f,
- 0xfe20, 0xfe23,
- 0xfe70, 0xfe74,
- 0xfe76, 0xfefc,
- 0xff10, 0xff19,
- 0xff21, 0xff3a,
- 0xff41, 0xff5a,
- 0xff66, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0x10000, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
- 0x10300, 0x1031e,
- 0x10330, 0x10349,
- 0x10380, 0x1039d,
- 0x10400, 0x1049d,
- 0x104a0, 0x104a9,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x1083f,
- 0x1d165, 0x1d169,
- 0x1d16d, 0x1d172,
- 0x1d17b, 0x1d182,
- 0x1d185, 0x1d18b,
- 0x1d1aa, 0x1d1ad,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a3,
- 0x1d6a8, 0x1d6c0,
- 0x1d6c2, 0x1d6da,
- 0x1d6dc, 0x1d6fa,
- 0x1d6fc, 0x1d714,
- 0x1d716, 0x1d734,
- 0x1d736, 0x1d74e,
- 0x1d750, 0x1d76e,
- 0x1d770, 0x1d788,
- 0x1d78a, 0x1d7a8,
- 0x1d7aa, 0x1d7c2,
- 0x1d7c4, 0x1d7c9,
- 0x1d7ce, 0x1d7ff,
- 0x20000, 0x2a6d6,
- 0x2f800, 0x2fa1d,
- 0xe0100, 0xe01ef
-#endif /* USE_UNICODE_FULL_RANGE_CTYPE */
-}; /* end of MBAlnum */
-
-static const OnigCodePoint SBAlpha[] = {
- 2,
- 0x0041, 0x005a,
- 0x0061, 0x007a
-};
-
-static const OnigCodePoint MBAlpha[] = {
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- 394,
-#else
- 6,
-#endif
- 0x00aa, 0x00aa,
- 0x00b5, 0x00b5,
- 0x00ba, 0x00ba,
- 0x00c0, 0x00d6,
- 0x00d8, 0x00f6,
- 0x00f8, 0x0236
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- ,
- 0x0250, 0x02c1,
- 0x02c6, 0x02d1,
- 0x02e0, 0x02e4,
- 0x02ee, 0x02ee,
- 0x0300, 0x0357,
- 0x035d, 0x036f,
- 0x037a, 0x037a,
- 0x0386, 0x0386,
- 0x0388, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x03ce,
- 0x03d0, 0x03f5,
- 0x03f7, 0x03fb,
- 0x0400, 0x0481,
- 0x0483, 0x0486,
- 0x0488, 0x04ce,
- 0x04d0, 0x04f5,
- 0x04f8, 0x04f9,
- 0x0500, 0x050f,
- 0x0531, 0x0556,
- 0x0559, 0x0559,
- 0x0561, 0x0587,
- 0x0591, 0x05a1,
- 0x05a3, 0x05b9,
- 0x05bb, 0x05bd,
- 0x05bf, 0x05bf,
- 0x05c1, 0x05c2,
- 0x05c4, 0x05c4,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f2,
- 0x0610, 0x0615,
- 0x0621, 0x063a,
- 0x0640, 0x0658,
- 0x066e, 0x06d3,
- 0x06d5, 0x06dc,
- 0x06de, 0x06e8,
- 0x06ea, 0x06ef,
- 0x06fa, 0x06fc,
- 0x06ff, 0x06ff,
- 0x0710, 0x074a,
- 0x074d, 0x074f,
- 0x0780, 0x07b1,
- 0x0901, 0x0939,
- 0x093c, 0x094d,
- 0x0950, 0x0954,
- 0x0958, 0x0963,
- 0x0981, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09cd,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09f0, 0x09f1,
- 0x0a01, 0x0a03,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a70, 0x0a74,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abc, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae3,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3c, 0x0b43,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b61,
- 0x0b71, 0x0b71,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb5,
- 0x0bb7, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd7, 0x0bd7,
- 0x0c01, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c33,
- 0x0c35, 0x0c39,
- 0x0c3e, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c60, 0x0c61,
- 0x0c82, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbc, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce1,
- 0x0d02, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d28,
- 0x0d2a, 0x0d39,
- 0x0d3e, 0x0d43,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4d,
- 0x0d57, 0x0d57,
- 0x0d60, 0x0d61,
- 0x0d82, 0x0d83,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dca, 0x0dca,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0df2, 0x0df3,
- 0x0e01, 0x0e3a,
- 0x0e40, 0x0e4e,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0edc, 0x0edd,
- 0x0f00, 0x0f00,
- 0x0f18, 0x0f19,
- 0x0f35, 0x0f35,
- 0x0f37, 0x0f37,
- 0x0f39, 0x0f39,
- 0x0f3e, 0x0f47,
- 0x0f49, 0x0f6a,
- 0x0f71, 0x0f84,
- 0x0f86, 0x0f8b,
- 0x0f90, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fc6, 0x0fc6,
- 0x1000, 0x1021,
- 0x1023, 0x1027,
- 0x1029, 0x102a,
- 0x102c, 0x1032,
- 0x1036, 0x1039,
- 0x1050, 0x1059,
- 0x10a0, 0x10c5,
- 0x10d0, 0x10f8,
- 0x1100, 0x1159,
- 0x115f, 0x11a2,
- 0x11a8, 0x11f9,
- 0x1200, 0x1206,
- 0x1208, 0x1246,
- 0x1248, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1286,
- 0x1288, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12ae,
- 0x12b0, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12ce,
- 0x12d0, 0x12d6,
- 0x12d8, 0x12ee,
- 0x12f0, 0x130e,
- 0x1310, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x131e,
- 0x1320, 0x1346,
- 0x1348, 0x135a,
- 0x13a0, 0x13f4,
- 0x1401, 0x166c,
- 0x166f, 0x1676,
- 0x1681, 0x169a,
- 0x16a0, 0x16ea,
- 0x1700, 0x170c,
- 0x170e, 0x1714,
- 0x1720, 0x1734,
- 0x1740, 0x1753,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1772, 0x1773,
- 0x1780, 0x17b3,
- 0x17b6, 0x17d3,
- 0x17d7, 0x17d7,
- 0x17dc, 0x17dd,
- 0x180b, 0x180d,
- 0x1820, 0x1877,
- 0x1880, 0x18a9,
- 0x1900, 0x191c,
- 0x1920, 0x192b,
- 0x1930, 0x193b,
- 0x1950, 0x196d,
- 0x1970, 0x1974,
- 0x1d00, 0x1d6b,
- 0x1e00, 0x1e9b,
- 0x1ea0, 0x1ef9,
- 0x1f00, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fbc,
- 0x1fbe, 0x1fbe,
- 0x1fc2, 0x1fc4,
- 0x1fc6, 0x1fcc,
- 0x1fd0, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fe0, 0x1fec,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffc,
- 0x2071, 0x2071,
- 0x207f, 0x207f,
- 0x20d0, 0x20ea,
- 0x2102, 0x2102,
- 0x2107, 0x2107,
- 0x210a, 0x2113,
- 0x2115, 0x2115,
- 0x2119, 0x211d,
- 0x2124, 0x2124,
- 0x2126, 0x2126,
- 0x2128, 0x2128,
- 0x212a, 0x212d,
- 0x212f, 0x2131,
- 0x2133, 0x2139,
- 0x213d, 0x213f,
- 0x2145, 0x2149,
- 0x3005, 0x3006,
- 0x302a, 0x302f,
- 0x3031, 0x3035,
- 0x303b, 0x303c,
- 0x3041, 0x3096,
- 0x3099, 0x309a,
- 0x309d, 0x309f,
- 0x30a1, 0x30fa,
- 0x30fc, 0x30ff,
- 0x3105, 0x312c,
- 0x3131, 0x318e,
- 0x31a0, 0x31b7,
- 0x31f0, 0x31ff,
- 0x3400, 0x4db5,
- 0x4e00, 0x9fa5,
- 0xa000, 0xa48c,
- 0xac00, 0xd7a3,
- 0xf900, 0xfa2d,
- 0xfa30, 0xfa6a,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb28,
- 0xfb2a, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbb1,
- 0xfbd3, 0xfd3d,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdf0, 0xfdfb,
- 0xfe00, 0xfe0f,
- 0xfe20, 0xfe23,
- 0xfe70, 0xfe74,
- 0xfe76, 0xfefc,
- 0xff21, 0xff3a,
- 0xff41, 0xff5a,
- 0xff66, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0x10000, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
- 0x10300, 0x1031e,
- 0x10330, 0x10349,
- 0x10380, 0x1039d,
- 0x10400, 0x1049d,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x1083f,
- 0x1d165, 0x1d169,
- 0x1d16d, 0x1d172,
- 0x1d17b, 0x1d182,
- 0x1d185, 0x1d18b,
- 0x1d1aa, 0x1d1ad,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a3,
- 0x1d6a8, 0x1d6c0,
- 0x1d6c2, 0x1d6da,
- 0x1d6dc, 0x1d6fa,
- 0x1d6fc, 0x1d714,
- 0x1d716, 0x1d734,
- 0x1d736, 0x1d74e,
- 0x1d750, 0x1d76e,
- 0x1d770, 0x1d788,
- 0x1d78a, 0x1d7a8,
- 0x1d7aa, 0x1d7c2,
- 0x1d7c4, 0x1d7c9,
- 0x20000, 0x2a6d6,
- 0x2f800, 0x2fa1d,
- 0xe0100, 0xe01ef
-#endif /* USE_UNICODE_FULL_RANGE_CTYPE */
-}; /* end of MBAlpha */
-
-static const OnigCodePoint SBBlank[] = {
- 2,
- 0x0009, 0x0009,
- 0x0020, 0x0020
-};
-
-static const OnigCodePoint MBBlank[] = {
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- 7,
-#else
- 1,
-#endif
- 0x00a0, 0x00a0
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- ,
- 0x1680, 0x1680,
- 0x180e, 0x180e,
- 0x2000, 0x200a,
- 0x202f, 0x202f,
- 0x205f, 0x205f,
- 0x3000, 0x3000
-#endif /* USE_UNICODE_FULL_RANGE_CTYPE */
-}; /* end of MBBlank */
-
-static const OnigCodePoint SBCntrl[] = {
- 2,
- 0x0000, 0x001f,
- 0x007f, 0x007f
-};
-
-static const OnigCodePoint MBCntrl[] = {
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- 18,
-#else
- 2,
-#endif
- 0x0080, 0x009f,
- 0x00ad, 0x00ad
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- ,
- 0x0600, 0x0603,
- 0x06dd, 0x06dd,
- 0x070f, 0x070f,
- 0x17b4, 0x17b5,
- 0x200b, 0x200f,
- 0x202a, 0x202e,
- 0x2060, 0x2063,
- 0x206a, 0x206f,
- 0xd800, 0xf8ff,
- 0xfeff, 0xfeff,
- 0xfff9, 0xfffb,
- 0x1d173, 0x1d17a,
- 0xe0001, 0xe0001,
- 0xe0020, 0xe007f,
- 0xf0000, 0xffffd,
- 0x100000, 0x10fffd
-#endif /* USE_UNICODE_FULL_RANGE_CTYPE */
-}; /* end of MBCntrl */
-
-static const OnigCodePoint SBDigit[] = {
- 1,
- 0x0030, 0x0039
-};
-
-static const OnigCodePoint MBDigit[] = {
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- 22,
-#else
- 0
-#endif
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- 0x0660, 0x0669,
- 0x06f0, 0x06f9,
- 0x0966, 0x096f,
- 0x09e6, 0x09ef,
- 0x0a66, 0x0a6f,
- 0x0ae6, 0x0aef,
- 0x0b66, 0x0b6f,
- 0x0be7, 0x0bef,
- 0x0c66, 0x0c6f,
- 0x0ce6, 0x0cef,
- 0x0d66, 0x0d6f,
- 0x0e50, 0x0e59,
- 0x0ed0, 0x0ed9,
- 0x0f20, 0x0f29,
- 0x1040, 0x1049,
- 0x1369, 0x1371,
- 0x17e0, 0x17e9,
- 0x1810, 0x1819,
- 0x1946, 0x194f,
- 0xff10, 0xff19,
- 0x104a0, 0x104a9,
- 0x1d7ce, 0x1d7ff
-#endif /* USE_UNICODE_FULL_RANGE_CTYPE */
-}; /* end of MBDigit */
-
-static const OnigCodePoint SBGraph[] = {
- 1,
- 0x0021, 0x007e
-};
-
-static const OnigCodePoint MBGraph[] = {
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- 404,
-#else
- 1,
-#endif
- 0x00a1, 0x0236
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- ,
- 0x0250, 0x0357,
- 0x035d, 0x036f,
- 0x0374, 0x0375,
- 0x037a, 0x037a,
- 0x037e, 0x037e,
- 0x0384, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x03ce,
- 0x03d0, 0x03fb,
- 0x0400, 0x0486,
- 0x0488, 0x04ce,
- 0x04d0, 0x04f5,
- 0x04f8, 0x04f9,
- 0x0500, 0x050f,
- 0x0531, 0x0556,
- 0x0559, 0x055f,
- 0x0561, 0x0587,
- 0x0589, 0x058a,
- 0x0591, 0x05a1,
- 0x05a3, 0x05b9,
- 0x05bb, 0x05c4,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f4,
- 0x0600, 0x0603,
- 0x060c, 0x0615,
- 0x061b, 0x061b,
- 0x061f, 0x061f,
- 0x0621, 0x063a,
- 0x0640, 0x0658,
- 0x0660, 0x070d,
- 0x070f, 0x074a,
- 0x074d, 0x074f,
- 0x0780, 0x07b1,
- 0x0901, 0x0939,
- 0x093c, 0x094d,
- 0x0950, 0x0954,
- 0x0958, 0x0970,
- 0x0981, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09cd,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09e6, 0x09fa,
- 0x0a01, 0x0a03,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a74,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abc, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae3,
- 0x0ae6, 0x0aef,
- 0x0af1, 0x0af1,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3c, 0x0b43,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b61,
- 0x0b66, 0x0b71,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb5,
- 0x0bb7, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd7, 0x0bd7,
- 0x0be7, 0x0bfa,
- 0x0c01, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c33,
- 0x0c35, 0x0c39,
- 0x0c3e, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c60, 0x0c61,
- 0x0c66, 0x0c6f,
- 0x0c82, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbc, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce1,
- 0x0ce6, 0x0cef,
- 0x0d02, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d28,
- 0x0d2a, 0x0d39,
- 0x0d3e, 0x0d43,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4d,
- 0x0d57, 0x0d57,
- 0x0d60, 0x0d61,
- 0x0d66, 0x0d6f,
- 0x0d82, 0x0d83,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dca, 0x0dca,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0df2, 0x0df4,
- 0x0e01, 0x0e3a,
- 0x0e3f, 0x0e5b,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edd,
- 0x0f00, 0x0f47,
- 0x0f49, 0x0f6a,
- 0x0f71, 0x0f8b,
- 0x0f90, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fbe, 0x0fcc,
- 0x0fcf, 0x0fcf,
- 0x1000, 0x1021,
- 0x1023, 0x1027,
- 0x1029, 0x102a,
- 0x102c, 0x1032,
- 0x1036, 0x1039,
- 0x1040, 0x1059,
- 0x10a0, 0x10c5,
- 0x10d0, 0x10f8,
- 0x10fb, 0x10fb,
- 0x1100, 0x1159,
- 0x115f, 0x11a2,
- 0x11a8, 0x11f9,
- 0x1200, 0x1206,
- 0x1208, 0x1246,
- 0x1248, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1286,
- 0x1288, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12ae,
- 0x12b0, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12ce,
- 0x12d0, 0x12d6,
- 0x12d8, 0x12ee,
- 0x12f0, 0x130e,
- 0x1310, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x131e,
- 0x1320, 0x1346,
- 0x1348, 0x135a,
- 0x1361, 0x137c,
- 0x13a0, 0x13f4,
- 0x1401, 0x1676,
- 0x1681, 0x169c,
- 0x16a0, 0x16f0,
- 0x1700, 0x170c,
- 0x170e, 0x1714,
- 0x1720, 0x1736,
- 0x1740, 0x1753,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1772, 0x1773,
- 0x1780, 0x17dd,
- 0x17e0, 0x17e9,
- 0x17f0, 0x17f9,
- 0x1800, 0x180d,
- 0x1810, 0x1819,
- 0x1820, 0x1877,
- 0x1880, 0x18a9,
- 0x1900, 0x191c,
- 0x1920, 0x192b,
- 0x1930, 0x193b,
- 0x1940, 0x1940,
- 0x1944, 0x196d,
- 0x1970, 0x1974,
- 0x19e0, 0x19ff,
- 0x1d00, 0x1d6b,
- 0x1e00, 0x1e9b,
- 0x1ea0, 0x1ef9,
- 0x1f00, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fc4,
- 0x1fc6, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fdd, 0x1fef,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffe,
- 0x200b, 0x2027,
- 0x202a, 0x202e,
- 0x2030, 0x2054,
- 0x2057, 0x2057,
- 0x2060, 0x2063,
- 0x206a, 0x2071,
- 0x2074, 0x208e,
- 0x20a0, 0x20b1,
- 0x20d0, 0x20ea,
- 0x2100, 0x213b,
- 0x213d, 0x214b,
- 0x2153, 0x2183,
- 0x2190, 0x23d0,
- 0x2400, 0x2426,
- 0x2440, 0x244a,
- 0x2460, 0x2617,
- 0x2619, 0x267d,
- 0x2680, 0x2691,
- 0x26a0, 0x26a1,
- 0x2701, 0x2704,
- 0x2706, 0x2709,
- 0x270c, 0x2727,
- 0x2729, 0x274b,
- 0x274d, 0x274d,
- 0x274f, 0x2752,
- 0x2756, 0x2756,
- 0x2758, 0x275e,
- 0x2761, 0x2794,
- 0x2798, 0x27af,
- 0x27b1, 0x27be,
- 0x27d0, 0x27eb,
- 0x27f0, 0x2b0d,
- 0x2e80, 0x2e99,
- 0x2e9b, 0x2ef3,
- 0x2f00, 0x2fd5,
- 0x2ff0, 0x2ffb,
- 0x3001, 0x303f,
- 0x3041, 0x3096,
- 0x3099, 0x30ff,
- 0x3105, 0x312c,
- 0x3131, 0x318e,
- 0x3190, 0x31b7,
- 0x31f0, 0x321e,
- 0x3220, 0x3243,
- 0x3250, 0x327d,
- 0x327f, 0x32fe,
- 0x3300, 0x4db5,
- 0x4dc0, 0x9fa5,
- 0xa000, 0xa48c,
- 0xa490, 0xa4c6,
- 0xac00, 0xd7a3,
- 0xe000, 0xfa2d,
- 0xfa30, 0xfa6a,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbb1,
- 0xfbd3, 0xfd3f,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdf0, 0xfdfd,
- 0xfe00, 0xfe0f,
- 0xfe20, 0xfe23,
- 0xfe30, 0xfe52,
- 0xfe54, 0xfe66,
- 0xfe68, 0xfe6b,
- 0xfe70, 0xfe74,
- 0xfe76, 0xfefc,
- 0xfeff, 0xfeff,
- 0xff01, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0xffe0, 0xffe6,
- 0xffe8, 0xffee,
- 0xfff9, 0xfffd,
- 0x10000, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
- 0x10100, 0x10102,
- 0x10107, 0x10133,
- 0x10137, 0x1013f,
- 0x10300, 0x1031e,
- 0x10320, 0x10323,
- 0x10330, 0x1034a,
- 0x10380, 0x1039d,
- 0x1039f, 0x1039f,
- 0x10400, 0x1049d,
- 0x104a0, 0x104a9,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x1083f,
- 0x1d000, 0x1d0f5,
- 0x1d100, 0x1d126,
- 0x1d12a, 0x1d1dd,
- 0x1d300, 0x1d356,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a3,
- 0x1d6a8, 0x1d7c9,
- 0x1d7ce, 0x1d7ff,
- 0x20000, 0x2a6d6,
- 0x2f800, 0x2fa1d,
- 0xe0001, 0xe0001,
- 0xe0020, 0xe007f,
- 0xe0100, 0xe01ef,
- 0xf0000, 0xffffd,
- 0x100000, 0x10fffd
-#endif /* USE_UNICODE_FULL_RANGE_CTYPE */
-}; /* end of MBGraph */
-
-static const OnigCodePoint SBLower[] = {
- 1,
- 0x0061, 0x007a
-};
-
-static const OnigCodePoint MBLower[] = {
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- 423,
-#else
- 5,
-#endif
- 0x00aa, 0x00aa,
- 0x00b5, 0x00b5,
- 0x00ba, 0x00ba,
- 0x00df, 0x00f6,
- 0x00f8, 0x00ff
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- ,
- 0x0101, 0x0101,
- 0x0103, 0x0103,
- 0x0105, 0x0105,
- 0x0107, 0x0107,
- 0x0109, 0x0109,
- 0x010b, 0x010b,
- 0x010d, 0x010d,
- 0x010f, 0x010f,
- 0x0111, 0x0111,
- 0x0113, 0x0113,
- 0x0115, 0x0115,
- 0x0117, 0x0117,
- 0x0119, 0x0119,
- 0x011b, 0x011b,
- 0x011d, 0x011d,
- 0x011f, 0x011f,
- 0x0121, 0x0121,
- 0x0123, 0x0123,
- 0x0125, 0x0125,
- 0x0127, 0x0127,
- 0x0129, 0x0129,
- 0x012b, 0x012b,
- 0x012d, 0x012d,
- 0x012f, 0x012f,
- 0x0131, 0x0131,
- 0x0133, 0x0133,
- 0x0135, 0x0135,
- 0x0137, 0x0138,
- 0x013a, 0x013a,
- 0x013c, 0x013c,
- 0x013e, 0x013e,
- 0x0140, 0x0140,
- 0x0142, 0x0142,
- 0x0144, 0x0144,
- 0x0146, 0x0146,
- 0x0148, 0x0149,
- 0x014b, 0x014b,
- 0x014d, 0x014d,
- 0x014f, 0x014f,
- 0x0151, 0x0151,
- 0x0153, 0x0153,
- 0x0155, 0x0155,
- 0x0157, 0x0157,
- 0x0159, 0x0159,
- 0x015b, 0x015b,
- 0x015d, 0x015d,
- 0x015f, 0x015f,
- 0x0161, 0x0161,
- 0x0163, 0x0163,
- 0x0165, 0x0165,
- 0x0167, 0x0167,
- 0x0169, 0x0169,
- 0x016b, 0x016b,
- 0x016d, 0x016d,
- 0x016f, 0x016f,
- 0x0171, 0x0171,
- 0x0173, 0x0173,
- 0x0175, 0x0175,
- 0x0177, 0x0177,
- 0x017a, 0x017a,
- 0x017c, 0x017c,
- 0x017e, 0x0180,
- 0x0183, 0x0183,
- 0x0185, 0x0185,
- 0x0188, 0x0188,
- 0x018c, 0x018d,
- 0x0192, 0x0192,
- 0x0195, 0x0195,
- 0x0199, 0x019b,
- 0x019e, 0x019e,
- 0x01a1, 0x01a1,
- 0x01a3, 0x01a3,
- 0x01a5, 0x01a5,
- 0x01a8, 0x01a8,
- 0x01aa, 0x01ab,
- 0x01ad, 0x01ad,
- 0x01b0, 0x01b0,
- 0x01b4, 0x01b4,
- 0x01b6, 0x01b6,
- 0x01b9, 0x01ba,
- 0x01bd, 0x01bf,
- 0x01c6, 0x01c6,
- 0x01c9, 0x01c9,
- 0x01cc, 0x01cc,
- 0x01ce, 0x01ce,
- 0x01d0, 0x01d0,
- 0x01d2, 0x01d2,
- 0x01d4, 0x01d4,
- 0x01d6, 0x01d6,
- 0x01d8, 0x01d8,
- 0x01da, 0x01da,
- 0x01dc, 0x01dd,
- 0x01df, 0x01df,
- 0x01e1, 0x01e1,
- 0x01e3, 0x01e3,
- 0x01e5, 0x01e5,
- 0x01e7, 0x01e7,
- 0x01e9, 0x01e9,
- 0x01eb, 0x01eb,
- 0x01ed, 0x01ed,
- 0x01ef, 0x01f0,
- 0x01f3, 0x01f3,
- 0x01f5, 0x01f5,
- 0x01f9, 0x01f9,
- 0x01fb, 0x01fb,
- 0x01fd, 0x01fd,
- 0x01ff, 0x01ff,
- 0x0201, 0x0201,
- 0x0203, 0x0203,
- 0x0205, 0x0205,
- 0x0207, 0x0207,
- 0x0209, 0x0209,
- 0x020b, 0x020b,
- 0x020d, 0x020d,
- 0x020f, 0x020f,
- 0x0211, 0x0211,
- 0x0213, 0x0213,
- 0x0215, 0x0215,
- 0x0217, 0x0217,
- 0x0219, 0x0219,
- 0x021b, 0x021b,
- 0x021d, 0x021d,
- 0x021f, 0x021f,
- 0x0221, 0x0221,
- 0x0223, 0x0223,
- 0x0225, 0x0225,
- 0x0227, 0x0227,
- 0x0229, 0x0229,
- 0x022b, 0x022b,
- 0x022d, 0x022d,
- 0x022f, 0x022f,
- 0x0231, 0x0231,
- 0x0233, 0x0236,
- 0x0250, 0x02af,
- 0x0390, 0x0390,
- 0x03ac, 0x03ce,
- 0x03d0, 0x03d1,
- 0x03d5, 0x03d7,
- 0x03d9, 0x03d9,
- 0x03db, 0x03db,
- 0x03dd, 0x03dd,
- 0x03df, 0x03df,
- 0x03e1, 0x03e1,
- 0x03e3, 0x03e3,
- 0x03e5, 0x03e5,
- 0x03e7, 0x03e7,
- 0x03e9, 0x03e9,
- 0x03eb, 0x03eb,
- 0x03ed, 0x03ed,
- 0x03ef, 0x03f3,
- 0x03f5, 0x03f5,
- 0x03f8, 0x03f8,
- 0x03fb, 0x03fb,
- 0x0430, 0x045f,
- 0x0461, 0x0461,
- 0x0463, 0x0463,
- 0x0465, 0x0465,
- 0x0467, 0x0467,
- 0x0469, 0x0469,
- 0x046b, 0x046b,
- 0x046d, 0x046d,
- 0x046f, 0x046f,
- 0x0471, 0x0471,
- 0x0473, 0x0473,
- 0x0475, 0x0475,
- 0x0477, 0x0477,
- 0x0479, 0x0479,
- 0x047b, 0x047b,
- 0x047d, 0x047d,
- 0x047f, 0x047f,
- 0x0481, 0x0481,
- 0x048b, 0x048b,
- 0x048d, 0x048d,
- 0x048f, 0x048f,
- 0x0491, 0x0491,
- 0x0493, 0x0493,
- 0x0495, 0x0495,
- 0x0497, 0x0497,
- 0x0499, 0x0499,
- 0x049b, 0x049b,
- 0x049d, 0x049d,
- 0x049f, 0x049f,
- 0x04a1, 0x04a1,
- 0x04a3, 0x04a3,
- 0x04a5, 0x04a5,
- 0x04a7, 0x04a7,
- 0x04a9, 0x04a9,
- 0x04ab, 0x04ab,
- 0x04ad, 0x04ad,
- 0x04af, 0x04af,
- 0x04b1, 0x04b1,
- 0x04b3, 0x04b3,
- 0x04b5, 0x04b5,
- 0x04b7, 0x04b7,
- 0x04b9, 0x04b9,
- 0x04bb, 0x04bb,
- 0x04bd, 0x04bd,
- 0x04bf, 0x04bf,
- 0x04c2, 0x04c2,
- 0x04c4, 0x04c4,
- 0x04c6, 0x04c6,
- 0x04c8, 0x04c8,
- 0x04ca, 0x04ca,
- 0x04cc, 0x04cc,
- 0x04ce, 0x04ce,
- 0x04d1, 0x04d1,
- 0x04d3, 0x04d3,
- 0x04d5, 0x04d5,
- 0x04d7, 0x04d7,
- 0x04d9, 0x04d9,
- 0x04db, 0x04db,
- 0x04dd, 0x04dd,
- 0x04df, 0x04df,
- 0x04e1, 0x04e1,
- 0x04e3, 0x04e3,
- 0x04e5, 0x04e5,
- 0x04e7, 0x04e7,
- 0x04e9, 0x04e9,
- 0x04eb, 0x04eb,
- 0x04ed, 0x04ed,
- 0x04ef, 0x04ef,
- 0x04f1, 0x04f1,
- 0x04f3, 0x04f3,
- 0x04f5, 0x04f5,
- 0x04f9, 0x04f9,
- 0x0501, 0x0501,
- 0x0503, 0x0503,
- 0x0505, 0x0505,
- 0x0507, 0x0507,
- 0x0509, 0x0509,
- 0x050b, 0x050b,
- 0x050d, 0x050d,
- 0x050f, 0x050f,
- 0x0561, 0x0587,
- 0x1d00, 0x1d2b,
- 0x1d62, 0x1d6b,
- 0x1e01, 0x1e01,
- 0x1e03, 0x1e03,
- 0x1e05, 0x1e05,
- 0x1e07, 0x1e07,
- 0x1e09, 0x1e09,
- 0x1e0b, 0x1e0b,
- 0x1e0d, 0x1e0d,
- 0x1e0f, 0x1e0f,
- 0x1e11, 0x1e11,
- 0x1e13, 0x1e13,
- 0x1e15, 0x1e15,
- 0x1e17, 0x1e17,
- 0x1e19, 0x1e19,
- 0x1e1b, 0x1e1b,
- 0x1e1d, 0x1e1d,
- 0x1e1f, 0x1e1f,
- 0x1e21, 0x1e21,
- 0x1e23, 0x1e23,
- 0x1e25, 0x1e25,
- 0x1e27, 0x1e27,
- 0x1e29, 0x1e29,
- 0x1e2b, 0x1e2b,
- 0x1e2d, 0x1e2d,
- 0x1e2f, 0x1e2f,
- 0x1e31, 0x1e31,
- 0x1e33, 0x1e33,
- 0x1e35, 0x1e35,
- 0x1e37, 0x1e37,
- 0x1e39, 0x1e39,
- 0x1e3b, 0x1e3b,
- 0x1e3d, 0x1e3d,
- 0x1e3f, 0x1e3f,
- 0x1e41, 0x1e41,
- 0x1e43, 0x1e43,
- 0x1e45, 0x1e45,
- 0x1e47, 0x1e47,
- 0x1e49, 0x1e49,
- 0x1e4b, 0x1e4b,
- 0x1e4d, 0x1e4d,
- 0x1e4f, 0x1e4f,
- 0x1e51, 0x1e51,
- 0x1e53, 0x1e53,
- 0x1e55, 0x1e55,
- 0x1e57, 0x1e57,
- 0x1e59, 0x1e59,
- 0x1e5b, 0x1e5b,
- 0x1e5d, 0x1e5d,
- 0x1e5f, 0x1e5f,
- 0x1e61, 0x1e61,
- 0x1e63, 0x1e63,
- 0x1e65, 0x1e65,
- 0x1e67, 0x1e67,
- 0x1e69, 0x1e69,
- 0x1e6b, 0x1e6b,
- 0x1e6d, 0x1e6d,
- 0x1e6f, 0x1e6f,
- 0x1e71, 0x1e71,
- 0x1e73, 0x1e73,
- 0x1e75, 0x1e75,
- 0x1e77, 0x1e77,
- 0x1e79, 0x1e79,
- 0x1e7b, 0x1e7b,
- 0x1e7d, 0x1e7d,
- 0x1e7f, 0x1e7f,
- 0x1e81, 0x1e81,
- 0x1e83, 0x1e83,
- 0x1e85, 0x1e85,
- 0x1e87, 0x1e87,
- 0x1e89, 0x1e89,
- 0x1e8b, 0x1e8b,
- 0x1e8d, 0x1e8d,
- 0x1e8f, 0x1e8f,
- 0x1e91, 0x1e91,
- 0x1e93, 0x1e93,
- 0x1e95, 0x1e9b,
- 0x1ea1, 0x1ea1,
- 0x1ea3, 0x1ea3,
- 0x1ea5, 0x1ea5,
- 0x1ea7, 0x1ea7,
- 0x1ea9, 0x1ea9,
- 0x1eab, 0x1eab,
- 0x1ead, 0x1ead,
- 0x1eaf, 0x1eaf,
- 0x1eb1, 0x1eb1,
- 0x1eb3, 0x1eb3,
- 0x1eb5, 0x1eb5,
- 0x1eb7, 0x1eb7,
- 0x1eb9, 0x1eb9,
- 0x1ebb, 0x1ebb,
- 0x1ebd, 0x1ebd,
- 0x1ebf, 0x1ebf,
- 0x1ec1, 0x1ec1,
- 0x1ec3, 0x1ec3,
- 0x1ec5, 0x1ec5,
- 0x1ec7, 0x1ec7,
- 0x1ec9, 0x1ec9,
- 0x1ecb, 0x1ecb,
- 0x1ecd, 0x1ecd,
- 0x1ecf, 0x1ecf,
- 0x1ed1, 0x1ed1,
- 0x1ed3, 0x1ed3,
- 0x1ed5, 0x1ed5,
- 0x1ed7, 0x1ed7,
- 0x1ed9, 0x1ed9,
- 0x1edb, 0x1edb,
- 0x1edd, 0x1edd,
- 0x1edf, 0x1edf,
- 0x1ee1, 0x1ee1,
- 0x1ee3, 0x1ee3,
- 0x1ee5, 0x1ee5,
- 0x1ee7, 0x1ee7,
- 0x1ee9, 0x1ee9,
- 0x1eeb, 0x1eeb,
- 0x1eed, 0x1eed,
- 0x1eef, 0x1eef,
- 0x1ef1, 0x1ef1,
- 0x1ef3, 0x1ef3,
- 0x1ef5, 0x1ef5,
- 0x1ef7, 0x1ef7,
- 0x1ef9, 0x1ef9,
- 0x1f00, 0x1f07,
- 0x1f10, 0x1f15,
- 0x1f20, 0x1f27,
- 0x1f30, 0x1f37,
- 0x1f40, 0x1f45,
- 0x1f50, 0x1f57,
- 0x1f60, 0x1f67,
- 0x1f70, 0x1f7d,
- 0x1f80, 0x1f87,
- 0x1f90, 0x1f97,
- 0x1fa0, 0x1fa7,
- 0x1fb0, 0x1fb4,
- 0x1fb6, 0x1fb7,
- 0x1fbe, 0x1fbe,
- 0x1fc2, 0x1fc4,
- 0x1fc6, 0x1fc7,
- 0x1fd0, 0x1fd3,
- 0x1fd6, 0x1fd7,
- 0x1fe0, 0x1fe7,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ff7,
- 0x2071, 0x2071,
- 0x207f, 0x207f,
- 0x210a, 0x210a,
- 0x210e, 0x210f,
- 0x2113, 0x2113,
- 0x212f, 0x212f,
- 0x2134, 0x2134,
- 0x2139, 0x2139,
- 0x213d, 0x213d,
- 0x2146, 0x2149,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xff41, 0xff5a,
- 0x10428, 0x1044f,
- 0x1d41a, 0x1d433,
- 0x1d44e, 0x1d454,
- 0x1d456, 0x1d467,
- 0x1d482, 0x1d49b,
- 0x1d4b6, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d4cf,
- 0x1d4ea, 0x1d503,
- 0x1d51e, 0x1d537,
- 0x1d552, 0x1d56b,
- 0x1d586, 0x1d59f,
- 0x1d5ba, 0x1d5d3,
- 0x1d5ee, 0x1d607,
- 0x1d622, 0x1d63b,
- 0x1d656, 0x1d66f,
- 0x1d68a, 0x1d6a3,
- 0x1d6c2, 0x1d6da,
- 0x1d6dc, 0x1d6e1,
- 0x1d6fc, 0x1d714,
- 0x1d716, 0x1d71b,
- 0x1d736, 0x1d74e,
- 0x1d750, 0x1d755,
- 0x1d770, 0x1d788,
- 0x1d78a, 0x1d78f,
- 0x1d7aa, 0x1d7c2,
- 0x1d7c4, 0x1d7c9
-#endif /* USE_UNICODE_FULL_RANGE_CTYPE */
-}; /* end of MBLower */
-
-static const OnigCodePoint SBPrint[] = {
- 2,
- 0x0009, 0x000d,
- 0x0020, 0x007e
-};
-
-static const OnigCodePoint MBPrint[] = {
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- 403,
-#else
- 2,
#endif
- 0x0085, 0x0085,
- 0x00a0, 0x0236
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- ,
- 0x0250, 0x0357,
- 0x035d, 0x036f,
- 0x0374, 0x0375,
- 0x037a, 0x037a,
- 0x037e, 0x037e,
- 0x0384, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x03ce,
- 0x03d0, 0x03fb,
- 0x0400, 0x0486,
- 0x0488, 0x04ce,
- 0x04d0, 0x04f5,
- 0x04f8, 0x04f9,
- 0x0500, 0x050f,
- 0x0531, 0x0556,
- 0x0559, 0x055f,
- 0x0561, 0x0587,
- 0x0589, 0x058a,
- 0x0591, 0x05a1,
- 0x05a3, 0x05b9,
- 0x05bb, 0x05c4,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f4,
- 0x0600, 0x0603,
- 0x060c, 0x0615,
- 0x061b, 0x061b,
- 0x061f, 0x061f,
- 0x0621, 0x063a,
- 0x0640, 0x0658,
- 0x0660, 0x070d,
- 0x070f, 0x074a,
- 0x074d, 0x074f,
- 0x0780, 0x07b1,
- 0x0901, 0x0939,
- 0x093c, 0x094d,
- 0x0950, 0x0954,
- 0x0958, 0x0970,
- 0x0981, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09cd,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09e6, 0x09fa,
- 0x0a01, 0x0a03,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a74,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abc, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae3,
- 0x0ae6, 0x0aef,
- 0x0af1, 0x0af1,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3c, 0x0b43,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b61,
- 0x0b66, 0x0b71,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb5,
- 0x0bb7, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd7, 0x0bd7,
- 0x0be7, 0x0bfa,
- 0x0c01, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c33,
- 0x0c35, 0x0c39,
- 0x0c3e, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c60, 0x0c61,
- 0x0c66, 0x0c6f,
- 0x0c82, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbc, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce1,
- 0x0ce6, 0x0cef,
- 0x0d02, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d28,
- 0x0d2a, 0x0d39,
- 0x0d3e, 0x0d43,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4d,
- 0x0d57, 0x0d57,
- 0x0d60, 0x0d61,
- 0x0d66, 0x0d6f,
- 0x0d82, 0x0d83,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dca, 0x0dca,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0df2, 0x0df4,
- 0x0e01, 0x0e3a,
- 0x0e3f, 0x0e5b,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edd,
- 0x0f00, 0x0f47,
- 0x0f49, 0x0f6a,
- 0x0f71, 0x0f8b,
- 0x0f90, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fbe, 0x0fcc,
- 0x0fcf, 0x0fcf,
- 0x1000, 0x1021,
- 0x1023, 0x1027,
- 0x1029, 0x102a,
- 0x102c, 0x1032,
- 0x1036, 0x1039,
- 0x1040, 0x1059,
- 0x10a0, 0x10c5,
- 0x10d0, 0x10f8,
- 0x10fb, 0x10fb,
- 0x1100, 0x1159,
- 0x115f, 0x11a2,
- 0x11a8, 0x11f9,
- 0x1200, 0x1206,
- 0x1208, 0x1246,
- 0x1248, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1286,
- 0x1288, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12ae,
- 0x12b0, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12ce,
- 0x12d0, 0x12d6,
- 0x12d8, 0x12ee,
- 0x12f0, 0x130e,
- 0x1310, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x131e,
- 0x1320, 0x1346,
- 0x1348, 0x135a,
- 0x1361, 0x137c,
- 0x13a0, 0x13f4,
- 0x1401, 0x1676,
- 0x1680, 0x169c,
- 0x16a0, 0x16f0,
- 0x1700, 0x170c,
- 0x170e, 0x1714,
- 0x1720, 0x1736,
- 0x1740, 0x1753,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1772, 0x1773,
- 0x1780, 0x17dd,
- 0x17e0, 0x17e9,
- 0x17f0, 0x17f9,
- 0x1800, 0x180e,
- 0x1810, 0x1819,
- 0x1820, 0x1877,
- 0x1880, 0x18a9,
- 0x1900, 0x191c,
- 0x1920, 0x192b,
- 0x1930, 0x193b,
- 0x1940, 0x1940,
- 0x1944, 0x196d,
- 0x1970, 0x1974,
- 0x19e0, 0x19ff,
- 0x1d00, 0x1d6b,
- 0x1e00, 0x1e9b,
- 0x1ea0, 0x1ef9,
- 0x1f00, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fc4,
- 0x1fc6, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fdd, 0x1fef,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffe,
- 0x2000, 0x2054,
- 0x2057, 0x2057,
- 0x205f, 0x2063,
- 0x206a, 0x2071,
- 0x2074, 0x208e,
- 0x20a0, 0x20b1,
- 0x20d0, 0x20ea,
- 0x2100, 0x213b,
- 0x213d, 0x214b,
- 0x2153, 0x2183,
- 0x2190, 0x23d0,
- 0x2400, 0x2426,
- 0x2440, 0x244a,
- 0x2460, 0x2617,
- 0x2619, 0x267d,
- 0x2680, 0x2691,
- 0x26a0, 0x26a1,
- 0x2701, 0x2704,
- 0x2706, 0x2709,
- 0x270c, 0x2727,
- 0x2729, 0x274b,
- 0x274d, 0x274d,
- 0x274f, 0x2752,
- 0x2756, 0x2756,
- 0x2758, 0x275e,
- 0x2761, 0x2794,
- 0x2798, 0x27af,
- 0x27b1, 0x27be,
- 0x27d0, 0x27eb,
- 0x27f0, 0x2b0d,
- 0x2e80, 0x2e99,
- 0x2e9b, 0x2ef3,
- 0x2f00, 0x2fd5,
- 0x2ff0, 0x2ffb,
- 0x3000, 0x303f,
- 0x3041, 0x3096,
- 0x3099, 0x30ff,
- 0x3105, 0x312c,
- 0x3131, 0x318e,
- 0x3190, 0x31b7,
- 0x31f0, 0x321e,
- 0x3220, 0x3243,
- 0x3250, 0x327d,
- 0x327f, 0x32fe,
- 0x3300, 0x4db5,
- 0x4dc0, 0x9fa5,
- 0xa000, 0xa48c,
- 0xa490, 0xa4c6,
- 0xac00, 0xd7a3,
- 0xe000, 0xfa2d,
- 0xfa30, 0xfa6a,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbb1,
- 0xfbd3, 0xfd3f,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdf0, 0xfdfd,
- 0xfe00, 0xfe0f,
- 0xfe20, 0xfe23,
- 0xfe30, 0xfe52,
- 0xfe54, 0xfe66,
- 0xfe68, 0xfe6b,
- 0xfe70, 0xfe74,
- 0xfe76, 0xfefc,
- 0xfeff, 0xfeff,
- 0xff01, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0xffe0, 0xffe6,
- 0xffe8, 0xffee,
- 0xfff9, 0xfffd,
- 0x10000, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
- 0x10100, 0x10102,
- 0x10107, 0x10133,
- 0x10137, 0x1013f,
- 0x10300, 0x1031e,
- 0x10320, 0x10323,
- 0x10330, 0x1034a,
- 0x10380, 0x1039d,
- 0x1039f, 0x1039f,
- 0x10400, 0x1049d,
- 0x104a0, 0x104a9,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x1083f,
- 0x1d000, 0x1d0f5,
- 0x1d100, 0x1d126,
- 0x1d12a, 0x1d1dd,
- 0x1d300, 0x1d356,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a3,
- 0x1d6a8, 0x1d7c9,
- 0x1d7ce, 0x1d7ff,
- 0x20000, 0x2a6d6,
- 0x2f800, 0x2fa1d,
- 0xe0001, 0xe0001,
- 0xe0020, 0xe007f,
- 0xe0100, 0xe01ef,
- 0xf0000, 0xffffd,
- 0x100000, 0x10fffd
-#endif /* USE_UNICODE_FULL_RANGE_CTYPE */
-}; /* end of MBPrint */
-
-static const OnigCodePoint SBPunct[] = {
- 9,
- 0x0021, 0x0023,
- 0x0025, 0x002a,
- 0x002c, 0x002f,
- 0x003a, 0x003b,
- 0x003f, 0x0040,
- 0x005b, 0x005d,
- 0x005f, 0x005f,
- 0x007b, 0x007b,
- 0x007d, 0x007d
-}; /* end of SBPunct */
-
-static const OnigCodePoint MBPunct[] = {
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- 77,
-#else
- 5,
-#endif
- 0x00a1, 0x00a1,
- 0x00ab, 0x00ab,
- 0x00b7, 0x00b7,
- 0x00bb, 0x00bb,
- 0x00bf, 0x00bf
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- ,
- 0x037e, 0x037e,
- 0x0387, 0x0387,
- 0x055a, 0x055f,
- 0x0589, 0x058a,
- 0x05be, 0x05be,
- 0x05c0, 0x05c0,
- 0x05c3, 0x05c3,
- 0x05f3, 0x05f4,
- 0x060c, 0x060d,
- 0x061b, 0x061b,
- 0x061f, 0x061f,
- 0x066a, 0x066d,
- 0x06d4, 0x06d4,
- 0x0700, 0x070d,
- 0x0964, 0x0965,
- 0x0970, 0x0970,
- 0x0df4, 0x0df4,
- 0x0e4f, 0x0e4f,
- 0x0e5a, 0x0e5b,
- 0x0f04, 0x0f12,
- 0x0f3a, 0x0f3d,
- 0x0f85, 0x0f85,
- 0x104a, 0x104f,
- 0x10fb, 0x10fb,
- 0x1361, 0x1368,
- 0x166d, 0x166e,
- 0x169b, 0x169c,
- 0x16eb, 0x16ed,
- 0x1735, 0x1736,
- 0x17d4, 0x17d6,
- 0x17d8, 0x17da,
- 0x1800, 0x180a,
- 0x1944, 0x1945,
- 0x2010, 0x2027,
- 0x2030, 0x2043,
- 0x2045, 0x2051,
- 0x2053, 0x2054,
- 0x2057, 0x2057,
- 0x207d, 0x207e,
- 0x208d, 0x208e,
- 0x2329, 0x232a,
- 0x23b4, 0x23b6,
- 0x2768, 0x2775,
- 0x27e6, 0x27eb,
- 0x2983, 0x2998,
- 0x29d8, 0x29db,
- 0x29fc, 0x29fd,
- 0x3001, 0x3003,
- 0x3008, 0x3011,
- 0x3014, 0x301f,
- 0x3030, 0x3030,
- 0x303d, 0x303d,
- 0x30a0, 0x30a0,
- 0x30fb, 0x30fb,
- 0xfd3e, 0xfd3f,
- 0xfe30, 0xfe52,
- 0xfe54, 0xfe61,
- 0xfe63, 0xfe63,
- 0xfe68, 0xfe68,
- 0xfe6a, 0xfe6b,
- 0xff01, 0xff03,
- 0xff05, 0xff0a,
- 0xff0c, 0xff0f,
- 0xff1a, 0xff1b,
- 0xff1f, 0xff20,
- 0xff3b, 0xff3d,
- 0xff3f, 0xff3f,
- 0xff5b, 0xff5b,
- 0xff5d, 0xff5d,
- 0xff5f, 0xff65,
- 0x10100, 0x10101,
- 0x1039f, 0x1039f
-#endif /* USE_UNICODE_FULL_RANGE_CTYPE */
-}; /* end of MBPunct */
-
-static const OnigCodePoint SBSpace[] = {
- 2,
- 0x0009, 0x000d,
- 0x0020, 0x0020
-};
-
-static const OnigCodePoint MBSpace[] = {
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- 9,
-#else
- 2,
-#endif
- 0x0085, 0x0085,
- 0x00a0, 0x00a0
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- ,
- 0x1680, 0x1680,
- 0x180e, 0x180e,
- 0x2000, 0x200a,
- 0x2028, 0x2029,
- 0x202f, 0x202f,
- 0x205f, 0x205f,
- 0x3000, 0x3000
-#endif /* USE_UNICODE_FULL_RANGE_CTYPE */
-}; /* end of MBSpace */
-
-static const OnigCodePoint SBUpper[] = {
- 1,
- 0x0041, 0x005a
-};
-
-static const OnigCodePoint MBUpper[] = {
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- 420,
-#else
- 2,
-#endif
- 0x00c0, 0x00d6,
- 0x00d8, 0x00de
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- ,
- 0x0100, 0x0100,
- 0x0102, 0x0102,
- 0x0104, 0x0104,
- 0x0106, 0x0106,
- 0x0108, 0x0108,
- 0x010a, 0x010a,
- 0x010c, 0x010c,
- 0x010e, 0x010e,
- 0x0110, 0x0110,
- 0x0112, 0x0112,
- 0x0114, 0x0114,
- 0x0116, 0x0116,
- 0x0118, 0x0118,
- 0x011a, 0x011a,
- 0x011c, 0x011c,
- 0x011e, 0x011e,
- 0x0120, 0x0120,
- 0x0122, 0x0122,
- 0x0124, 0x0124,
- 0x0126, 0x0126,
- 0x0128, 0x0128,
- 0x012a, 0x012a,
- 0x012c, 0x012c,
- 0x012e, 0x012e,
- 0x0130, 0x0130,
- 0x0132, 0x0132,
- 0x0134, 0x0134,
- 0x0136, 0x0136,
- 0x0139, 0x0139,
- 0x013b, 0x013b,
- 0x013d, 0x013d,
- 0x013f, 0x013f,
- 0x0141, 0x0141,
- 0x0143, 0x0143,
- 0x0145, 0x0145,
- 0x0147, 0x0147,
- 0x014a, 0x014a,
- 0x014c, 0x014c,
- 0x014e, 0x014e,
- 0x0150, 0x0150,
- 0x0152, 0x0152,
- 0x0154, 0x0154,
- 0x0156, 0x0156,
- 0x0158, 0x0158,
- 0x015a, 0x015a,
- 0x015c, 0x015c,
- 0x015e, 0x015e,
- 0x0160, 0x0160,
- 0x0162, 0x0162,
- 0x0164, 0x0164,
- 0x0166, 0x0166,
- 0x0168, 0x0168,
- 0x016a, 0x016a,
- 0x016c, 0x016c,
- 0x016e, 0x016e,
- 0x0170, 0x0170,
- 0x0172, 0x0172,
- 0x0174, 0x0174,
- 0x0176, 0x0176,
- 0x0178, 0x0179,
- 0x017b, 0x017b,
- 0x017d, 0x017d,
- 0x0181, 0x0182,
- 0x0184, 0x0184,
- 0x0186, 0x0187,
- 0x0189, 0x018b,
- 0x018e, 0x0191,
- 0x0193, 0x0194,
- 0x0196, 0x0198,
- 0x019c, 0x019d,
- 0x019f, 0x01a0,
- 0x01a2, 0x01a2,
- 0x01a4, 0x01a4,
- 0x01a6, 0x01a7,
- 0x01a9, 0x01a9,
- 0x01ac, 0x01ac,
- 0x01ae, 0x01af,
- 0x01b1, 0x01b3,
- 0x01b5, 0x01b5,
- 0x01b7, 0x01b8,
- 0x01bc, 0x01bc,
- 0x01c4, 0x01c4,
- 0x01c7, 0x01c7,
- 0x01ca, 0x01ca,
- 0x01cd, 0x01cd,
- 0x01cf, 0x01cf,
- 0x01d1, 0x01d1,
- 0x01d3, 0x01d3,
- 0x01d5, 0x01d5,
- 0x01d7, 0x01d7,
- 0x01d9, 0x01d9,
- 0x01db, 0x01db,
- 0x01de, 0x01de,
- 0x01e0, 0x01e0,
- 0x01e2, 0x01e2,
- 0x01e4, 0x01e4,
- 0x01e6, 0x01e6,
- 0x01e8, 0x01e8,
- 0x01ea, 0x01ea,
- 0x01ec, 0x01ec,
- 0x01ee, 0x01ee,
- 0x01f1, 0x01f1,
- 0x01f4, 0x01f4,
- 0x01f6, 0x01f8,
- 0x01fa, 0x01fa,
- 0x01fc, 0x01fc,
- 0x01fe, 0x01fe,
- 0x0200, 0x0200,
- 0x0202, 0x0202,
- 0x0204, 0x0204,
- 0x0206, 0x0206,
- 0x0208, 0x0208,
- 0x020a, 0x020a,
- 0x020c, 0x020c,
- 0x020e, 0x020e,
- 0x0210, 0x0210,
- 0x0212, 0x0212,
- 0x0214, 0x0214,
- 0x0216, 0x0216,
- 0x0218, 0x0218,
- 0x021a, 0x021a,
- 0x021c, 0x021c,
- 0x021e, 0x021e,
- 0x0220, 0x0220,
- 0x0222, 0x0222,
- 0x0224, 0x0224,
- 0x0226, 0x0226,
- 0x0228, 0x0228,
- 0x022a, 0x022a,
- 0x022c, 0x022c,
- 0x022e, 0x022e,
- 0x0230, 0x0230,
- 0x0232, 0x0232,
- 0x0386, 0x0386,
- 0x0388, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x038f,
- 0x0391, 0x03a1,
- 0x03a3, 0x03ab,
- 0x03d2, 0x03d4,
- 0x03d8, 0x03d8,
- 0x03da, 0x03da,
- 0x03dc, 0x03dc,
- 0x03de, 0x03de,
- 0x03e0, 0x03e0,
- 0x03e2, 0x03e2,
- 0x03e4, 0x03e4,
- 0x03e6, 0x03e6,
- 0x03e8, 0x03e8,
- 0x03ea, 0x03ea,
- 0x03ec, 0x03ec,
- 0x03ee, 0x03ee,
- 0x03f4, 0x03f4,
- 0x03f7, 0x03f7,
- 0x03f9, 0x03fa,
- 0x0400, 0x042f,
- 0x0460, 0x0460,
- 0x0462, 0x0462,
- 0x0464, 0x0464,
- 0x0466, 0x0466,
- 0x0468, 0x0468,
- 0x046a, 0x046a,
- 0x046c, 0x046c,
- 0x046e, 0x046e,
- 0x0470, 0x0470,
- 0x0472, 0x0472,
- 0x0474, 0x0474,
- 0x0476, 0x0476,
- 0x0478, 0x0478,
- 0x047a, 0x047a,
- 0x047c, 0x047c,
- 0x047e, 0x047e,
- 0x0480, 0x0480,
- 0x048a, 0x048a,
- 0x048c, 0x048c,
- 0x048e, 0x048e,
- 0x0490, 0x0490,
- 0x0492, 0x0492,
- 0x0494, 0x0494,
- 0x0496, 0x0496,
- 0x0498, 0x0498,
- 0x049a, 0x049a,
- 0x049c, 0x049c,
- 0x049e, 0x049e,
- 0x04a0, 0x04a0,
- 0x04a2, 0x04a2,
- 0x04a4, 0x04a4,
- 0x04a6, 0x04a6,
- 0x04a8, 0x04a8,
- 0x04aa, 0x04aa,
- 0x04ac, 0x04ac,
- 0x04ae, 0x04ae,
- 0x04b0, 0x04b0,
- 0x04b2, 0x04b2,
- 0x04b4, 0x04b4,
- 0x04b6, 0x04b6,
- 0x04b8, 0x04b8,
- 0x04ba, 0x04ba,
- 0x04bc, 0x04bc,
- 0x04be, 0x04be,
- 0x04c0, 0x04c1,
- 0x04c3, 0x04c3,
- 0x04c5, 0x04c5,
- 0x04c7, 0x04c7,
- 0x04c9, 0x04c9,
- 0x04cb, 0x04cb,
- 0x04cd, 0x04cd,
- 0x04d0, 0x04d0,
- 0x04d2, 0x04d2,
- 0x04d4, 0x04d4,
- 0x04d6, 0x04d6,
- 0x04d8, 0x04d8,
- 0x04da, 0x04da,
- 0x04dc, 0x04dc,
- 0x04de, 0x04de,
- 0x04e0, 0x04e0,
- 0x04e2, 0x04e2,
- 0x04e4, 0x04e4,
- 0x04e6, 0x04e6,
- 0x04e8, 0x04e8,
- 0x04ea, 0x04ea,
- 0x04ec, 0x04ec,
- 0x04ee, 0x04ee,
- 0x04f0, 0x04f0,
- 0x04f2, 0x04f2,
- 0x04f4, 0x04f4,
- 0x04f8, 0x04f8,
- 0x0500, 0x0500,
- 0x0502, 0x0502,
- 0x0504, 0x0504,
- 0x0506, 0x0506,
- 0x0508, 0x0508,
- 0x050a, 0x050a,
- 0x050c, 0x050c,
- 0x050e, 0x050e,
- 0x0531, 0x0556,
- 0x10a0, 0x10c5,
- 0x1e00, 0x1e00,
- 0x1e02, 0x1e02,
- 0x1e04, 0x1e04,
- 0x1e06, 0x1e06,
- 0x1e08, 0x1e08,
- 0x1e0a, 0x1e0a,
- 0x1e0c, 0x1e0c,
- 0x1e0e, 0x1e0e,
- 0x1e10, 0x1e10,
- 0x1e12, 0x1e12,
- 0x1e14, 0x1e14,
- 0x1e16, 0x1e16,
- 0x1e18, 0x1e18,
- 0x1e1a, 0x1e1a,
- 0x1e1c, 0x1e1c,
- 0x1e1e, 0x1e1e,
- 0x1e20, 0x1e20,
- 0x1e22, 0x1e22,
- 0x1e24, 0x1e24,
- 0x1e26, 0x1e26,
- 0x1e28, 0x1e28,
- 0x1e2a, 0x1e2a,
- 0x1e2c, 0x1e2c,
- 0x1e2e, 0x1e2e,
- 0x1e30, 0x1e30,
- 0x1e32, 0x1e32,
- 0x1e34, 0x1e34,
- 0x1e36, 0x1e36,
- 0x1e38, 0x1e38,
- 0x1e3a, 0x1e3a,
- 0x1e3c, 0x1e3c,
- 0x1e3e, 0x1e3e,
- 0x1e40, 0x1e40,
- 0x1e42, 0x1e42,
- 0x1e44, 0x1e44,
- 0x1e46, 0x1e46,
- 0x1e48, 0x1e48,
- 0x1e4a, 0x1e4a,
- 0x1e4c, 0x1e4c,
- 0x1e4e, 0x1e4e,
- 0x1e50, 0x1e50,
- 0x1e52, 0x1e52,
- 0x1e54, 0x1e54,
- 0x1e56, 0x1e56,
- 0x1e58, 0x1e58,
- 0x1e5a, 0x1e5a,
- 0x1e5c, 0x1e5c,
- 0x1e5e, 0x1e5e,
- 0x1e60, 0x1e60,
- 0x1e62, 0x1e62,
- 0x1e64, 0x1e64,
- 0x1e66, 0x1e66,
- 0x1e68, 0x1e68,
- 0x1e6a, 0x1e6a,
- 0x1e6c, 0x1e6c,
- 0x1e6e, 0x1e6e,
- 0x1e70, 0x1e70,
- 0x1e72, 0x1e72,
- 0x1e74, 0x1e74,
- 0x1e76, 0x1e76,
- 0x1e78, 0x1e78,
- 0x1e7a, 0x1e7a,
- 0x1e7c, 0x1e7c,
- 0x1e7e, 0x1e7e,
- 0x1e80, 0x1e80,
- 0x1e82, 0x1e82,
- 0x1e84, 0x1e84,
- 0x1e86, 0x1e86,
- 0x1e88, 0x1e88,
- 0x1e8a, 0x1e8a,
- 0x1e8c, 0x1e8c,
- 0x1e8e, 0x1e8e,
- 0x1e90, 0x1e90,
- 0x1e92, 0x1e92,
- 0x1e94, 0x1e94,
- 0x1ea0, 0x1ea0,
- 0x1ea2, 0x1ea2,
- 0x1ea4, 0x1ea4,
- 0x1ea6, 0x1ea6,
- 0x1ea8, 0x1ea8,
- 0x1eaa, 0x1eaa,
- 0x1eac, 0x1eac,
- 0x1eae, 0x1eae,
- 0x1eb0, 0x1eb0,
- 0x1eb2, 0x1eb2,
- 0x1eb4, 0x1eb4,
- 0x1eb6, 0x1eb6,
- 0x1eb8, 0x1eb8,
- 0x1eba, 0x1eba,
- 0x1ebc, 0x1ebc,
- 0x1ebe, 0x1ebe,
- 0x1ec0, 0x1ec0,
- 0x1ec2, 0x1ec2,
- 0x1ec4, 0x1ec4,
- 0x1ec6, 0x1ec6,
- 0x1ec8, 0x1ec8,
- 0x1eca, 0x1eca,
- 0x1ecc, 0x1ecc,
- 0x1ece, 0x1ece,
- 0x1ed0, 0x1ed0,
- 0x1ed2, 0x1ed2,
- 0x1ed4, 0x1ed4,
- 0x1ed6, 0x1ed6,
- 0x1ed8, 0x1ed8,
- 0x1eda, 0x1eda,
- 0x1edc, 0x1edc,
- 0x1ede, 0x1ede,
- 0x1ee0, 0x1ee0,
- 0x1ee2, 0x1ee2,
- 0x1ee4, 0x1ee4,
- 0x1ee6, 0x1ee6,
- 0x1ee8, 0x1ee8,
- 0x1eea, 0x1eea,
- 0x1eec, 0x1eec,
- 0x1eee, 0x1eee,
- 0x1ef0, 0x1ef0,
- 0x1ef2, 0x1ef2,
- 0x1ef4, 0x1ef4,
- 0x1ef6, 0x1ef6,
- 0x1ef8, 0x1ef8,
- 0x1f08, 0x1f0f,
- 0x1f18, 0x1f1d,
- 0x1f28, 0x1f2f,
- 0x1f38, 0x1f3f,
- 0x1f48, 0x1f4d,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f5f,
- 0x1f68, 0x1f6f,
- 0x1fb8, 0x1fbb,
- 0x1fc8, 0x1fcb,
- 0x1fd8, 0x1fdb,
- 0x1fe8, 0x1fec,
- 0x1ff8, 0x1ffb,
- 0x2102, 0x2102,
- 0x2107, 0x2107,
- 0x210b, 0x210d,
- 0x2110, 0x2112,
- 0x2115, 0x2115,
- 0x2119, 0x211d,
- 0x2124, 0x2124,
- 0x2126, 0x2126,
- 0x2128, 0x2128,
- 0x212a, 0x212d,
- 0x2130, 0x2131,
- 0x2133, 0x2133,
- 0x213e, 0x213f,
- 0x2145, 0x2145,
- 0xff21, 0xff3a,
- 0x10400, 0x10427,
- 0x1d400, 0x1d419,
- 0x1d434, 0x1d44d,
- 0x1d468, 0x1d481,
- 0x1d49c, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b5,
- 0x1d4d0, 0x1d4e9,
- 0x1d504, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d538, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d56c, 0x1d585,
- 0x1d5a0, 0x1d5b9,
- 0x1d5d4, 0x1d5ed,
- 0x1d608, 0x1d621,
- 0x1d63c, 0x1d655,
- 0x1d670, 0x1d689,
- 0x1d6a8, 0x1d6c0,
- 0x1d6e2, 0x1d6fa,
- 0x1d71c, 0x1d734,
- 0x1d756, 0x1d76e,
- 0x1d790, 0x1d7a8
-#endif /* USE_UNICODE_FULL_RANGE_CTYPE */
-}; /* end of MBUpper */
-
-static const OnigCodePoint SBXDigit[] = {
- 3,
- 0x0030, 0x0039,
- 0x0041, 0x0046,
- 0x0061, 0x0066
-};
-
-static const OnigCodePoint SBASCII[] = {
- 1,
- 0x0000, 0x007f
-};
-
-static const OnigCodePoint SBWord[] = {
- 4,
- 0x0030, 0x0039,
- 0x0041, 0x005a,
- 0x005f, 0x005f,
- 0x0061, 0x007a
-};
-
-static const OnigCodePoint MBWord[] = {
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- 432,
-#else
- 8,
-#endif
- 0x00aa, 0x00aa,
- 0x00b2, 0x00b3,
- 0x00b5, 0x00b5,
- 0x00b9, 0x00ba,
- 0x00bc, 0x00be,
- 0x00c0, 0x00d6,
- 0x00d8, 0x00f6,
-#ifndef USE_UNICODE_FULL_RANGE_CTYPE
- 0x00f8, 0x7fffffff
-#else /* not USE_UNICODE_FULL_RANGE_CTYPE */
- 0x00f8, 0x0236,
- 0x0250, 0x02c1,
- 0x02c6, 0x02d1,
- 0x02e0, 0x02e4,
- 0x02ee, 0x02ee,
- 0x0300, 0x0357,
- 0x035d, 0x036f,
- 0x037a, 0x037a,
- 0x0386, 0x0386,
- 0x0388, 0x038a,
- 0x038c, 0x038c,
- 0x038e, 0x03a1,
- 0x03a3, 0x03ce,
- 0x03d0, 0x03f5,
- 0x03f7, 0x03fb,
- 0x0400, 0x0481,
- 0x0483, 0x0486,
- 0x0488, 0x04ce,
- 0x04d0, 0x04f5,
- 0x04f8, 0x04f9,
- 0x0500, 0x050f,
- 0x0531, 0x0556,
- 0x0559, 0x0559,
- 0x0561, 0x0587,
- 0x0591, 0x05a1,
- 0x05a3, 0x05b9,
- 0x05bb, 0x05bd,
- 0x05bf, 0x05bf,
- 0x05c1, 0x05c2,
- 0x05c4, 0x05c4,
- 0x05d0, 0x05ea,
- 0x05f0, 0x05f2,
- 0x0610, 0x0615,
- 0x0621, 0x063a,
- 0x0640, 0x0658,
- 0x0660, 0x0669,
- 0x066e, 0x06d3,
- 0x06d5, 0x06dc,
- 0x06de, 0x06e8,
- 0x06ea, 0x06fc,
- 0x06ff, 0x06ff,
- 0x0710, 0x074a,
- 0x074d, 0x074f,
- 0x0780, 0x07b1,
- 0x0901, 0x0939,
- 0x093c, 0x094d,
- 0x0950, 0x0954,
- 0x0958, 0x0963,
- 0x0966, 0x096f,
- 0x0981, 0x0983,
- 0x0985, 0x098c,
- 0x098f, 0x0990,
- 0x0993, 0x09a8,
- 0x09aa, 0x09b0,
- 0x09b2, 0x09b2,
- 0x09b6, 0x09b9,
- 0x09bc, 0x09c4,
- 0x09c7, 0x09c8,
- 0x09cb, 0x09cd,
- 0x09d7, 0x09d7,
- 0x09dc, 0x09dd,
- 0x09df, 0x09e3,
- 0x09e6, 0x09f1,
- 0x09f4, 0x09f9,
- 0x0a01, 0x0a03,
- 0x0a05, 0x0a0a,
- 0x0a0f, 0x0a10,
- 0x0a13, 0x0a28,
- 0x0a2a, 0x0a30,
- 0x0a32, 0x0a33,
- 0x0a35, 0x0a36,
- 0x0a38, 0x0a39,
- 0x0a3c, 0x0a3c,
- 0x0a3e, 0x0a42,
- 0x0a47, 0x0a48,
- 0x0a4b, 0x0a4d,
- 0x0a59, 0x0a5c,
- 0x0a5e, 0x0a5e,
- 0x0a66, 0x0a74,
- 0x0a81, 0x0a83,
- 0x0a85, 0x0a8d,
- 0x0a8f, 0x0a91,
- 0x0a93, 0x0aa8,
- 0x0aaa, 0x0ab0,
- 0x0ab2, 0x0ab3,
- 0x0ab5, 0x0ab9,
- 0x0abc, 0x0ac5,
- 0x0ac7, 0x0ac9,
- 0x0acb, 0x0acd,
- 0x0ad0, 0x0ad0,
- 0x0ae0, 0x0ae3,
- 0x0ae6, 0x0aef,
- 0x0b01, 0x0b03,
- 0x0b05, 0x0b0c,
- 0x0b0f, 0x0b10,
- 0x0b13, 0x0b28,
- 0x0b2a, 0x0b30,
- 0x0b32, 0x0b33,
- 0x0b35, 0x0b39,
- 0x0b3c, 0x0b43,
- 0x0b47, 0x0b48,
- 0x0b4b, 0x0b4d,
- 0x0b56, 0x0b57,
- 0x0b5c, 0x0b5d,
- 0x0b5f, 0x0b61,
- 0x0b66, 0x0b6f,
- 0x0b71, 0x0b71,
- 0x0b82, 0x0b83,
- 0x0b85, 0x0b8a,
- 0x0b8e, 0x0b90,
- 0x0b92, 0x0b95,
- 0x0b99, 0x0b9a,
- 0x0b9c, 0x0b9c,
- 0x0b9e, 0x0b9f,
- 0x0ba3, 0x0ba4,
- 0x0ba8, 0x0baa,
- 0x0bae, 0x0bb5,
- 0x0bb7, 0x0bb9,
- 0x0bbe, 0x0bc2,
- 0x0bc6, 0x0bc8,
- 0x0bca, 0x0bcd,
- 0x0bd7, 0x0bd7,
- 0x0be7, 0x0bf2,
- 0x0c01, 0x0c03,
- 0x0c05, 0x0c0c,
- 0x0c0e, 0x0c10,
- 0x0c12, 0x0c28,
- 0x0c2a, 0x0c33,
- 0x0c35, 0x0c39,
- 0x0c3e, 0x0c44,
- 0x0c46, 0x0c48,
- 0x0c4a, 0x0c4d,
- 0x0c55, 0x0c56,
- 0x0c60, 0x0c61,
- 0x0c66, 0x0c6f,
- 0x0c82, 0x0c83,
- 0x0c85, 0x0c8c,
- 0x0c8e, 0x0c90,
- 0x0c92, 0x0ca8,
- 0x0caa, 0x0cb3,
- 0x0cb5, 0x0cb9,
- 0x0cbc, 0x0cc4,
- 0x0cc6, 0x0cc8,
- 0x0cca, 0x0ccd,
- 0x0cd5, 0x0cd6,
- 0x0cde, 0x0cde,
- 0x0ce0, 0x0ce1,
- 0x0ce6, 0x0cef,
- 0x0d02, 0x0d03,
- 0x0d05, 0x0d0c,
- 0x0d0e, 0x0d10,
- 0x0d12, 0x0d28,
- 0x0d2a, 0x0d39,
- 0x0d3e, 0x0d43,
- 0x0d46, 0x0d48,
- 0x0d4a, 0x0d4d,
- 0x0d57, 0x0d57,
- 0x0d60, 0x0d61,
- 0x0d66, 0x0d6f,
- 0x0d82, 0x0d83,
- 0x0d85, 0x0d96,
- 0x0d9a, 0x0db1,
- 0x0db3, 0x0dbb,
- 0x0dbd, 0x0dbd,
- 0x0dc0, 0x0dc6,
- 0x0dca, 0x0dca,
- 0x0dcf, 0x0dd4,
- 0x0dd6, 0x0dd6,
- 0x0dd8, 0x0ddf,
- 0x0df2, 0x0df3,
- 0x0e01, 0x0e3a,
- 0x0e40, 0x0e4e,
- 0x0e50, 0x0e59,
- 0x0e81, 0x0e82,
- 0x0e84, 0x0e84,
- 0x0e87, 0x0e88,
- 0x0e8a, 0x0e8a,
- 0x0e8d, 0x0e8d,
- 0x0e94, 0x0e97,
- 0x0e99, 0x0e9f,
- 0x0ea1, 0x0ea3,
- 0x0ea5, 0x0ea5,
- 0x0ea7, 0x0ea7,
- 0x0eaa, 0x0eab,
- 0x0ead, 0x0eb9,
- 0x0ebb, 0x0ebd,
- 0x0ec0, 0x0ec4,
- 0x0ec6, 0x0ec6,
- 0x0ec8, 0x0ecd,
- 0x0ed0, 0x0ed9,
- 0x0edc, 0x0edd,
- 0x0f00, 0x0f00,
- 0x0f18, 0x0f19,
- 0x0f20, 0x0f33,
- 0x0f35, 0x0f35,
- 0x0f37, 0x0f37,
- 0x0f39, 0x0f39,
- 0x0f3e, 0x0f47,
- 0x0f49, 0x0f6a,
- 0x0f71, 0x0f84,
- 0x0f86, 0x0f8b,
- 0x0f90, 0x0f97,
- 0x0f99, 0x0fbc,
- 0x0fc6, 0x0fc6,
- 0x1000, 0x1021,
- 0x1023, 0x1027,
- 0x1029, 0x102a,
- 0x102c, 0x1032,
- 0x1036, 0x1039,
- 0x1040, 0x1049,
- 0x1050, 0x1059,
- 0x10a0, 0x10c5,
- 0x10d0, 0x10f8,
- 0x1100, 0x1159,
- 0x115f, 0x11a2,
- 0x11a8, 0x11f9,
- 0x1200, 0x1206,
- 0x1208, 0x1246,
- 0x1248, 0x1248,
- 0x124a, 0x124d,
- 0x1250, 0x1256,
- 0x1258, 0x1258,
- 0x125a, 0x125d,
- 0x1260, 0x1286,
- 0x1288, 0x1288,
- 0x128a, 0x128d,
- 0x1290, 0x12ae,
- 0x12b0, 0x12b0,
- 0x12b2, 0x12b5,
- 0x12b8, 0x12be,
- 0x12c0, 0x12c0,
- 0x12c2, 0x12c5,
- 0x12c8, 0x12ce,
- 0x12d0, 0x12d6,
- 0x12d8, 0x12ee,
- 0x12f0, 0x130e,
- 0x1310, 0x1310,
- 0x1312, 0x1315,
- 0x1318, 0x131e,
- 0x1320, 0x1346,
- 0x1348, 0x135a,
- 0x1369, 0x137c,
- 0x13a0, 0x13f4,
- 0x1401, 0x166c,
- 0x166f, 0x1676,
- 0x1681, 0x169a,
- 0x16a0, 0x16ea,
- 0x16ee, 0x16f0,
- 0x1700, 0x170c,
- 0x170e, 0x1714,
- 0x1720, 0x1734,
- 0x1740, 0x1753,
- 0x1760, 0x176c,
- 0x176e, 0x1770,
- 0x1772, 0x1773,
- 0x1780, 0x17b3,
- 0x17b6, 0x17d3,
- 0x17d7, 0x17d7,
- 0x17dc, 0x17dd,
- 0x17e0, 0x17e9,
- 0x17f0, 0x17f9,
- 0x180b, 0x180d,
- 0x1810, 0x1819,
- 0x1820, 0x1877,
- 0x1880, 0x18a9,
- 0x1900, 0x191c,
- 0x1920, 0x192b,
- 0x1930, 0x193b,
- 0x1946, 0x196d,
- 0x1970, 0x1974,
- 0x1d00, 0x1d6b,
- 0x1e00, 0x1e9b,
- 0x1ea0, 0x1ef9,
- 0x1f00, 0x1f15,
- 0x1f18, 0x1f1d,
- 0x1f20, 0x1f45,
- 0x1f48, 0x1f4d,
- 0x1f50, 0x1f57,
- 0x1f59, 0x1f59,
- 0x1f5b, 0x1f5b,
- 0x1f5d, 0x1f5d,
- 0x1f5f, 0x1f7d,
- 0x1f80, 0x1fb4,
- 0x1fb6, 0x1fbc,
- 0x1fbe, 0x1fbe,
- 0x1fc2, 0x1fc4,
- 0x1fc6, 0x1fcc,
- 0x1fd0, 0x1fd3,
- 0x1fd6, 0x1fdb,
- 0x1fe0, 0x1fec,
- 0x1ff2, 0x1ff4,
- 0x1ff6, 0x1ffc,
- 0x203f, 0x2040,
- 0x2054, 0x2054,
- 0x2070, 0x2071,
- 0x2074, 0x2079,
- 0x207f, 0x2089,
- 0x20d0, 0x20ea,
- 0x2102, 0x2102,
- 0x2107, 0x2107,
- 0x210a, 0x2113,
- 0x2115, 0x2115,
- 0x2119, 0x211d,
- 0x2124, 0x2124,
- 0x2126, 0x2126,
- 0x2128, 0x2128,
- 0x212a, 0x212d,
- 0x212f, 0x2131,
- 0x2133, 0x2139,
- 0x213d, 0x213f,
- 0x2145, 0x2149,
- 0x2153, 0x2183,
- 0x2460, 0x249b,
- 0x24ea, 0x24ff,
- 0x2776, 0x2793,
- 0x3005, 0x3007,
- 0x3021, 0x302f,
- 0x3031, 0x3035,
- 0x3038, 0x303c,
- 0x3041, 0x3096,
- 0x3099, 0x309a,
- 0x309d, 0x309f,
- 0x30a1, 0x30ff,
- 0x3105, 0x312c,
- 0x3131, 0x318e,
- 0x3192, 0x3195,
- 0x31a0, 0x31b7,
- 0x31f0, 0x31ff,
- 0x3220, 0x3229,
- 0x3251, 0x325f,
- 0x3280, 0x3289,
- 0x32b1, 0x32bf,
- 0x3400, 0x4db5,
- 0x4e00, 0x9fa5,
- 0xa000, 0xa48c,
- 0xac00, 0xd7a3,
- 0xf900, 0xfa2d,
- 0xfa30, 0xfa6a,
- 0xfb00, 0xfb06,
- 0xfb13, 0xfb17,
- 0xfb1d, 0xfb28,
- 0xfb2a, 0xfb36,
- 0xfb38, 0xfb3c,
- 0xfb3e, 0xfb3e,
- 0xfb40, 0xfb41,
- 0xfb43, 0xfb44,
- 0xfb46, 0xfbb1,
- 0xfbd3, 0xfd3d,
- 0xfd50, 0xfd8f,
- 0xfd92, 0xfdc7,
- 0xfdf0, 0xfdfb,
- 0xfe00, 0xfe0f,
- 0xfe20, 0xfe23,
- 0xfe33, 0xfe34,
- 0xfe4d, 0xfe4f,
- 0xfe70, 0xfe74,
- 0xfe76, 0xfefc,
- 0xff10, 0xff19,
- 0xff21, 0xff3a,
- 0xff3f, 0xff3f,
- 0xff41, 0xff5a,
- 0xff65, 0xffbe,
- 0xffc2, 0xffc7,
- 0xffca, 0xffcf,
- 0xffd2, 0xffd7,
- 0xffda, 0xffdc,
- 0x10000, 0x1000b,
- 0x1000d, 0x10026,
- 0x10028, 0x1003a,
- 0x1003c, 0x1003d,
- 0x1003f, 0x1004d,
- 0x10050, 0x1005d,
- 0x10080, 0x100fa,
- 0x10107, 0x10133,
- 0x10300, 0x1031e,
- 0x10320, 0x10323,
- 0x10330, 0x1034a,
- 0x10380, 0x1039d,
- 0x10400, 0x1049d,
- 0x104a0, 0x104a9,
- 0x10800, 0x10805,
- 0x10808, 0x10808,
- 0x1080a, 0x10835,
- 0x10837, 0x10838,
- 0x1083c, 0x1083c,
- 0x1083f, 0x1083f,
- 0x1d165, 0x1d169,
- 0x1d16d, 0x1d172,
- 0x1d17b, 0x1d182,
- 0x1d185, 0x1d18b,
- 0x1d1aa, 0x1d1ad,
- 0x1d400, 0x1d454,
- 0x1d456, 0x1d49c,
- 0x1d49e, 0x1d49f,
- 0x1d4a2, 0x1d4a2,
- 0x1d4a5, 0x1d4a6,
- 0x1d4a9, 0x1d4ac,
- 0x1d4ae, 0x1d4b9,
- 0x1d4bb, 0x1d4bb,
- 0x1d4bd, 0x1d4c3,
- 0x1d4c5, 0x1d505,
- 0x1d507, 0x1d50a,
- 0x1d50d, 0x1d514,
- 0x1d516, 0x1d51c,
- 0x1d51e, 0x1d539,
- 0x1d53b, 0x1d53e,
- 0x1d540, 0x1d544,
- 0x1d546, 0x1d546,
- 0x1d54a, 0x1d550,
- 0x1d552, 0x1d6a3,
- 0x1d6a8, 0x1d6c0,
- 0x1d6c2, 0x1d6da,
- 0x1d6dc, 0x1d6fa,
- 0x1d6fc, 0x1d714,
- 0x1d716, 0x1d734,
- 0x1d736, 0x1d74e,
- 0x1d750, 0x1d76e,
- 0x1d770, 0x1d788,
- 0x1d78a, 0x1d7a8,
- 0x1d7aa, 0x1d7c2,
- 0x1d7c4, 0x1d7c9,
- 0x1d7ce, 0x1d7ff,
- 0x20000, 0x2a6d6,
- 0x2f800, 0x2fa1d,
- 0xe0100, 0xe01ef
-#endif /* USE_UNICODE_FULL_RANGE_CTYPE */
-}; /* end of MBWord */
static int
-utf8_get_ctype_code_range(int ctype,
- const OnigCodePoint* sbr[], const OnigCodePoint* mbr[])
+get_ctype_code_range(OnigCtype ctype, OnigCodePoint *sb_out,
+ const OnigCodePoint* ranges[])
{
-#define CR_SET(sbl,mbl) do { \
- *sbr = sbl; \
- *mbr = mbl; \
-} while (0)
-
-#define CR_SB_SET(sbl) do { \
- *sbr = sbl; \
- *mbr = EmptyRange; \
-} while (0)
-
- switch (ctype) {
- case ONIGENC_CTYPE_ALPHA:
- CR_SET(SBAlpha, MBAlpha);
- break;
- case ONIGENC_CTYPE_BLANK:
- CR_SET(SBBlank, MBBlank);
- break;
- case ONIGENC_CTYPE_CNTRL:
- CR_SET(SBCntrl, MBCntrl);
- break;
- case ONIGENC_CTYPE_DIGIT:
- CR_SET(SBDigit, MBDigit);
- break;
- case ONIGENC_CTYPE_GRAPH:
- CR_SET(SBGraph, MBGraph);
- break;
- case ONIGENC_CTYPE_LOWER:
- CR_SET(SBLower, MBLower);
- break;
- case ONIGENC_CTYPE_PRINT:
- CR_SET(SBPrint, MBPrint);
- break;
- case ONIGENC_CTYPE_PUNCT:
- CR_SET(SBPunct, MBPunct);
- break;
- case ONIGENC_CTYPE_SPACE:
- CR_SET(SBSpace, MBSpace);
- break;
- case ONIGENC_CTYPE_UPPER:
- CR_SET(SBUpper, MBUpper);
- break;
- case ONIGENC_CTYPE_XDIGIT:
- CR_SB_SET(SBXDigit);
- break;
- case ONIGENC_CTYPE_WORD:
- CR_SET(SBWord, MBWord);
- break;
- case ONIGENC_CTYPE_ASCII:
- CR_SB_SET(SBASCII);
- break;
- case ONIGENC_CTYPE_ALNUM:
- CR_SET(SBAlnum, MBAlnum);
- break;
-
- default:
- return ONIGENCERR_TYPE_BUG;
- break;
- }
-
- return 0;
+ *sb_out = 0x80;
+ return onigenc_unicode_ctype_code_range(ctype, ranges);
}
-static int
-utf8_is_code_ctype(OnigCodePoint code, unsigned int ctype)
-{
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
- const OnigCodePoint *range;
-#endif
-
- if (code < 256) {
- return ONIGENC_IS_UNICODE_ISO_8859_1_CTYPE(code, ctype);
- }
-
-#ifdef USE_UNICODE_FULL_RANGE_CTYPE
-
- switch (ctype) {
- case ONIGENC_CTYPE_ALPHA:
- range = MBAlpha;
- break;
- case ONIGENC_CTYPE_BLANK:
- range = MBBlank;
- break;
- case ONIGENC_CTYPE_CNTRL:
- range = MBCntrl;
- break;
- case ONIGENC_CTYPE_DIGIT:
- range = MBDigit;
- break;
- case ONIGENC_CTYPE_GRAPH:
- range = MBGraph;
- break;
- case ONIGENC_CTYPE_LOWER:
- range = MBLower;
- break;
- case ONIGENC_CTYPE_PRINT:
- range = MBPrint;
- break;
- case ONIGENC_CTYPE_PUNCT:
- range = MBPunct;
- break;
- case ONIGENC_CTYPE_SPACE:
- range = MBSpace;
- break;
- case ONIGENC_CTYPE_UPPER:
- range = MBUpper;
- break;
- case ONIGENC_CTYPE_XDIGIT:
- return FALSE;
- break;
- case ONIGENC_CTYPE_WORD:
- range = MBWord;
- break;
- case ONIGENC_CTYPE_ASCII:
- return FALSE;
- break;
- case ONIGENC_CTYPE_ALNUM:
- range = MBAlnum;
- break;
- case ONIGENC_CTYPE_NEWLINE:
- return FALSE;
- break;
-
- default:
- return ONIGENCERR_TYPE_BUG;
- break;
- }
-
- return onig_is_in_code_range((UChar* )range, code);
-
-#else
-
- if ((ctype & ONIGENC_CTYPE_WORD) != 0) {
-#ifdef USE_INVALID_CODE_SCHEME
- if (code <= VALID_CODE_LIMIT)
-#endif
- return TRUE;
- }
-#endif /* USE_UNICODE_FULL_RANGE_CTYPE */
-
- return FALSE;
-}
static UChar*
-utf8_left_adjust_char_head(const UChar* start, const UChar* s)
+left_adjust_char_head(const UChar* start, const UChar* s)
{
const UChar *p;
@@ -3700,31 +277,29 @@ utf8_left_adjust_char_head(const UChar* start, const UChar* s)
return (UChar* )p;
}
+static int
+get_case_fold_codes_by_str(OnigCaseFoldType flag,
+ const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[])
+{
+ return onigenc_unicode_get_case_fold_codes_by_str(ONIG_ENCODING_UTF8,
+ flag, p, end, items);
+}
+
OnigEncodingType OnigEncodingUTF8 = {
- utf8_mbc_enc_len,
+ mbc_enc_len,
"UTF-8", /* name */
6, /* max byte length */
1, /* min byte length */
- (ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE |
- ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE ),
- {
- (OnigCodePoint )'\\' /* esc */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
- , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
- },
- utf8_is_mbc_newline,
- utf8_mbc_to_code,
- utf8_code_to_mbclen,
- utf8_code_to_mbc,
- utf8_mbc_to_normalize,
- utf8_is_mbc_ambiguous,
- onigenc_iso_8859_1_get_all_pair_ambig_codes,
- onigenc_ess_tsett_get_all_comp_ambig_codes,
- utf8_is_code_ctype,
- utf8_get_ctype_code_range,
- utf8_left_adjust_char_head,
+ is_mbc_newline,
+ mbc_to_code,
+ code_to_mbclen,
+ code_to_mbc,
+ mbc_case_fold,
+ onigenc_unicode_apply_all_case_fold,
+ get_case_fold_codes_by_str,
+ onigenc_unicode_property_name_to_ctype,
+ onigenc_unicode_is_code_ctype,
+ get_ctype_code_range,
+ left_adjust_char_head,
onigenc_always_true_is_allowed_reverse_match
};
diff --git a/ext/mbstring/oniguruma/index.html b/ext/mbstring/oniguruma/index.html
index d55f1cc94f..af3426ce32 100755
--- a/ext/mbstring/oniguruma/index.html
+++ b/ext/mbstring/oniguruma/index.html
@@ -8,7 +8,7 @@
<h1>Oniguruma</h1> (<a href="index_ja.html">Japanese</a>)
<p>
-(c) K.Kosako, updated at: 2007/08/16
+(c) K.Kosako, updated at: 2010/01/09
</p>
<dl>
@@ -16,8 +16,8 @@
<dt><b>What's new</b>
</font>
<ul>
+<li>2010/01/09: Version 5.9.2 released.</li>
<li>2007/08/16: Version 4.7.1 released.</li>
-<li>2007/07/14: Version 5.9.0 released.</li>
<li>2007/06/20: Version 2.5.9 released.</li>
<li>2007/06/20: Maintainer of 2.x was changed.</li>
</ul>
@@ -62,9 +62,8 @@ ISO-8859-11, ISO-8859-13, ISO-8859-14, ISO-8859-15, ISO-8859-16<br>
<dt><b>Download:</b>
<ul>
-<li> <a href="archive/onig-5.9.0.tar.gz">Latest release version 5.9.0</a> (2007/07/14) <a href="HISTORY_5X.txt">Change Log</a>
-<li> <a href="archive/onig-5.8.0.tar.gz">5.8.0</a> (2007/06/04)
-<li> <a href="archive/onig-5.7.0.tar.gz">5.7.0</a> (2007/04/27)
+<li> <a href="archive/onig-5.9.2.tar.gz">Latest release version 5.9.2</a> (2010/01/09) <a href="HISTORY_5X.txt">Change Log</a>
+<li> <a href="archive/onig-5.9.1.tar.gz">5.9.1</a> (2007/12/22)
<li> <a href="archive/onig-4.7.1.tar.gz">Latest release version 4.7.1</a> (2007/08/16) <a href="HISTORY_4X.txt">Change Log</a>
<li> <a href="archive/onig-4.7.0.tar.gz">4.7.0</a> (2007/06/18)
<li> <a href="archive/onigd2_5_9.tar.gz">Latest release version 2.5.9</a> (2007/06/20) <a href="HISTORY_2X.txt">Change Log</a>
@@ -79,7 +78,7 @@ About 2.x, please contact him.<br>
* 2.x supports Ruby1.6/1.8.<br>
<br>
-<dt><b>Documents:</b> (version 5.9.0)
+<dt><b>Documents:</b> (version 5.9.2)
<ul>
<li> <a href="doc/RE.txt">Regular Expressions</a>
<a href="doc/RE.ja.txt">(Japanese: EUC-JP)</a>
@@ -133,6 +132,7 @@ About 2.x, please contact him.<br>
<li> <a href="http://www.php.gr.jp/">Japan PHP User Group</a> PHP 5.0 mb_ereg (Japanese page)
<li> <a href="http://yatsu.info/wiki/Pufui/">Pufui (Mac OS X)</a> (Japanese page)
<li> <a href="http://ultrapop.jp/?q2ch">q2ch</a> (Japanese page)
+<li> <a href="http://search.cpan.org/~andya/re-engine-Oniguruma">re-engine-Oniguruma</a>
<li> <a href="http://harumune.s56.xrea.com/assari/index.php?RSSTyping">RSSTyping</a> (Japanese page)
<li> <a href="http://tobysoft.net/wiki/index.php?Ruby%2Fruby-win32-oniguruma">ruby-win32-oniguruma</a> (Japanese page)
<li> <a href="http://quux.s74.xrea.com/">SevenFour (Mac OS X)</a> (Japanese page)
@@ -142,6 +142,7 @@ About 2.x, please contact him.<br>
<li> <a href="http://www.cyanworks.net/mac.html">TunesTEXT (Mac OS X)</a>
<li> <a href="http://sourceforge.jp/projects/frogger/">XML parser</a>
<li> <a href="http://www.yokkasoft.net/">YokkaSoft (Win32)</a> (Japanese page)
+<li> <a href="http://www.hi-ho.ne.jp/kuze/tool.htm">Zed (Win32)</a> (Japanese page)
</ul>
<br>
@@ -174,14 +175,13 @@ and I'm thankful to Akinori MUSHA.
<li> <a href="http://re2c.org/">re2c</a>
<li> <a href="http://tiny-rex.sourceforge.net/">T-Rex</a>
<li> <a href="http://laurikari.net/tre/">TRE</a>
+<li> <a href="http://svn.codehaus.org/jruby/joni/">Joni (Java)</a>
<li> <a href="http://jregex.sourceforge.net/">JRegex (Java)</a>
<li> <a href="http://www.cacas.org/java/gnu/regexp/">gnu.regexp for Java</a>
<li> <a href="http://jakarta.apache.org/regexp/index.html">Jakarta Project Regexp</a>
<li> <a href="http://jakarta.apache.org/oro/">Jakarta Project ORO</a>
+<li> <a href="http://sourceforge.jp/projects/onig4j/">Oniguruma for Java</a>
</ul>
</dl>
-
-<hr>
-<a href="../">Back to Home</a>
</body>
</html>
diff --git a/ext/mbstring/oniguruma/index_ja.html b/ext/mbstring/oniguruma/index_ja.html
new file mode 100644
index 0000000000..e03b045b98
--- /dev/null
+++ b/ext/mbstring/oniguruma/index_ja.html
@@ -0,0 +1,190 @@
+<html>
+<head>
+ <meta HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=utf-8">
+ <title>鬼車</title>
+</head>
+<body BGCOLOR="#ffffff" VLINK="#808040" TEXT="#696969">
+
+<h1>鬼車</h1>
+
+<p>
+(c) K.Kosako, 最終更新: 2010/01/09
+</p>
+
+<dl>
+<font color="orange">
+<dt><b>更新情報</b>
+</font>
+<ul>
+<li>2010/01/09: Version 5.9.2 リリース</li>
+<li>2007/08/16: Version 4.7.1 リリース</li>
+<li>2007/06/20: Version 2.5.9 リリース</li>
+<li>2007/06/20: 2.xの保守担当者を変更</li>
+</ul>
+</dl>
+<hr>
+
+<p>
+鬼車は正規表現ライブラリである。<br>
+このライブラリの特徴は、それぞれの正規表現オブジェクトごとに異なる文字エンコーディングを
+指定できること。<br>
+(API: GNU regex, POSIX and Oniguruma native)
+</p>
+
+<dl>
+<dt><b>対応している文字エンコーディング:</b><br>
+ASCII, UTF-8, UTF-16BE, UTF-16LE, UTF-32BE, UTF-32LE,<br>
+EUC-JP, EUC-TW, EUC-KR, EUC-CN,<br>
+Shift_JIS, Big5, GB18030, KOI8-R, CP1251,<br>
+ISO-8859-1, ISO-8859-2, ISO-8859-3, ISO-8859-4, ISO-8859-5,<br>
+ISO-8859-6, ISO-8859-7, ISO-8859-8, ISO-8859-9, ISO-8859-10,<br>
+ISO-8859-11, ISO-8859-13, ISO-8859-14, ISO-8859-15, ISO-8859-16<br>
+<font color="orange">
+(GB18030は、KUBO Takehiro氏提供)<br>
+(CP1251は、Byte氏提供)
+</font>
+</p>
+</dl>
+
+<hr>
+
+<dt><b>ライセンス:</b>BSDライセンス
+
+<dl>
+<dt><b>プラットフォーム:</b>
+<ul>
+<li> Unix (Mac OS Xを含む)
+<li> Cygwin
+<li> Win32
+</ul>
+
+<br>
+
+<dt><b>ダウンロード:</b>
+<ul>
+<li> <a href="archive/onig-5.9.2.tar.gz">5.9.2 最新版</a> (2010/01/09) <a href="HISTORY_5X.txt">更新履歴</a>
+<li> <a href="archive/onig-5.9.1.tar.gz">5.9.1</a> (2007/12/22)
+<li> <a href="archive/onig-4.7.1.tar.gz">4.7.1 最新版</a> (2007/08/16) <a href="HISTORY_4X.txt">更新履歴</a>
+<li> <a href="archive/onig-4.7.0.tar.gz">4.7.0</a> (2007/06/18)
+<li> <a href="archive/onigd2_5_9.tar.gz">2.5.9 最新版</a> (2007/06/20) <a href="HISTORY_2X.txt">更新履歴</a>
+</ul>
+
+<br>
+<font color="red">
+2.xの保守担当は、Hannes Wyss &lt;hwyss AT ywesee.com&gt;に交替しました。<br>
+2.xについては、彼に連絡してください。<br>
+</font>
+* 5.xはUnicode Property/Scriptを提供<br>
+* 2.xはRuby1.6/1.8組込みライブラリとして動作する。 (2006年末で保守を終了)<br>
+
+<br>
+<dt><b>ドキュメント:</b> (version 5.9.2)
+<ul>
+ <li> <a href="doc/RE.txt">正規表現</a>
+ <a href="doc/RE.ja.txt">(日本語: EUC-JP)</a>
+ <li> <a href="doc/API.txt">鬼車API</a>
+ <a href="doc/API.ja.txt">(日本語: EUC-JP)</a>
+</ul>
+
+<br>
+<dt><b>サンプルプログラム:</b>
+<ul>
+ <li><a href="sample/simple.c">最小使用例</a>
+ <li><a href="sample/sql.c">可変文法と可変メタ文字機能使用例(SQL-like pattern match)</a>
+</ul>
+
+<br>
+<dt><b>サイト:</b>
+<ul>
+<li> <a href="http://www.freebsd.org/cgi/cvsweb.cgi/ports/devel/oniguruma/">FreeBSD ports</a>
+<li> <a href="http://www.softantenna.com/lib/1953/index.html">SoftAntenna &gt; Lib &gt; Oniguruma</a> (日本語)
+</ul>
+
+<br>
+<dt><b>リンク:</b>
+<ul>
+<li> <a href="http://homepage3.nifty.com/k-takata/mysoft/bregonig.html">bregonig.dll (Win32)</a> (日本語)
+<li> <a href="http://www.halbiz.com/osaru/cnregex.html">cnRegex 4D Plugin (Mac OS X)</a> (日本語)
+<li> <a href="http://kmaebashi.com/">crowbar</a> (日本語)
+<li> <a href="http://oniguruma5.darwinports.com">Darwin Ports (Mac OS X)</a>
+<li> <a href="http://homepage2.nifty.com/Km/onig.htm">Delphi interface (Win32)</a> (日本語)
+<li> <a href="http://pyxis-project.net/ensemble/">Ensemble (Mac OS X)</a> (日本語)
+<li> <a href="http://www.srcw.net/FaEdit/">FaEdit (Win32)</a> (日本語)
+<li> <a href="http://www.tom.sfc.keio.ac.jp/~sakai/d/?date=20050209">GHC patch</a> Masahiro Sakai (Japanese Blog)
+<li> <a href="http://www.gyazsquare.com/gyazmail/index.php">GyazMail (Mac OS X)</a>
+<li> <a href="http://www5d.biglobe.ne.jp/~f-taste/knt3/jcref3.html">J-cref v3</a> (日本語)
+<li> <a href="http://www.artman21.net/">Jedit X (Mac OS X)</a>
+<li> <a href="http://www.chitora.jp/lhaz.html">Lhaz (Win32)</a> (日本語)
+<li> <a href="http://limechat.net/">LimeChat</a> (日本語)
+<li> <a href="http://medb.enhiro.com/">meDB</a> (日本語)
+<li> <a href="http://monaos.org/">Mona OS</a>
+<li> <a href="http://mongoose.jp/">mongoose</a> (日本語)
+<li> <a href="http://www.irori.org/tool/mregexp.html">mregexp</a> (日本語)
+<li> <a href="http://ochusha.sourceforge.jp/">おちゅ〜しゃ</a> (日本語)
+<li> <a href="http://www8.ocn.ne.jp/%7esonoisa/OgreKit/index.html">OgreKit (Mac OS X)</a> Regular Expression Framework for Cocoa (日本語)
+<li> <a href="http://www.kanetaka.net/4dapi/wiki4d.dll/4dcgi/wiki.cgi?plugins-oniguruma">OnigRegexp</a> (日本語)
+<li> <a href="http://rubyforge.org/projects/oniguruma">Oniguruma for Ruby</a>
+<li> <a href="http://openspace.timedia.co.jp/~yasuyuki/wiliki/wiliki.cgi?Oniguruma-mysqld&l=jp">Oniguruma-mysqld</a>
+<li> <a href="http://www.void.in/wiki/OnigPP">OnigPP</a> (日本語)
+<li> <a href="http://www.kt.rim.or.jp/~kbk/sed/index.html">Onigsed (Win32)</a> (日本語)
+<li> <a href="http://glozer.net/code.html#oregexp">oregexp</a> Erlang binding
+<li> <a href="http://www.kt.rim.or.jp/~kbk/yagrep/index.html">yagrep (Win32)</a> (日本語)
+<li> <a href="http://www.php.gr.jp/">日本PHPユーザ会</a> PHP 5.0 mb_ereg (日本語)
+<li> <a href="http://yatsu.info/wiki/Pufui/">Pufui (Mac OS X)</a> (日本語)
+<li> <a href="http://ultrapop.jp/?q2ch">q2ch</a> (日本語)
+<li> <a href="http://search.cpan.org/~andya/re-engine-Oniguruma">re-engine-Oniguruma</a>
+<li> <a href="http://harumune.s56.xrea.com/assari/index.php?RSSTyping">RSSTyping</a> (日本語)
+<li> <a href="http://tobysoft.net/wiki/index.php?Ruby%2Fruby-win32-oniguruma">ruby-win32-oniguruma</a> (日本語)
+<li> <a href="http://quux.s74.xrea.com/">SevenFour (Mac OS X)</a> (日本語)
+<li> <a href="http://storklab.cyber-ninja.jp/">Stork Lab. Products (Mac OS X)</a> (日本語)
+<li> <a href="http://sourceforge.jp/projects/ttssh2/">TeraTerm (Win32)</a>
+<li> <a href="http://www8.ocn.ne.jp/~sonoisa/TiddlyWikiPod/">TiddlyWikiPod (Mac OS X)</a>
+<li> <a href="http://www.cyanworks.net/mac.html">TunesTEXT (Mac OS X)</a>
+<li> <a href="http://sourceforge.jp/projects/frogger/">XML parser</a>
+<li> <a href="http://www.yokkasoft.net/">YokkaSoft (Win32)</a> (日本語)
+<li> <a href="http://www.hi-ho.ne.jp/kuze/tool.htm">Zed (Win32)</a> (日本語)
+</ul>
+
+<br>
+<dt><b>参考資料:</b>
+<ul>
+<li> <a href="http://www.ruby-lang.org/ja/man/index.cgi?cmd=view;name=%C0%B5%B5%AC%C9%BD%B8%BD">Rubyリファレンスマニュアル</a> (日本語)
+<li> <a href="http://www.perl.com/doc/manual/html/pod/perlre.html">Perl regular expressions</a>
+<li> <a href="http://java.sun.com/j2se/1.4.2/docs/api/java/util/regex/Pattern.html">java.util.regex.Pattern (J2SE 1.4.2)</a>
+<li> <a href="http://www.opengroup.org/onlinepubs/007908799/xbd/re.html">The Open Group</a>
+<li> <a href="http://regex.info/">Mastering Regular Expressions</a>
+<li> <a href="http://www.unicode.org/">Unicode Home Page</a>
+<li> <a href="http://www.kt.rim.or.jp/~kbk/regex/regex.html">正規表現メモ</a> (日本語)
+<li> <a href="http://www.din.or.jp/~ohzaki/regex.htm">Perl正規表現雑技</a> (日本語)
+</ul>
+
+<br>
+</dl>
+<p>
+and I'm thankful to Akinori MUSHA.
+</p>
+
+<hr>
+<dl>
+<dt><b>他のライブラリ:</b>
+<ul>
+<li> <a href="http://www.boost.org/libs/regex/doc/">Boost.Regex</a>
+<li> <a href="http://arglist.com/regex/">A copy of Henry Spencer's</a>
+<li> <a href="http://directory.fsf.org/regex.html">GNU regex</a>
+<li> <a href="http://www.pcre.org/">PCRE</a>
+<li> <a href="http://re2c.org/">re2c</a>
+<li> <a href="http://tiny-rex.sourceforge.net/">T-Rex</a>
+<li> <a href="http://laurikari.net/tre/">TRE</a>
+<li> <a href="http://svn.codehaus.org/jruby/joni/">Joni (Java)</a>
+<li> <a href="http://jregex.sourceforge.net/">JRegex (Java)</a>
+<li> <a href="http://www.cacas.org/java/gnu/regexp/">gnu.regexp for Java</a>
+<li> <a href="http://jakarta.apache.org/regexp/index.html">Jakarta Project Regexp</a>
+<li> <a href="http://jakarta.apache.org/oro/">Jakarta Project ORO</a>
+<li> <a href="http://sourceforge.jp/projects/onig4j/">Oniguruma for Java</a>
+</ul>
+</dl>
+
+<hr>
+<a href="../">ホームにもどる</a>
+</body>
+</html>
diff --git a/ext/mbstring/oniguruma/onigposix.h b/ext/mbstring/oniguruma/onigposix.h
index cfeb88a292..f1cb35fbd8 100644
--- a/ext/mbstring/oniguruma/onigposix.h
+++ b/ext/mbstring/oniguruma/onigposix.h
@@ -97,7 +97,7 @@ typedef struct {
#ifndef ONIG_EXTERN
#if defined(_WIN32) && !defined(__GNUC__)
-#if defined(EXPORT) || defined(RUBY_EXPORT)
+#if defined(EXPORT)
#define ONIG_EXTERN extern __declspec(dllexport)
#else
#define ONIG_EXTERN extern __declspec(dllimport)
diff --git a/ext/mbstring/oniguruma/oniguruma.h b/ext/mbstring/oniguruma/oniguruma.h
index 5196a3d585..bf00e20f63 100644
--- a/ext/mbstring/oniguruma/oniguruma.h
+++ b/ext/mbstring/oniguruma/oniguruma.h
@@ -4,7 +4,7 @@
oniguruma.h - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2007 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2009 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -29,16 +29,14 @@
* SUCH DAMAGE.
*/
-#include "../php_onig_compat.h"
-
#ifdef __cplusplus
extern "C" {
#endif
#define ONIGURUMA
-#define ONIGURUMA_VERSION_MAJOR 4
-#define ONIGURUMA_VERSION_MINOR 7
-#define ONIGURUMA_VERSION_TEENY 1
+#define ONIGURUMA_VERSION_MAJOR 5
+#define ONIGURUMA_VERSION_MINOR 9
+#define ONIGURUMA_VERSION_TEENY 2
#ifdef __cplusplus
# ifndef HAVE_PROTOTYPES
@@ -56,6 +54,12 @@ extern "C" {
# endif
#endif
+#ifdef HAVE_STDARG_H
+# ifndef HAVE_STDARG_PROTOTYPES
+# define HAVE_STDARG_PROTOTYPES 1
+# endif
+#endif
+
#ifndef P_
#if defined(__STDC__) || defined(_WIN32)
# define P_(args) args
@@ -92,30 +96,34 @@ extern "C" {
#define UChar OnigUChar
#endif
-typedef unsigned char OnigUChar;
+#ifdef _WIN32
+# include <windows.h>
+typedef ULONG_PTR OnigCodePoint;
+#else
typedef unsigned long OnigCodePoint;
+#endif
+typedef unsigned char OnigUChar;
+typedef unsigned int OnigCtype;
typedef unsigned int OnigDistance;
#define ONIG_INFINITE_DISTANCE ~((OnigDistance )0)
-/* ambiguous match flag */
-typedef unsigned int OnigAmbigType;
-
-ONIG_EXTERN OnigAmbigType OnigDefaultAmbigFlag;
+typedef unsigned int OnigCaseFoldType; /* case fold flag */
-#define ONIGENC_AMBIGUOUS_MATCH_NONE 0
-#define ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE (1<<0)
-#define ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE (1<<1)
+ONIG_EXTERN OnigCaseFoldType OnigDefaultCaseFoldFlag;
-#define ONIGENC_AMBIGUOUS_MATCH_LIMIT (1<<1)
+/* #define ONIGENC_CASE_FOLD_HIRAGANA_KATAKANA (1<<1) */
+/* #define ONIGENC_CASE_FOLD_KATAKANA_WIDTH (1<<2) */
+#define ONIGENC_CASE_FOLD_TURKISH_AZERI (1<<20)
+#define INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR (1<<30)
-#define ONIGENC_AMBIGUOUS_MATCH_FULL \
- ( ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE | ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE )
-#define ONIGENC_AMBIGUOUS_MATCH_DEFAULT OnigDefaultAmbigFlag
+#define ONIGENC_CASE_FOLD_MIN INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR
+#define ONIGENC_CASE_FOLD_DEFAULT OnigDefaultCaseFoldFlag
-#define ONIGENC_MAX_COMP_AMBIG_CODE_LEN 3
-#define ONIGENC_MAX_COMP_AMBIG_CODE_ITEM_NUM 4
+#define ONIGENC_MAX_COMP_CASE_FOLD_CODE_LEN 3
+#define ONIGENC_GET_CASE_FOLD_CODES_MAX_NUM 13
+/* 13 => Unicode:0x1ffc */
/* code range */
#define ONIGENC_CODE_RANGE_NUM(range) ((int )range[0])
@@ -123,20 +131,10 @@ ONIG_EXTERN OnigAmbigType OnigDefaultAmbigFlag;
#define ONIGENC_CODE_RANGE_TO(range,i) range[((i)*2) + 2]
typedef struct {
- int len;
- OnigCodePoint code[ONIGENC_MAX_COMP_AMBIG_CODE_LEN];
-} OnigCompAmbigCodeItem;
-
-typedef struct {
- int n;
- OnigCodePoint code;
- OnigCompAmbigCodeItem items[ONIGENC_MAX_COMP_AMBIG_CODE_ITEM_NUM];
-} OnigCompAmbigCodes;
-
-typedef struct {
- OnigCodePoint from;
- OnigCodePoint to;
-} OnigPairAmbigCodes;
+ int byte_len; /* argument(original) character(s) byte length */
+ int code_len; /* number of code */
+ OnigCodePoint code[ONIGENC_MAX_COMP_CASE_FOLD_CODE_LEN];
+} OnigCaseFoldCodeItem;
typedef struct {
OnigCodePoint esc;
@@ -146,32 +144,24 @@ typedef struct {
OnigCodePoint one_or_more_time;
OnigCodePoint anychar_anytime;
} OnigMetaCharTableType;
+
+typedef int (*OnigApplyAllCaseFoldFunc)(OnigCodePoint from, OnigCodePoint* to, int to_len, void* arg);
-
-#if defined(RUBY_PLATFORM) && defined(M17N_H)
-
-#define ONIG_RUBY_M17N
-typedef m17n_encoding* OnigEncoding;
-
-#else
-
-typedef struct {
+typedef struct OnigEncodingTypeST {
int (*mbc_enc_len)(const OnigUChar* p);
const char* name;
int max_enc_len;
int min_enc_len;
- OnigAmbigType support_ambig_flag;
- OnigMetaCharTableType meta_char_table;
int (*is_mbc_newline)(const OnigUChar* p, const OnigUChar* end);
OnigCodePoint (*mbc_to_code)(const OnigUChar* p, const OnigUChar* end);
int (*code_to_mbclen)(OnigCodePoint code);
int (*code_to_mbc)(OnigCodePoint code, OnigUChar *buf);
- int (*mbc_to_normalize)(OnigAmbigType flag, const OnigUChar** pp, const OnigUChar* end, OnigUChar* to);
- int (*is_mbc_ambiguous)(OnigAmbigType flag, const OnigUChar** pp, const OnigUChar* end);
- int (*get_all_pair_ambig_codes)(OnigAmbigType flag, const OnigPairAmbigCodes** acs);
- int (*get_all_comp_ambig_codes)(OnigAmbigType flag, const OnigCompAmbigCodes** acs);
- int (*is_code_ctype)(OnigCodePoint code, unsigned int ctype);
- int (*get_ctype_code_range)(int ctype, const OnigCodePoint* sb_range[], const OnigCodePoint* mb_range[]);
+ int (*mbc_case_fold)(OnigCaseFoldType flag, const OnigUChar** pp, const OnigUChar* end, OnigUChar* to);
+ int (*apply_all_case_fold)(OnigCaseFoldType flag, OnigApplyAllCaseFoldFunc f, void* arg);
+ int (*get_case_fold_codes_by_str)(OnigCaseFoldType flag, const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem acs[]);
+ int (*property_name_to_ctype)(struct OnigEncodingTypeST* enc, OnigUChar* p, OnigUChar* end);
+ int (*is_code_ctype)(OnigCodePoint code, OnigCtype ctype);
+ int (*get_ctype_code_range)(OnigCtype ctype, OnigCodePoint* sb_out, const OnigCodePoint* ranges[]);
OnigUChar* (*left_adjust_char_head)(const OnigUChar* start, const OnigUChar* p);
int (*is_allowed_reverse_match)(const OnigUChar* p, const OnigUChar* end);
} OnigEncodingType;
@@ -206,6 +196,7 @@ ONIG_EXTERN OnigEncodingType OnigEncodingEUC_CN;
ONIG_EXTERN OnigEncodingType OnigEncodingSJIS;
ONIG_EXTERN OnigEncodingType OnigEncodingKOI8;
ONIG_EXTERN OnigEncodingType OnigEncodingKOI8_R;
+ONIG_EXTERN OnigEncodingType OnigEncodingCP1251;
ONIG_EXTERN OnigEncodingType OnigEncodingBIG5;
ONIG_EXTERN OnigEncodingType OnigEncodingGB18030;
@@ -237,136 +228,60 @@ ONIG_EXTERN OnigEncodingType OnigEncodingGB18030;
#define ONIG_ENCODING_SJIS (&OnigEncodingSJIS)
#define ONIG_ENCODING_KOI8 (&OnigEncodingKOI8)
#define ONIG_ENCODING_KOI8_R (&OnigEncodingKOI8_R)
+#define ONIG_ENCODING_CP1251 (&OnigEncodingCP1251)
#define ONIG_ENCODING_BIG5 (&OnigEncodingBIG5)
#define ONIG_ENCODING_GB18030 (&OnigEncodingGB18030)
-#endif /* else RUBY && M17N */
-
#define ONIG_ENCODING_UNDEF ((OnigEncoding )0)
/* work size */
-#define ONIGENC_CODE_TO_MBC_MAXLEN 7
-#define ONIGENC_MBC_NORMALIZE_MAXLEN ONIGENC_CODE_TO_MBC_MAXLEN
+#define ONIGENC_CODE_TO_MBC_MAXLEN 7
+#define ONIGENC_MBC_CASE_FOLD_MAXLEN 18
+/* 18: 6(max-byte) * 3(case-fold chars) */
/* character types */
-#define ONIGENC_CTYPE_NEWLINE (1<< 0)
-#define ONIGENC_CTYPE_ALPHA (1<< 1)
-#define ONIGENC_CTYPE_BLANK (1<< 2)
-#define ONIGENC_CTYPE_CNTRL (1<< 3)
-#define ONIGENC_CTYPE_DIGIT (1<< 4)
-#define ONIGENC_CTYPE_GRAPH (1<< 5)
-#define ONIGENC_CTYPE_LOWER (1<< 6)
-#define ONIGENC_CTYPE_PRINT (1<< 7)
-#define ONIGENC_CTYPE_PUNCT (1<< 8)
-#define ONIGENC_CTYPE_SPACE (1<< 9)
-#define ONIGENC_CTYPE_UPPER (1<<10)
-#define ONIGENC_CTYPE_XDIGIT (1<<11)
-#define ONIGENC_CTYPE_WORD (1<<12)
-#define ONIGENC_CTYPE_ASCII (1<<13)
-#define ONIGENC_CTYPE_ALNUM (ONIGENC_CTYPE_ALPHA | ONIGENC_CTYPE_DIGIT)
-
-#define enc_len(enc,p) ONIGENC_MBC_ENC_LEN(enc, p)
+#define ONIGENC_CTYPE_NEWLINE 0
+#define ONIGENC_CTYPE_ALPHA 1
+#define ONIGENC_CTYPE_BLANK 2
+#define ONIGENC_CTYPE_CNTRL 3
+#define ONIGENC_CTYPE_DIGIT 4
+#define ONIGENC_CTYPE_GRAPH 5
+#define ONIGENC_CTYPE_LOWER 6
+#define ONIGENC_CTYPE_PRINT 7
+#define ONIGENC_CTYPE_PUNCT 8
+#define ONIGENC_CTYPE_SPACE 9
+#define ONIGENC_CTYPE_UPPER 10
+#define ONIGENC_CTYPE_XDIGIT 11
+#define ONIGENC_CTYPE_WORD 12
+#define ONIGENC_CTYPE_ALNUM 13 /* alpha || digit */
+#define ONIGENC_CTYPE_ASCII 14
+#define ONIGENC_MAX_STD_CTYPE ONIGENC_CTYPE_ASCII
+
+
+#define onig_enc_len(enc,p,end) ONIGENC_MBC_ENC_LEN(enc,p)
#define ONIGENC_IS_UNDEF(enc) ((enc) == ONIG_ENCODING_UNDEF)
#define ONIGENC_IS_SINGLEBYTE(enc) (ONIGENC_MBC_MAXLEN(enc) == 1)
#define ONIGENC_IS_MBC_HEAD(enc,p) (ONIGENC_MBC_ENC_LEN(enc,p) != 1)
#define ONIGENC_IS_MBC_ASCII(p) (*(p) < 128)
#define ONIGENC_IS_CODE_ASCII(code) ((code) < 128)
-#define ONIGENC_IS_CODE_SB_WORD(enc,code) \
- (ONIGENC_IS_CODE_ASCII(code) && ONIGENC_IS_CODE_WORD(enc,code))
#define ONIGENC_IS_MBC_WORD(enc,s,end) \
ONIGENC_IS_CODE_WORD(enc,ONIGENC_MBC_TO_CODE(enc,s,end))
-#ifdef ONIG_RUBY_M17N
-
-#include <ctype.h> /* for isblank(), isgraph() */
-
-#define ONIGENC_MBC_TO_NORMALIZE(enc,flag,pp,end,buf) \
- onigenc_mbc_to_normalize(enc,flag,pp,end,buf)
-#define ONIGENC_IS_MBC_AMBIGUOUS(enc,flag,pp,end) \
- onigenc_is_mbc_ambiguous(enc,flag,pp,end)
-
-#define ONIGENC_SUPPORT_AMBIG_FLAG(enc) ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE
-#define ONIGENC_IS_ALLOWED_REVERSE_MATCH(enc,s,end) \
- onigenc_is_allowed_reverse_match(enc, s, end)
-#define ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc,start,s) \
- onigenc_get_left_adjust_char_head(enc, start, s)
-#define ONIGENC_GET_ALL_PAIR_AMBIG_CODES(enc, ambig_flag, acs) 0
-#define ONIGENC_GET_ALL_COMP_AMBIG_CODES(enc, ambig_flag, acs) 0
-#define ONIGENC_GET_CTYPE_CODE_RANGE(enc,ctype,sbr,mbr) \
- ONIG_NO_SUPPORT_CONFIG
-#define ONIGENC_MBC_ENC_LEN(enc,p) m17n_mbclen(enc,(int )(*p))
-#define ONIGENC_MBC_MAXLEN(enc) m17n_mbmaxlen(enc)
-#define ONIGENC_MBC_MAXLEN_DIST(enc) \
- (ONIGENC_MBC_MAXLEN(enc) > 0 ? ONIGENC_MBC_MAXLEN(enc) \
- : ONIG_INFINITE_DISTANCE)
-#define ONIGENC_MBC_MINLEN(enc) 1
-#define ONIGENC_MBC_TO_CODE(enc,p,e) m17n_codepoint((enc),(p),(e))
-#define ONIGENC_CODE_TO_MBCLEN(enc,code) m17n_codelen((enc),(code))
-#define ONIGENC_CODE_TO_MBC(enc,code,buf) onigenc_code_to_mbc(enc, code, buf)
-
-#if 0 /* !! not supported !! */
-#define ONIGENC_IS_MBC_NEWLINE(enc,p,end)
-#define ONIGENC_STEP_BACK(enc,start,s,n)
-#endif
-
-#define ONIGENC_IS_CODE_CTYPE(enc,code,ctype) \
- onigenc_is_code_ctype(enc,code,ctype)
-
-#ifdef isblank
-# define ONIGENC_IS_CODE_BLANK(enc,code) isblank((int )code)
-#else
-# define ONIGENC_IS_CODE_BLANK(enc,code) ((code) == ' ' || (code) == '\t')
-#endif
-#ifdef isgraph
-# define ONIGENC_IS_CODE_GRAPH(enc,code) isgraph((int )code)
-#else
-# define ONIGENC_IS_CODE_GRAPH(enc,code) \
- (isprint((int )code) && !isspace((int )code))
-#endif
-
-#define ONIGENC_IS_CODE_PRINT(enc,code) m17n_isprint(enc,code)
-#define ONIGENC_IS_CODE_ALNUM(enc,code) m17n_isalnum(enc,code)
-#define ONIGENC_IS_CODE_ALPHA(enc,code) m17n_isalpha(enc,code)
-#define ONIGENC_IS_CODE_LOWER(enc,code) m17n_islower(enc,code)
-#define ONIGENC_IS_CODE_UPPER(enc,code) m17n_isupper(enc,code)
-#define ONIGENC_IS_CODE_CNTRL(enc,code) m17n_iscntrl(enc,code)
-#define ONIGENC_IS_CODE_PUNCT(enc,code) m17n_ispunct(enc,code)
-#define ONIGENC_IS_CODE_SPACE(enc,code) m17n_isspace(enc,code)
-#define ONIGENC_IS_CODE_DIGIT(enc,code) m17n_isdigit(enc,code)
-#define ONIGENC_IS_CODE_XDIGIT(enc,code) m17n_isxdigit(enc,code)
-#define ONIGENC_IS_CODE_WORD(enc,code) m17n_iswchar(enc,code)
-
-ONIG_EXTERN
-int onigenc_is_code_ctype P_((OnigEncoding enc, OnigCodePoint code, int ctype));
-ONIG_EXTERN
-int onigenc_code_to_mbc P_((OnigEncoding enc, OnigCodePoint code, OnigUChar *buf));
-ONIG_EXTERN
-int onigenc_mbc_to_normalize P_((OnigEncoding enc, OnigAmbigType flag, const OnigUChar** pp, const OnigUChar* end, OnigUChar* buf));
-ONIG_EXTERN
-int onigenc_is_mbc_ambiguous P_((OnigEncoding enc, OnigAmbigType flag, const OnigUChar** pp, const OnigUChar* end));
-ONIG_EXTERN
-int onigenc_is_allowed_reverse_match P_((OnigEncoding enc, const OnigUChar* s, const OnigUChar* end));
-
-#else /* ONIG_RUBY_M17N */
-
#define ONIGENC_NAME(enc) ((enc)->name)
-#define ONIGENC_MBC_TO_NORMALIZE(enc,flag,pp,end,buf) \
- (enc)->mbc_to_normalize(flag,(const OnigUChar** )pp,end,buf)
-#define ONIGENC_IS_MBC_AMBIGUOUS(enc,flag,pp,end) \
- (enc)->is_mbc_ambiguous(flag,(const OnigUChar** )pp,end)
-#define ONIGENC_SUPPORT_AMBIG_FLAG(enc) ((enc)->support_ambig_flag)
+#define ONIGENC_MBC_CASE_FOLD(enc,flag,pp,end,buf) \
+ (enc)->mbc_case_fold(flag,(const OnigUChar** )pp,end,buf)
#define ONIGENC_IS_ALLOWED_REVERSE_MATCH(enc,s,end) \
(enc)->is_allowed_reverse_match(s,end)
#define ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc,start,s) \
(enc)->left_adjust_char_head(start, s)
-#define ONIGENC_GET_ALL_PAIR_AMBIG_CODES(enc,ambig_flag,acs) \
- (enc)->get_all_pair_ambig_codes(ambig_flag,acs)
-#define ONIGENC_GET_ALL_COMP_AMBIG_CODES(enc,ambig_flag,acs) \
- (enc)->get_all_comp_ambig_codes(ambig_flag,acs)
+#define ONIGENC_APPLY_ALL_CASE_FOLD(enc,case_fold_flag,f,arg) \
+ (enc)->apply_all_case_fold(case_fold_flag,f,arg)
+#define ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc,case_fold_flag,p,end,acs) \
+ (enc)->get_case_fold_codes_by_str(case_fold_flag,p,end,acs)
#define ONIGENC_STEP_BACK(enc,start,s,n) \
onigenc_step_back((enc),(start),(s),(n))
@@ -378,6 +293,8 @@ int onigenc_is_allowed_reverse_match P_((OnigEncoding enc, const OnigUChar* s, c
#define ONIGENC_MBC_TO_CODE(enc,p,end) (enc)->mbc_to_code((p),(end))
#define ONIGENC_CODE_TO_MBCLEN(enc,code) (enc)->code_to_mbclen(code)
#define ONIGENC_CODE_TO_MBC(enc,code,buf) (enc)->code_to_mbc(code,buf)
+#define ONIGENC_PROPERTY_NAME_TO_CTYPE(enc,p,end) \
+ (enc)->property_name_to_ctype(enc,p,end)
#define ONIGENC_IS_CODE_CTYPE(enc,code,ctype) (enc)->is_code_ctype(code,ctype)
@@ -410,14 +327,12 @@ int onigenc_is_allowed_reverse_match P_((OnigEncoding enc, const OnigUChar* s, c
#define ONIGENC_IS_CODE_WORD(enc,code) \
ONIGENC_IS_CODE_CTYPE(enc,code,ONIGENC_CTYPE_WORD)
-#define ONIGENC_GET_CTYPE_CODE_RANGE(enc,ctype,sbr,mbr) \
- (enc)->get_ctype_code_range(ctype,sbr,mbr)
+#define ONIGENC_GET_CTYPE_CODE_RANGE(enc,ctype,sbout,ranges) \
+ (enc)->get_ctype_code_range(ctype,sbout,ranges)
ONIG_EXTERN
OnigUChar* onigenc_step_back P_((OnigEncoding enc, const OnigUChar* start, const OnigUChar* s, int n));
-#endif /* is not ONIG_RUBY_M17N */
-
/* encoding API */
ONIG_EXTERN
@@ -482,10 +397,11 @@ typedef unsigned int OnigOptionType;
/* syntax */
typedef struct {
- unsigned int op;
- unsigned int op2;
- unsigned int behavior;
- OnigOptionType options; /* default option */
+ unsigned int op;
+ unsigned int op2;
+ unsigned int behavior;
+ OnigOptionType options; /* default option */
+ OnigMetaCharTableType meta_char_table;
} OnigSyntaxType;
ONIG_EXTERN OnigSyntaxType OnigSyntaxASIS;
@@ -566,7 +482,7 @@ ONIG_EXTERN OnigSyntaxType* OnigDefaultSyntax;
#define ONIG_SYN_OP2_ESC_GNU_BUF_ANCHOR (1U<<15) /* \`, \' */
#define ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY (1U<<16) /* \p{...}, \P{...} */
#define ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT (1U<<17) /* \p{^..}, \P{^..} */
-#define ONIG_SYN_OP2_CHAR_PROPERTY_PREFIX_IS (1U<<18) /* \p{IsXDigit} */
+/* #define ONIG_SYN_OP2_CHAR_PROPERTY_PREFIX_IS (1U<<18) */
#define ONIG_SYN_OP2_ESC_H_XDIGIT (1U<<19) /* \h, \H */
#define ONIG_SYN_OP2_INEFFECTIVE_ESCAPE (1U<<20) /* \ */
@@ -666,6 +582,7 @@ ONIG_EXTERN OnigSyntaxType* OnigDefaultSyntax;
#define ONIGERR_NEVER_ENDING_RECURSION -221
#define ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY -222
#define ONIGERR_INVALID_CHAR_PROPERTY_NAME -223
+#define ONIGERR_INVALID_CODE_POINT_VALUE -400
#define ONIGERR_INVALID_WIDE_CHAR_VALUE -400
#define ONIGERR_TOO_BIG_WIDE_CHAR_VALUE -401
#define ONIGERR_NOT_SUPPORTED_ENCODING_COMBINATION -402
@@ -755,10 +672,10 @@ typedef struct re_pattern_buffer {
int repeat_range_alloc;
OnigRepeatRange* repeat_range;
- OnigEncoding enc;
+ OnigEncoding enc;
OnigOptionType options;
OnigSyntaxType* syntax;
- OnigAmbigType ambig_flag;
+ OnigCaseFoldType case_fold_flag;
void* name_table;
/* optimization info (string search, char-map and anchors) */
@@ -793,7 +710,7 @@ typedef struct {
OnigEncoding target_enc;
OnigSyntaxType* syntax;
OnigOptionType option;
- OnigAmbigType ambig_flag;
+ OnigCaseFoldType case_fold_flag;
} OnigCompileInfo;
/* Oniguruma Native API */
@@ -808,10 +725,15 @@ void onig_set_verb_warn_func P_((OnigWarnFunc f));
ONIG_EXTERN
int onig_new P_((OnigRegex*, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigOptionType option, OnigEncoding enc, OnigSyntaxType* syntax, OnigErrorInfo* einfo));
ONIG_EXTERN
+int onig_reg_init P_((regex_t* reg, OnigOptionType option, OnigCaseFoldType case_fold_flag, OnigEncoding enc, OnigSyntaxType* syntax));
+int onig_new_without_alloc P_((OnigRegex, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigOptionType option, OnigEncoding enc, OnigSyntaxType* syntax, OnigErrorInfo* einfo));
+ONIG_EXTERN
int onig_new_deluxe P_((OnigRegex* reg, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigCompileInfo* ci, OnigErrorInfo* einfo));
ONIG_EXTERN
void onig_free P_((OnigRegex));
ONIG_EXTERN
+void onig_free_body P_((OnigRegex));
+ONIG_EXTERN
int onig_recompile P_((OnigRegex, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigOptionType option, OnigEncoding enc, OnigSyntaxType* syntax, OnigErrorInfo* einfo));
ONIG_EXTERN
int onig_recompile_deluxe P_((OnigRegex reg, const OnigUChar* pattern, const OnigUChar* pattern_end, OnigCompileInfo* ci, OnigErrorInfo* einfo));
@@ -856,7 +778,7 @@ OnigEncoding onig_get_encoding P_((OnigRegex reg));
ONIG_EXTERN
OnigOptionType onig_get_options P_((OnigRegex reg));
ONIG_EXTERN
-OnigAmbigType onig_get_ambig_flag P_((OnigRegex reg));
+OnigCaseFoldType onig_get_case_fold_flag P_((OnigRegex reg));
ONIG_EXTERN
OnigSyntaxType* onig_get_syntax P_((OnigRegex reg));
ONIG_EXTERN
@@ -880,13 +802,13 @@ void onig_set_syntax_behavior P_((OnigSyntaxType* syntax, unsigned int behavior)
ONIG_EXTERN
void onig_set_syntax_options P_((OnigSyntaxType* syntax, OnigOptionType options));
ONIG_EXTERN
-int onig_set_meta_char P_((OnigEncoding enc, unsigned int what, OnigCodePoint code));
+int onig_set_meta_char P_((OnigSyntaxType* syntax, unsigned int what, OnigCodePoint code));
ONIG_EXTERN
void onig_copy_encoding P_((OnigEncoding to, OnigEncoding from));
ONIG_EXTERN
-OnigAmbigType onig_get_default_ambig_flag P_((void));
+OnigCaseFoldType onig_get_default_case_fold_flag P_((void));
ONIG_EXTERN
-int onig_set_default_ambig_flag P_((OnigAmbigType ambig_flag));
+int onig_set_default_case_fold_flag P_((OnigCaseFoldType case_fold_flag));
ONIG_EXTERN
unsigned int onig_get_match_stack_limit_size P_((void));
ONIG_EXTERN
diff --git a/ext/mbstring/oniguruma/regcomp.c b/ext/mbstring/oniguruma/regcomp.c
index 6a0976dee2..f9d99563b3 100644
--- a/ext/mbstring/oniguruma/regcomp.c
+++ b/ext/mbstring/oniguruma/regcomp.c
@@ -2,7 +2,7 @@
regcomp.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2007 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2008 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -29,26 +29,28 @@
#include "regparse.h"
-OnigAmbigType OnigDefaultAmbigFlag =
- (ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE |
- ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE);
+OnigCaseFoldType OnigDefaultCaseFoldFlag = ONIGENC_CASE_FOLD_MIN;
-extern OnigAmbigType
-onig_get_default_ambig_flag(void)
+extern OnigCaseFoldType
+onig_get_default_case_fold_flag(void)
{
- return OnigDefaultAmbigFlag;
+ return OnigDefaultCaseFoldFlag;
}
extern int
-onig_set_default_ambig_flag(OnigAmbigType ambig_flag)
+onig_set_default_case_fold_flag(OnigCaseFoldType case_fold_flag)
{
- OnigDefaultAmbigFlag = ambig_flag;
+ OnigDefaultCaseFoldFlag = case_fold_flag;
return 0;
}
+#ifndef PLATFORM_UNALIGNED_WORD_ACCESS
+static unsigned char PadBuf[WORD_ALIGNMENT_SIZE];
+#endif
+
static UChar*
-k_strdup(UChar* s, UChar* end)
+str_dup(UChar* s, UChar* end)
{
int len = end - s;
@@ -62,15 +64,29 @@ k_strdup(UChar* s, UChar* end)
else return NULL;
}
-/*
- Caution: node should not be a string node.
- (s and end member address break)
-*/
static void
swap_node(Node* a, Node* b)
{
Node c;
c = *a; *a = *b; *b = c;
+
+ if (NTYPE(a) == NT_STR) {
+ StrNode* sn = NSTR(a);
+ if (sn->capa == 0) {
+ int len = sn->end - sn->s;
+ sn->s = sn->buf;
+ sn->end = sn->s + len;
+ }
+ }
+
+ if (NTYPE(b) == NT_STR) {
+ StrNode* sn = NSTR(b);
+ if (sn->capa == 0) {
+ int len = sn->end - sn->s;
+ sn->s = sn->buf;
+ sn->end = sn->s + len;
+ }
+ }
}
static OnigDistance
@@ -99,7 +115,7 @@ static int
bitset_is_empty(BitSetRef bs)
{
int i;
- for (i = 0; i < BITSET_SIZE; i++) {
+ for (i = 0; i < (int )BITSET_SIZE; i++) {
if (bs[i] != 0) return 0;
}
return 1;
@@ -122,8 +138,14 @@ bitset_on_num(BitSetRef bs)
extern int
onig_bbuf_init(BBuf* buf, int size)
{
- buf->p = (UChar* )xmalloc(size);
- if (IS_NULL(buf->p)) return(ONIGERR_MEMORY);
+ if (size <= 0) {
+ size = 0;
+ buf->p = NULL;
+ }
+ else {
+ buf->p = (UChar* )xmalloc(size);
+ if (IS_NULL(buf->p)) return(ONIGERR_MEMORY);
+ }
buf->alloc = size;
buf->used = 0;
@@ -139,7 +161,7 @@ unset_addr_list_init(UnsetAddrList* uslist, int size)
UnsetAddr* p;
p = (UnsetAddr* )xmalloc(sizeof(UnsetAddr)* size);
- CHECK_NULL_RETURN_VAL(p, ONIGERR_MEMORY);
+ CHECK_NULL_RETURN_MEMERR(p);
uslist->num = 0;
uslist->alloc = size;
uslist->us = p;
@@ -162,7 +184,7 @@ unset_addr_list_add(UnsetAddrList* uslist, int offset, struct _Node* node)
if (uslist->num >= uslist->alloc) {
size = uslist->alloc * 2;
p = (UnsetAddr* )xrealloc(uslist->us, sizeof(UnsetAddr) * size);
- CHECK_NULL_RETURN_VAL(p, ONIGERR_MEMORY);
+ CHECK_NULL_RETURN_MEMERR(p);
uslist->alloc = size;
uslist->us = p;
}
@@ -394,8 +416,8 @@ compile_tree_n_times(Node* node, int n, regex_t* reg)
}
static int
-add_compile_string_length(UChar* s, int mb_len, int str_len,
- regex_t* reg, int ignore_case)
+add_compile_string_length(UChar* s ARG_UNUSED, int mb_len, int str_len,
+ regex_t* reg ARG_UNUSED, int ignore_case)
{
int len;
int op = select_str_opcode(mb_len, str_len, ignore_case);
@@ -440,20 +462,20 @@ compile_length_string_node(Node* node, regex_t* reg)
UChar *p, *prev;
StrNode* sn;
- sn = &(NSTRING(node));
+ sn = NSTR(node);
if (sn->end <= sn->s)
return 0;
ambig = NSTRING_IS_AMBIG(node);
p = prev = sn->s;
- prev_len = enc_len(enc, p);
+ prev_len = enclen(enc, p);
p += prev_len;
slen = 1;
rlen = 0;
for (; p < sn->end; ) {
- len = enc_len(enc, p);
+ len = enclen(enc, p);
if (len == prev_len) {
slen++;
}
@@ -488,7 +510,7 @@ compile_string_node(Node* node, regex_t* reg)
UChar *p, *prev, *end;
StrNode* sn;
- sn = &(NSTRING(node));
+ sn = NSTR(node);
if (sn->end <= sn->s)
return 0;
@@ -496,12 +518,12 @@ compile_string_node(Node* node, regex_t* reg)
ambig = NSTRING_IS_AMBIG(node);
p = prev = sn->s;
- prev_len = enc_len(enc, p);
+ prev_len = enclen(enc, p);
p += prev_len;
slen = 1;
for (; p < end; ) {
- len = enc_len(enc, p);
+ len = enclen(enc, p);
if (len == prev_len) {
slen++;
}
@@ -535,8 +557,6 @@ add_multi_byte_cclass(BBuf* mbuf, regex_t* reg)
add_length(reg, mbuf->used);
return add_bytes(reg, mbuf->p, mbuf->used);
#else
- static unsigned char PadBuf[WORD_ALIGNMENT_SIZE];
-
int r, pad_size;
UChar* p = BBUF_GET_ADD_ADDRESS(reg) + SIZE_LENGTH;
@@ -558,7 +578,7 @@ compile_length_cclass_node(CClassNode* cc, regex_t* reg)
{
int len;
- if (IS_CCLASS_SHARE(cc)) {
+ if (IS_NCCLASS_SHARE(cc)) {
len = SIZE_OPCODE + SIZE_POINTER;
return len;
}
@@ -588,14 +608,14 @@ compile_cclass_node(CClassNode* cc, regex_t* reg)
{
int r;
- if (IS_CCLASS_SHARE(cc)) {
+ if (IS_NCCLASS_SHARE(cc)) {
add_opcode(reg, OP_CCLASS_NODE);
r = add_pointer(reg, cc);
return r;
}
if (IS_NULL(cc->mbuf)) {
- if (IS_CCLASS_NOT(cc))
+ if (IS_NCCLASS_NOT(cc))
add_opcode(reg, OP_CCLASS_NOT);
else
add_opcode(reg, OP_CCLASS);
@@ -604,7 +624,7 @@ compile_cclass_node(CClassNode* cc, regex_t* reg)
}
else {
if (ONIGENC_MBC_MINLEN(reg->enc) > 1 || bitset_is_empty(cc->bs)) {
- if (IS_CCLASS_NOT(cc))
+ if (IS_NCCLASS_NOT(cc))
add_opcode(reg, OP_CCLASS_MB_NOT);
else
add_opcode(reg, OP_CCLASS_MB);
@@ -612,7 +632,7 @@ compile_cclass_node(CClassNode* cc, regex_t* reg)
r = add_multi_byte_cclass(cc->mbuf, reg);
}
else {
- if (IS_CCLASS_NOT(cc))
+ if (IS_NCCLASS_NOT(cc))
add_opcode(reg, OP_CCLASS_MIX_NOT);
else
add_opcode(reg, OP_CCLASS_MIX);
@@ -635,7 +655,7 @@ entry_repeat_range(regex_t* reg, int id, int lower, int upper)
if (reg->repeat_range_alloc == 0) {
p = (OnigRepeatRange* )xmalloc(sizeof(OnigRepeatRange) * REPEAT_RANGE_ALLOC);
- CHECK_NULL_RETURN_VAL(p, ONIGERR_MEMORY);
+ CHECK_NULL_RETURN_MEMERR(p);
reg->repeat_range = p;
reg->repeat_range_alloc = REPEAT_RANGE_ALLOC;
}
@@ -644,7 +664,7 @@ entry_repeat_range(regex_t* reg, int id, int lower, int upper)
n = reg->repeat_range_alloc + REPEAT_RANGE_ALLOC;
p = (OnigRepeatRange* )xrealloc(reg->repeat_range,
sizeof(OnigRepeatRange) * n);
- CHECK_NULL_RETURN_VAL(p, ONIGERR_MEMORY);
+ CHECK_NULL_RETURN_MEMERR(p);
reg->repeat_range = p;
reg->repeat_range_alloc = n;
}
@@ -658,7 +678,7 @@ entry_repeat_range(regex_t* reg, int id, int lower, int upper)
}
static int
-compile_range_repeat_node(QuantifierNode* qn, int target_len, int empty_info,
+compile_range_repeat_node(QtfrNode* qn, int target_len, int empty_info,
regex_t* reg)
{
int r;
@@ -694,10 +714,10 @@ compile_range_repeat_node(QuantifierNode* qn, int target_len, int empty_info,
}
static int
-is_anychar_star_quantifier(QuantifierNode* qn)
+is_anychar_star_quantifier(QtfrNode* qn)
{
if (qn->greedy && IS_REPEAT_INFINITE(qn->upper) &&
- NTYPE(qn->target) == N_ANYCHAR)
+ NTYPE(qn->target) == NT_CANY)
return 1;
else
return 0;
@@ -709,7 +729,7 @@ is_anychar_star_quantifier(QuantifierNode* qn)
#ifdef USE_COMBINATION_EXPLOSION_CHECK
static int
-compile_length_quantifier_node(QuantifierNode* qn, regex_t* reg)
+compile_length_quantifier_node(QtfrNode* qn, regex_t* reg)
{
int len, mod_tlen, cklen;
int ckn;
@@ -724,7 +744,7 @@ compile_length_quantifier_node(QuantifierNode* qn, regex_t* reg)
cklen = (CKN_ON ? SIZE_STATE_CHECK_NUM: 0);
/* anychar repeat */
- if (NTYPE(qn->target) == N_ANYCHAR) {
+ if (NTYPE(qn->target) == NT_CANY) {
if (qn->greedy && infinite) {
if (IS_NOT_NULL(qn->next_head_exact) && !CKN_ON)
return SIZE_OP_ANYCHAR_STAR_PEEK_NEXT + tlen * qn->lower + cklen;
@@ -789,7 +809,7 @@ compile_length_quantifier_node(QuantifierNode* qn, regex_t* reg)
}
static int
-compile_quantifier_node(QuantifierNode* qn, regex_t* reg)
+compile_quantifier_node(QtfrNode* qn, regex_t* reg)
{
int r, mod_tlen;
int ckn;
@@ -815,7 +835,7 @@ compile_quantifier_node(QuantifierNode* qn, regex_t* reg)
if (r) return r;
}
- return add_bytes(reg, NSTRING(qn->next_head_exact).s, 1);
+ return add_bytes(reg, NSTR(qn->next_head_exact)->s, 1);
}
else {
if (IS_MULTILINE(reg->options)) {
@@ -943,7 +963,7 @@ compile_quantifier_node(QuantifierNode* qn, regex_t* reg)
#else /* USE_COMBINATION_EXPLOSION_CHECK */
static int
-compile_length_quantifier_node(QuantifierNode* qn, regex_t* reg)
+compile_length_quantifier_node(QtfrNode* qn, regex_t* reg)
{
int len, mod_tlen;
int infinite = IS_REPEAT_INFINITE(qn->upper);
@@ -953,7 +973,7 @@ compile_length_quantifier_node(QuantifierNode* qn, regex_t* reg)
if (tlen < 0) return tlen;
/* anychar repeat */
- if (NTYPE(qn->target) == N_ANYCHAR) {
+ if (NTYPE(qn->target) == NT_CANY) {
if (qn->greedy && infinite) {
if (IS_NOT_NULL(qn->next_head_exact))
return SIZE_OP_ANYCHAR_STAR_PEEK_NEXT + tlen * qn->lower;
@@ -1008,7 +1028,7 @@ compile_length_quantifier_node(QuantifierNode* qn, regex_t* reg)
}
static int
-compile_quantifier_node(QuantifierNode* qn, regex_t* reg)
+compile_quantifier_node(QtfrNode* qn, regex_t* reg)
{
int i, r, mod_tlen;
int infinite = IS_REPEAT_INFINITE(qn->upper);
@@ -1026,7 +1046,7 @@ compile_quantifier_node(QuantifierNode* qn, regex_t* reg)
else
r = add_opcode(reg, OP_ANYCHAR_STAR_PEEK_NEXT);
if (r) return r;
- return add_bytes(reg, NSTRING(qn->next_head_exact).s, 1);
+ return add_bytes(reg, NSTR(qn->next_head_exact)->s, 1);
}
else {
if (IS_MULTILINE(reg->options))
@@ -1067,7 +1087,7 @@ compile_quantifier_node(QuantifierNode* qn, regex_t* reg)
r = add_opcode_rel_addr(reg, OP_PUSH_OR_JUMP_EXACT1,
mod_tlen + SIZE_OP_JUMP);
if (r) return r;
- add_bytes(reg, NSTRING(qn->head_exact).s, 1);
+ add_bytes(reg, NSTR(qn->head_exact)->s, 1);
r = compile_tree_empty_check(qn->target, reg, empty_info);
if (r) return r;
r = add_opcode_rel_addr(reg, OP_JUMP,
@@ -1077,7 +1097,7 @@ compile_quantifier_node(QuantifierNode* qn, regex_t* reg)
r = add_opcode_rel_addr(reg, OP_PUSH_IF_PEEK_NEXT,
mod_tlen + SIZE_OP_JUMP);
if (r) return r;
- add_bytes(reg, NSTRING(qn->next_head_exact).s, 1);
+ add_bytes(reg, NSTR(qn->next_head_exact)->s, 1);
r = compile_tree_empty_check(qn->target, reg, empty_info);
if (r) return r;
r = add_opcode_rel_addr(reg, OP_JUMP,
@@ -1136,7 +1156,7 @@ compile_quantifier_node(QuantifierNode* qn, regex_t* reg)
#endif /* USE_COMBINATION_EXPLOSION_CHECK */
static int
-compile_length_option_node(EffectNode* node, regex_t* reg)
+compile_length_option_node(EncloseNode* node, regex_t* reg)
{
int tlen;
OnigOptionType prev = reg->options;
@@ -1156,7 +1176,7 @@ compile_length_option_node(EffectNode* node, regex_t* reg)
}
static int
-compile_option_node(EffectNode* node, regex_t* reg)
+compile_option_node(EncloseNode* node, regex_t* reg)
{
int r;
OnigOptionType prev = reg->options;
@@ -1182,12 +1202,12 @@ compile_option_node(EffectNode* node, regex_t* reg)
}
static int
-compile_length_effect_node(EffectNode* node, regex_t* reg)
+compile_length_enclose_node(EncloseNode* node, regex_t* reg)
{
int len;
int tlen;
- if (node->type == EFFECT_OPTION)
+ if (node->type == ENCLOSE_OPTION)
return compile_length_option_node(node, reg);
if (node->target) {
@@ -1198,16 +1218,16 @@ compile_length_effect_node(EffectNode* node, regex_t* reg)
tlen = 0;
switch (node->type) {
- case EFFECT_MEMORY:
+ case ENCLOSE_MEMORY:
#ifdef USE_SUBEXP_CALL
- if (IS_EFFECT_CALLED(node)) {
+ if (IS_ENCLOSE_CALLED(node)) {
len = SIZE_OP_MEMORY_START_PUSH + tlen
+ SIZE_OP_CALL + SIZE_OP_JUMP + SIZE_OP_RETURN;
if (BIT_STATUS_AT(reg->bt_mem_end, node->regnum))
- len += (IS_EFFECT_RECURSION(node)
+ len += (IS_ENCLOSE_RECURSION(node)
? SIZE_OP_MEMORY_END_PUSH_REC : SIZE_OP_MEMORY_END_PUSH);
else
- len += (IS_EFFECT_RECURSION(node)
+ len += (IS_ENCLOSE_RECURSION(node)
? SIZE_OP_MEMORY_END_REC : SIZE_OP_MEMORY_END);
}
else
@@ -1223,9 +1243,9 @@ compile_length_effect_node(EffectNode* node, regex_t* reg)
}
break;
- case EFFECT_STOP_BACKTRACK:
- if (IS_EFFECT_STOP_BT_SIMPLE_REPEAT(node)) {
- QuantifierNode* qn = &NQUANTIFIER(node->target);
+ case ENCLOSE_STOP_BACKTRACK:
+ if (IS_ENCLOSE_STOP_BT_SIMPLE_REPEAT(node)) {
+ QtfrNode* qn = NQTFR(node->target);
tlen = compile_length_tree(qn->target, reg);
if (tlen < 0) return tlen;
@@ -1248,17 +1268,17 @@ compile_length_effect_node(EffectNode* node, regex_t* reg)
static int get_char_length_tree(Node* node, regex_t* reg, int* len);
static int
-compile_effect_node(EffectNode* node, regex_t* reg)
+compile_enclose_node(EncloseNode* node, regex_t* reg)
{
int r, len;
- if (node->type == EFFECT_OPTION)
+ if (node->type == ENCLOSE_OPTION)
return compile_option_node(node, reg);
switch (node->type) {
- case EFFECT_MEMORY:
+ case ENCLOSE_MEMORY:
#ifdef USE_SUBEXP_CALL
- if (IS_EFFECT_CALLED(node)) {
+ if (IS_ENCLOSE_CALLED(node)) {
r = add_opcode(reg, OP_CALL);
if (r) return r;
node->call_addr = BBUF_GET_OFFSET_POS(reg) + SIZE_ABSADDR + SIZE_OP_JUMP;
@@ -1268,10 +1288,10 @@ compile_effect_node(EffectNode* node, regex_t* reg)
len = compile_length_tree(node->target, reg);
len += (SIZE_OP_MEMORY_START_PUSH + SIZE_OP_RETURN);
if (BIT_STATUS_AT(reg->bt_mem_end, node->regnum))
- len += (IS_EFFECT_RECURSION(node)
+ len += (IS_ENCLOSE_RECURSION(node)
? SIZE_OP_MEMORY_END_PUSH_REC : SIZE_OP_MEMORY_END_PUSH);
else
- len += (IS_EFFECT_RECURSION(node)
+ len += (IS_ENCLOSE_RECURSION(node)
? SIZE_OP_MEMORY_END_REC : SIZE_OP_MEMORY_END);
r = add_opcode_rel_addr(reg, OP_JUMP, len);
@@ -1288,12 +1308,12 @@ compile_effect_node(EffectNode* node, regex_t* reg)
r = compile_tree(node->target, reg);
if (r) return r;
#ifdef USE_SUBEXP_CALL
- if (IS_EFFECT_CALLED(node)) {
+ if (IS_ENCLOSE_CALLED(node)) {
if (BIT_STATUS_AT(reg->bt_mem_end, node->regnum))
- r = add_opcode(reg, (IS_EFFECT_RECURSION(node)
+ r = add_opcode(reg, (IS_ENCLOSE_RECURSION(node)
? OP_MEMORY_END_PUSH_REC : OP_MEMORY_END_PUSH));
else
- r = add_opcode(reg, (IS_EFFECT_RECURSION(node)
+ r = add_opcode(reg, (IS_ENCLOSE_RECURSION(node)
? OP_MEMORY_END_REC : OP_MEMORY_END));
if (r) return r;
@@ -1313,9 +1333,9 @@ compile_effect_node(EffectNode* node, regex_t* reg)
}
break;
- case EFFECT_STOP_BACKTRACK:
- if (IS_EFFECT_STOP_BT_SIMPLE_REPEAT(node)) {
- QuantifierNode* qn = &NQUANTIFIER(node->target);
+ case ENCLOSE_STOP_BACKTRACK:
+ if (IS_ENCLOSE_STOP_BT_SIMPLE_REPEAT(node)) {
+ QtfrNode* qn = NQTFR(node->target);
r = compile_tree_n_times(qn->target, qn->lower, reg);
if (r) return r;
@@ -1472,50 +1492,50 @@ compile_length_tree(Node* node, regex_t* reg)
type = NTYPE(node);
switch (type) {
- case N_LIST:
+ case NT_LIST:
len = 0;
do {
- r = compile_length_tree(NCONS(node).left, reg);
+ r = compile_length_tree(NCAR(node), reg);
if (r < 0) return r;
len += r;
- } while (IS_NOT_NULL(node = NCONS(node).right));
+ } while (IS_NOT_NULL(node = NCDR(node)));
r = len;
break;
- case N_ALT:
+ case NT_ALT:
{
int n;
n = r = 0;
do {
- r += compile_length_tree(NCONS(node).left, reg);
+ r += compile_length_tree(NCAR(node), reg);
n++;
- } while (IS_NOT_NULL(node = NCONS(node).right));
+ } while (IS_NOT_NULL(node = NCDR(node)));
r += (SIZE_OP_PUSH + SIZE_OP_JUMP) * (n - 1);
}
break;
- case N_STRING:
+ case NT_STR:
if (NSTRING_IS_RAW(node))
- r = compile_length_string_raw_node(&(NSTRING(node)), reg);
+ r = compile_length_string_raw_node(NSTR(node), reg);
else
r = compile_length_string_node(node, reg);
break;
- case N_CCLASS:
- r = compile_length_cclass_node(&(NCCLASS(node)), reg);
+ case NT_CCLASS:
+ r = compile_length_cclass_node(NCCLASS(node), reg);
break;
- case N_CTYPE:
- case N_ANYCHAR:
+ case NT_CTYPE:
+ case NT_CANY:
r = SIZE_OPCODE;
break;
- case N_BACKREF:
+ case NT_BREF:
{
- BackrefNode* br = &(NBACKREF(node));
+ BRefNode* br = NBREF(node);
-#ifdef USE_BACKREF_AT_LEVEL
+#ifdef USE_BACKREF_WITH_LEVEL
if (IS_BACKREF_NEST_LEVEL(br)) {
r = SIZE_OPCODE + SIZE_OPTION + SIZE_LENGTH +
SIZE_LENGTH + (SIZE_MEMNUM * br->back_num);
@@ -1533,21 +1553,21 @@ compile_length_tree(Node* node, regex_t* reg)
break;
#ifdef USE_SUBEXP_CALL
- case N_CALL:
+ case NT_CALL:
r = SIZE_OP_CALL;
break;
#endif
- case N_QUANTIFIER:
- r = compile_length_quantifier_node(&(NQUANTIFIER(node)), reg);
+ case NT_QTFR:
+ r = compile_length_quantifier_node(NQTFR(node), reg);
break;
- case N_EFFECT:
- r = compile_length_effect_node(&NEFFECT(node), reg);
+ case NT_ENCLOSE:
+ r = compile_length_enclose_node(NENCLOSE(node), reg);
break;
- case N_ANCHOR:
- r = compile_length_anchor_node(&(NANCHOR(node)), reg);
+ case NT_ANCHOR:
+ r = compile_length_anchor_node(NANCHOR(node), reg);
break;
default:
@@ -1565,59 +1585,61 @@ compile_tree(Node* node, regex_t* reg)
type = NTYPE(node);
switch (type) {
- case N_LIST:
+ case NT_LIST:
do {
- r = compile_tree(NCONS(node).left, reg);
- } while (r == 0 && IS_NOT_NULL(node = NCONS(node).right));
+ r = compile_tree(NCAR(node), reg);
+ } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
break;
- case N_ALT:
+ case NT_ALT:
{
Node* x = node;
len = 0;
do {
- len += compile_length_tree(NCONS(x).left, reg);
- if (NCONS(x).right != NULL) {
+ len += compile_length_tree(NCAR(x), reg);
+ if (NCDR(x) != NULL) {
len += SIZE_OP_PUSH + SIZE_OP_JUMP;
}
- } while (IS_NOT_NULL(x = NCONS(x).right));
+ } while (IS_NOT_NULL(x = NCDR(x)));
pos = reg->used + len; /* goal position */
do {
- len = compile_length_tree(NCONS(node).left, reg);
- if (IS_NOT_NULL(NCONS(node).right)) {
+ len = compile_length_tree(NCAR(node), reg);
+ if (IS_NOT_NULL(NCDR(node))) {
r = add_opcode_rel_addr(reg, OP_PUSH, len + SIZE_OP_JUMP);
if (r) break;
}
- r = compile_tree(NCONS(node).left, reg);
+ r = compile_tree(NCAR(node), reg);
if (r) break;
- if (IS_NOT_NULL(NCONS(node).right)) {
+ if (IS_NOT_NULL(NCDR(node))) {
len = pos - (reg->used + SIZE_OP_JUMP);
r = add_opcode_rel_addr(reg, OP_JUMP, len);
if (r) break;
}
- } while (IS_NOT_NULL(node = NCONS(node).right));
+ } while (IS_NOT_NULL(node = NCDR(node)));
}
break;
- case N_STRING:
+ case NT_STR:
if (NSTRING_IS_RAW(node))
- r = compile_string_raw_node(&(NSTRING(node)), reg);
+ r = compile_string_raw_node(NSTR(node), reg);
else
r = compile_string_node(node, reg);
break;
- case N_CCLASS:
- r = compile_cclass_node(&(NCCLASS(node)), reg);
+ case NT_CCLASS:
+ r = compile_cclass_node(NCCLASS(node), reg);
break;
- case N_CTYPE:
+ case NT_CTYPE:
{
int op;
- switch (NCTYPE(node).type) {
- case CTYPE_WORD: op = OP_WORD; break;
- case CTYPE_NOT_WORD: op = OP_NOT_WORD; break;
+ switch (NCTYPE(node)->ctype) {
+ case ONIGENC_CTYPE_WORD:
+ if (NCTYPE(node)->not != 0) op = OP_NOT_WORD;
+ else op = OP_WORD;
+ break;
default:
return ONIGERR_TYPE_BUG;
break;
@@ -1626,20 +1648,20 @@ compile_tree(Node* node, regex_t* reg)
}
break;
- case N_ANYCHAR:
+ case NT_CANY:
if (IS_MULTILINE(reg->options))
r = add_opcode(reg, OP_ANYCHAR_ML);
else
r = add_opcode(reg, OP_ANYCHAR);
break;
- case N_BACKREF:
+ case NT_BREF:
{
- BackrefNode* br = &(NBACKREF(node));
+ BRefNode* br = NBREF(node);
-#ifdef USE_BACKREF_AT_LEVEL
+#ifdef USE_BACKREF_WITH_LEVEL
if (IS_BACKREF_NEST_LEVEL(br)) {
- r = add_opcode(reg, OP_BACKREF_AT_LEVEL);
+ r = add_opcode(reg, OP_BACKREF_WITH_LEVEL);
if (r) return r;
r = add_option(reg, (reg->options & ONIG_OPTION_IGNORECASE));
if (r) return r;
@@ -1681,7 +1703,7 @@ compile_tree(Node* node, regex_t* reg)
}
if (r) return r;
-#ifdef USE_BACKREF_AT_LEVEL
+#ifdef USE_BACKREF_WITH_LEVEL
add_bacref_mems:
#endif
r = add_length(reg, br->back_num);
@@ -1696,21 +1718,21 @@ compile_tree(Node* node, regex_t* reg)
break;
#ifdef USE_SUBEXP_CALL
- case N_CALL:
- r = compile_call(&(NCALL(node)), reg);
+ case NT_CALL:
+ r = compile_call(NCALL(node), reg);
break;
#endif
- case N_QUANTIFIER:
- r = compile_quantifier_node(&(NQUANTIFIER(node)), reg);
+ case NT_QTFR:
+ r = compile_quantifier_node(NQTFR(node), reg);
break;
- case N_EFFECT:
- r = compile_effect_node(&NEFFECT(node), reg);
+ case NT_ENCLOSE:
+ r = compile_enclose_node(NENCLOSE(node), reg);
break;
- case N_ANCHOR:
- r = compile_anchor_node(&(NANCHOR(node)), reg);
+ case NT_ANCHOR:
+ r = compile_anchor_node(NANCHOR(node), reg);
break;
default:
@@ -1732,29 +1754,29 @@ noname_disable_map(Node** plink, GroupNumRemap* map, int* counter)
Node* node = *plink;
switch (NTYPE(node)) {
- case N_LIST:
- case N_ALT:
+ case NT_LIST:
+ case NT_ALT:
do {
- r = noname_disable_map(&(NCONS(node).left), map, counter);
- } while (r == 0 && IS_NOT_NULL(node = NCONS(node).right));
+ r = noname_disable_map(&(NCAR(node)), map, counter);
+ } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
break;
- case N_QUANTIFIER:
+ case NT_QTFR:
{
- Node** ptarget = &(NQUANTIFIER(node).target);
+ Node** ptarget = &(NQTFR(node)->target);
Node* old = *ptarget;
r = noname_disable_map(ptarget, map, counter);
- if (*ptarget != old && NTYPE(*ptarget) == N_QUANTIFIER) {
+ if (*ptarget != old && NTYPE(*ptarget) == NT_QTFR) {
onig_reduce_nested_quantifier(node, *ptarget);
}
}
break;
- case N_EFFECT:
+ case NT_ENCLOSE:
{
- EffectNode* en = &(NEFFECT(node));
- if (en->type == EFFECT_MEMORY) {
- if (IS_EFFECT_NAMED_GROUP(en)) {
+ EncloseNode* en = NENCLOSE(node);
+ if (en->type == ENCLOSE_MEMORY) {
+ if (IS_ENCLOSE_NAMED_GROUP(en)) {
(*counter)++;
map[en->regnum].new_val = *counter;
en->regnum = *counter;
@@ -1784,7 +1806,7 @@ renumber_node_backref(Node* node, GroupNumRemap* map)
{
int i, pos, n, old_num;
int *backs;
- BackrefNode* bn = &(NBACKREF(node));
+ BRefNode* bn = NBREF(node);
if (! IS_BACKREF_NAME_REF(bn))
return ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED;
@@ -1813,20 +1835,20 @@ renumber_by_map(Node* node, GroupNumRemap* map)
int r = 0;
switch (NTYPE(node)) {
- case N_LIST:
- case N_ALT:
+ case NT_LIST:
+ case NT_ALT:
do {
- r = renumber_by_map(NCONS(node).left, map);
- } while (r == 0 && IS_NOT_NULL(node = NCONS(node).right));
+ r = renumber_by_map(NCAR(node), map);
+ } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
break;
- case N_QUANTIFIER:
- r = renumber_by_map(NQUANTIFIER(node).target, map);
+ case NT_QTFR:
+ r = renumber_by_map(NQTFR(node)->target, map);
break;
- case N_EFFECT:
- r = renumber_by_map(NEFFECT(node).target, map);
+ case NT_ENCLOSE:
+ r = renumber_by_map(NENCLOSE(node)->target, map);
break;
- case N_BACKREF:
+ case NT_BREF:
r = renumber_node_backref(node, map);
break;
@@ -1843,21 +1865,21 @@ numbered_ref_check(Node* node)
int r = 0;
switch (NTYPE(node)) {
- case N_LIST:
- case N_ALT:
+ case NT_LIST:
+ case NT_ALT:
do {
- r = numbered_ref_check(NCONS(node).left);
- } while (r == 0 && IS_NOT_NULL(node = NCONS(node).right));
+ r = numbered_ref_check(NCAR(node));
+ } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
break;
- case N_QUANTIFIER:
- r = numbered_ref_check(NQUANTIFIER(node).target);
+ case NT_QTFR:
+ r = numbered_ref_check(NQTFR(node)->target);
break;
- case N_EFFECT:
- r = numbered_ref_check(NEFFECT(node).target);
+ case NT_ENCLOSE:
+ r = numbered_ref_check(NENCLOSE(node)->target);
break;
- case N_BACKREF:
- if (! IS_BACKREF_NAME_REF(&(NBACKREF(node))))
+ case NT_BREF:
+ if (! IS_BACKREF_NAME_REF(NBREF(node)))
return ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED;
break;
@@ -1876,7 +1898,7 @@ disable_noname_group_capture(Node** root, regex_t* reg, ScanEnv* env)
GroupNumRemap* map;
map = (GroupNumRemap* )xalloca(sizeof(GroupNumRemap) * (env->num_mem + 1));
- CHECK_NULL_RETURN_VAL(map, ONIGERR_MEMORY);
+ CHECK_NULL_RETURN_MEMERR(map);
for (i = 1; i <= env->num_mem; i++) {
map[i].new_val = 0;
}
@@ -1914,12 +1936,12 @@ static int
unset_addr_list_fix(UnsetAddrList* uslist, regex_t* reg)
{
int i, offset;
- EffectNode* en;
+ EncloseNode* en;
AbsAddrType addr;
for (i = 0; i < uslist->num; i++) {
- en = &(NEFFECT(uslist->us[i].target));
- if (! IS_EFFECT_ADDR_FIXED(en)) return ONIGERR_PARSER_BUG;
+ en = NENCLOSE(uslist->us[i].target);
+ if (! IS_ENCLOSE_ADDR_FIXED(en)) return ONIGERR_PARSER_BUG;
addr = en->call_addr;
offset = uslist->us[i].offset;
@@ -1929,53 +1951,53 @@ unset_addr_list_fix(UnsetAddrList* uslist, regex_t* reg)
}
#endif
-#ifdef USE_INFINITE_REPEAT_MONOMANIAC_MEM_STATUS_CHECK
+#ifdef USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT
static int
quantifiers_memory_node_info(Node* node)
{
int r = 0;
switch (NTYPE(node)) {
- case N_LIST:
- case N_ALT:
+ case NT_LIST:
+ case NT_ALT:
{
int v;
do {
- v = quantifiers_memory_node_info(NCONS(node).left);
+ v = quantifiers_memory_node_info(NCAR(node));
if (v > r) r = v;
- } while (v >= 0 && IS_NOT_NULL(node = NCONS(node).right));
+ } while (v >= 0 && IS_NOT_NULL(node = NCDR(node)));
}
break;
#ifdef USE_SUBEXP_CALL
- case N_CALL:
- if (IS_CALL_RECURSION(&NCALL(node))) {
+ case NT_CALL:
+ if (IS_CALL_RECURSION(NCALL(node))) {
return NQ_TARGET_IS_EMPTY_REC; /* tiny version */
}
else
- r = quantifiers_memory_node_info(NCALL(node).target);
+ r = quantifiers_memory_node_info(NCALL(node)->target);
break;
#endif
- case N_QUANTIFIER:
+ case NT_QTFR:
{
- QuantifierNode* qn = &(NQUANTIFIER(node));
+ QtfrNode* qn = NQTFR(node);
if (qn->upper != 0) {
r = quantifiers_memory_node_info(qn->target);
}
}
break;
- case N_EFFECT:
+ case NT_ENCLOSE:
{
- EffectNode* en = &(NEFFECT(node));
+ EncloseNode* en = NENCLOSE(node);
switch (en->type) {
- case EFFECT_MEMORY:
+ case ENCLOSE_MEMORY:
return NQ_TARGET_IS_EMPTY_MEM;
break;
- case EFFECT_OPTION:
- case EFFECT_STOP_BACKTRACK:
+ case ENCLOSE_OPTION:
+ case ENCLOSE_STOP_BACKTRACK:
r = quantifiers_memory_node_info(en->target);
break;
default:
@@ -1984,19 +2006,19 @@ quantifiers_memory_node_info(Node* node)
}
break;
- case N_BACKREF:
- case N_STRING:
- case N_CTYPE:
- case N_CCLASS:
- case N_ANYCHAR:
- case N_ANCHOR:
+ case NT_BREF:
+ case NT_STR:
+ case NT_CTYPE:
+ case NT_CCLASS:
+ case NT_CANY:
+ case NT_ANCHOR:
default:
break;
}
return r;
}
-#endif /* USE_INFINITE_REPEAT_MONOMANIAC_MEM_STATUS_CHECK */
+#endif /* USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT */
static int
get_min_match_length(Node* node, OnigDistance *min, ScanEnv* env)
@@ -2006,12 +2028,12 @@ get_min_match_length(Node* node, OnigDistance *min, ScanEnv* env)
*min = 0;
switch (NTYPE(node)) {
- case N_BACKREF:
+ case NT_BREF:
{
int i;
int* backs;
Node** nodes = SCANENV_MEM_NODES(env);
- BackrefNode* br = &(NBACKREF(node));
+ BRefNode* br = NBREF(node);
if (br->state & NST_RECURSION) break;
backs = BACKREFS_P(br);
@@ -2028,62 +2050,57 @@ get_min_match_length(Node* node, OnigDistance *min, ScanEnv* env)
break;
#ifdef USE_SUBEXP_CALL
- case N_CALL:
- if (IS_CALL_RECURSION(&NCALL(node))) {
- EffectNode* en = &(NEFFECT(NCALL(node).target));
- if (IS_EFFECT_MIN_FIXED(en))
+ case NT_CALL:
+ if (IS_CALL_RECURSION(NCALL(node))) {
+ EncloseNode* en = NENCLOSE(NCALL(node)->target);
+ if (IS_ENCLOSE_MIN_FIXED(en))
*min = en->min_len;
}
else
- r = get_min_match_length(NCALL(node).target, min, env);
+ r = get_min_match_length(NCALL(node)->target, min, env);
break;
#endif
- case N_LIST:
+ case NT_LIST:
do {
- r = get_min_match_length(NCONS(node).left, &tmin, env);
+ r = get_min_match_length(NCAR(node), &tmin, env);
if (r == 0) *min += tmin;
- } while (r == 0 && IS_NOT_NULL(node = NCONS(node).right));
+ } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
break;
- case N_ALT:
+ case NT_ALT:
{
Node *x, *y;
y = node;
do {
- x = NCONS(y).left;
+ x = NCAR(y);
r = get_min_match_length(x, &tmin, env);
if (r != 0) break;
if (y == node) *min = tmin;
else if (*min > tmin) *min = tmin;
- } while (r == 0 && IS_NOT_NULL(y = NCONS(y).right));
+ } while (r == 0 && IS_NOT_NULL(y = NCDR(y)));
}
break;
- case N_STRING:
+ case NT_STR:
{
- StrNode* sn = &(NSTRING(node));
+ StrNode* sn = NSTR(node);
*min = sn->end - sn->s;
}
break;
- case N_CTYPE:
- switch (NCTYPE(node).type) {
- case CTYPE_WORD: *min = 1; break;
- case CTYPE_NOT_WORD: *min = 1; break;
- default:
- break;
- }
+ case NT_CTYPE:
+ *min = 1;
break;
- case N_CCLASS:
- case N_ANYCHAR:
+ case NT_CCLASS:
+ case NT_CANY:
*min = 1;
break;
- case N_QUANTIFIER:
+ case NT_QTFR:
{
- QuantifierNode* qn = &(NQUANTIFIER(node));
+ QtfrNode* qn = NQTFR(node);
if (qn->lower > 0) {
r = get_min_match_length(qn->target, min, env);
@@ -2093,32 +2110,32 @@ get_min_match_length(Node* node, OnigDistance *min, ScanEnv* env)
}
break;
- case N_EFFECT:
+ case NT_ENCLOSE:
{
- EffectNode* en = &(NEFFECT(node));
+ EncloseNode* en = NENCLOSE(node);
switch (en->type) {
- case EFFECT_MEMORY:
+ case ENCLOSE_MEMORY:
#ifdef USE_SUBEXP_CALL
- if (IS_EFFECT_MIN_FIXED(en))
+ if (IS_ENCLOSE_MIN_FIXED(en))
*min = en->min_len;
else {
r = get_min_match_length(en->target, min, env);
if (r == 0) {
en->min_len = *min;
- SET_EFFECT_STATUS(node, NST_MIN_FIXED);
+ SET_ENCLOSE_STATUS(node, NST_MIN_FIXED);
}
}
break;
#endif
- case EFFECT_OPTION:
- case EFFECT_STOP_BACKTRACK:
+ case ENCLOSE_OPTION:
+ case ENCLOSE_STOP_BACKTRACK:
r = get_min_match_length(en->target, min, env);
break;
}
}
break;
- case N_ANCHOR:
+ case NT_ANCHOR:
default:
break;
}
@@ -2134,51 +2151,43 @@ get_max_match_length(Node* node, OnigDistance *max, ScanEnv* env)
*max = 0;
switch (NTYPE(node)) {
- case N_LIST:
+ case NT_LIST:
do {
- r = get_max_match_length(NCONS(node).left, &tmax, env);
+ r = get_max_match_length(NCAR(node), &tmax, env);
if (r == 0)
*max = distance_add(*max, tmax);
- } while (r == 0 && IS_NOT_NULL(node = NCONS(node).right));
+ } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
break;
- case N_ALT:
+ case NT_ALT:
do {
- r = get_max_match_length(NCONS(node).left, &tmax, env);
+ r = get_max_match_length(NCAR(node), &tmax, env);
if (r == 0 && *max < tmax) *max = tmax;
- } while (r == 0 && IS_NOT_NULL(node = NCONS(node).right));
+ } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
break;
- case N_STRING:
+ case NT_STR:
{
- StrNode* sn = &(NSTRING(node));
+ StrNode* sn = NSTR(node);
*max = sn->end - sn->s;
}
break;
- case N_CTYPE:
- switch (NCTYPE(node).type) {
- case CTYPE_WORD:
- case CTYPE_NOT_WORD:
- *max = ONIGENC_MBC_MAXLEN_DIST(env->enc);
- break;
-
- default:
- break;
- }
+ case NT_CTYPE:
+ *max = ONIGENC_MBC_MAXLEN_DIST(env->enc);
break;
- case N_CCLASS:
- case N_ANYCHAR:
+ case NT_CCLASS:
+ case NT_CANY:
*max = ONIGENC_MBC_MAXLEN_DIST(env->enc);
break;
- case N_BACKREF:
+ case NT_BREF:
{
int i;
int* backs;
Node** nodes = SCANENV_MEM_NODES(env);
- BackrefNode* br = &(NBACKREF(node));
+ BRefNode* br = NBREF(node);
if (br->state & NST_RECURSION) {
*max = ONIG_INFINITE_DISTANCE;
break;
@@ -2194,17 +2203,17 @@ get_max_match_length(Node* node, OnigDistance *max, ScanEnv* env)
break;
#ifdef USE_SUBEXP_CALL
- case N_CALL:
- if (! IS_CALL_RECURSION(&(NCALL(node))))
- r = get_max_match_length(NCALL(node).target, max, env);
+ case NT_CALL:
+ if (! IS_CALL_RECURSION(NCALL(node)))
+ r = get_max_match_length(NCALL(node)->target, max, env);
else
*max = ONIG_INFINITE_DISTANCE;
break;
#endif
- case N_QUANTIFIER:
+ case NT_QTFR:
{
- QuantifierNode* qn = &(NQUANTIFIER(node));
+ QtfrNode* qn = NQTFR(node);
if (qn->upper != 0) {
r = get_max_match_length(qn->target, max, env);
@@ -2218,32 +2227,32 @@ get_max_match_length(Node* node, OnigDistance *max, ScanEnv* env)
}
break;
- case N_EFFECT:
+ case NT_ENCLOSE:
{
- EffectNode* en = &(NEFFECT(node));
+ EncloseNode* en = NENCLOSE(node);
switch (en->type) {
- case EFFECT_MEMORY:
+ case ENCLOSE_MEMORY:
#ifdef USE_SUBEXP_CALL
- if (IS_EFFECT_MAX_FIXED(en))
+ if (IS_ENCLOSE_MAX_FIXED(en))
*max = en->max_len;
else {
r = get_max_match_length(en->target, max, env);
if (r == 0) {
en->max_len = *max;
- SET_EFFECT_STATUS(node, NST_MAX_FIXED);
+ SET_ENCLOSE_STATUS(node, NST_MAX_FIXED);
}
}
break;
#endif
- case EFFECT_OPTION:
- case EFFECT_STOP_BACKTRACK:
+ case ENCLOSE_OPTION:
+ case ENCLOSE_STOP_BACKTRACK:
r = get_max_match_length(en->target, max, env);
break;
}
}
break;
- case N_ANCHOR:
+ case NT_ANCHOR:
default:
break;
}
@@ -2264,22 +2273,22 @@ get_char_length_tree1(Node* node, regex_t* reg, int* len, int level)
level++;
*len = 0;
switch (NTYPE(node)) {
- case N_LIST:
+ case NT_LIST:
do {
- r = get_char_length_tree1(NCONS(node).left, reg, &tlen, level);
+ r = get_char_length_tree1(NCAR(node), reg, &tlen, level);
if (r == 0)
*len = distance_add(*len, tlen);
- } while (r == 0 && IS_NOT_NULL(node = NCONS(node).right));
+ } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
break;
- case N_ALT:
+ case NT_ALT:
{
int tlen2;
int varlen = 0;
- r = get_char_length_tree1(NCONS(node).left, reg, &tlen, level);
- while (r == 0 && IS_NOT_NULL(node = NCONS(node).right)) {
- r = get_char_length_tree1(NCONS(node).left, reg, &tlen2, level);
+ r = get_char_length_tree1(NCAR(node), reg, &tlen, level);
+ while (r == 0 && IS_NOT_NULL(node = NCDR(node))) {
+ r = get_char_length_tree1(NCAR(node), reg, &tlen2, level);
if (r == 0) {
if (tlen != tlen2)
varlen = 1;
@@ -2298,20 +2307,20 @@ get_char_length_tree1(Node* node, regex_t* reg, int* len, int level)
}
break;
- case N_STRING:
+ case NT_STR:
{
- StrNode* sn = &(NSTRING(node));
+ StrNode* sn = NSTR(node);
UChar *s = sn->s;
while (s < sn->end) {
- s += enc_len(reg->enc, s);
+ s += enclen(reg->enc, s);
(*len)++;
}
}
break;
- case N_QUANTIFIER:
+ case NT_QTFR:
{
- QuantifierNode* qn = &(NQUANTIFIER(node));
+ QtfrNode* qn = NQTFR(node);
if (qn->lower == qn->upper) {
r = get_char_length_tree1(qn->target, reg, &tlen, level);
if (r == 0)
@@ -2323,47 +2332,42 @@ get_char_length_tree1(Node* node, regex_t* reg, int* len, int level)
break;
#ifdef USE_SUBEXP_CALL
- case N_CALL:
- if (! IS_CALL_RECURSION(&(NCALL(node))))
- r = get_char_length_tree1(NCALL(node).target, reg, len, level);
+ case NT_CALL:
+ if (! IS_CALL_RECURSION(NCALL(node)))
+ r = get_char_length_tree1(NCALL(node)->target, reg, len, level);
else
r = GET_CHAR_LEN_VARLEN;
break;
#endif
- case N_CTYPE:
- switch (NCTYPE(node).type) {
- case CTYPE_WORD:
- case CTYPE_NOT_WORD:
- *len = 1;
- break;
- }
+ case NT_CTYPE:
+ *len = 1;
break;
- case N_CCLASS:
- case N_ANYCHAR:
+ case NT_CCLASS:
+ case NT_CANY:
*len = 1;
break;
- case N_EFFECT:
+ case NT_ENCLOSE:
{
- EffectNode* en = &(NEFFECT(node));
+ EncloseNode* en = NENCLOSE(node);
switch (en->type) {
- case EFFECT_MEMORY:
+ case ENCLOSE_MEMORY:
#ifdef USE_SUBEXP_CALL
- if (IS_EFFECT_CLEN_FIXED(en))
+ if (IS_ENCLOSE_CLEN_FIXED(en))
*len = en->char_len;
else {
r = get_char_length_tree1(en->target, reg, len, level);
if (r == 0) {
en->char_len = *len;
- SET_EFFECT_STATUS(node, NST_CLEN_FIXED);
+ SET_ENCLOSE_STATUS(node, NST_CLEN_FIXED);
}
}
break;
#endif
- case EFFECT_OPTION:
- case EFFECT_STOP_BACKTRACK:
+ case ENCLOSE_OPTION:
+ case ENCLOSE_STOP_BACKTRACK:
r = get_char_length_tree1(en->target, reg, len, level);
break;
default:
@@ -2372,7 +2376,7 @@ get_char_length_tree1(Node* node, regex_t* reg, int* len, int level)
}
break;
- case N_ANCHOR:
+ case NT_ANCHOR:
break;
default:
@@ -2401,29 +2405,18 @@ is_not_included(Node* x, Node* y, regex_t* reg)
retry:
ytype = NTYPE(y);
switch (NTYPE(x)) {
- case N_CTYPE:
+ case NT_CTYPE:
{
switch (ytype) {
- case N_CTYPE:
- switch (NCTYPE(x).type) {
- case CTYPE_WORD:
- if (NCTYPE(y).type == CTYPE_NOT_WORD)
- return 1;
- else
- return 0;
- break;
- case CTYPE_NOT_WORD:
- if (NCTYPE(y).type == CTYPE_WORD)
- return 1;
- else
- return 0;
- break;
- default:
- break;
- }
+ case NT_CTYPE:
+ if (NCTYPE(y)->ctype == NCTYPE(x)->ctype &&
+ NCTYPE(y)->not != NCTYPE(x)->not)
+ return 1;
+ else
+ return 0;
break;
- case N_CCLASS:
+ case NT_CCLASS:
swap:
{
Node* tmp;
@@ -2432,7 +2425,7 @@ is_not_included(Node* x, Node* y, regex_t* reg)
}
break;
- case N_STRING:
+ case NT_STR:
goto swap;
break;
@@ -2442,37 +2435,39 @@ is_not_included(Node* x, Node* y, regex_t* reg)
}
break;
- case N_CCLASS:
+ case NT_CCLASS:
{
- CClassNode* xc = &(NCCLASS(x));
+ CClassNode* xc = NCCLASS(x);
switch (ytype) {
- case N_CTYPE:
- switch (NCTYPE(y).type) {
- case CTYPE_WORD:
- if (IS_NULL(xc->mbuf) && !IS_CCLASS_NOT(xc)) {
- for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
- if (BITSET_AT(xc->bs, i)) {
- if (ONIGENC_IS_CODE_SB_WORD(reg->enc, i)) return 0;
+ case NT_CTYPE:
+ switch (NCTYPE(y)->ctype) {
+ case ONIGENC_CTYPE_WORD:
+ if (NCTYPE(y)->not == 0) {
+ if (IS_NULL(xc->mbuf) && !IS_NCCLASS_NOT(xc)) {
+ for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
+ if (BITSET_AT(xc->bs, i)) {
+ if (IS_CODE_SB_WORD(reg->enc, i)) return 0;
+ }
}
+ return 1;
}
- return 1;
+ return 0;
}
- return 0;
- break;
- case CTYPE_NOT_WORD:
- for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
- if (! ONIGENC_IS_CODE_SB_WORD(reg->enc, i)) {
- if (!IS_CCLASS_NOT(xc)) {
- if (BITSET_AT(xc->bs, i))
- return 0;
- }
- else {
- if (! BITSET_AT(xc->bs, i))
- return 0;
+ else {
+ for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
+ if (! IS_CODE_SB_WORD(reg->enc, i)) {
+ if (!IS_NCCLASS_NOT(xc)) {
+ if (BITSET_AT(xc->bs, i))
+ return 0;
+ }
+ else {
+ if (! BITSET_AT(xc->bs, i))
+ return 0;
+ }
}
}
+ return 1;
}
- return 1;
break;
default:
@@ -2480,29 +2475,29 @@ is_not_included(Node* x, Node* y, regex_t* reg)
}
break;
- case N_CCLASS:
+ case NT_CCLASS:
{
int v;
- CClassNode* yc = &(NCCLASS(y));
+ CClassNode* yc = NCCLASS(y);
for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
v = BITSET_AT(xc->bs, i);
- if ((v != 0 && !IS_CCLASS_NOT(xc)) ||
- (v == 0 && IS_CCLASS_NOT(xc))) {
+ if ((v != 0 && !IS_NCCLASS_NOT(xc)) ||
+ (v == 0 && IS_NCCLASS_NOT(xc))) {
v = BITSET_AT(yc->bs, i);
- if ((v != 0 && !IS_CCLASS_NOT(yc)) ||
- (v == 0 && IS_CCLASS_NOT(yc)))
+ if ((v != 0 && !IS_NCCLASS_NOT(yc)) ||
+ (v == 0 && IS_NCCLASS_NOT(yc)))
return 0;
}
}
- if ((IS_NULL(xc->mbuf) && !IS_CCLASS_NOT(xc)) ||
- (IS_NULL(yc->mbuf) && !IS_CCLASS_NOT(yc)))
+ if ((IS_NULL(xc->mbuf) && !IS_NCCLASS_NOT(xc)) ||
+ (IS_NULL(yc->mbuf) && !IS_NCCLASS_NOT(yc)))
return 1;
return 0;
}
break;
- case N_STRING:
+ case NT_STR:
goto swap;
break;
@@ -2512,30 +2507,30 @@ is_not_included(Node* x, Node* y, regex_t* reg)
}
break;
- case N_STRING:
+ case NT_STR:
{
- StrNode* xs = &(NSTRING(x));
+ StrNode* xs = NSTR(x);
if (NSTRING_LEN(x) == 0)
break;
c = *(xs->s);
switch (ytype) {
- case N_CTYPE:
- switch (NCTYPE(y).type) {
- case CTYPE_WORD:
- return (ONIGENC_IS_MBC_WORD(reg->enc, xs->s, xs->end) ? 0 : 1);
- break;
- case CTYPE_NOT_WORD:
- return (ONIGENC_IS_MBC_WORD(reg->enc, xs->s, xs->end) ? 1 : 0);
+ case NT_CTYPE:
+ switch (NCTYPE(y)->ctype) {
+ case ONIGENC_CTYPE_WORD:
+ if (ONIGENC_IS_MBC_WORD(reg->enc, xs->s, xs->end))
+ return NCTYPE(y)->not;
+ else
+ return !(NCTYPE(y)->not);
break;
default:
break;
}
break;
- case N_CCLASS:
+ case NT_CCLASS:
{
- CClassNode* cc = &(NCCLASS(y));
+ CClassNode* cc = NCCLASS(y);
code = ONIGENC_MBC_TO_CODE(reg->enc, xs->s,
xs->s + ONIGENC_MBC_MAXLEN(reg->enc));
@@ -2543,10 +2538,10 @@ is_not_included(Node* x, Node* y, regex_t* reg)
}
break;
- case N_STRING:
+ case NT_STR:
{
UChar *q;
- StrNode* ys = &(NSTRING(y));
+ StrNode* ys = NSTR(y);
len = NSTRING_LEN(x);
if (len > NSTRING_LEN(y)) len = NSTRING_LEN(y);
if (NSTRING_IS_AMBIG(x) || NSTRING_IS_AMBIG(y)) {
@@ -2580,40 +2575,34 @@ get_head_value_node(Node* node, int exact, regex_t* reg)
Node* n = NULL_NODE;
switch (NTYPE(node)) {
- case N_BACKREF:
- case N_ALT:
- case N_ANYCHAR:
+ case NT_BREF:
+ case NT_ALT:
+ case NT_CANY:
#ifdef USE_SUBEXP_CALL
- case N_CALL:
+ case NT_CALL:
#endif
break;
- case N_CTYPE:
- case N_CCLASS:
+ case NT_CTYPE:
+ case NT_CCLASS:
if (exact == 0) {
n = node;
}
break;
- case N_LIST:
- n = get_head_value_node(NCONS(node).left, exact, reg);
+ case NT_LIST:
+ n = get_head_value_node(NCAR(node), exact, reg);
break;
- case N_STRING:
+ case NT_STR:
{
- StrNode* sn = &(NSTRING(node));
+ StrNode* sn = NSTR(node);
if (sn->end <= sn->s)
break;
if (exact != 0 &&
!NSTRING_IS_RAW(node) && IS_IGNORECASE(reg->options)) {
-#if 0
- UChar* tmp = sn->s;
- if (! ONIGENC_IS_MBC_AMBIGUOUS(reg->enc, reg->ambig_flag,
- &tmp, sn->end))
- n = node;
-#endif
}
else {
n = node;
@@ -2621,9 +2610,9 @@ get_head_value_node(Node* node, int exact, regex_t* reg)
}
break;
- case N_QUANTIFIER:
+ case NT_QTFR:
{
- QuantifierNode* qn = &(NQUANTIFIER(node));
+ QtfrNode* qn = NQTFR(node);
if (qn->lower > 0) {
if (IS_NOT_NULL(qn->head_exact))
n = qn->head_exact;
@@ -2633,31 +2622,31 @@ get_head_value_node(Node* node, int exact, regex_t* reg)
}
break;
- case N_EFFECT:
+ case NT_ENCLOSE:
{
- EffectNode* en = &(NEFFECT(node));
+ EncloseNode* en = NENCLOSE(node);
switch (en->type) {
- case EFFECT_OPTION:
+ case ENCLOSE_OPTION:
{
OnigOptionType options = reg->options;
- reg->options = NEFFECT(node).option;
- n = get_head_value_node(NEFFECT(node).target, exact, reg);
+ reg->options = NENCLOSE(node)->option;
+ n = get_head_value_node(NENCLOSE(node)->target, exact, reg);
reg->options = options;
}
break;
- case EFFECT_MEMORY:
- case EFFECT_STOP_BACKTRACK:
+ case ENCLOSE_MEMORY:
+ case ENCLOSE_STOP_BACKTRACK:
n = get_head_value_node(en->target, exact, reg);
break;
}
}
break;
- case N_ANCHOR:
- if (NANCHOR(node).type == ANCHOR_PREC_READ)
- n = get_head_value_node(NANCHOR(node).target, exact, reg);
+ case NT_ANCHOR:
+ if (NANCHOR(node)->type == ANCHOR_PREC_READ)
+ n = get_head_value_node(NANCHOR(node)->target, exact, reg);
break;
default:
@@ -2668,45 +2657,46 @@ get_head_value_node(Node* node, int exact, regex_t* reg)
}
static int
-check_type_tree(Node* node, int type_mask, int effect_mask, int anchor_mask)
+check_type_tree(Node* node, int type_mask, int enclose_mask, int anchor_mask)
{
int type, r = 0;
type = NTYPE(node);
- if ((type & type_mask) == 0)
+ if ((NTYPE2BIT(type) & type_mask) == 0)
return 1;
switch (type) {
- case N_LIST:
- case N_ALT:
+ case NT_LIST:
+ case NT_ALT:
do {
- r = check_type_tree(NCONS(node).left, type_mask, effect_mask, anchor_mask);
- } while (r == 0 && IS_NOT_NULL(node = NCONS(node).right));
+ r = check_type_tree(NCAR(node), type_mask, enclose_mask,
+ anchor_mask);
+ } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
break;
- case N_QUANTIFIER:
- r = check_type_tree(NQUANTIFIER(node).target, type_mask, effect_mask,
+ case NT_QTFR:
+ r = check_type_tree(NQTFR(node)->target, type_mask, enclose_mask,
anchor_mask);
break;
- case N_EFFECT:
+ case NT_ENCLOSE:
{
- EffectNode* en = &(NEFFECT(node));
- if ((en->type & effect_mask) == 0)
+ EncloseNode* en = NENCLOSE(node);
+ if ((en->type & enclose_mask) == 0)
return 1;
- r = check_type_tree(en->target, type_mask, effect_mask, anchor_mask);
+ r = check_type_tree(en->target, type_mask, enclose_mask, anchor_mask);
}
break;
- case N_ANCHOR:
- type = NANCHOR(node).type;
+ case NT_ANCHOR:
+ type = NANCHOR(node)->type;
if ((type & anchor_mask) == 0)
return 1;
- if (NANCHOR(node).target)
- r = check_type_tree(NANCHOR(node).target,
- type_mask, effect_mask, anchor_mask);
+ if (NANCHOR(node)->target)
+ r = check_type_tree(NANCHOR(node)->target,
+ type_mask, enclose_mask, anchor_mask);
break;
default:
@@ -2728,7 +2718,7 @@ subexp_inf_recursive_check(Node* node, ScanEnv* env, int head)
type = NTYPE(node);
switch (type) {
- case N_LIST:
+ case NT_LIST:
{
Node *x;
OnigDistance min;
@@ -2736,40 +2726,40 @@ subexp_inf_recursive_check(Node* node, ScanEnv* env, int head)
x = node;
do {
- ret = subexp_inf_recursive_check(NCONS(x).left, env, head);
+ ret = subexp_inf_recursive_check(NCAR(x), env, head);
if (ret < 0 || ret == RECURSION_INFINITE) return ret;
r |= ret;
if (head) {
- ret = get_min_match_length(NCONS(x).left, &min, env);
+ ret = get_min_match_length(NCAR(x), &min, env);
if (ret != 0) return ret;
if (min != 0) head = 0;
}
- } while (IS_NOT_NULL(x = NCONS(x).right));
+ } while (IS_NOT_NULL(x = NCDR(x)));
}
break;
- case N_ALT:
+ case NT_ALT:
{
int ret;
r = RECURSION_EXIST;
do {
- ret = subexp_inf_recursive_check(NCONS(node).left, env, head);
+ ret = subexp_inf_recursive_check(NCAR(node), env, head);
if (ret < 0 || ret == RECURSION_INFINITE) return ret;
r &= ret;
- } while (IS_NOT_NULL(node = NCONS(node).right));
+ } while (IS_NOT_NULL(node = NCDR(node)));
}
break;
- case N_QUANTIFIER:
- r = subexp_inf_recursive_check(NQUANTIFIER(node).target, env, head);
+ case NT_QTFR:
+ r = subexp_inf_recursive_check(NQTFR(node)->target, env, head);
if (r == RECURSION_EXIST) {
- if (NQUANTIFIER(node).lower == 0) r = 0;
+ if (NQTFR(node)->lower == 0) r = 0;
}
break;
- case N_ANCHOR:
+ case NT_ANCHOR:
{
- AnchorNode* an = &(NANCHOR(node));
+ AnchorNode* an = NANCHOR(node);
switch (an->type) {
case ANCHOR_PREC_READ:
case ANCHOR_PREC_READ_NOT:
@@ -2781,19 +2771,19 @@ subexp_inf_recursive_check(Node* node, ScanEnv* env, int head)
}
break;
- case N_CALL:
- r = subexp_inf_recursive_check(NCALL(node).target, env, head);
+ case NT_CALL:
+ r = subexp_inf_recursive_check(NCALL(node)->target, env, head);
break;
- case N_EFFECT:
- if (IS_EFFECT_MARK2(&(NEFFECT(node))))
+ case NT_ENCLOSE:
+ if (IS_ENCLOSE_MARK2(NENCLOSE(node)))
return 0;
- else if (IS_EFFECT_MARK1(&(NEFFECT(node))))
+ else if (IS_ENCLOSE_MARK1(NENCLOSE(node)))
return (head == 0 ? RECURSION_EXIST : RECURSION_INFINITE);
else {
- SET_EFFECT_STATUS(node, NST_MARK2);
- r = subexp_inf_recursive_check(NEFFECT(node).target, env, head);
- CLEAR_EFFECT_STATUS(node, NST_MARK2);
+ SET_ENCLOSE_STATUS(node, NST_MARK2);
+ r = subexp_inf_recursive_check(NENCLOSE(node)->target, env, head);
+ CLEAR_ENCLOSE_STATUS(node, NST_MARK2);
}
break;
@@ -2812,20 +2802,20 @@ subexp_inf_recursive_check_trav(Node* node, ScanEnv* env)
type = NTYPE(node);
switch (type) {
- case N_LIST:
- case N_ALT:
+ case NT_LIST:
+ case NT_ALT:
do {
- r = subexp_inf_recursive_check_trav(NCONS(node).left, env);
- } while (r == 0 && IS_NOT_NULL(node = NCONS(node).right));
+ r = subexp_inf_recursive_check_trav(NCAR(node), env);
+ } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
break;
- case N_QUANTIFIER:
- r = subexp_inf_recursive_check_trav(NQUANTIFIER(node).target, env);
+ case NT_QTFR:
+ r = subexp_inf_recursive_check_trav(NQTFR(node)->target, env);
break;
- case N_ANCHOR:
+ case NT_ANCHOR:
{
- AnchorNode* an = &(NANCHOR(node));
+ AnchorNode* an = NANCHOR(node);
switch (an->type) {
case ANCHOR_PREC_READ:
case ANCHOR_PREC_READ_NOT:
@@ -2837,15 +2827,15 @@ subexp_inf_recursive_check_trav(Node* node, ScanEnv* env)
}
break;
- case N_EFFECT:
+ case NT_ENCLOSE:
{
- EffectNode* en = &(NEFFECT(node));
+ EncloseNode* en = NENCLOSE(node);
- if (IS_EFFECT_RECURSION(en)) {
- SET_EFFECT_STATUS(node, NST_MARK1);
+ if (IS_ENCLOSE_RECURSION(en)) {
+ SET_ENCLOSE_STATUS(node, NST_MARK1);
r = subexp_inf_recursive_check(en->target, env, 1);
if (r > 0) return ONIGERR_NEVER_ENDING_RECURSION;
- CLEAR_EFFECT_STATUS(node, NST_MARK1);
+ CLEAR_ENCLOSE_STATUS(node, NST_MARK1);
}
r = subexp_inf_recursive_check_trav(en->target, env);
}
@@ -2862,25 +2852,23 @@ subexp_inf_recursive_check_trav(Node* node, ScanEnv* env)
static int
subexp_recursive_check(Node* node)
{
- int type;
int r = 0;
- type = NTYPE(node);
- switch (type) {
- case N_LIST:
- case N_ALT:
+ switch (NTYPE(node)) {
+ case NT_LIST:
+ case NT_ALT:
do {
- r |= subexp_recursive_check(NCONS(node).left);
- } while (IS_NOT_NULL(node = NCONS(node).right));
+ r |= subexp_recursive_check(NCAR(node));
+ } while (IS_NOT_NULL(node = NCDR(node)));
break;
- case N_QUANTIFIER:
- r = subexp_recursive_check(NQUANTIFIER(node).target);
+ case NT_QTFR:
+ r = subexp_recursive_check(NQTFR(node)->target);
break;
- case N_ANCHOR:
+ case NT_ANCHOR:
{
- AnchorNode* an = &(NANCHOR(node));
+ AnchorNode* an = NANCHOR(node);
switch (an->type) {
case ANCHOR_PREC_READ:
case ANCHOR_PREC_READ_NOT:
@@ -2892,20 +2880,20 @@ subexp_recursive_check(Node* node)
}
break;
- case N_CALL:
- r = subexp_recursive_check(NCALL(node).target);
+ case NT_CALL:
+ r = subexp_recursive_check(NCALL(node)->target);
if (r != 0) SET_CALL_RECURSION(node);
break;
- case N_EFFECT:
- if (IS_EFFECT_MARK2(&(NEFFECT(node))))
+ case NT_ENCLOSE:
+ if (IS_ENCLOSE_MARK2(NENCLOSE(node)))
return 0;
- else if (IS_EFFECT_MARK1(&(NEFFECT(node))))
+ else if (IS_ENCLOSE_MARK1(NENCLOSE(node)))
return 1; /* recursion */
else {
- SET_EFFECT_STATUS(node, NST_MARK2);
- r = subexp_recursive_check(NEFFECT(node).target);
- CLEAR_EFFECT_STATUS(node, NST_MARK2);
+ SET_ENCLOSE_STATUS(node, NST_MARK2);
+ r = subexp_recursive_check(NENCLOSE(node)->target);
+ CLEAR_ENCLOSE_STATUS(node, NST_MARK2);
}
break;
@@ -2927,29 +2915,29 @@ subexp_recursive_check_trav(Node* node, ScanEnv* env)
type = NTYPE(node);
switch (type) {
- case N_LIST:
- case N_ALT:
+ case NT_LIST:
+ case NT_ALT:
{
int ret;
do {
- ret = subexp_recursive_check_trav(NCONS(node).left, env);
+ ret = subexp_recursive_check_trav(NCAR(node), env);
if (ret == FOUND_CALLED_NODE) r = FOUND_CALLED_NODE;
else if (ret < 0) return ret;
- } while (IS_NOT_NULL(node = NCONS(node).right));
+ } while (IS_NOT_NULL(node = NCDR(node)));
}
break;
- case N_QUANTIFIER:
- r = subexp_recursive_check_trav(NQUANTIFIER(node).target, env);
- if (NQUANTIFIER(node).upper == 0) {
+ case NT_QTFR:
+ r = subexp_recursive_check_trav(NQTFR(node)->target, env);
+ if (NQTFR(node)->upper == 0) {
if (r == FOUND_CALLED_NODE)
- NQUANTIFIER(node).is_refered = 1;
+ NQTFR(node)->is_refered = 1;
}
break;
- case N_ANCHOR:
+ case NT_ANCHOR:
{
- AnchorNode* an = &(NANCHOR(node));
+ AnchorNode* an = NANCHOR(node);
switch (an->type) {
case ANCHOR_PREC_READ:
case ANCHOR_PREC_READ_NOT:
@@ -2961,20 +2949,20 @@ subexp_recursive_check_trav(Node* node, ScanEnv* env)
}
break;
- case N_EFFECT:
+ case NT_ENCLOSE:
{
- EffectNode* en = &(NEFFECT(node));
+ EncloseNode* en = NENCLOSE(node);
- if (! IS_EFFECT_RECURSION(en)) {
- if (IS_EFFECT_CALLED(en)) {
- SET_EFFECT_STATUS(node, NST_MARK1);
+ if (! IS_ENCLOSE_RECURSION(en)) {
+ if (IS_ENCLOSE_CALLED(en)) {
+ SET_ENCLOSE_STATUS(node, NST_MARK1);
r = subexp_recursive_check(en->target);
- if (r != 0) SET_EFFECT_STATUS(node, NST_RECURSION);
- CLEAR_EFFECT_STATUS(node, NST_MARK1);
+ if (r != 0) SET_ENCLOSE_STATUS(node, NST_RECURSION);
+ CLEAR_ENCLOSE_STATUS(node, NST_MARK1);
}
}
r = subexp_recursive_check_trav(en->target, env);
- if (IS_EFFECT_CALLED(en))
+ if (IS_ENCLOSE_CALLED(en))
r |= FOUND_CALLED_NODE;
}
break;
@@ -2994,46 +2982,33 @@ setup_subexp_call(Node* node, ScanEnv* env)
type = NTYPE(node);
switch (type) {
- case N_LIST:
+ case NT_LIST:
do {
- r = setup_subexp_call(NCONS(node).left, env);
- } while (r == 0 && IS_NOT_NULL(node = NCONS(node).right));
+ r = setup_subexp_call(NCAR(node), env);
+ } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
break;
- case N_ALT:
+ case NT_ALT:
do {
- r = setup_subexp_call(NCONS(node).left, env);
- } while (r == 0 && IS_NOT_NULL(node = NCONS(node).right));
+ r = setup_subexp_call(NCAR(node), env);
+ } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
break;
- case N_QUANTIFIER:
- r = setup_subexp_call(NQUANTIFIER(node).target, env);
+ case NT_QTFR:
+ r = setup_subexp_call(NQTFR(node)->target, env);
break;
- case N_EFFECT:
- r = setup_subexp_call(NEFFECT(node).target, env);
+ case NT_ENCLOSE:
+ r = setup_subexp_call(NENCLOSE(node)->target, env);
break;
- case N_CALL:
+ case NT_CALL:
{
- int n, num, *refs;
- UChar *p;
- CallNode* cn = &(NCALL(node));
+ CallNode* cn = NCALL(node);
Node** nodes = SCANENV_MEM_NODES(env);
-#ifdef USE_NAMED_GROUP
- n = onig_name_to_group_numbers(env->reg, cn->name, cn->name_end, &refs);
-#else
- n = -1;
-#endif
- if (n <= 0) {
- /* name not found, check group number. (?*ddd) */
- p = cn->name;
- num = onig_scan_unsigned_number(&p, cn->name_end, env->enc);
- if (num <= 0 || p != cn->name_end) {
- onig_scan_env_set_error_string(env,
- ONIGERR_UNDEFINED_NAME_REFERENCE, cn->name, cn->name_end);
- return ONIGERR_UNDEFINED_NAME_REFERENCE;
- }
+ if (cn->group_num != 0) {
+ int gnum = cn->group_num;
+
#ifdef USE_NAMED_GROUP
if (env->num_named > 0 &&
IS_SYNTAX_BV(env->syntax, ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP) &&
@@ -3041,38 +3016,53 @@ setup_subexp_call(Node* node, ScanEnv* env)
return ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED;
}
#endif
- if (num > env->num_mem) {
+ if (gnum > env->num_mem) {
onig_scan_env_set_error_string(env,
ONIGERR_UNDEFINED_GROUP_REFERENCE, cn->name, cn->name_end);
return ONIGERR_UNDEFINED_GROUP_REFERENCE;
}
- cn->ref_num = num;
- goto set_call_attr;
- }
- else if (n > 1) {
- onig_scan_env_set_error_string(env,
- ONIGERR_MULTIPLEX_DEFINITION_NAME_CALL, cn->name, cn->name_end);
- return ONIGERR_MULTIPLEX_DEFINITION_NAME_CALL;
- }
- else {
- cn->ref_num = refs[0];
+
+#ifdef USE_NAMED_GROUP
set_call_attr:
- cn->target = nodes[cn->ref_num];
+#endif
+ cn->target = nodes[cn->group_num];
if (IS_NULL(cn->target)) {
onig_scan_env_set_error_string(env,
- ONIGERR_UNDEFINED_NAME_REFERENCE, cn->name, cn->name_end);
+ ONIGERR_UNDEFINED_NAME_REFERENCE, cn->name, cn->name_end);
return ONIGERR_UNDEFINED_NAME_REFERENCE;
}
- SET_EFFECT_STATUS(cn->target, NST_CALLED);
- BIT_STATUS_ON_AT(env->bt_mem_start, cn->ref_num);
+ SET_ENCLOSE_STATUS(cn->target, NST_CALLED);
+ BIT_STATUS_ON_AT(env->bt_mem_start, cn->group_num);
cn->unset_addr_list = env->unset_addr_list;
}
+#ifdef USE_NAMED_GROUP
+ else {
+ int *refs;
+
+ int n = onig_name_to_group_numbers(env->reg, cn->name, cn->name_end,
+ &refs);
+ if (n <= 0) {
+ onig_scan_env_set_error_string(env,
+ ONIGERR_UNDEFINED_NAME_REFERENCE, cn->name, cn->name_end);
+ return ONIGERR_UNDEFINED_NAME_REFERENCE;
+ }
+ else if (n > 1) {
+ onig_scan_env_set_error_string(env,
+ ONIGERR_MULTIPLEX_DEFINITION_NAME_CALL, cn->name, cn->name_end);
+ return ONIGERR_MULTIPLEX_DEFINITION_NAME_CALL;
+ }
+ else {
+ cn->group_num = refs[0];
+ goto set_call_attr;
+ }
+ }
+#endif
}
break;
- case N_ANCHOR:
+ case NT_ANCHOR:
{
- AnchorNode* an = &(NANCHOR(node));
+ AnchorNode* an = NANCHOR(node);
switch (an->type) {
case ANCHOR_PREC_READ:
@@ -3100,30 +3090,29 @@ setup_subexp_call(Node* node, ScanEnv* env)
static int
divide_look_behind_alternatives(Node* node)
{
- Node tmp_node;
Node *head, *np, *insert_node;
- AnchorNode* an = &(NANCHOR(node));
+ AnchorNode* an = NANCHOR(node);
int anc_type = an->type;
head = an->target;
- np = NCONS(head).left;
- tmp_node = *node; *node = *head; *head = tmp_node;
- NCONS(node).left = head;
- NANCHOR(head).target = np;
+ np = NCAR(head);
+ swap_node(node, head);
+ NCAR(node) = head;
+ NANCHOR(head)->target = np;
np = node;
- while ((np = NCONS(np).right) != NULL_NODE) {
+ while ((np = NCDR(np)) != NULL_NODE) {
insert_node = onig_node_new_anchor(anc_type);
- CHECK_NULL_RETURN_VAL(insert_node, ONIGERR_MEMORY);
- NANCHOR(insert_node).target = NCONS(np).left;
- NCONS(np).left = insert_node;
+ CHECK_NULL_RETURN_MEMERR(insert_node);
+ NANCHOR(insert_node)->target = NCAR(np);
+ NCAR(np) = insert_node;
}
if (anc_type == ANCHOR_LOOK_BEHIND_NOT) {
np = node;
do {
- np->type = N_LIST; /* alt -> list */
- } while ((np = NCONS(np).right) != NULL_NODE);
+ SET_NTYPE(np, NT_LIST); /* alt -> list */
+ } while ((np = NCDR(np)) != NULL_NODE);
}
return 0;
}
@@ -3132,7 +3121,7 @@ static int
setup_look_behind(Node* node, regex_t* reg, ScanEnv* env)
{
int r, len;
- AnchorNode* an = &(NANCHOR(node));
+ AnchorNode* an = NANCHOR(node);
r = get_char_length_tree(an->target, reg, &len);
if (r == 0)
@@ -3156,11 +3145,15 @@ next_setup(Node* node, Node* next_node, regex_t* reg)
retry:
type = NTYPE(node);
- if (type == N_QUANTIFIER) {
- QuantifierNode* qn = &(NQUANTIFIER(node));
+ if (type == NT_QTFR) {
+ QtfrNode* qn = NQTFR(node);
if (qn->greedy && IS_REPEAT_INFINITE(qn->upper)) {
-#ifdef USE_QUANTIFIER_PEEK_NEXT
- qn->next_head_exact = get_head_value_node(next_node, 1, reg);
+#ifdef USE_QTFR_PEEK_NEXT
+ Node* n = get_head_value_node(next_node, 1, reg);
+ /* '\0': for UTF-16BE etc... */
+ if (IS_NOT_NULL(n) && NSTR(n)->s[0] != '\0') {
+ qn->next_head_exact = n;
+ }
#endif
/* automatic posseivation a*b ==> (?>a*)b */
if (qn->lower <= 1) {
@@ -3171,20 +3164,20 @@ next_setup(Node* node, Node* next_node, regex_t* reg)
if (IS_NOT_NULL(x)) {
y = get_head_value_node(next_node, 0, reg);
if (IS_NOT_NULL(y) && is_not_included(x, y, reg)) {
- Node* en = onig_node_new_effect(EFFECT_STOP_BACKTRACK);
- CHECK_NULL_RETURN_VAL(en, ONIGERR_MEMORY);
- SET_EFFECT_STATUS(en, NST_STOP_BT_SIMPLE_REPEAT);
+ Node* en = onig_node_new_enclose(ENCLOSE_STOP_BACKTRACK);
+ CHECK_NULL_RETURN_MEMERR(en);
+ SET_ENCLOSE_STATUS(en, NST_STOP_BT_SIMPLE_REPEAT);
swap_node(node, en);
- NEFFECT(node).target = en;
+ NENCLOSE(node)->target = en;
}
}
}
}
}
}
- else if (type == N_EFFECT) {
- EffectNode* en = &(NEFFECT(node));
- if (en->type == EFFECT_MEMORY) {
+ else if (type == NT_ENCLOSE) {
+ EncloseNode* en = NENCLOSE(node);
+ if (en->type == ENCLOSE_MEMORY) {
node = en->target;
goto retry;
}
@@ -3194,100 +3187,318 @@ next_setup(Node* node, Node* next_node, regex_t* reg)
static int
-divide_ambig_string_node_sub(regex_t* reg, int prev_ambig,
- UChar* prev_start, UChar* prev,
- UChar* end, Node*** tailp, Node** root)
+update_string_node_case_fold(regex_t* reg, Node *node)
{
- UChar *tmp, *wp;
- Node* snode;
+ UChar *p, *q, *end, buf[ONIGENC_MBC_CASE_FOLD_MAXLEN];
+ UChar *sbuf, *ebuf, *sp;
+ int r, i, len, sbuf_size;
+ StrNode* sn = NSTR(node);
+
+ end = sn->end;
+ sbuf_size = (end - sn->s) * 2;
+ sbuf = (UChar* )xmalloc(sbuf_size);
+ CHECK_NULL_RETURN_MEMERR(sbuf);
+ ebuf = sbuf + sbuf_size;
- if (prev_ambig != 0) {
- tmp = prev_start;
- wp = prev_start;
- while (tmp < prev) {
- wp += ONIGENC_MBC_TO_NORMALIZE(reg->enc, reg->ambig_flag,
- &tmp, end, wp);
+ sp = sbuf;
+ p = sn->s;
+ while (p < end) {
+ len = ONIGENC_MBC_CASE_FOLD(reg->enc, reg->case_fold_flag, &p, end, buf);
+ q = buf;
+ for (i = 0; i < len; i++) {
+ if (sp >= ebuf) {
+ sbuf = (UChar* )xrealloc(sbuf, sbuf_size * 2);
+ CHECK_NULL_RETURN_MEMERR(sbuf);
+ sp = sbuf + sbuf_size;
+ sbuf_size *= 2;
+ ebuf = sbuf + sbuf_size;
+ }
+
+ *sp++ = buf[i];
}
- snode = onig_node_new_str(prev_start, wp);
- CHECK_NULL_RETURN_VAL(snode, ONIGERR_MEMORY);
- NSTRING_SET_AMBIG(snode);
- if (wp != prev) NSTRING_SET_AMBIG_REDUCE(snode);
}
- else {
- snode = onig_node_new_str(prev_start, prev);
- CHECK_NULL_RETURN_VAL(snode, ONIGERR_MEMORY);
+
+ r = onig_node_str_set(node, sbuf, sp);
+ if (r != 0) {
+ xfree(sbuf);
+ return r;
+ }
+
+ xfree(sbuf);
+ return 0;
+}
+
+static int
+expand_case_fold_make_rem_string(Node** rnode, UChar *s, UChar *end,
+ regex_t* reg)
+{
+ int r;
+ Node *node;
+
+ node = onig_node_new_str(s, end);
+ if (IS_NULL(node)) return ONIGERR_MEMORY;
+
+ r = update_string_node_case_fold(reg, node);
+ if (r != 0) {
+ onig_node_free(node);
+ return r;
+ }
+
+ NSTRING_SET_AMBIG(node);
+ NSTRING_SET_DONT_GET_OPT_INFO(node);
+ *rnode = node;
+ return 0;
+}
+
+static int
+expand_case_fold_string_alt(int item_num, OnigCaseFoldCodeItem items[],
+ UChar *p, int slen, UChar *end,
+ regex_t* reg, Node **rnode)
+{
+ int r, i, j, len, varlen;
+ Node *anode, *var_anode, *snode, *xnode, *an;
+ UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN];
+
+ *rnode = var_anode = NULL_NODE;
+
+ varlen = 0;
+ for (i = 0; i < item_num; i++) {
+ if (items[i].byte_len != slen) {
+ varlen = 1;
+ break;
+ }
}
- if (*tailp == (Node** )0) {
- *root = onig_node_new_list(snode, NULL);
- CHECK_NULL_RETURN_VAL(*root, ONIGERR_MEMORY);
- *tailp = &(NCONS(*root).right);
+ if (varlen != 0) {
+ *rnode = var_anode = onig_node_new_alt(NULL_NODE, NULL_NODE);
+ if (IS_NULL(var_anode)) return ONIGERR_MEMORY;
+
+ xnode = onig_node_new_list(NULL, NULL);
+ if (IS_NULL(xnode)) goto mem_err;
+ NCAR(var_anode) = xnode;
+
+ anode = onig_node_new_alt(NULL_NODE, NULL_NODE);
+ if (IS_NULL(anode)) goto mem_err;
+ NCAR(xnode) = anode;
}
else {
- **tailp = onig_node_new_list(snode, NULL);
- CHECK_NULL_RETURN_VAL(**tailp, ONIGERR_MEMORY);
- *tailp = &(NCONS(**tailp).right);
+ *rnode = anode = onig_node_new_alt(NULL_NODE, NULL_NODE);
+ if (IS_NULL(anode)) return ONIGERR_MEMORY;
}
- return 0;
+ snode = onig_node_new_str(p, p + slen);
+ if (IS_NULL(snode)) goto mem_err;
+
+ NCAR(anode) = snode;
+
+ for (i = 0; i < item_num; i++) {
+ snode = onig_node_new_str(NULL, NULL);
+ if (IS_NULL(snode)) goto mem_err;
+
+ for (j = 0; j < items[i].code_len; j++) {
+ len = ONIGENC_CODE_TO_MBC(reg->enc, items[i].code[j], buf);
+ if (len < 0) {
+ r = len;
+ goto mem_err2;
+ }
+
+ r = onig_node_str_cat(snode, buf, buf + len);
+ if (r != 0) goto mem_err2;
+ }
+
+ an = onig_node_new_alt(NULL_NODE, NULL_NODE);
+ if (IS_NULL(an)) {
+ goto mem_err2;
+ }
+
+ if (items[i].byte_len != slen) {
+ Node *rem;
+ UChar *q = p + items[i].byte_len;
+
+ if (q < end) {
+ r = expand_case_fold_make_rem_string(&rem, q, end, reg);
+ if (r != 0) {
+ onig_node_free(an);
+ goto mem_err2;
+ }
+
+ xnode = onig_node_list_add(NULL_NODE, snode);
+ if (IS_NULL(xnode)) {
+ onig_node_free(an);
+ onig_node_free(rem);
+ goto mem_err2;
+ }
+ if (IS_NULL(onig_node_list_add(xnode, rem))) {
+ onig_node_free(an);
+ onig_node_free(xnode);
+ onig_node_free(rem);
+ goto mem_err;
+ }
+
+ NCAR(an) = xnode;
+ }
+ else {
+ NCAR(an) = snode;
+ }
+
+ NCDR(var_anode) = an;
+ var_anode = an;
+ }
+ else {
+ NCAR(an) = snode;
+ NCDR(anode) = an;
+ anode = an;
+ }
+ }
+
+ return varlen;
+
+ mem_err2:
+ onig_node_free(snode);
+
+ mem_err:
+ onig_node_free(*rnode);
+
+ return ONIGERR_MEMORY;
}
static int
-divide_ambig_string_node(Node* node, regex_t* reg)
+expand_case_fold_string(Node* node, regex_t* reg)
{
- StrNode* sn = &NSTRING(node);
- int ambig, prev_ambig;
- UChar *prev, *p, *end, *prev_start, *start, *tmp, *wp;
- Node *root = NULL_NODE;
- Node **tailp = (Node** )0;
- int r;
+#define THRESHOLD_CASE_FOLD_ALT_FOR_EXPANSION 8
- start = prev_start = p = sn->s;
- end = sn->end;
- if (p >= end) return 0;
+ int r, n, len, alt_num;
+ UChar *start, *end, *p;
+ Node *top_root, *root, *snode, *prev_node;
+ OnigCaseFoldCodeItem items[ONIGENC_GET_CASE_FOLD_CODES_MAX_NUM];
+ StrNode* sn = NSTR(node);
- prev_ambig = ONIGENC_IS_MBC_AMBIGUOUS(reg->enc, reg->ambig_flag, &p, end);
+ if (NSTRING_IS_AMBIG(node)) return 0;
+ start = sn->s;
+ end = sn->end;
+ if (start >= end) return 0;
+
+ r = 0;
+ top_root = root = prev_node = snode = NULL_NODE;
+ alt_num = 1;
+ p = start;
while (p < end) {
- prev = p;
- if (prev_ambig != (ambig = ONIGENC_IS_MBC_AMBIGUOUS(reg->enc,
- reg->ambig_flag, &p, end))) {
+ n = ONIGENC_GET_CASE_FOLD_CODES_BY_STR(reg->enc, reg->case_fold_flag,
+ p, end, items);
+ if (n < 0) {
+ r = n;
+ goto err;
+ }
+
+ len = enclen(reg->enc, p);
+
+ if (n == 0) {
+ if (IS_NULL(snode)) {
+ if (IS_NULL(root) && IS_NOT_NULL(prev_node)) {
+ top_root = root = onig_node_list_add(NULL_NODE, prev_node);
+ if (IS_NULL(root)) {
+ onig_node_free(prev_node);
+ goto mem_err;
+ }
+ }
- r = divide_ambig_string_node_sub(reg, prev_ambig, prev_start, prev,
- end, &tailp, &root);
- if (r != 0) return r;
+ prev_node = snode = onig_node_new_str(NULL, NULL);
+ if (IS_NULL(snode)) goto mem_err;
+ if (IS_NOT_NULL(root)) {
+ if (IS_NULL(onig_node_list_add(root, snode))) {
+ onig_node_free(snode);
+ goto mem_err;
+ }
+ }
+ }
- prev_ambig = ambig;
- prev_start = prev;
+ r = onig_node_str_cat(snode, p, p + len);
+ if (r != 0) goto err;
}
- }
+ else {
+ alt_num *= (n + 1);
+ if (alt_num > THRESHOLD_CASE_FOLD_ALT_FOR_EXPANSION) break;
+
+ if (IS_NULL(root) && IS_NOT_NULL(prev_node)) {
+ top_root = root = onig_node_list_add(NULL_NODE, prev_node);
+ if (IS_NULL(root)) {
+ onig_node_free(prev_node);
+ goto mem_err;
+ }
+ }
- if (prev_start == start) {
- if (prev_ambig != 0) {
- NSTRING_SET_AMBIG(node);
- tmp = start;
- wp = start;
- while (tmp < end) {
- wp += ONIGENC_MBC_TO_NORMALIZE(reg->enc, reg->ambig_flag,
- &tmp, end, wp);
+ r = expand_case_fold_string_alt(n, items, p, len, end, reg, &prev_node);
+ if (r < 0) goto mem_err;
+ if (r == 1) {
+ if (IS_NULL(root)) {
+ top_root = prev_node;
+ }
+ else {
+ if (IS_NULL(onig_node_list_add(root, prev_node))) {
+ onig_node_free(prev_node);
+ goto mem_err;
+ }
+ }
+
+ root = NCAR(prev_node);
+ }
+ else { /* r == 0 */
+ if (IS_NOT_NULL(root)) {
+ if (IS_NULL(onig_node_list_add(root, prev_node))) {
+ onig_node_free(prev_node);
+ goto mem_err;
+ }
+ }
}
- if (wp != sn->end) NSTRING_SET_AMBIG_REDUCE(node);
- sn->end = wp;
+
+ snode = NULL_NODE;
}
+
+ p += len;
}
- else {
- r = divide_ambig_string_node_sub(reg, prev_ambig, prev_start, end,
- end, &tailp, &root);
- if (r != 0) return r;
- swap_node(node, root);
- onig_node_str_clear(root); /* should be after swap! */
- onig_node_free(root); /* free original string node */
+ if (p < end) {
+ Node *srem;
+
+ r = expand_case_fold_make_rem_string(&srem, p, end, reg);
+ if (r != 0) goto mem_err;
+
+ if (IS_NOT_NULL(prev_node) && IS_NULL(root)) {
+ top_root = root = onig_node_list_add(NULL_NODE, prev_node);
+ if (IS_NULL(root)) {
+ onig_node_free(srem);
+ onig_node_free(prev_node);
+ goto mem_err;
+ }
+ }
+
+ if (IS_NULL(root)) {
+ prev_node = srem;
+ }
+ else {
+ if (IS_NULL(onig_node_list_add(root, srem))) {
+ onig_node_free(srem);
+ goto mem_err;
+ }
+ }
}
+ /* ending */
+ top_root = (IS_NOT_NULL(top_root) ? top_root : prev_node);
+ swap_node(node, top_root);
+ onig_node_free(top_root);
return 0;
+
+ mem_err:
+ r = ONIGERR_MEMORY;
+
+ err:
+ onig_node_free(top_root);
+ return r;
}
+
#ifdef USE_COMBINATION_EXPLOSION_CHECK
#define CEC_THRES_NUM_BIG_REPEAT 512
@@ -3305,31 +3516,31 @@ setup_comb_exp_check(Node* node, int state, ScanEnv* env)
type = NTYPE(node);
switch (type) {
- case N_LIST:
+ case NT_LIST:
{
Node* prev = NULL_NODE;
do {
- r = setup_comb_exp_check(NCONS(node).left, r, env);
- prev = NCONS(node).left;
- } while (r >= 0 && IS_NOT_NULL(node = NCONS(node).right));
+ r = setup_comb_exp_check(NCAR(node), r, env);
+ prev = NCAR(node);
+ } while (r >= 0 && IS_NOT_NULL(node = NCDR(node)));
}
break;
- case N_ALT:
+ case NT_ALT:
{
int ret;
do {
- ret = setup_comb_exp_check(NCONS(node).left, state, env);
+ ret = setup_comb_exp_check(NCAR(node), state, env);
r |= ret;
- } while (ret >= 0 && IS_NOT_NULL(node = NCONS(node).right));
+ } while (ret >= 0 && IS_NOT_NULL(node = NCDR(node)));
}
break;
- case N_QUANTIFIER:
+ case NT_QTFR:
{
int child_state = state;
int add_state = 0;
- QuantifierNode* qn = &(NQUANTIFIER(node));
+ QtfrNode* qn = NQTFR(node);
Node* target = qn->target;
int var_num;
@@ -3340,11 +3551,11 @@ setup_comb_exp_check(Node* node, int state, ScanEnv* env)
/* check (a*){n,m}, (a+){n,m} => (a*){n,n}, (a+){n,n} */
if (env->backrefed_mem == 0) {
- if (NTYPE(qn->target) == N_EFFECT) {
- EffectNode* en = &(NEFFECT(qn->target));
- if (en->type == EFFECT_MEMORY) {
- if (NTYPE(en->target) == N_QUANTIFIER) {
- QuantifierNode* q = &(NQUANTIFIER(en->target));
+ if (NTYPE(qn->target) == NT_ENCLOSE) {
+ EncloseNode* en = NENCLOSE(qn->target);
+ if (en->type == ENCLOSE_MEMORY) {
+ if (NTYPE(en->target) == NT_QTFR) {
+ QtfrNode* q = NQTFR(en->target);
if (IS_REPEAT_INFINITE(q->upper)
&& q->greedy == qn->greedy) {
qn->upper = (qn->lower == 0 ? 1 : qn->lower);
@@ -3390,12 +3601,12 @@ setup_comb_exp_check(Node* node, int state, ScanEnv* env)
}
break;
- case N_EFFECT:
+ case NT_ENCLOSE:
{
- EffectNode* en = &(NEFFECT(node));
+ EncloseNode* en = NENCLOSE(node);
switch (en->type) {
- case EFFECT_MEMORY:
+ case ENCLOSE_MEMORY:
{
if (env->curr_max_regnum < en->regnum)
env->curr_max_regnum = en->regnum;
@@ -3412,11 +3623,11 @@ setup_comb_exp_check(Node* node, int state, ScanEnv* env)
break;
#ifdef USE_SUBEXP_CALL
- case N_CALL:
- if (IS_CALL_RECURSION(&(NCALL(node))))
+ case NT_CALL:
+ if (IS_CALL_RECURSION(NCALL(node)))
env->has_recursion = 1;
else
- r = setup_comb_exp_check(NCALL(node).target, state, env);
+ r = setup_comb_exp_check(NCALL(node)->target, state, env);
break;
#endif
@@ -3449,68 +3660,68 @@ setup_tree(Node* node, regex_t* reg, int state, ScanEnv* env)
type = NTYPE(node);
switch (type) {
- case N_LIST:
+ case NT_LIST:
{
Node* prev = NULL_NODE;
do {
- r = setup_tree(NCONS(node).left, reg, state, env);
+ r = setup_tree(NCAR(node), reg, state, env);
if (IS_NOT_NULL(prev) && r == 0) {
- r = next_setup(prev, NCONS(node).left, reg);
+ r = next_setup(prev, NCAR(node), reg);
}
- prev = NCONS(node).left;
- } while (r == 0 && IS_NOT_NULL(node = NCONS(node).right));
+ prev = NCAR(node);
+ } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
}
break;
- case N_ALT:
+ case NT_ALT:
do {
- r = setup_tree(NCONS(node).left, reg, (state | IN_ALT), env);
- } while (r == 0 && IS_NOT_NULL(node = NCONS(node).right));
+ r = setup_tree(NCAR(node), reg, (state | IN_ALT), env);
+ } while (r == 0 && IS_NOT_NULL(node = NCDR(node)));
break;
- case N_CCLASS:
+ case NT_CCLASS:
break;
- case N_STRING:
+ case NT_STR:
if (IS_IGNORECASE(reg->options) && !NSTRING_IS_RAW(node)) {
- r = divide_ambig_string_node(node, reg);
+ r = expand_case_fold_string(node, reg);
}
break;
- case N_CTYPE:
- case N_ANYCHAR:
+ case NT_CTYPE:
+ case NT_CANY:
break;
#ifdef USE_SUBEXP_CALL
- case N_CALL:
+ case NT_CALL:
break;
#endif
- case N_BACKREF:
+ case NT_BREF:
{
int i;
int* p;
Node** nodes = SCANENV_MEM_NODES(env);
- BackrefNode* br = &(NBACKREF(node));
+ BRefNode* br = NBREF(node);
p = BACKREFS_P(br);
for (i = 0; i < br->back_num; i++) {
if (p[i] > env->num_mem) return ONIGERR_INVALID_BACKREF;
BIT_STATUS_ON_AT(env->backrefed_mem, p[i]);
BIT_STATUS_ON_AT(env->bt_mem_start, p[i]);
-#ifdef USE_BACKREF_AT_LEVEL
+#ifdef USE_BACKREF_WITH_LEVEL
if (IS_BACKREF_NEST_LEVEL(br)) {
BIT_STATUS_ON_AT(env->bt_mem_end, p[i]);
}
#endif
- SET_EFFECT_STATUS(nodes[p[i]], NST_MEM_BACKREFED);
+ SET_ENCLOSE_STATUS(nodes[p[i]], NST_MEM_BACKREFED);
}
}
break;
- case N_QUANTIFIER:
+ case NT_QTFR:
{
OnigDistance d;
- QuantifierNode* qn = &(NQUANTIFIER(node));
+ QtfrNode* qn = NQTFR(node);
Node* target = qn->target;
if ((state & IN_REPEAT) != 0) {
@@ -3522,7 +3733,7 @@ setup_tree(Node* node, regex_t* reg, int state, ScanEnv* env)
if (r) break;
if (d == 0) {
qn->target_empty_info = NQ_TARGET_IS_EMPTY;
-#ifdef USE_INFINITE_REPEAT_MONOMANIAC_MEM_STATUS_CHECK
+#ifdef USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT
r = quantifiers_memory_node_info(target);
if (r < 0) break;
if (r > 0) {
@@ -3535,7 +3746,7 @@ setup_tree(Node* node, regex_t* reg, int state, ScanEnv* env)
/* ()* ==> ()?, ()+ ==> () */
qn->upper = 1;
if (qn->lower > 1) qn->lower = 1;
- if (NTYPE(target) == N_STRING) {
+ if (NTYPE(target) == NT_STR) {
qn->upper = qn->lower = 0; /* /(?:)+/ ==> // */
}
}
@@ -3551,29 +3762,29 @@ setup_tree(Node* node, regex_t* reg, int state, ScanEnv* env)
/* expand string */
#define EXPAND_STRING_MAX_LENGTH 100
- if (NTYPE(target) == N_STRING) {
+ if (NTYPE(target) == NT_STR) {
if (!IS_REPEAT_INFINITE(qn->lower) && qn->lower == qn->upper &&
qn->lower > 1 && qn->lower <= EXPAND_STRING_MAX_LENGTH) {
int len = NSTRING_LEN(target);
- StrNode* sn = &(NSTRING(target));
+ StrNode* sn = NSTR(target);
if (len * qn->lower <= EXPAND_STRING_MAX_LENGTH) {
int i, n = qn->lower;
- onig_node_conv_to_str_node(node, NSTRING(target).flag);
+ onig_node_conv_to_str_node(node, NSTR(target)->flag);
for (i = 0; i < n; i++) {
r = onig_node_str_cat(node, sn->s, sn->end);
if (r) break;
}
onig_node_free(target);
- break; /* break case N_QUANTIFIER: */
+ break; /* break case NT_QTFR: */
}
}
}
#ifdef USE_OP_PUSH_OR_JUMP_EXACT
if (qn->greedy && (qn->target_empty_info != 0)) {
- if (NTYPE(target) == N_QUANTIFIER) {
- QuantifierNode* tqn = &(NQUANTIFIER(target));
+ if (NTYPE(target) == NT_QTFR) {
+ QtfrNode* tqn = NQTFR(target);
if (IS_NOT_NULL(tqn->head_exact)) {
qn->head_exact = tqn->head_exact;
tqn->head_exact = NULL;
@@ -3587,39 +3798,39 @@ setup_tree(Node* node, regex_t* reg, int state, ScanEnv* env)
}
break;
- case N_EFFECT:
+ case NT_ENCLOSE:
{
- EffectNode* en = &(NEFFECT(node));
+ EncloseNode* en = NENCLOSE(node);
switch (en->type) {
- case EFFECT_OPTION:
+ case ENCLOSE_OPTION:
{
OnigOptionType options = reg->options;
- reg->options = NEFFECT(node).option;
- r = setup_tree(NEFFECT(node).target, reg, state, env);
+ reg->options = NENCLOSE(node)->option;
+ r = setup_tree(NENCLOSE(node)->target, reg, state, env);
reg->options = options;
}
break;
- case EFFECT_MEMORY:
+ case ENCLOSE_MEMORY:
if ((state & (IN_ALT | IN_NOT | IN_VAR_REPEAT)) != 0) {
BIT_STATUS_ON_AT(env->bt_mem_start, en->regnum);
- /* SET_EFFECT_STATUS(node, NST_MEM_IN_ALT_NOT); */
+ /* SET_ENCLOSE_STATUS(node, NST_MEM_IN_ALT_NOT); */
}
r = setup_tree(en->target, reg, state, env);
break;
- case EFFECT_STOP_BACKTRACK:
+ case ENCLOSE_STOP_BACKTRACK:
{
Node* target = en->target;
r = setup_tree(target, reg, state, env);
- if (NTYPE(target) == N_QUANTIFIER) {
- QuantifierNode* tqn = &(NQUANTIFIER(target));
+ if (NTYPE(target) == NT_QTFR) {
+ QtfrNode* tqn = NQTFR(target);
if (IS_REPEAT_INFINITE(tqn->upper) && tqn->lower <= 1 &&
tqn->greedy != 0) { /* (?>a*), a*+ etc... */
int qtype = NTYPE(tqn->target);
if (IS_NODE_TYPE_SIMPLE(qtype))
- SET_EFFECT_STATUS(node, NST_STOP_BT_SIMPLE_REPEAT);
+ SET_ENCLOSE_STATUS(node, NST_STOP_BT_SIMPLE_REPEAT);
}
}
}
@@ -3628,9 +3839,9 @@ setup_tree(Node* node, regex_t* reg, int state, ScanEnv* env)
}
break;
- case N_ANCHOR:
+ case NT_ANCHOR:
{
- AnchorNode* an = &(NANCHOR(node));
+ AnchorNode* an = NANCHOR(node);
switch (an->type) {
case ANCHOR_PREC_READ:
@@ -3642,11 +3853,11 @@ setup_tree(Node* node, regex_t* reg, int state, ScanEnv* env)
/* allowed node types in look-behind */
#define ALLOWED_TYPE_IN_LB \
- ( N_LIST | N_ALT | N_STRING | N_CCLASS | N_CTYPE | \
- N_ANYCHAR | N_ANCHOR | N_EFFECT | N_QUANTIFIER | N_CALL )
+ ( BIT_NT_LIST | BIT_NT_ALT | BIT_NT_STR | BIT_NT_CCLASS | BIT_NT_CTYPE | \
+ BIT_NT_CANY | BIT_NT_ANCHOR | BIT_NT_ENCLOSE | BIT_NT_QTFR | BIT_NT_CALL )
-#define ALLOWED_EFFECT_IN_LB ( EFFECT_MEMORY )
-#define ALLOWED_EFFECT_IN_LB_NOT 0
+#define ALLOWED_ENCLOSE_IN_LB ( ENCLOSE_MEMORY )
+#define ALLOWED_ENCLOSE_IN_LB_NOT 0
#define ALLOWED_ANCHOR_IN_LB \
( ANCHOR_LOOK_BEHIND | ANCHOR_BEGIN_LINE | ANCHOR_END_LINE | ANCHOR_BEGIN_BUF | ANCHOR_BEGIN_POSITION )
@@ -3656,7 +3867,7 @@ setup_tree(Node* node, regex_t* reg, int state, ScanEnv* env)
case ANCHOR_LOOK_BEHIND:
{
r = check_type_tree(an->target, ALLOWED_TYPE_IN_LB,
- ALLOWED_EFFECT_IN_LB, ALLOWED_ANCHOR_IN_LB);
+ ALLOWED_ENCLOSE_IN_LB, ALLOWED_ANCHOR_IN_LB);
if (r < 0) return r;
if (r > 0) return ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
r = setup_look_behind(node, reg, env);
@@ -3668,7 +3879,7 @@ setup_tree(Node* node, regex_t* reg, int state, ScanEnv* env)
case ANCHOR_LOOK_BEHIND_NOT:
{
r = check_type_tree(an->target, ALLOWED_TYPE_IN_LB,
- ALLOWED_EFFECT_IN_LB_NOT, ALLOWED_ANCHOR_IN_LB_NOT);
+ ALLOWED_ENCLOSE_IN_LB_NOT, ALLOWED_ANCHOR_IN_LB_NOT);
if (r < 0) return r;
if (r > 0) return ONIGERR_INVALID_LOOK_BEHIND_PATTERN;
r = setup_look_behind(node, reg, env);
@@ -3689,7 +3900,7 @@ setup_tree(Node* node, regex_t* reg, int state, ScanEnv* env)
/* set skip map for Boyer-Moor search */
static int
-set_bm_skip(UChar* s, UChar* end, OnigEncoding enc,
+set_bm_skip(UChar* s, UChar* end, OnigEncoding enc ARG_UNUSED,
UChar skip[], int** int_skip)
{
int i, len;
@@ -3722,11 +3933,11 @@ typedef struct {
} MinMaxLen;
typedef struct {
- MinMaxLen mmd;
- OnigEncoding enc;
- OnigOptionType options;
- OnigAmbigType ambig_flag;
- ScanEnv* scan_env;
+ MinMaxLen mmd;
+ OnigEncoding enc;
+ OnigOptionType options;
+ OnigCaseFoldType case_fold_flag;
+ ScanEnv* scan_env;
} OptEnv;
typedef struct {
@@ -3778,7 +3989,7 @@ map_position_value(OnigEncoding enc, int i)
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 1
};
- if (i < sizeof(ByteValTable)/sizeof(ByteValTable[0])) {
+ if (i < (int )(sizeof(ByteValTable)/sizeof(ByteValTable[0]))) {
if (i == 0 && ONIGENC_MBC_MINLEN(enc) > 1)
return 20;
else
@@ -3810,7 +4021,7 @@ distance_value(MinMaxLen* mm)
if (mm->max == ONIG_INFINITE_DISTANCE) return 0;
d = mm->max - mm->min;
- if (d < sizeof(dist_vals)/sizeof(dist_vals[0]))
+ if (d < (int )(sizeof(dist_vals)/sizeof(dist_vals[0])))
/* return dist_vals[d] * 16 / (mm->min + 12); */
return (int )dist_vals[d];
else
@@ -4003,7 +4214,7 @@ concat_opt_exact_info(OptExactInfo* to, OptExactInfo* add, OnigEncoding enc)
p = add->s;
end = p + add->len;
for (i = to->len; p < end; ) {
- len = enc_len(enc, p);
+ len = enclen(enc, p);
if (i + len > OPT_EXACT_MAXLEN) break;
for (j = 0; j < len && p < end; j++)
to->s[i++] = *p++;
@@ -4018,14 +4229,14 @@ concat_opt_exact_info(OptExactInfo* to, OptExactInfo* add, OnigEncoding enc)
}
static void
-concat_opt_exact_info_str(OptExactInfo* to,
- UChar* s, UChar* end, int raw, OnigEncoding enc)
+concat_opt_exact_info_str(OptExactInfo* to, UChar* s, UChar* end,
+ int raw ARG_UNUSED, OnigEncoding enc)
{
int i, j, len;
UChar *p;
for (i = to->len, p = s; p < end && i < OPT_EXACT_MAXLEN; ) {
- len = enc_len(enc, p);
+ len = enclen(enc, p);
if (i + len > OPT_EXACT_MAXLEN) break;
for (j = 0; j < len && p < end; j++)
to->s[i++] = *p++;
@@ -4051,7 +4262,7 @@ alt_merge_opt_exact_info(OptExactInfo* to, OptExactInfo* add, OptEnv* env)
for (i = 0; i < to->len && i < add->len; ) {
if (to->s[i] != add->s[i]) break;
- len = enc_len(env->enc, to->s + i);
+ len = enclen(env->enc, to->s + i);
for (j = 1; j < len; j++) {
if (to->s[i+j] != add->s[i+j]) break;
@@ -4146,29 +4357,23 @@ add_char_opt_map_info(OptMapInfo* map, UChar c, OnigEncoding enc)
static int
add_char_amb_opt_map_info(OptMapInfo* map, UChar* p, UChar* end,
- OnigEncoding enc, OnigAmbigType ambig_flag)
+ OnigEncoding enc, OnigCaseFoldType case_fold_flag)
{
- int i, n, len;
- UChar buf[ONIGENC_MBC_NORMALIZE_MAXLEN];
- OnigCodePoint code;
- const OnigPairAmbigCodes* pccs;
- OnigAmbigType amb;
+ OnigCaseFoldCodeItem items[ONIGENC_GET_CASE_FOLD_CODES_MAX_NUM];
+ UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN];
+ int i, n;
add_char_opt_map_info(map, p[0], enc);
- code = ONIGENC_MBC_TO_CODE(enc, p, end);
- for (amb = 0x01; amb <= ONIGENC_AMBIGUOUS_MATCH_LIMIT; amb <<= 1) {
- if ((amb & ambig_flag) == 0) continue;
+ case_fold_flag = DISABLE_CASE_FOLD_MULTI_CHAR(case_fold_flag);
+ n = ONIGENC_GET_CASE_FOLD_CODES_BY_STR(enc, case_fold_flag, p, end, items);
+ if (n < 0) return n;
- n = ONIGENC_GET_ALL_PAIR_AMBIG_CODES(enc, amb, &pccs);
- for (i = 0; i < n; i++) {
- if (pccs[i].from == code) {
- len = ONIGENC_CODE_TO_MBC(enc, pccs[i].to, buf);
- if (len < 0) return len;
- add_char_opt_map_info(map, buf[0], enc);
- }
- }
+ for (i = 0; i < n; i++) {
+ ONIGENC_CODE_TO_MBC(enc, items[i].code[0], buf);
+ add_char_opt_map_info(map, buf[0], enc);
}
+
return 0;
}
@@ -4341,7 +4546,7 @@ optimize_node_left(Node* node, NodeOptInfo* opt, OptEnv* env)
type = NTYPE(node);
switch (type) {
- case N_LIST:
+ case NT_LIST:
{
OptEnv nenv;
NodeOptInfo nopt;
@@ -4349,33 +4554,33 @@ optimize_node_left(Node* node, NodeOptInfo* opt, OptEnv* env)
copy_opt_env(&nenv, env);
do {
- r = optimize_node_left(NCONS(nd).left, &nopt, &nenv);
+ r = optimize_node_left(NCAR(nd), &nopt, &nenv);
if (r == 0) {
add_mml(&nenv.mmd, &nopt.len);
concat_left_node_opt_info(env->enc, opt, &nopt);
}
- } while (r == 0 && IS_NOT_NULL(nd = NCONS(nd).right));
+ } while (r == 0 && IS_NOT_NULL(nd = NCDR(nd)));
}
break;
- case N_ALT:
+ case NT_ALT:
{
NodeOptInfo nopt;
Node* nd = node;
do {
- r = optimize_node_left(NCONS(nd).left, &nopt, env);
+ r = optimize_node_left(NCAR(nd), &nopt, env);
if (r == 0) {
if (nd == node) copy_node_opt_info(opt, &nopt);
else alt_merge_node_opt_info(opt, &nopt, env);
}
- } while ((r == 0) && IS_NOT_NULL(nd = NCONS(nd).right));
+ } while ((r == 0) && IS_NOT_NULL(nd = NCDR(nd)));
}
break;
- case N_STRING:
+ case NT_STR:
{
- StrNode* sn = &(NSTRING(node));
+ StrNode* sn = NSTR(node);
int slen = sn->end - sn->s;
int is_raw = NSTRING_IS_RAW(node);
@@ -4388,25 +4593,26 @@ optimize_node_left(Node* node, NodeOptInfo* opt, OptEnv* env)
set_mml(&opt->len, slen, slen);
}
else {
- int n, max;
+ int max;
- concat_opt_exact_info_str(&opt->exb, sn->s, sn->end,
- is_raw, env->enc);
- opt->exb.ignore_case = 1;
+ if (NSTRING_IS_DONT_GET_OPT_INFO(node)) {
+ int n = onigenc_strlen(env->enc, sn->s, sn->end);
+ max = ONIGENC_MBC_MAXLEN_DIST(env->enc) * n;
+ }
+ else {
+ concat_opt_exact_info_str(&opt->exb, sn->s, sn->end,
+ is_raw, env->enc);
+ opt->exb.ignore_case = 1;
+
+ if (slen > 0) {
+ r = add_char_amb_opt_map_info(&opt->map, sn->s, sn->end,
+ env->enc, env->case_fold_flag);
+ if (r != 0) break;
+ }
- if (slen > 0) {
- r = add_char_amb_opt_map_info(&opt->map, sn->s, sn->end,
- env->enc, env->ambig_flag);
- if (r != 0) break;
+ max = slen;
}
- if (NSTRING_IS_AMBIG_REDUCE(node)) {
- n = onigenc_strlen(env->enc, sn->s, sn->end);
- max = ONIGENC_MBC_MAXLEN_DIST(env->enc) * n;
- }
- else {
- max = slen;
- }
set_mml(&opt->len, slen, max);
}
@@ -4415,14 +4621,14 @@ optimize_node_left(Node* node, NodeOptInfo* opt, OptEnv* env)
}
break;
- case N_CCLASS:
+ case NT_CCLASS:
{
int i, z;
- CClassNode* cc = &(NCCLASS(node));
+ CClassNode* cc = NCCLASS(node);
/* no need to check ignore case. (setted in setup_tree()) */
- if (IS_NOT_NULL(cc->mbuf) || IS_CCLASS_NOT(cc)) {
+ if (IS_NOT_NULL(cc->mbuf) || IS_NCCLASS_NOT(cc)) {
OnigDistance min = ONIGENC_MBC_MINLEN(env->enc);
OnigDistance max = ONIGENC_MBC_MAXLEN_DIST(env->enc);
@@ -4431,7 +4637,7 @@ optimize_node_left(Node* node, NodeOptInfo* opt, OptEnv* env)
else {
for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
z = BITSET_AT(cc->bs, i);
- if ((z && !IS_CCLASS_NOT(cc)) || (!z && IS_CCLASS_NOT(cc))) {
+ if ((z && !IS_NCCLASS_NOT(cc)) || (!z && IS_NCCLASS_NOT(cc))) {
add_char_opt_map_info(&opt->map, (UChar )i, env->enc);
}
}
@@ -4440,7 +4646,7 @@ optimize_node_left(Node* node, NodeOptInfo* opt, OptEnv* env)
}
break;
- case N_CTYPE:
+ case NT_CTYPE:
{
int i, min, max;
@@ -4449,21 +4655,22 @@ optimize_node_left(Node* node, NodeOptInfo* opt, OptEnv* env)
if (max == 1) {
min = 1;
- switch (NCTYPE(node).type) {
- case CTYPE_NOT_WORD:
- for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
- if (! ONIGENC_IS_CODE_WORD(env->enc, i)) {
- add_char_opt_map_info(&opt->map, (UChar )i, env->enc);
- }
- }
- break;
-
- case CTYPE_WORD:
- for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
- if (ONIGENC_IS_CODE_WORD(env->enc, i)) {
- add_char_opt_map_info(&opt->map, (UChar )i, env->enc);
- }
- }
+ switch (NCTYPE(node)->ctype) {
+ case ONIGENC_CTYPE_WORD:
+ if (NCTYPE(node)->not != 0) {
+ for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
+ if (! ONIGENC_IS_CODE_WORD(env->enc, i)) {
+ add_char_opt_map_info(&opt->map, (UChar )i, env->enc);
+ }
+ }
+ }
+ else {
+ for (i = 0; i < SINGLE_BYTE_SIZE; i++) {
+ if (ONIGENC_IS_CODE_WORD(env->enc, i)) {
+ add_char_opt_map_info(&opt->map, (UChar )i, env->enc);
+ }
+ }
+ }
break;
}
}
@@ -4474,7 +4681,7 @@ optimize_node_left(Node* node, NodeOptInfo* opt, OptEnv* env)
}
break;
- case N_ANYCHAR:
+ case NT_CANY:
{
OnigDistance min = ONIGENC_MBC_MINLEN(env->enc);
OnigDistance max = ONIGENC_MBC_MAXLEN_DIST(env->enc);
@@ -4482,22 +4689,22 @@ optimize_node_left(Node* node, NodeOptInfo* opt, OptEnv* env)
}
break;
- case N_ANCHOR:
- switch (NANCHOR(node).type) {
+ case NT_ANCHOR:
+ switch (NANCHOR(node)->type) {
case ANCHOR_BEGIN_BUF:
case ANCHOR_BEGIN_POSITION:
case ANCHOR_BEGIN_LINE:
case ANCHOR_END_BUF:
case ANCHOR_SEMI_END_BUF:
case ANCHOR_END_LINE:
- add_opt_anc_info(&opt->anc, NANCHOR(node).type);
+ add_opt_anc_info(&opt->anc, NANCHOR(node)->type);
break;
case ANCHOR_PREC_READ:
{
NodeOptInfo nopt;
- r = optimize_node_left(NANCHOR(node).target, &nopt, env);
+ r = optimize_node_left(NANCHOR(node)->target, &nopt, env);
if (r == 0) {
if (nopt.exb.len > 0)
copy_opt_exact_info(&opt->expr, &nopt.exb);
@@ -4519,13 +4726,13 @@ optimize_node_left(Node* node, NodeOptInfo* opt, OptEnv* env)
}
break;
- case N_BACKREF:
+ case NT_BREF:
{
int i;
int* backs;
OnigDistance min, max, tmin, tmax;
Node** nodes = SCANENV_MEM_NODES(env->scan_env);
- BackrefNode* br = &(NBACKREF(node));
+ BRefNode* br = NBREF(node);
if (br->state & NST_RECURSION) {
set_mml(&opt->len, 0, ONIG_INFINITE_DISTANCE);
@@ -4549,31 +4756,31 @@ optimize_node_left(Node* node, NodeOptInfo* opt, OptEnv* env)
break;
#ifdef USE_SUBEXP_CALL
- case N_CALL:
- if (IS_CALL_RECURSION(&(NCALL(node))))
+ case NT_CALL:
+ if (IS_CALL_RECURSION(NCALL(node)))
set_mml(&opt->len, 0, ONIG_INFINITE_DISTANCE);
else {
OnigOptionType save = env->options;
- env->options = NEFFECT(NCALL(node).target).option;
- r = optimize_node_left(NCALL(node).target, opt, env);
+ env->options = NENCLOSE(NCALL(node)->target)->option;
+ r = optimize_node_left(NCALL(node)->target, opt, env);
env->options = save;
}
break;
#endif
- case N_QUANTIFIER:
+ case NT_QTFR:
{
int i;
OnigDistance min, max;
NodeOptInfo nopt;
- QuantifierNode* qn = &(NQUANTIFIER(node));
+ QtfrNode* qn = NQTFR(node);
r = optimize_node_left(qn->target, &nopt, env);
if (r) break;
if (qn->lower == 0 && IS_REPEAT_INFINITE(qn->upper)) {
if (env->mmd.max == 0 &&
- NTYPE(qn->target) == N_ANYCHAR && qn->greedy) {
+ NTYPE(qn->target) == NT_CANY && qn->greedy) {
if (IS_MULTILINE(env->options))
add_opt_anc_info(&opt->anc, ANCHOR_ANYCHAR_STAR_ML);
else
@@ -4585,7 +4792,7 @@ optimize_node_left(Node* node, NodeOptInfo* opt, OptEnv* env)
copy_node_opt_info(opt, &nopt);
if (nopt.exb.len > 0) {
if (nopt.exb.reach_end) {
- for (i = 2; i < qn->lower &&
+ for (i = 2; i <= qn->lower &&
! is_full_opt_exact_info(&opt->exb); i++) {
concat_opt_exact_info(&opt->exb, &nopt.exb, env->enc);
}
@@ -4614,12 +4821,12 @@ optimize_node_left(Node* node, NodeOptInfo* opt, OptEnv* env)
}
break;
- case N_EFFECT:
+ case NT_ENCLOSE:
{
- EffectNode* en = &(NEFFECT(node));
+ EncloseNode* en = NENCLOSE(node);
switch (en->type) {
- case EFFECT_OPTION:
+ case ENCLOSE_OPTION:
{
OnigOptionType save = env->options;
@@ -4629,7 +4836,7 @@ optimize_node_left(Node* node, NodeOptInfo* opt, OptEnv* env)
}
break;
- case EFFECT_MEMORY:
+ case ENCLOSE_MEMORY:
#ifdef USE_SUBEXP_CALL
en->opt_count++;
if (en->opt_count > MAX_NODE_OPT_INFO_REF_COUNT) {
@@ -4637,8 +4844,8 @@ optimize_node_left(Node* node, NodeOptInfo* opt, OptEnv* env)
min = 0;
max = ONIG_INFINITE_DISTANCE;
- if (IS_EFFECT_MIN_FIXED(en)) min = en->min_len;
- if (IS_EFFECT_MAX_FIXED(en)) max = en->max_len;
+ if (IS_ENCLOSE_MIN_FIXED(en)) min = en->min_len;
+ if (IS_ENCLOSE_MAX_FIXED(en)) max = en->max_len;
set_mml(&opt->len, min, max);
}
else
@@ -4653,7 +4860,7 @@ optimize_node_left(Node* node, NodeOptInfo* opt, OptEnv* env)
}
break;
- case EFFECT_STOP_BACKTRACK:
+ case ENCLOSE_STOP_BACKTRACK:
r = optimize_node_left(en->target, opt, env);
break;
}
@@ -4681,7 +4888,7 @@ set_optimize_exact_info(regex_t* reg, OptExactInfo* e)
if (e->ignore_case) {
reg->exact = (UChar* )xmalloc(e->len);
- CHECK_NULL_RETURN_VAL(reg->exact, ONIGERR_MEMORY);
+ CHECK_NULL_RETURN_MEMERR(reg->exact);
xmemcpy(reg->exact, e->s, e->len);
reg->exact_end = reg->exact + e->len;
reg->optimize = ONIG_OPTIMIZE_EXACT_IC;
@@ -4689,8 +4896,8 @@ set_optimize_exact_info(regex_t* reg, OptExactInfo* e)
else {
int allow_reverse;
- reg->exact = k_strdup(e->s, e->s + e->len);
- CHECK_NULL_RETURN_VAL(reg->exact, ONIGERR_MEMORY);
+ reg->exact = str_dup(e->s, e->s + e->len);
+ CHECK_NULL_RETURN_MEMERR(reg->exact);
reg->exact_end = reg->exact + e->len;
allow_reverse =
@@ -4755,9 +4962,9 @@ set_optimize_info_from_tree(Node* node, regex_t* reg, ScanEnv* scan_env)
NodeOptInfo opt;
OptEnv env;
- env.enc = reg->enc;
- env.options = reg->options;
- env.ambig_flag = reg->ambig_flag;
+ env.enc = reg->enc;
+ env.options = reg->options;
+ env.case_fold_flag = reg->case_fold_flag;
env.scan_env = scan_env;
clear_mml(&env.mmd);
@@ -4839,7 +5046,7 @@ static void print_enc_string(FILE* fp, OnigEncoding enc,
fputc((int )code, fp);
}
- p += enc_len(enc, p);
+ p += enclen(enc, p);
}
}
else {
@@ -4971,19 +5178,21 @@ print_optimize_info(FILE* f, regex_t* reg)
#endif /* ONIG_DEBUG */
-static void
+extern void
onig_free_body(regex_t* reg)
{
- if (IS_NOT_NULL(reg->p)) xfree(reg->p);
- if (IS_NOT_NULL(reg->exact)) xfree(reg->exact);
- if (IS_NOT_NULL(reg->int_map)) xfree(reg->int_map);
- if (IS_NOT_NULL(reg->int_map_backward)) xfree(reg->int_map_backward);
- if (IS_NOT_NULL(reg->repeat_range)) xfree(reg->repeat_range);
- if (IS_NOT_NULL(reg->chain)) onig_free(reg->chain);
+ if (IS_NOT_NULL(reg)) {
+ if (IS_NOT_NULL(reg->p)) xfree(reg->p);
+ if (IS_NOT_NULL(reg->exact)) xfree(reg->exact);
+ if (IS_NOT_NULL(reg->int_map)) xfree(reg->int_map);
+ if (IS_NOT_NULL(reg->int_map_backward)) xfree(reg->int_map_backward);
+ if (IS_NOT_NULL(reg->repeat_range)) xfree(reg->repeat_range);
+ if (IS_NOT_NULL(reg->chain)) onig_free(reg->chain);
#ifdef USE_NAMED_GROUP
- onig_names_free(reg);
+ onig_names_free(reg);
#endif
+ }
}
extern void
@@ -5043,84 +5252,6 @@ onig_chain_reduce(regex_t* reg)
}
}
-#if 0
-extern int
-onig_clone(regex_t** to, regex_t* from)
-{
- int r, size;
- regex_t* reg;
-
-#ifdef USE_MULTI_THREAD_SYSTEM
- if (ONIG_STATE(from) >= ONIG_STATE_NORMAL) {
- ONIG_STATE_INC(from);
- if (IS_NOT_NULL(from->chain) && ONIG_STATE(reg) == ONIG_STATE_NORMAL) {
- onig_chain_reduce(from);
- ONIG_STATE_INC(from);
- }
- }
- else {
- int n = 0;
- while (ONIG_STATE(from) < ONIG_STATE_NORMAL) {
- if (++n > THREAD_PASS_LIMIT_COUNT)
- return ONIGERR_OVER_THREAD_PASS_LIMIT_COUNT;
- THREAD_PASS;
- }
- ONIG_STATE_INC(from);
- }
-#endif /* USE_MULTI_THREAD_SYSTEM */
-
- r = onig_alloc_init(&reg, ONIG_OPTION_NONE, ONIGENC_AMBIGUOUS_MATCH_DEFAULT,
- from->enc, ONIG_SYNTAX_DEFAULT);
- if (r != 0) {
- ONIG_STATE_DEC(from);
- return r;
- }
-
- xmemcpy(reg, from, sizeof(onig_t));
- reg->chain = (regex_t* )NULL;
- reg->state = ONIG_STATE_NORMAL;
-
- if (from->p) {
- reg->p = (UChar* )xmalloc(reg->alloc);
- if (IS_NULL(reg->p)) goto mem_error;
- xmemcpy(reg->p, from->p, reg->alloc);
- }
-
- if (from->exact) {
- reg->exact = (UChar* )xmalloc(from->exact_end - from->exact);
- if (IS_NULL(reg->exact)) goto mem_error;
- reg->exact_end = reg->exact + (from->exact_end - from->exact);
- xmemcpy(reg->exact, from->exact, reg->exact_end - reg->exact);
- }
-
- if (from->int_map) {
- size = sizeof(int) * ONIG_CHAR_TABLE_SIZE;
- reg->int_map = (int* )xmalloc(size);
- if (IS_NULL(reg->int_map)) goto mem_error;
- xmemcpy(reg->int_map, from->int_map, size);
- }
-
- if (from->int_map_backward) {
- size = sizeof(int) * ONIG_CHAR_TABLE_SIZE;
- reg->int_map_backward = (int* )xmalloc(size);
- if (IS_NULL(reg->int_map_backward)) goto mem_error;
- xmemcpy(reg->int_map_backward, from->int_map_backward, size);
- }
-
-#ifdef USE_NAMED_GROUP
- reg->name_table = names_clone(from); /* names_clone is not implemented */
-#endif
-
- ONIG_STATE_DEC(from);
- *to = reg;
- return 0;
-
- mem_error:
- ONIG_STATE_DEC(from);
- return ONIGERR_MEMORY;
-}
-#endif
-
#ifdef ONIG_DEBUG
static void print_compiled_byte_code_list P_((FILE* f, regex_t* reg));
#endif
@@ -5141,6 +5272,8 @@ onig_compile(regex_t* reg, const UChar* pattern, const UChar* pattern_end,
UnsetAddrList uslist;
#endif
+ if (IS_NOT_NULL(einfo)) einfo->par = (UChar* )NULL;
+
reg->state = ONIG_STATE_COMPILING;
#ifdef ONIG_DEBUG
@@ -5182,10 +5315,6 @@ onig_compile(regex_t* reg, const UChar* pattern, const UChar* pattern_end,
}
#endif
-#ifdef ONIG_DEBUG_PARSE_TREE
- print_tree(stderr, root);
-#endif
-
#ifdef USE_SUBEXP_CALL
if (scan_env.num_call > 0) {
r = unset_addr_list_init(&uslist, scan_env.num_call);
@@ -5207,6 +5336,10 @@ onig_compile(regex_t* reg, const UChar* pattern, const UChar* pattern_end,
r = setup_tree(root, reg, 0, &scan_env);
if (r != 0) goto err_unset;
+#ifdef ONIG_DEBUG_PARSE_TREE
+ print_tree(stderr, root);
+#endif
+
reg->capture_history = scan_env.capture_history;
reg->bt_mem_start = scan_env.bt_mem_start;
reg->bt_mem_start |= reg->capture_history;
@@ -5308,7 +5441,7 @@ onig_compile(regex_t* reg, const UChar* pattern, const UChar* pattern_end,
}
}
- if (IS_NOT_NULL(root)) onig_node_free(root);
+ onig_node_free(root);
if (IS_NOT_NULL(scan_env.mem_nodes_dynamic))
xfree(scan_env.mem_nodes_dynamic);
return r;
@@ -5338,12 +5471,16 @@ onig_recompile(regex_t* reg, const UChar* pattern, const UChar* pattern_end,
static int onig_inited = 0;
extern int
-onig_alloc_init(regex_t** reg, OnigOptionType option, OnigAmbigType ambig_flag,
- OnigEncoding enc, OnigSyntaxType* syntax)
+onig_reg_init(regex_t* reg, OnigOptionType option,
+ OnigCaseFoldType case_fold_flag,
+ OnigEncoding enc, OnigSyntaxType* syntax)
{
if (! onig_inited)
onig_init();
+ if (IS_NULL(reg))
+ return ONIGERR_INVALID_ARGUMENT;
+
if (ONIGENC_IS_UNDEF(enc))
return ONIGERR_DEFAULT_ENCODING_IS_NOT_SETTED;
@@ -5352,9 +5489,7 @@ onig_alloc_init(regex_t** reg, OnigOptionType option, OnigAmbigType ambig_flag,
return ONIGERR_INVALID_COMBINATION_OF_OPTIONS;
}
- *reg = (regex_t* )xmalloc(sizeof(regex_t));
- if (IS_NULL(*reg)) return ONIGERR_MEMORY;
- (*reg)->state = ONIG_STATE_MODIFY;
+ (reg)->state = ONIG_STATE_MODIFY;
if ((option & ONIG_OPTION_NEGATE_SINGLELINE) != 0) {
option |= syntax->options;
@@ -5363,24 +5498,36 @@ onig_alloc_init(regex_t** reg, OnigOptionType option, OnigAmbigType ambig_flag,
else
option |= syntax->options;
- (*reg)->enc = enc;
- (*reg)->options = option;
- (*reg)->syntax = syntax;
- (*reg)->optimize = 0;
- (*reg)->exact = (UChar* )NULL;
- (*reg)->int_map = (int* )NULL;
- (*reg)->int_map_backward = (int* )NULL;
- (*reg)->chain = (regex_t* )NULL;
+ (reg)->enc = enc;
+ (reg)->options = option;
+ (reg)->syntax = syntax;
+ (reg)->optimize = 0;
+ (reg)->exact = (UChar* )NULL;
+ (reg)->int_map = (int* )NULL;
+ (reg)->int_map_backward = (int* )NULL;
+ (reg)->chain = (regex_t* )NULL;
+
+ (reg)->p = (UChar* )NULL;
+ (reg)->alloc = 0;
+ (reg)->used = 0;
+ (reg)->name_table = (void* )NULL;
+
+ (reg)->case_fold_flag = case_fold_flag;
+ return 0;
+}
- (*reg)->p = (UChar* )NULL;
- (*reg)->alloc = 0;
- (*reg)->used = 0;
- (*reg)->name_table = (void* )NULL;
+extern int
+onig_new_without_alloc(regex_t* reg, const UChar* pattern,
+ const UChar* pattern_end, OnigOptionType option, OnigEncoding enc,
+ OnigSyntaxType* syntax, OnigErrorInfo* einfo)
+{
+ int r;
- (*reg)->ambig_flag = ambig_flag;
- (*reg)->ambig_flag &= ONIGENC_SUPPORT_AMBIG_FLAG(enc);
+ r = onig_reg_init(reg, option, ONIGENC_CASE_FOLD_DEFAULT, enc, syntax);
+ if (r) return r;
- return 0;
+ r = onig_compile(reg, pattern, pattern_end, einfo);
+ return r;
}
extern int
@@ -5390,33 +5537,35 @@ onig_new(regex_t** reg, const UChar* pattern, const UChar* pattern_end,
{
int r;
- if (IS_NOT_NULL(einfo)) einfo->par = (UChar* )NULL;
+ *reg = (regex_t* )xmalloc(sizeof(regex_t));
+ if (IS_NULL(*reg)) return ONIGERR_MEMORY;
- r = onig_alloc_init(reg, option, ONIGENC_AMBIGUOUS_MATCH_DEFAULT,
- enc, syntax);
- if (r) return r;
+ r = onig_reg_init(*reg, option, ONIGENC_CASE_FOLD_DEFAULT, enc, syntax);
+ if (r) goto err;
r = onig_compile(*reg, pattern, pattern_end, einfo);
if (r) {
+ err:
onig_free(*reg);
*reg = NULL;
}
return r;
}
+
extern int
onig_init(void)
{
if (onig_inited != 0)
return 0;
- onig_inited = 1;
-
THREAD_SYSTEM_INIT;
THREAD_ATOMIC_START;
+ onig_inited = 1;
+
onigenc_init();
- onigenc_set_default_caseconv_table((UChar* )0);
+ /* onigenc_set_default_caseconv_table((UChar* )0); */
#ifdef ONIG_DEBUG_STATISTICS
onig_statistics_init();
@@ -5430,8 +5579,6 @@ onig_init(void)
extern int
onig_end(void)
{
- extern int onig_free_shared_cclass_table(void);
-
THREAD_ATOMIC_START;
#ifdef ONIG_DEBUG_STATISTICS
@@ -5442,7 +5589,7 @@ onig_end(void)
onig_free_shared_cclass_table();
#endif
-#ifdef USE_RECYCLE_NODE
+#ifdef USE_PARSE_TREE_NODE_RECYCLE
onig_free_node_list();
#endif
@@ -5453,6 +5600,64 @@ onig_end(void)
return 0;
}
+extern int
+onig_is_in_code_range(const UChar* p, OnigCodePoint code)
+{
+ OnigCodePoint n, *data;
+ OnigCodePoint low, high, x;
+
+ GET_CODE_POINT(n, p);
+ data = (OnigCodePoint* )p;
+ data++;
+
+ for (low = 0, high = n; low < high; ) {
+ x = (low + high) >> 1;
+ if (code > data[x * 2 + 1])
+ low = x + 1;
+ else
+ high = x;
+ }
+
+ return ((low < n && code >= data[low * 2]) ? 1 : 0);
+}
+
+extern int
+onig_is_code_in_cc_len(int elen, OnigCodePoint code, CClassNode* cc)
+{
+ int found;
+
+ if (elen > 1 || (code >= SINGLE_BYTE_SIZE)) {
+ if (IS_NULL(cc->mbuf)) {
+ found = 0;
+ }
+ else {
+ found = (onig_is_in_code_range(cc->mbuf->p, code) != 0 ? 1 : 0);
+ }
+ }
+ else {
+ found = (BITSET_AT(cc->bs, code) == 0 ? 0 : 1);
+ }
+
+ if (IS_NCCLASS_NOT(cc))
+ return !found;
+ else
+ return found;
+}
+
+extern int
+onig_is_code_in_cc(OnigEncoding enc, OnigCodePoint code, CClassNode* cc)
+{
+ int len;
+
+ if (ONIGENC_MBC_MINLEN(enc) > 1) {
+ len = 2;
+ }
+ else {
+ len = ONIGENC_CODE_TO_MBCLEN(enc, code);
+ }
+ return onig_is_code_in_cc_len(len, code, cc);
+}
+
#ifdef ONIG_DEBUG
@@ -5514,7 +5719,7 @@ OnigOpInfoType OnigOpInfo[] = {
{ OP_BACKREFN_IC, "backrefn-ic", ARG_SPECIAL },
{ OP_BACKREF_MULTI, "backref_multi", ARG_SPECIAL },
{ OP_BACKREF_MULTI_IC, "backref_multi-ic", ARG_SPECIAL },
- { OP_BACKREF_AT_LEVEL, "backref_at_level", ARG_SPECIAL },
+ { OP_BACKREF_WITH_LEVEL, "backref_at_level", ARG_SPECIAL },
{ OP_MEMORY_START_PUSH, "mem-start-push", ARG_MEMNUM },
{ OP_MEMORY_START, "mem-start", ARG_MEMNUM },
{ OP_MEMORY_END_PUSH, "mem-end-push", ARG_MEMNUM },
@@ -5706,7 +5911,7 @@ onig_print_compiled_byte_code(FILE* f, UChar* bp, UChar** nextp,
break;
case OP_EXACT1_IC:
- len = enc_len(enc, bp);
+ len = enclen(enc, bp);
p_string(f, len, bp);
bp += len;
break;
@@ -5781,7 +5986,7 @@ onig_print_compiled_byte_code(FILE* f, UChar* bp, UChar** nextp,
}
break;
- case OP_BACKREF_AT_LEVEL:
+ case OP_BACKREF_WITH_LEVEL:
{
OnigOptionType option;
LengthType level;
@@ -5889,27 +6094,27 @@ print_indent_tree(FILE* f, Node* node, int indent)
type = NTYPE(node);
switch (type) {
- case N_LIST:
- case N_ALT:
- if (NTYPE(node) == N_LIST)
+ case NT_LIST:
+ case NT_ALT:
+ if (NTYPE(node) == NT_LIST)
fprintf(f, "<list:%x>\n", (int )node);
else
fprintf(f, "<alt:%x>\n", (int )node);
- print_indent_tree(f, NCONS(node).left, indent + add);
- while (IS_NOT_NULL(node = NCONS(node).right)) {
+ print_indent_tree(f, NCAR(node), indent + add);
+ while (IS_NOT_NULL(node = NCDR(node))) {
if (NTYPE(node) != type) {
fprintf(f, "ERROR: list/alt right is not a cons. %d\n", NTYPE(node));
exit(0);
}
- print_indent_tree(f, NCONS(node).left, indent + add);
+ print_indent_tree(f, NCAR(node), indent + add);
}
break;
- case N_STRING:
+ case NT_STR:
fprintf(f, "<string%s:%x>",
(NSTRING_IS_RAW(node) ? "-raw" : ""), (int )node);
- for (p = NSTRING(node).s; p < NSTRING(node).end; p++) {
+ for (p = NSTR(node)->s; p < NSTR(node)->end; p++) {
if (*p >= 0x20 && *p < 0x7f)
fputc(*p, f);
else {
@@ -5918,11 +6123,11 @@ print_indent_tree(FILE* f, Node* node, int indent)
}
break;
- case N_CCLASS:
+ case NT_CCLASS:
fprintf(f, "<cclass:%x>", (int )node);
- if (IS_CCLASS_NOT(&NCCLASS(node))) fputs(" not", f);
- if (NCCLASS(node).mbuf) {
- BBuf* bbuf = NCCLASS(node).mbuf;
+ if (IS_NCCLASS_NOT(NCCLASS(node))) fputs(" not", f);
+ if (NCCLASS(node)->mbuf) {
+ BBuf* bbuf = NCCLASS(node)->mbuf;
for (i = 0; i < bbuf->used; i++) {
if (i > 0) fprintf(f, ",");
fprintf(f, "%0x", bbuf->p[i]);
@@ -5930,24 +6135,29 @@ print_indent_tree(FILE* f, Node* node, int indent)
}
break;
- case N_CTYPE:
+ case NT_CTYPE:
fprintf(f, "<ctype:%x> ", (int )node);
- switch (NCTYPE(node).type) {
- case CTYPE_WORD: fputs("word", f); break;
- case CTYPE_NOT_WORD: fputs("not word", f); break;
+ switch (NCTYPE(node)->ctype) {
+ case ONIGENC_CTYPE_WORD:
+ if (NCTYPE(node)->not != 0)
+ fputs("not word", f);
+ else
+ fputs("word", f);
+ break;
+
default:
fprintf(f, "ERROR: undefined ctype.\n");
exit(0);
}
break;
- case N_ANYCHAR:
+ case NT_CANY:
fprintf(f, "<anychar:%x>", (int )node);
break;
- case N_ANCHOR:
+ case NT_ANCHOR:
fprintf(f, "<anchor:%x> ", (int )node);
- switch (NANCHOR(node).type) {
+ switch (NANCHOR(node)->type) {
case ANCHOR_BEGIN_BUF: fputs("begin buf", f); break;
case ANCHOR_END_BUF: fputs("end buf", f); break;
case ANCHOR_BEGIN_LINE: fputs("begin line", f); break;
@@ -5972,10 +6182,10 @@ print_indent_tree(FILE* f, Node* node, int indent)
}
break;
- case N_BACKREF:
+ case NT_BREF:
{
int* p;
- BackrefNode* br = &(NBACKREF(node));
+ BRefNode* br = NBREF(node);
p = BACKREFS_P(br);
fprintf(f, "<backref:%x>", (int )node);
for (i = 0; i < br->back_num; i++) {
@@ -5986,33 +6196,33 @@ print_indent_tree(FILE* f, Node* node, int indent)
break;
#ifdef USE_SUBEXP_CALL
- case N_CALL:
+ case NT_CALL:
{
- CallNode* cn = &(NCALL(node));
+ CallNode* cn = NCALL(node);
fprintf(f, "<call:%x>", (int )node);
p_string(f, cn->name_end - cn->name, cn->name);
}
break;
#endif
- case N_QUANTIFIER:
+ case NT_QTFR:
fprintf(f, "<quantifier:%x>{%d,%d}%s\n", (int )node,
- NQUANTIFIER(node).lower, NQUANTIFIER(node).upper,
- (NQUANTIFIER(node).greedy ? "" : "?"));
- print_indent_tree(f, NQUANTIFIER(node).target, indent + add);
+ NQTFR(node)->lower, NQTFR(node)->upper,
+ (NQTFR(node)->greedy ? "" : "?"));
+ print_indent_tree(f, NQTFR(node)->target, indent + add);
break;
- case N_EFFECT:
- fprintf(f, "<effect:%x> ", (int )node);
- switch (NEFFECT(node).type) {
- case EFFECT_OPTION:
- fprintf(f, "option:%d\n", NEFFECT(node).option);
- print_indent_tree(f, NEFFECT(node).target, indent + add);
+ case NT_ENCLOSE:
+ fprintf(f, "<enclose:%x> ", (int )node);
+ switch (NENCLOSE(node)->type) {
+ case ENCLOSE_OPTION:
+ fprintf(f, "option:%d\n", NENCLOSE(node)->option);
+ print_indent_tree(f, NENCLOSE(node)->target, indent + add);
break;
- case EFFECT_MEMORY:
- fprintf(f, "memory:%d", NEFFECT(node).regnum);
+ case ENCLOSE_MEMORY:
+ fprintf(f, "memory:%d", NENCLOSE(node)->regnum);
break;
- case EFFECT_STOP_BACKTRACK:
+ case ENCLOSE_STOP_BACKTRACK:
fprintf(f, "stop-bt");
break;
@@ -6020,7 +6230,7 @@ print_indent_tree(FILE* f, Node* node, int indent)
break;
}
fprintf(f, "\n");
- print_indent_tree(f, NEFFECT(node).target, indent + add);
+ print_indent_tree(f, NENCLOSE(node)->target, indent + add);
break;
default:
@@ -6028,8 +6238,8 @@ print_indent_tree(FILE* f, Node* node, int indent)
break;
}
- if (type != N_LIST && type != N_ALT && type != N_QUANTIFIER &&
- type != N_EFFECT)
+ if (type != NT_LIST && type != NT_ALT && type != NT_QTFR &&
+ type != NT_ENCLOSE)
fprintf(f, "\n");
fflush(f);
}
diff --git a/ext/mbstring/oniguruma/regenc.c b/ext/mbstring/oniguruma/regenc.c
index 958917e122..80903508b8 100644
--- a/ext/mbstring/oniguruma/regenc.c
+++ b/ext/mbstring/oniguruma/regenc.c
@@ -55,7 +55,7 @@ onigenc_get_right_adjust_char_head(OnigEncoding enc, const UChar* start, const U
{
UChar* p = ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc, start, s);
if (p < s) {
- p += enc_len(enc, p);
+ p += enclen(enc, p);
}
return p;
}
@@ -68,7 +68,7 @@ onigenc_get_right_adjust_char_head_with_prev(OnigEncoding enc,
if (p < s) {
if (prev) *prev = (const UChar* )p;
- p += enc_len(enc, p);
+ p += enclen(enc, p);
}
else {
if (prev) *prev = (const UChar* )NULL; /* Sorry */
@@ -169,52 +169,7 @@ onigenc_str_bytelen_null(OnigEncoding enc, const UChar* s)
}
}
-#ifndef ONIG_RUBY_M17N
-
-#ifndef NOT_RUBY
-
-#define USE_APPLICATION_TO_LOWER_CASE_TABLE
-
-const unsigned short OnigEnc_Unicode_ISO_8859_1_CtypeTable[256] = {
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x228c, 0x2289, 0x2288, 0x2288, 0x2288, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2284, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0,
- 0x38b0, 0x38b0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x31a0,
- 0x21a0, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x2008,
- 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0288, 0x0008, 0x0008,
- 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
- 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
- 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
- 0x0284, 0x01a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0, 0x00a0,
- 0x00a0, 0x00a0, 0x10e2, 0x01a0, 0x00a0, 0x00a8, 0x00a0, 0x00a0,
- 0x00a0, 0x00a0, 0x10a0, 0x10a0, 0x00a0, 0x10e2, 0x00a0, 0x01a0,
- 0x00a0, 0x10a0, 0x10e2, 0x01a0, 0x10a0, 0x10a0, 0x10a0, 0x01a0,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x00a0,
- 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x14a2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x00a0,
- 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2, 0x10e2
-};
-#endif
-
-const UChar* OnigEncAsciiToLowerCaseTable = (const UChar* )0;
-
-#ifndef USE_APPLICATION_TO_LOWER_CASE_TABLE
-static const UChar BuiltInAsciiToLowerCaseTable[] = {
+const UChar OnigEncAsciiToLowerCaseTable[] = {
'\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
'\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
'\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
@@ -248,7 +203,6 @@ static const UChar BuiltInAsciiToLowerCaseTable[] = {
'\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
'\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
};
-#endif /* not USE_APPLICATION_TO_LOWER_CASE_TABLE */
#ifdef USE_UPPER_CASE_TABLE
const UChar OnigEncAsciiToUpperCaseTable[256] = {
@@ -288,23 +242,22 @@ const UChar OnigEncAsciiToUpperCaseTable[256] = {
#endif
const unsigned short OnigEncAsciiCtypeTable[256] = {
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x220c, 0x2209, 0x2208, 0x2208, 0x2208, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008, 0x2008,
- 0x2284, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0, 0x38b0,
- 0x38b0, 0x38b0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x21a0,
- 0x21a0, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x3ca2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2, 0x34a2,
- 0x34a2, 0x34a2, 0x34a2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x31a0,
- 0x21a0, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x38e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2, 0x30e2,
- 0x30e2, 0x30e2, 0x30e2, 0x21a0, 0x21a0, 0x21a0, 0x21a0, 0x2008,
-
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x420c, 0x4209, 0x4208, 0x4208, 0x4208, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008, 0x4008,
+ 0x4284, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0, 0x78b0,
+ 0x78b0, 0x78b0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x41a0,
+ 0x41a0, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x7ca2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2, 0x74a2,
+ 0x74a2, 0x74a2, 0x74a2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x51a0,
+ 0x41a0, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x78e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2, 0x70e2,
+ 0x70e2, 0x70e2, 0x70e2, 0x41a0, 0x41a0, 0x41a0, 0x41a0, 0x4008,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
@@ -396,19 +349,10 @@ const UChar OnigEncISO_8859_1_ToUpperCaseTable[256] = {
#endif
extern void
-onigenc_set_default_caseconv_table(const UChar* table)
+onigenc_set_default_caseconv_table(const UChar* table ARG_UNUSED)
{
- if (table == (const UChar* )0) {
-#ifndef USE_APPLICATION_TO_LOWER_CASE_TABLE
- table = BuiltInAsciiToLowerCaseTable;
-#else
- return ;
-#endif
- }
-
- if (table != OnigEncAsciiToLowerCaseTable) {
- OnigEncAsciiToLowerCaseTable = table;
- }
+ /* nothing */
+ /* obsoleted. */
}
extern UChar*
@@ -417,7 +361,7 @@ onigenc_get_left_adjust_char_head(OnigEncoding enc, const UChar* start, const UC
return ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc, start, s);
}
-const OnigPairAmbigCodes OnigAsciiPairAmbigCodes[] = {
+const OnigPairCaseFoldCodes OnigAsciiLowerMap[] = {
{ 0x41, 0x61 },
{ 0x42, 0x62 },
{ 0x43, 0x63 },
@@ -443,157 +387,175 @@ const OnigPairAmbigCodes OnigAsciiPairAmbigCodes[] = {
{ 0x57, 0x77 },
{ 0x58, 0x78 },
{ 0x59, 0x79 },
- { 0x5a, 0x7a },
-
- { 0x61, 0x41 },
- { 0x62, 0x42 },
- { 0x63, 0x43 },
- { 0x64, 0x44 },
- { 0x65, 0x45 },
- { 0x66, 0x46 },
- { 0x67, 0x47 },
- { 0x68, 0x48 },
- { 0x69, 0x49 },
- { 0x6a, 0x4a },
- { 0x6b, 0x4b },
- { 0x6c, 0x4c },
- { 0x6d, 0x4d },
- { 0x6e, 0x4e },
- { 0x6f, 0x4f },
- { 0x70, 0x50 },
- { 0x71, 0x51 },
- { 0x72, 0x52 },
- { 0x73, 0x53 },
- { 0x74, 0x54 },
- { 0x75, 0x55 },
- { 0x76, 0x56 },
- { 0x77, 0x57 },
- { 0x78, 0x58 },
- { 0x79, 0x59 },
- { 0x7a, 0x5a }
+ { 0x5a, 0x7a }
};
extern int
-onigenc_ascii_get_all_pair_ambig_codes(OnigAmbigType flag,
- const OnigPairAmbigCodes** ccs)
+onigenc_ascii_apply_all_case_fold(OnigCaseFoldType flag ARG_UNUSED,
+ OnigApplyAllCaseFoldFunc f, void* arg)
{
- if (flag == ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) {
- *ccs = OnigAsciiPairAmbigCodes;
- return (sizeof(OnigAsciiPairAmbigCodes) / sizeof(OnigPairAmbigCodes));
- }
- else {
- return 0;
+ OnigCodePoint code;
+ int i, r;
+
+ for (i = 0;
+ i < (int )(sizeof(OnigAsciiLowerMap)/sizeof(OnigPairCaseFoldCodes));
+ i++) {
+ code = OnigAsciiLowerMap[i].to;
+ r = (*f)(OnigAsciiLowerMap[i].from, &code, 1, arg);
+ if (r != 0) return r;
+
+ code = OnigAsciiLowerMap[i].from;
+ r = (*f)(OnigAsciiLowerMap[i].to, &code, 1, arg);
+ if (r != 0) return r;
}
-}
-extern int
-onigenc_nothing_get_all_comp_ambig_codes(OnigAmbigType flag,
- const OnigCompAmbigCodes** ccs)
-{
return 0;
}
extern int
-onigenc_iso_8859_1_get_all_pair_ambig_codes(OnigAmbigType flag,
- const OnigPairAmbigCodes** ccs)
+onigenc_ascii_get_case_fold_codes_by_str(OnigCaseFoldType flag ARG_UNUSED,
+ const OnigUChar* p, const OnigUChar* end ARG_UNUSED,
+ OnigCaseFoldCodeItem items[])
{
- static const OnigPairAmbigCodes cc[] = {
- { 0xc0, 0xe0 },
- { 0xc1, 0xe1 },
- { 0xc2, 0xe2 },
- { 0xc3, 0xe3 },
- { 0xc4, 0xe4 },
- { 0xc5, 0xe5 },
- { 0xc6, 0xe6 },
- { 0xc7, 0xe7 },
- { 0xc8, 0xe8 },
- { 0xc9, 0xe9 },
- { 0xca, 0xea },
- { 0xcb, 0xeb },
- { 0xcc, 0xec },
- { 0xcd, 0xed },
- { 0xce, 0xee },
- { 0xcf, 0xef },
-
- { 0xd0, 0xf0 },
- { 0xd1, 0xf1 },
- { 0xd2, 0xf2 },
- { 0xd3, 0xf3 },
- { 0xd4, 0xf4 },
- { 0xd5, 0xf5 },
- { 0xd6, 0xf6 },
- { 0xd8, 0xf8 },
- { 0xd9, 0xf9 },
- { 0xda, 0xfa },
- { 0xdb, 0xfb },
- { 0xdc, 0xfc },
- { 0xdd, 0xfd },
- { 0xde, 0xfe },
-
- { 0xe0, 0xc0 },
- { 0xe1, 0xc1 },
- { 0xe2, 0xc2 },
- { 0xe3, 0xc3 },
- { 0xe4, 0xc4 },
- { 0xe5, 0xc5 },
- { 0xe6, 0xc6 },
- { 0xe7, 0xc7 },
- { 0xe8, 0xc8 },
- { 0xe9, 0xc9 },
- { 0xea, 0xca },
- { 0xeb, 0xcb },
- { 0xec, 0xcc },
- { 0xed, 0xcd },
- { 0xee, 0xce },
- { 0xef, 0xcf },
-
- { 0xf0, 0xd0 },
- { 0xf1, 0xd1 },
- { 0xf2, 0xd2 },
- { 0xf3, 0xd3 },
- { 0xf4, 0xd4 },
- { 0xf5, 0xd5 },
- { 0xf6, 0xd6 },
- { 0xf8, 0xd8 },
- { 0xf9, 0xd9 },
- { 0xfa, 0xda },
- { 0xfb, 0xdb },
- { 0xfc, 0xdc },
- { 0xfd, 0xdd },
- { 0xfe, 0xde }
- };
-
- if (flag == ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) {
- *ccs = OnigAsciiPairAmbigCodes;
- return (sizeof(OnigAsciiPairAmbigCodes) / sizeof(OnigPairAmbigCodes));
+ if (0x41 <= *p && *p <= 0x5a) {
+ items[0].byte_len = 1;
+ items[0].code_len = 1;
+ items[0].code[0] = (OnigCodePoint )(*p + 0x20);
+ return 1;
}
- else if (flag == ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) {
- *ccs = cc;
- return sizeof(cc) / sizeof(OnigPairAmbigCodes);
+ else if (0x61 <= *p && *p <= 0x7a) {
+ items[0].byte_len = 1;
+ items[0].code_len = 1;
+ items[0].code[0] = (OnigCodePoint )(*p - 0x20);
+ return 1;
}
else
return 0;
}
+static int
+ss_apply_all_case_fold(OnigCaseFoldType flag ARG_UNUSED,
+ OnigApplyAllCaseFoldFunc f, void* arg)
+{
+ static OnigCodePoint ss[] = { 0x73, 0x73 };
+
+ return (*f)((OnigCodePoint )0xdf, ss, 2, arg);
+}
+
extern int
-onigenc_ess_tsett_get_all_comp_ambig_codes(OnigAmbigType flag,
- const OnigCompAmbigCodes** ccs)
+onigenc_apply_all_case_fold_with_map(int map_size,
+ const OnigPairCaseFoldCodes map[],
+ int ess_tsett_flag, OnigCaseFoldType flag,
+ OnigApplyAllCaseFoldFunc f, void* arg)
{
- static const OnigCompAmbigCodes folds[] = {
- { 2, 0xdf, {{ 2, { 0x53, 0x53 } }, { 2, { 0x73, 0x73} } } }
- };
+ OnigCodePoint code;
+ int i, r;
+
+ r = onigenc_ascii_apply_all_case_fold(flag, f, arg);
+ if (r != 0) return r;
- if (flag == ONIGENC_AMBIGUOUS_MATCH_NONASCII_CASE) {
- *ccs = folds;
- return sizeof(folds) / sizeof(OnigCompAmbigCodes);
+ for (i = 0; i < map_size; i++) {
+ code = map[i].to;
+ r = (*f)(map[i].from, &code, 1, arg);
+ if (r != 0) return r;
+
+ code = map[i].from;
+ r = (*f)(map[i].to, &code, 1, arg);
+ if (r != 0) return r;
}
- else
- return 0;
+
+ if (ess_tsett_flag != 0)
+ return ss_apply_all_case_fold(flag, f, arg);
+
+ return 0;
}
extern int
-onigenc_not_support_get_ctype_code_range(int ctype,
- const OnigCodePoint* sbr[], const OnigCodePoint* mbr[])
+onigenc_get_case_fold_codes_by_str_with_map(int map_size,
+ const OnigPairCaseFoldCodes map[],
+ int ess_tsett_flag, OnigCaseFoldType flag ARG_UNUSED,
+ const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[])
+{
+ if (0x41 <= *p && *p <= 0x5a) {
+ items[0].byte_len = 1;
+ items[0].code_len = 1;
+ items[0].code[0] = (OnigCodePoint )(*p + 0x20);
+ if (*p == 0x53 && ess_tsett_flag != 0 && end > p + 1
+ && (*(p+1) == 0x53 || *(p+1) == 0x73)) {
+ /* SS */
+ items[1].byte_len = 2;
+ items[1].code_len = 1;
+ items[1].code[0] = (OnigCodePoint )0xdf;
+ return 2;
+ }
+ else
+ return 1;
+ }
+ else if (0x61 <= *p && *p <= 0x7a) {
+ items[0].byte_len = 1;
+ items[0].code_len = 1;
+ items[0].code[0] = (OnigCodePoint )(*p - 0x20);
+ if (*p == 0x73 && ess_tsett_flag != 0 && end > p + 1
+ && (*(p+1) == 0x73 || *(p+1) == 0x53)) {
+ /* ss */
+ items[1].byte_len = 2;
+ items[1].code_len = 1;
+ items[1].code[0] = (OnigCodePoint )0xdf;
+ return 2;
+ }
+ else
+ return 1;
+ }
+ else if (*p == 0xdf && ess_tsett_flag != 0) {
+ items[0].byte_len = 1;
+ items[0].code_len = 2;
+ items[0].code[0] = (OnigCodePoint )'s';
+ items[0].code[1] = (OnigCodePoint )'s';
+
+ items[1].byte_len = 1;
+ items[1].code_len = 2;
+ items[1].code[0] = (OnigCodePoint )'S';
+ items[1].code[1] = (OnigCodePoint )'S';
+
+ items[2].byte_len = 1;
+ items[2].code_len = 2;
+ items[2].code[0] = (OnigCodePoint )'s';
+ items[2].code[1] = (OnigCodePoint )'S';
+
+ items[3].byte_len = 1;
+ items[3].code_len = 2;
+ items[3].code[0] = (OnigCodePoint )'S';
+ items[3].code[1] = (OnigCodePoint )'s';
+
+ return 4;
+ }
+ else {
+ int i;
+
+ for (i = 0; i < map_size; i++) {
+ if (*p == map[i].from) {
+ items[0].byte_len = 1;
+ items[0].code_len = 1;
+ items[0].code[0] = map[i].to;
+ return 1;
+ }
+ else if (*p == map[i].to) {
+ items[0].byte_len = 1;
+ items[0].code_len = 1;
+ items[0].code[0] = map[i].from;
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+extern int
+onigenc_not_support_get_ctype_code_range(OnigCtype ctype ARG_UNUSED,
+ OnigCodePoint* sb_out ARG_UNUSED,
+ const OnigCodePoint* ranges[] ARG_UNUSED)
{
return ONIG_NO_SUPPORT_CONFIG;
}
@@ -609,57 +571,43 @@ onigenc_is_mbc_newline_0x0a(const UChar* p, const UChar* end)
/* for single byte encodings */
extern int
-onigenc_ascii_mbc_to_normalize(OnigAmbigType flag, const UChar** p, const UChar*end,
- UChar* lower)
+onigenc_ascii_mbc_case_fold(OnigCaseFoldType flag ARG_UNUSED, const UChar** p,
+ const UChar*end ARG_UNUSED, UChar* lower)
{
- if ((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0) {
- *lower = ONIGENC_ASCII_CODE_TO_LOWER_CASE(**p);
- }
- else {
- *lower = **p;
- }
+ *lower = ONIGENC_ASCII_CODE_TO_LOWER_CASE(**p);
(*p)++;
return 1; /* return byte length of converted char to lower */
}
+#if 0
extern int
-onigenc_ascii_is_mbc_ambiguous(OnigAmbigType flag,
+onigenc_ascii_is_mbc_ambiguous(OnigCaseFoldType flag,
const UChar** pp, const UChar* end)
{
const UChar* p = *pp;
(*pp)++;
- if ((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0) {
- return ONIGENC_IS_ASCII_CODE_CASE_AMBIG(*p);
- }
- else {
- return FALSE;
- }
+ return ONIGENC_IS_ASCII_CODE_CASE_AMBIG(*p);
}
+#endif
extern int
-onigenc_single_byte_mbc_enc_len(const UChar* p)
+onigenc_single_byte_mbc_enc_len(const UChar* p ARG_UNUSED)
{
return 1;
}
extern OnigCodePoint
-onigenc_single_byte_mbc_to_code(const UChar* p, const UChar* end)
+onigenc_single_byte_mbc_to_code(const UChar* p, const UChar* end ARG_UNUSED)
{
return (OnigCodePoint )(*p);
}
extern int
-onigenc_single_byte_code_to_mbclen(OnigCodePoint code)
-{
- return 1;
-}
-
-extern int
-onigenc_single_byte_code_to_mbc_first(OnigCodePoint code)
+onigenc_single_byte_code_to_mbclen(OnigCodePoint code ARG_UNUSED)
{
- return (code & 0xff);
+ return (code < 0x100 ? 1 : ONIGERR_INVALID_CODE_POINT_VALUE);
}
extern int
@@ -670,19 +618,22 @@ onigenc_single_byte_code_to_mbc(OnigCodePoint code, UChar *buf)
}
extern UChar*
-onigenc_single_byte_left_adjust_char_head(const UChar* start, const UChar* s)
+onigenc_single_byte_left_adjust_char_head(const UChar* start ARG_UNUSED,
+ const UChar* s)
{
return (UChar* )s;
}
extern int
-onigenc_always_true_is_allowed_reverse_match(const UChar* s, const UChar* end)
+onigenc_always_true_is_allowed_reverse_match(const UChar* s ARG_UNUSED,
+ const UChar* end ARG_UNUSED)
{
return TRUE;
}
extern int
-onigenc_always_false_is_allowed_reverse_match(const UChar* s, const UChar* end)
+onigenc_always_false_is_allowed_reverse_match(const UChar* s ARG_UNUSED,
+ const UChar* end ARG_UNUSED)
{
return FALSE;
}
@@ -693,7 +644,7 @@ onigenc_mbn_mbc_to_code(OnigEncoding enc, const UChar* p, const UChar* end)
int c, i, len;
OnigCodePoint n;
- len = enc_len(enc, p);
+ len = enclen(enc, p);
n = (OnigCodePoint )(*p++);
if (len == 1) return n;
@@ -706,54 +657,46 @@ onigenc_mbn_mbc_to_code(OnigEncoding enc, const UChar* p, const UChar* end)
}
extern int
-onigenc_mbn_mbc_to_normalize(OnigEncoding enc, OnigAmbigType flag,
- const UChar** pp, const UChar* end, UChar* lower)
+onigenc_mbn_mbc_case_fold(OnigEncoding enc, OnigCaseFoldType flag ARG_UNUSED,
+ const UChar** pp, const UChar* end ARG_UNUSED,
+ UChar* lower)
{
int len;
const UChar *p = *pp;
if (ONIGENC_IS_MBC_ASCII(p)) {
- if ((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0) {
- *lower = ONIGENC_ASCII_CODE_TO_LOWER_CASE(*p);
- }
- else {
- *lower = *p;
- }
+ *lower = ONIGENC_ASCII_CODE_TO_LOWER_CASE(*p);
(*pp)++;
return 1;
}
else {
- len = enc_len(enc, p);
- if (lower != p) {
- int i;
- for (i = 0; i < len; i++) {
- *lower++ = *p++;
- }
+ int i;
+
+ len = enclen(enc, p);
+ for (i = 0; i < len; i++) {
+ *lower++ = *p++;
}
(*pp) += len;
return len; /* return byte length of converted to lower char */
}
}
+#if 0
extern int
-onigenc_mbn_is_mbc_ambiguous(OnigEncoding enc, OnigAmbigType flag,
+onigenc_mbn_is_mbc_ambiguous(OnigEncoding enc, OnigCaseFoldType flag,
const UChar** pp, const UChar* end)
{
const UChar* p = *pp;
if (ONIGENC_IS_MBC_ASCII(p)) {
(*pp)++;
- if ((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0) {
- return ONIGENC_IS_ASCII_CODE_CASE_AMBIG(*p);
- }
- else {
- return FALSE;
- }
+ return ONIGENC_IS_ASCII_CODE_CASE_AMBIG(*p);
}
- (*pp) += enc_len(enc, p);
+ (*pp) += enclen(enc, p);
return FALSE;
}
+#endif
extern int
onigenc_mb2_code_to_mbclen(OnigCodePoint code)
@@ -772,40 +715,6 @@ onigenc_mb4_code_to_mbclen(OnigCodePoint code)
}
extern int
-onigenc_mb2_code_to_mbc_first(OnigCodePoint code)
-{
- int first;
-
- if ((code & 0xff00) != 0) {
- first = (code >> 8) & 0xff;
- }
- else {
- return (int )code;
- }
- return first;
-}
-
-extern int
-onigenc_mb4_code_to_mbc_first(OnigCodePoint code)
-{
- int first;
-
- if ((code & 0xff000000) != 0) {
- first = (code >> 24) & 0xff;
- }
- else if ((code & 0xff0000) != 0) {
- first = (code >> 16) & 0xff;
- }
- else if ((code & 0xff00) != 0) {
- first = (code >> 8) & 0xff;
- }
- else {
- return (int )code;
- }
- return first;
-}
-
-extern int
onigenc_mb2_code_to_mbc(OnigEncoding enc, OnigCodePoint code, UChar *buf)
{
UChar *p = buf;
@@ -816,8 +725,8 @@ onigenc_mb2_code_to_mbc(OnigEncoding enc, OnigCodePoint code, UChar *buf)
*p++ = (UChar )(code & 0xff);
#if 1
- if (enc_len(enc, buf) != (p - buf))
- return ONIGENCERR_INVALID_WIDE_CHAR_VALUE;
+ if (enclen(enc, buf) != (p - buf))
+ return ONIGERR_INVALID_CODE_POINT_VALUE;
#endif
return p - buf;
}
@@ -839,21 +748,54 @@ onigenc_mb4_code_to_mbc(OnigEncoding enc, OnigCodePoint code, UChar *buf)
*p++ = (UChar )(code & 0xff);
#if 1
- if (enc_len(enc, buf) != (p - buf))
- return ONIGENCERR_INVALID_WIDE_CHAR_VALUE;
+ if (enclen(enc, buf) != (p - buf))
+ return ONIGERR_INVALID_CODE_POINT_VALUE;
#endif
return p - buf;
}
extern int
+onigenc_minimum_property_name_to_ctype(OnigEncoding enc, UChar* p, UChar* end)
+{
+ static PosixBracketEntryType PBS[] = {
+ { (UChar* )"Alnum", ONIGENC_CTYPE_ALNUM, 5 },
+ { (UChar* )"Alpha", ONIGENC_CTYPE_ALPHA, 5 },
+ { (UChar* )"Blank", ONIGENC_CTYPE_BLANK, 5 },
+ { (UChar* )"Cntrl", ONIGENC_CTYPE_CNTRL, 5 },
+ { (UChar* )"Digit", ONIGENC_CTYPE_DIGIT, 5 },
+ { (UChar* )"Graph", ONIGENC_CTYPE_GRAPH, 5 },
+ { (UChar* )"Lower", ONIGENC_CTYPE_LOWER, 5 },
+ { (UChar* )"Print", ONIGENC_CTYPE_PRINT, 5 },
+ { (UChar* )"Punct", ONIGENC_CTYPE_PUNCT, 5 },
+ { (UChar* )"Space", ONIGENC_CTYPE_SPACE, 5 },
+ { (UChar* )"Upper", ONIGENC_CTYPE_UPPER, 5 },
+ { (UChar* )"XDigit", ONIGENC_CTYPE_XDIGIT, 6 },
+ { (UChar* )"ASCII", ONIGENC_CTYPE_ASCII, 5 },
+ { (UChar* )"Word", ONIGENC_CTYPE_WORD, 4 },
+ { (UChar* )NULL, -1, 0 }
+ };
+
+ PosixBracketEntryType *pb;
+ int len;
+
+ len = onigenc_strlen(enc, p, end);
+ for (pb = PBS; IS_NOT_NULL(pb->name); pb++) {
+ if (len == pb->len &&
+ onigenc_with_ascii_strncmp(enc, p, end, pb->name, pb->len) == 0)
+ return pb->ctype;
+ }
+
+ return ONIGERR_INVALID_CHAR_PROPERTY_NAME;
+}
+
+extern int
onigenc_mb2_is_code_ctype(OnigEncoding enc, OnigCodePoint code,
unsigned int ctype)
{
if (code < 128)
return ONIGENC_IS_ASCII_CODE_CTYPE(code, ctype);
else {
- if ((ctype & (ONIGENC_CTYPE_WORD |
- ONIGENC_CTYPE_GRAPH | ONIGENC_CTYPE_PRINT)) != 0) {
+ if (CTYPE_IS_WORD_GRAPH_PRINT(ctype)) {
return (ONIGENC_CODE_TO_MBCLEN(enc, code) > 1 ? TRUE : FALSE);
}
}
@@ -868,8 +810,7 @@ onigenc_mb4_is_code_ctype(OnigEncoding enc, OnigCodePoint code,
if (code < 128)
return ONIGENC_IS_ASCII_CODE_CTYPE(code, ctype);
else {
- if ((ctype & (ONIGENC_CTYPE_WORD |
- ONIGENC_CTYPE_GRAPH | ONIGENC_CTYPE_PRINT)) != 0) {
+ if (CTYPE_IS_WORD_GRAPH_PRINT(ctype)) {
return (ONIGENC_CODE_TO_MBCLEN(enc, code) > 1 ? TRUE : FALSE);
}
}
@@ -891,138 +832,71 @@ onigenc_with_ascii_strncmp(OnigEncoding enc, const UChar* p, const UChar* end,
if (x) return x;
sascii++;
- p += enc_len(enc, p);
+ p += enclen(enc, p);
}
return 0;
}
-#else /* ONIG_RUBY_M17N */
-
-extern int
-onigenc_is_code_ctype(OnigEncoding enc, OnigCodePoint code, int ctype)
+/* Property management */
+static int
+resize_property_list(int new_size, const OnigCodePoint*** plist, int* psize)
{
- switch (ctype) {
- case ONIGENC_CTYPE_NEWLINE:
- if (code == 0x0a) return 1;
- break;
-
- case ONIGENC_CTYPE_ALPHA:
- return m17n_isalpha(enc, code);
- break;
- case ONIGENC_CTYPE_BLANK:
- return ONIGENC_IS_CODE_BLANK(enc, (int )(code));
- break;
- case ONIGENC_CTYPE_CNTRL:
- return m17n_iscntrl(enc, code);
- break;
- case ONIGENC_CTYPE_DIGIT:
- return m17n_isdigit(enc, code);
- break;
- case ONIGENC_CTYPE_GRAPH:
- return ONIGENC_IS_CODE_GRAPH(enc, (int )(code));
- break;
- case ONIGENC_CTYPE_LOWER:
- return m17n_islower(enc, code);
- break;
- case ONIGENC_CTYPE_PRINT:
- return m17n_isprint(enc, code);
- break;
- case ONIGENC_CTYPE_PUNCT:
- return m17n_ispunct(enc, code);
- break;
- case ONIGENC_CTYPE_SPACE:
- return m17n_isspace(enc, code);
- break;
- case ONIGENC_CTYPE_UPPER:
- return m17n_isupper(enc, code);
- break;
- case ONIGENC_CTYPE_XDIGIT:
- return m17n_isxdigit(enc, code);
- break;
- case ONIGENC_CTYPE_WORD:
- return m17n_iswchar(enc, code);
- break;
- case ONIGENC_CTYPE_ASCII:
- return (code < 128 ? TRUE : FALSE);
- break;
- case ONIGENC_CTYPE_ALNUM:
- return m17n_isalnum(enc, code);
- break;
- default:
- break;
+ int size;
+ const OnigCodePoint **list = *plist;
+
+ size = sizeof(OnigCodePoint*) * new_size;
+ if (IS_NULL(list)) {
+ list = (const OnigCodePoint** )xmalloc(size);
+ }
+ else {
+ list = (const OnigCodePoint** )xrealloc((void* )list, size);
}
- return 0;
-}
+ if (IS_NULL(list)) return ONIGERR_MEMORY;
-extern int
-onigenc_code_to_mbc(OnigEncoding enc, OnigCodePoint code, UChar *buf)
-{
- int c, len;
+ *plist = list;
+ *psize = new_size;
- m17n_mbcput(enc, code, buf);
- c = m17n_firstbyte(enc, code);
- len = enc_len(enc, c);
- return len;
+ return 0;
}
extern int
-onigenc_mbc_to_lower(OnigEncoding enc, UChar* p, UChar* buf)
+onigenc_property_list_add_property(UChar* name, const OnigCodePoint* prop,
+ hash_table_type **table, const OnigCodePoint*** plist, int *pnum,
+ int *psize)
{
- unsigned int c, low;
-
- c = m17n_codepoint(enc, p, p + enc_len(enc, *p));
- low = m17n_tolower(enc, c);
- m17n_mbcput(enc, low, buf);
+#define PROP_INIT_SIZE 16
- return m17n_codelen(enc, low);
-}
+ int r;
-extern int
-onigenc_is_mbc_ambiguous(OnigEncoding enc, OnigAmbigType flag,
- UChar** pp, UChar* end)
-{
- int len;
- unsigned int c;
- UChar* p = *pp;
+ if (*psize <= *pnum) {
+ int new_size = (*psize == 0 ? PROP_INIT_SIZE : *psize * 2);
+ r = resize_property_list(new_size, plist, psize);
+ if (r != 0) return r;
+ }
- len = enc_len(enc, *p);
- (*pp) += len;
- c = m17n_codepoint(enc, p, p + len);
+ (*plist)[*pnum] = prop;
- if ((flag & ONIGENC_AMBIGUOUS_MATCH_ASCII_CASE) != 0) {
- if (m17n_isupper(enc, c) || m17n_islower(enc, c))
- return TRUE;
+ if (ONIG_IS_NULL(*table)) {
+ *table = onig_st_init_strend_table_with_size(PROP_INIT_SIZE);
+ if (ONIG_IS_NULL(*table)) return ONIGERR_MEMORY;
}
- return FALSE;
+ *pnum = *pnum + 1;
+ onig_st_insert_strend(*table, name, name + strlen((char* )name),
+ (hash_data_type )(*pnum + ONIGENC_MAX_STD_CTYPE));
+ return 0;
}
-extern UChar*
-onigenc_get_left_adjust_char_head(OnigEncoding enc, UChar* start, UChar* s)
+extern int
+onigenc_property_list_init(int (*f)(void))
{
- UChar *p;
- int len;
+ int r;
- if (s <= start) return s;
- p = s;
+ THREAD_ATOMIC_START;
- while (!m17n_islead(enc, *p) && p > start) p--;
- while (p + (len = enc_len(enc, *p)) < s) {
- p += len;
- }
- if (p + len == s) return s;
- return p;
-}
+ r = f();
-extern int
-onigenc_is_allowed_reverse_match(OnigEncoding enc,
- const UChar* s, const UChar* end)
-{
- return ONIGENC_IS_SINGLEBYTE(enc);
+ THREAD_ATOMIC_END;
+ return r;
}
-
-extern void
-onigenc_set_default_caseconv_table(UChar* table) { }
-
-#endif /* ONIG_RUBY_M17N */
diff --git a/ext/mbstring/oniguruma/regenc.h b/ext/mbstring/oniguruma/regenc.h
index 58ee3e7f22..40963280dc 100644
--- a/ext/mbstring/oniguruma/regenc.h
+++ b/ext/mbstring/oniguruma/regenc.h
@@ -4,7 +4,7 @@
regenc.h - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2006 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2008 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -29,11 +29,23 @@
* SUCH DAMAGE.
*/
-#ifndef RUBY_PLATFORM
+#ifndef PACKAGE
+/* PACKAGE is defined in config.h */
#include "config.h"
#endif
+
+#ifdef ONIG_ESCAPE_UCHAR_COLLISION
+#undef ONIG_ESCAPE_UCHAR_COLLISION
+#endif
+
#include "oniguruma.h"
+typedef struct {
+ OnigCodePoint from;
+ OnigCodePoint to;
+} OnigPairCaseFoldCodes;
+
+
#ifndef NULL
#define NULL ((void* )0)
#endif
@@ -46,45 +58,73 @@
#define FALSE 0
#endif
-/* error codes */
-#define ONIGENCERR_MEMORY -5
-#define ONIGENCERR_TYPE_BUG -6
-#define ONIGENCERR_INVALID_WIDE_CHAR_VALUE -400
-#define ONIGENCERR_TOO_BIG_WIDE_CHAR_VALUE -401
+#ifndef ARG_UNUSED
+#if defined(__GNUC__)
+# define ARG_UNUSED __attribute__ ((unused))
+#else
+# define ARG_UNUSED
+#endif
+#endif
#define ONIG_IS_NULL(p) (((void*)(p)) == (void*)0)
#define ONIG_IS_NOT_NULL(p) (((void*)(p)) != (void*)0)
#define ONIG_CHECK_NULL_RETURN(p) if (ONIG_IS_NULL(p)) return NULL
#define ONIG_CHECK_NULL_RETURN_VAL(p,val) if (ONIG_IS_NULL(p)) return (val)
-
-#ifdef ONIG_RUBY_M17N
-
-#define ONIG_ENCODING_INIT_DEFAULT ONIG_ENCODING_UNDEF
-
-#else /* ONIG_RUBY_M17N */
-
-#define USE_UNICODE_FULL_RANGE_CTYPE
-/* following must not use with USE_CRNL_AS_LINE_TERMINATOR */
+#define enclen(enc,p) ONIGENC_MBC_ENC_LEN(enc,p)
+
+/* character types bit flag */
+#define BIT_CTYPE_NEWLINE (1<< ONIGENC_CTYPE_NEWLINE)
+#define BIT_CTYPE_ALPHA (1<< ONIGENC_CTYPE_ALPHA)
+#define BIT_CTYPE_BLANK (1<< ONIGENC_CTYPE_BLANK)
+#define BIT_CTYPE_CNTRL (1<< ONIGENC_CTYPE_CNTRL)
+#define BIT_CTYPE_DIGIT (1<< ONIGENC_CTYPE_DIGIT)
+#define BIT_CTYPE_GRAPH (1<< ONIGENC_CTYPE_GRAPH)
+#define BIT_CTYPE_LOWER (1<< ONIGENC_CTYPE_LOWER)
+#define BIT_CTYPE_PRINT (1<< ONIGENC_CTYPE_PRINT)
+#define BIT_CTYPE_PUNCT (1<< ONIGENC_CTYPE_PUNCT)
+#define BIT_CTYPE_SPACE (1<< ONIGENC_CTYPE_SPACE)
+#define BIT_CTYPE_UPPER (1<< ONIGENC_CTYPE_UPPER)
+#define BIT_CTYPE_XDIGIT (1<< ONIGENC_CTYPE_XDIGIT)
+#define BIT_CTYPE_WORD (1<< ONIGENC_CTYPE_WORD)
+#define BIT_CTYPE_ALNUM (1<< ONIGENC_CTYPE_ALNUM)
+#define BIT_CTYPE_ASCII (1<< ONIGENC_CTYPE_ASCII)
+
+#define CTYPE_TO_BIT(ctype) (1<<(ctype))
+#define CTYPE_IS_WORD_GRAPH_PRINT(ctype) \
+ ((ctype) == ONIGENC_CTYPE_WORD || (ctype) == ONIGENC_CTYPE_GRAPH ||\
+ (ctype) == ONIGENC_CTYPE_PRINT)
+
+
+typedef struct {
+ UChar *name;
+ int ctype;
+ short int len;
+} PosixBracketEntryType;
+
+
+/* #define USE_CRNL_AS_LINE_TERMINATOR */
+#define USE_UNICODE_PROPERTIES
+/* #define USE_UNICODE_CASE_FOLD_TURKISH_AZERI */
/* #define USE_UNICODE_ALL_LINE_TERMINATORS */ /* see Unicode.org UTF#18 */
+
#define ONIG_ENCODING_INIT_DEFAULT ONIG_ENCODING_ASCII
/* for encoding system implementation (internal) */
-ONIG_EXTERN int onigenc_ascii_get_all_pair_ambig_codes P_((OnigAmbigType flag, const OnigPairAmbigCodes** acs));
-ONIG_EXTERN int onigenc_nothing_get_all_comp_ambig_codes P_((OnigAmbigType flag, const OnigCompAmbigCodes** acs));
-ONIG_EXTERN int onigenc_iso_8859_1_get_all_pair_ambig_codes P_((OnigAmbigType flag, const OnigPairAmbigCodes** acs));
-ONIG_EXTERN int onigenc_ess_tsett_get_all_comp_ambig_codes P_((OnigAmbigType flag, const OnigCompAmbigCodes** acs));
-ONIG_EXTERN int onigenc_not_support_get_ctype_code_range P_((int ctype, const OnigCodePoint* sbr[], const OnigCodePoint* mbr[]));
+ONIG_EXTERN int onigenc_ascii_apply_all_case_fold P_((OnigCaseFoldType flag, OnigApplyAllCaseFoldFunc f, void* arg));
+ONIG_EXTERN int onigenc_ascii_get_case_fold_codes_by_str P_((OnigCaseFoldType flag, const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[]));
+ONIG_EXTERN int onigenc_apply_all_case_fold_with_map P_((int map_size, const OnigPairCaseFoldCodes map[], int ess_tsett_flag, OnigCaseFoldType flag, OnigApplyAllCaseFoldFunc f, void* arg));
+ONIG_EXTERN int onigenc_get_case_fold_codes_by_str_with_map P_((int map_size, const OnigPairCaseFoldCodes map[], int ess_tsett_flag, OnigCaseFoldType flag, const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[]));
+ONIG_EXTERN int onigenc_not_support_get_ctype_code_range P_((OnigCtype ctype, OnigCodePoint* sb_out, const OnigCodePoint* ranges[]));
ONIG_EXTERN int onigenc_is_mbc_newline_0x0a P_((const UChar* p, const UChar* end));
+
/* methods for single byte encoding */
-ONIG_EXTERN int onigenc_ascii_mbc_to_normalize P_((OnigAmbigType flag, const UChar** p, const UChar* end, UChar* lower));
-ONIG_EXTERN int onigenc_ascii_is_mbc_ambiguous P_((OnigAmbigType flag, const UChar** p, const UChar* end));
+ONIG_EXTERN int onigenc_ascii_mbc_case_fold P_((OnigCaseFoldType flag, const UChar** p, const UChar* end, UChar* lower));
ONIG_EXTERN int onigenc_single_byte_mbc_enc_len P_((const UChar* p));
ONIG_EXTERN OnigCodePoint onigenc_single_byte_mbc_to_code P_((const UChar* p, const UChar* end));
ONIG_EXTERN int onigenc_single_byte_code_to_mbclen P_((OnigCodePoint code));
-ONIG_EXTERN int onigenc_single_byte_code_to_mbc_first P_((OnigCodePoint code));
ONIG_EXTERN int onigenc_single_byte_code_to_mbc P_((OnigCodePoint code, UChar *buf));
ONIG_EXTERN UChar* onigenc_single_byte_left_adjust_char_head P_((const UChar* start, const UChar* s));
ONIG_EXTERN int onigenc_always_true_is_allowed_reverse_match P_((const UChar* s, const UChar* end));
@@ -92,37 +132,36 @@ ONIG_EXTERN int onigenc_always_false_is_allowed_reverse_match P_((const UChar* s
/* methods for multi byte encoding */
ONIG_EXTERN OnigCodePoint onigenc_mbn_mbc_to_code P_((OnigEncoding enc, const UChar* p, const UChar* end));
-ONIG_EXTERN int onigenc_mbn_mbc_to_normalize P_((OnigEncoding enc, OnigAmbigType flag, const UChar** p, const UChar* end, UChar* lower));
-ONIG_EXTERN int onigenc_mbn_is_mbc_ambiguous P_((OnigEncoding enc, OnigAmbigType flag, const UChar** p, const UChar* end));
+ONIG_EXTERN int onigenc_mbn_mbc_case_fold P_((OnigEncoding enc, OnigCaseFoldType flag, const UChar** p, const UChar* end, UChar* lower));
ONIG_EXTERN int onigenc_mb2_code_to_mbclen P_((OnigCodePoint code));
-ONIG_EXTERN int onigenc_mb2_code_to_mbc_first P_((OnigCodePoint code));
ONIG_EXTERN int onigenc_mb2_code_to_mbc P_((OnigEncoding enc, OnigCodePoint code, UChar *buf));
+ONIG_EXTERN int onigenc_minimum_property_name_to_ctype P_((OnigEncoding enc, UChar* p, UChar* end));
+ONIG_EXTERN int onigenc_unicode_property_name_to_ctype P_((OnigEncoding enc, UChar* p, UChar* end));
ONIG_EXTERN int onigenc_mb2_is_code_ctype P_((OnigEncoding enc, OnigCodePoint code, unsigned int ctype));
ONIG_EXTERN int onigenc_mb4_code_to_mbclen P_((OnigCodePoint code));
-ONIG_EXTERN int onigenc_mb4_code_to_mbc_first P_((OnigCodePoint code));
ONIG_EXTERN int onigenc_mb4_code_to_mbc P_((OnigEncoding enc, OnigCodePoint code, UChar *buf));
ONIG_EXTERN int onigenc_mb4_is_code_ctype P_((OnigEncoding enc, OnigCodePoint code, unsigned int ctype));
-ONIG_EXTERN int onigenc_get_all_fold_match_code_ss_0xdf P_((OnigCodePoint** codes));
/* in enc/unicode.c */
ONIG_EXTERN int onigenc_unicode_is_code_ctype P_((OnigCodePoint code, unsigned int ctype));
-ONIG_EXTERN int onigenc_unicode_get_ctype_code_range P_((int ctype, const OnigCodePoint* sbr[], const OnigCodePoint* mbr[]));
+ONIG_EXTERN int onigenc_utf16_32_get_ctype_code_range P_((OnigCtype ctype, OnigCodePoint *sb_out, const OnigCodePoint* ranges[]));
+ONIG_EXTERN int onigenc_unicode_ctype_code_range P_((int ctype, const OnigCodePoint* ranges[]));
+ONIG_EXTERN int onigenc_unicode_get_case_fold_codes_by_str P_((OnigEncoding enc, OnigCaseFoldType flag, const OnigUChar* p, const OnigUChar* end, OnigCaseFoldCodeItem items[]));
+ONIG_EXTERN int onigenc_unicode_mbc_case_fold P_((OnigEncoding enc, OnigCaseFoldType flag, const UChar** pp, const UChar* end, UChar* fold));
+ONIG_EXTERN int onigenc_unicode_apply_all_case_fold P_((OnigCaseFoldType flag, OnigApplyAllCaseFoldFunc f, void* arg));
+
+#define UTF16_IS_SURROGATE_FIRST(c) (((c) & 0xfc) == 0xd8)
+#define UTF16_IS_SURROGATE_SECOND(c) (((c) & 0xfc) == 0xdc)
#define ONIGENC_ISO_8859_1_TO_LOWER_CASE(c) \
OnigEncISO_8859_1_ToLowerCaseTable[c]
#define ONIGENC_ISO_8859_1_TO_UPPER_CASE(c) \
OnigEncISO_8859_1_ToUpperCaseTable[c]
-#define ONIGENC_IS_UNICODE_ISO_8859_1_CTYPE(code,ctype) \
- ((OnigEnc_Unicode_ISO_8859_1_CtypeTable[code] & ctype) != 0)
ONIG_EXTERN const UChar OnigEncISO_8859_1_ToLowerCaseTable[];
ONIG_EXTERN const UChar OnigEncISO_8859_1_ToUpperCaseTable[];
-ONIG_EXTERN const unsigned short OnigEnc_Unicode_ISO_8859_1_CtypeTable[];
-ONIG_EXTERN const OnigPairAmbigCodes OnigAsciiPairAmbigCodes[];
-
-#endif /* is not ONIG_RUBY_M17N */
ONIG_EXTERN int
onigenc_with_ascii_strncmp P_((OnigEncoding enc, const UChar* p, const UChar* end, const UChar* sascii /* ascii */, int n));
@@ -133,15 +172,18 @@ onigenc_step P_((OnigEncoding enc, const UChar* p, const UChar* end, int n));
extern int onig_is_in_code_range P_((const UChar* p, OnigCodePoint code));
ONIG_EXTERN OnigEncoding OnigEncDefaultCharEncoding;
-ONIG_EXTERN const UChar* OnigEncAsciiToLowerCaseTable;
+ONIG_EXTERN const UChar OnigEncAsciiToLowerCaseTable[];
ONIG_EXTERN const UChar OnigEncAsciiToUpperCaseTable[];
ONIG_EXTERN const unsigned short OnigEncAsciiCtypeTable[];
+#define ONIGENC_IS_ASCII_CODE(code) ((code) < 0x80)
#define ONIGENC_ASCII_CODE_TO_LOWER_CASE(c) OnigEncAsciiToLowerCaseTable[c]
#define ONIGENC_ASCII_CODE_TO_UPPER_CASE(c) OnigEncAsciiToUpperCaseTable[c]
#define ONIGENC_IS_ASCII_CODE_CTYPE(code,ctype) \
- ((OnigEncAsciiCtypeTable[code] & ctype) != 0)
+ ((OnigEncAsciiCtypeTable[code] & CTYPE_TO_BIT(ctype)) != 0)
#define ONIGENC_IS_ASCII_CODE_CASE_AMBIG(code) \
- ONIGENC_IS_ASCII_CODE_CTYPE(code, (ONIGENC_CTYPE_UPPER | ONIGENC_CTYPE_LOWER))
+ (ONIGENC_IS_ASCII_CODE_CTYPE(code, ONIGENC_CTYPE_UPPER) ||\
+ ONIGENC_IS_ASCII_CODE_CTYPE(code, ONIGENC_CTYPE_LOWER))
+
#endif /* REGENC_H */
diff --git a/ext/mbstring/oniguruma/regerror.c b/ext/mbstring/oniguruma/regerror.c
index d6ec91856d..385e560d98 100644
--- a/ext/mbstring/oniguruma/regerror.c
+++ b/ext/mbstring/oniguruma/regerror.c
@@ -2,7 +2,7 @@
regerror.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2006 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2007 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -85,9 +85,9 @@ onig_error_code_to_format(int code)
case ONIGERR_END_PATTERN_AT_CONTROL:
p = "end pattern at control"; break;
case ONIGERR_META_CODE_SYNTAX:
- p = "illegal meta-code syntax"; break;
+ p = "invalid meta-code syntax"; break;
case ONIGERR_CONTROL_CODE_SYNTAX:
- p = "illegal control-code syntax"; break;
+ p = "invalid control-code syntax"; break;
case ONIGERR_CHAR_CLASS_VALUE_AT_END_OF_RANGE:
p = "char-class value at end of range"; break;
case ONIGERR_CHAR_CLASS_VALUE_AT_START_OF_RANGE:
@@ -142,8 +142,8 @@ onig_error_code_to_format(int code)
p = "too big wide-char value"; break;
case ONIGERR_TOO_LONG_WIDE_CHAR_VALUE:
p = "too long wide-char value"; break;
- case ONIGERR_INVALID_WIDE_CHAR_VALUE:
- p = "invalid wide-char value"; break;
+ case ONIGERR_INVALID_CODE_POINT_VALUE:
+ p = "invalid code point value"; break;
case ONIGERR_EMPTY_GROUP_NAME:
p = "group name is empty"; break;
case ONIGERR_INVALID_GROUP_NAME:
@@ -182,6 +182,15 @@ onig_error_code_to_format(int code)
return (UChar* )p;
}
+static void sprint_byte(char* s, unsigned int v)
+{
+ sprintf(s, "%02x", (v & 0377));
+}
+
+static void sprint_byte_with_x(char* s, unsigned int v)
+{
+ sprintf(s, "\\x%02x", (v & 0377));
+}
static int to_ascii(OnigEncoding enc, UChar *s, UChar *end,
UChar buf[], int buf_size, int *is_over)
@@ -196,10 +205,17 @@ static int to_ascii(OnigEncoding enc, UChar *s, UChar *end,
while (p < end) {
code = ONIGENC_MBC_TO_CODE(enc, p, end);
if (code >= 0x80) {
- if (len + 5 <= buf_size) {
- sprintf((char* )(&(buf[len])), "\\%03o",
- (unsigned int)(code & 0377));
- len += 5;
+ if (code > 0xffff && len + 10 <= buf_size) {
+ sprint_byte_with_x((char*)(&(buf[len])), (unsigned int)(code >> 24));
+ sprint_byte((char*)(&(buf[len+4])), (unsigned int)(code >> 16));
+ sprint_byte((char*)(&(buf[len+6])), (unsigned int)(code >> 8));
+ sprint_byte((char*)(&(buf[len+8])), (unsigned int)code);
+ len += 10;
+ }
+ else if (len + 6 <= buf_size) {
+ sprint_byte_with_x((char*)(&(buf[len])), (unsigned int)(code >> 8));
+ sprint_byte((char*)(&(buf[len+4])), (unsigned int)code);
+ len += 6;
}
else {
break;
@@ -209,7 +225,7 @@ static int to_ascii(OnigEncoding enc, UChar *s, UChar *end,
buf[len++] = (UChar )code;
}
- p += enc_len(enc, p);
+ p += enclen(enc, p);
if (len >= buf_size) break;
}
@@ -317,7 +333,7 @@ onig_snprintf_with_pattern(buf, bufsize, enc, pat, pat_end, fmt, va_alist)
va_list args;
va_init_list(args, fmt);
- n = vsnprintf((char* )buf, bufsize, (const char* )fmt, args);
+ n = xvsnprintf((char* )buf, bufsize, (const char* )fmt, args);
va_end(args);
need = (pat_end - pat) * 4 + 4;
@@ -328,17 +344,17 @@ onig_snprintf_with_pattern(buf, bufsize, enc, pat, pat_end, fmt, va_alist)
p = pat;
while (p < pat_end) {
- if (*p == MC_ESC(enc)) {
+ if (*p == '\\') {
*s++ = *p++;
- len = enc_len(enc, p);
+ len = enclen(enc, p);
while (len-- > 0) *s++ = *p++;
}
else if (*p == '/') {
- *s++ = (unsigned char )MC_ESC(enc);
+ *s++ = (unsigned char )'\\';
*s++ = *p++;
}
else if (ONIGENC_IS_MBC_HEAD(enc, p)) {
- len = enc_len(enc, p);
+ len = enclen(enc, p);
if (ONIGENC_MBC_MINLEN(enc) == 1) {
while (len-- > 0) *s++ = *p++;
}
@@ -346,7 +362,7 @@ onig_snprintf_with_pattern(buf, bufsize, enc, pat, pat_end, fmt, va_alist)
int blen;
while (len-- > 0) {
- sprintf((char* )bs, "\\%03o", *p++ & 0377);
+ sprint_byte_with_x((char* )bs, (unsigned int )(*p++));
blen = onigenc_str_bytelen_null(ONIG_ENCODING_ASCII, bs);
bp = bs;
while (blen-- > 0) *s++ = *bp++;
@@ -355,7 +371,7 @@ onig_snprintf_with_pattern(buf, bufsize, enc, pat, pat_end, fmt, va_alist)
}
else if (!ONIGENC_IS_CODE_PRINT(enc, *p) &&
!ONIGENC_IS_CODE_SPACE(enc, *p)) {
- sprintf((char* )bs, "\\%03o", *p++ & 0377);
+ sprint_byte_with_x((char* )bs, (unsigned int )(*p++));
len = onigenc_str_bytelen_null(ONIG_ENCODING_ASCII, bs);
bp = bs;
while (len-- > 0) *s++ = *bp++;
diff --git a/ext/mbstring/oniguruma/regexec.c b/ext/mbstring/oniguruma/regexec.c
index 918aa67aa8..7430d78514 100644
--- a/ext/mbstring/oniguruma/regexec.c
+++ b/ext/mbstring/oniguruma/regexec.c
@@ -2,7 +2,7 @@
regexec.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2007 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2008 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -29,10 +29,12 @@
#include "regint.h"
+#define USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
+
#ifdef USE_CRNL_AS_LINE_TERMINATOR
#define ONIGENC_IS_MBC_CRNL(enc,p,end) \
(ONIGENC_MBC_TO_CODE(enc,p,end) == 13 && \
- ONIGENC_IS_MBC_NEWLINE(enc,(p+enc_len(enc,p)),end))
+ ONIGENC_IS_MBC_NEWLINE(enc,(p+enclen(enc,p)),end))
#endif
#ifdef USE_CAPTURE_HISTORY
@@ -111,7 +113,7 @@ history_tree_add_child(OnigCaptureTreeNode* parent, OnigCaptureTreeNode* child)
(OnigCaptureTreeNode** )xrealloc(parent->childs,
sizeof(OnigCaptureTreeNode*) * n);
}
- CHECK_NULL_RETURN_VAL(parent->childs, ONIGERR_MEMORY);
+ CHECK_NULL_RETURN_MEMERR(parent->childs);
for (i = parent->allocated; i < n; i++) {
parent->childs[i] = (OnigCaptureTreeNode* )0;
}
@@ -196,7 +198,7 @@ onig_region_resize(OnigRegion* region, int n)
return 0;
}
-extern int
+static int
onig_region_resize_clear(OnigRegion* region, int n)
{
int r;
@@ -297,47 +299,6 @@ onig_region_copy(OnigRegion* to, OnigRegion* from)
/** stack **/
#define INVALID_STACK_INDEX -1
-typedef long StackIndex;
-
-typedef struct _StackType {
- unsigned int type;
- union {
- struct {
- UChar *pcode; /* byte code position */
- UChar *pstr; /* string position */
- UChar *pstr_prev; /* previous char position of pstr */
-#ifdef USE_COMBINATION_EXPLOSION_CHECK
- unsigned int state_check;
-#endif
- } state;
- struct {
- int count; /* for OP_REPEAT_INC, OP_REPEAT_INC_NG */
- UChar *pcode; /* byte code position (head of repeated target) */
- int num; /* repeat id */
- } repeat;
- struct {
- StackIndex si; /* index of stack */
- } repeat_inc;
- struct {
- int num; /* memory num */
- UChar *pstr; /* start/end position */
- /* Following information is setted, if this stack type is MEM-START */
- StackIndex start; /* prev. info (for backtrack "(...)*" ) */
- StackIndex end; /* prev. info (for backtrack "(...)*" ) */
- } mem;
- struct {
- int num; /* null check id */
- UChar *pstr; /* start position */
- } null_check;
-#ifdef USE_SUBEXP_CALL
- struct {
- UChar *ret_addr; /* byte code position */
- int num; /* null check id */
- UChar *pstr; /* string position */
- } call_frame;
-#endif
- } u;
-} StackType;
/* stack type */
/* used by normal-POP */
@@ -365,22 +326,6 @@ typedef struct _StackType {
#define STK_MASK_TO_VOID_TARGET 0x10ff
#define STK_MASK_MEM_END_OR_MARK 0x8000 /* MEM_END or MEM_END_MARK */
-typedef struct {
- void* stack_p;
- int stack_n;
- OnigOptionType options;
- OnigRegion* region;
- const UChar* start; /* search start position (for \G: BEGIN_POSITION) */
-#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
- int best_len; /* for ONIG_OPTION_FIND_LONGEST */
- UChar* best_s;
-#endif
-#ifdef USE_COMBINATION_EXPLOSION_CHECK
- void* state_check_buff;
- int state_check_buff_size;
-#endif
-} MatchArg;
-
#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
#define MATCH_ARG_INIT(msa, arg_option, arg_region, arg_start) do {\
(msa).stack_p = (void* )0;\
@@ -388,14 +333,14 @@ typedef struct {
(msa).region = (arg_region);\
(msa).start = (arg_start);\
(msa).best_len = ONIG_MISMATCH;\
-} while (0)
+} while(0)
#else
#define MATCH_ARG_INIT(msa, arg_option, arg_region, arg_start) do {\
(msa).stack_p = (void* )0;\
(msa).options = (arg_option);\
(msa).region = (arg_region);\
(msa).start = (arg_start);\
-} while (0)
+} while(0)
#endif
#ifdef USE_COMBINATION_EXPLOSION_CHECK
@@ -424,14 +369,14 @@ typedef struct {
(msa).state_check_buff = (void* )0;\
(msa).state_check_buff_size = 0;\
}\
-} while (0)
+ } while(0)
#define MATCH_ARG_FREE(msa) do {\
if ((msa).stack_p) xfree((msa).stack_p);\
if ((msa).state_check_buff_size >= STATE_CHECK_BUFF_MALLOC_THRESHOLD_SIZE) { \
if ((msa).state_check_buff) xfree((msa).state_check_buff);\
}\
-} while (0);
+} while(0)
#else
#define STATE_CHECK_BUFF_INIT(msa, str_len, offset, state_num)
#define MATCH_ARG_FREE(msa) if ((msa).stack_p) xfree((msa).stack_p)
@@ -442,15 +387,15 @@ typedef struct {
#define STACK_INIT(alloc_addr, ptr_num, stack_num) do {\
if (msa->stack_p) {\
alloc_addr = (char* )xalloca(sizeof(char*) * (ptr_num));\
- stk_alloc = (StackType* )(msa->stack_p);\
+ stk_alloc = (OnigStackType* )(msa->stack_p);\
stk_base = stk_alloc;\
stk = stk_base;\
stk_end = stk_base + msa->stack_n;\
}\
else {\
alloc_addr = (char* )xalloca(sizeof(char*) * (ptr_num)\
- + sizeof(StackType) * (stack_num));\
- stk_alloc = (StackType* )(alloc_addr + sizeof(char*) * (ptr_num));\
+ + sizeof(OnigStackType) * (stack_num));\
+ stk_alloc = (OnigStackType* )(alloc_addr + sizeof(char*) * (ptr_num));\
stk_base = stk_alloc;\
stk = stk_base;\
stk_end = stk_base + (stack_num);\
@@ -480,11 +425,11 @@ onig_set_match_stack_limit_size(unsigned int size)
}
static int
-stack_double(StackType** arg_stk_base, StackType** arg_stk_end,
- StackType** arg_stk, StackType* stk_alloc, MatchArg* msa)
+stack_double(OnigStackType** arg_stk_base, OnigStackType** arg_stk_end,
+ OnigStackType** arg_stk, OnigStackType* stk_alloc, OnigMatchArg* msa)
{
unsigned int n;
- StackType *x, *stk_base, *stk_end, *stk;
+ OnigStackType *x, *stk_base, *stk_end, *stk;
stk_base = *arg_stk_base;
stk_end = *arg_stk_end;
@@ -492,12 +437,12 @@ stack_double(StackType** arg_stk_base, StackType** arg_stk_end,
n = stk_end - stk_base;
if (stk_base == stk_alloc && IS_NULL(msa->stack_p)) {
- x = (StackType* )xmalloc(sizeof(StackType) * n * 2);
+ x = (OnigStackType* )xmalloc(sizeof(OnigStackType) * n * 2);
if (IS_NULL(x)) {
STACK_SAVE;
return ONIGERR_MEMORY;
}
- xmemcpy(x, stk_base, n * sizeof(StackType));
+ xmemcpy(x, stk_base, n * sizeof(OnigStackType));
n *= 2;
}
else {
@@ -508,7 +453,7 @@ stack_double(StackType** arg_stk_base, StackType** arg_stk_end,
else
n = MatchStackLimitSize;
}
- x = (StackType* )xrealloc(stk_base, sizeof(StackType) * n);
+ x = (OnigStackType* )xrealloc(stk_base, sizeof(OnigStackType) * n);
if (IS_NULL(x)) {
STACK_SAVE;
return ONIGERR_MEMORY;
@@ -680,7 +625,7 @@ stack_double(StackType** arg_stk_base, StackType** arg_stk_end,
level--;\
}\
}\
-} while (0)
+} while(0)
#define STACK_GET_MEM_RANGE(k, mnum, start, end) do {\
int level = 0;\
@@ -698,7 +643,7 @@ stack_double(StackType** arg_stk_base, StackType** arg_stk_end,
}\
k++;\
}\
-} while (0)
+} while(0)
#define STACK_PUSH_NULL_CHECK_START(cnum, s) do {\
STACK_ENSURE(1);\
@@ -844,7 +789,7 @@ stack_double(StackType** arg_stk_base, StackType** arg_stk_end,
} while(0)
#define STACK_STOP_BT_END do {\
- StackType *k = stk;\
+ OnigStackType *k = stk;\
while (1) {\
k--;\
STACK_BASE_CHECK(k, "STACK_STOP_BT_END"); \
@@ -859,7 +804,7 @@ stack_double(StackType** arg_stk_base, StackType** arg_stk_end,
} while(0)
#define STACK_NULL_CHECK(isnull,id,s) do {\
- StackType* k = stk;\
+ OnigStackType* k = stk;\
while (1) {\
k--;\
STACK_BASE_CHECK(k, "STACK_NULL_CHECK"); \
@@ -874,7 +819,7 @@ stack_double(StackType** arg_stk_base, StackType** arg_stk_end,
#define STACK_NULL_CHECK_REC(isnull,id,s) do {\
int level = 0;\
- StackType* k = stk;\
+ OnigStackType* k = stk;\
while (1) {\
k--;\
STACK_BASE_CHECK(k, "STACK_NULL_CHECK_REC"); \
@@ -894,7 +839,7 @@ stack_double(StackType** arg_stk_base, StackType** arg_stk_end,
} while(0)
#define STACK_NULL_CHECK_MEMST(isnull,id,s,reg) do {\
- StackType* k = stk;\
+ OnigStackType* k = stk;\
while (1) {\
k--;\
STACK_BASE_CHECK(k, "STACK_NULL_CHECK_MEMST"); \
@@ -934,7 +879,7 @@ stack_double(StackType** arg_stk_base, StackType** arg_stk_end,
#define STACK_NULL_CHECK_MEMST_REC(isnull,id,s,reg) do {\
int level = 0;\
- StackType* k = stk;\
+ OnigStackType* k = stk;\
while (1) {\
k--;\
STACK_BASE_CHECK(k, "STACK_NULL_CHECK_MEMST_REC"); \
@@ -996,11 +941,11 @@ stack_double(StackType** arg_stk_base, StackType** arg_stk_end,
else if (k->type == STK_CALL_FRAME) level--;\
else if (k->type == STK_RETURN) level++;\
}\
-} while (0)
+} while(0)
#define STACK_RETURN(addr) do {\
int level = 0;\
- StackType* k = stk;\
+ OnigStackType* k = stk;\
while (1) {\
k--;\
STACK_BASE_CHECK(k, "STACK_RETURN"); \
@@ -1023,25 +968,25 @@ stack_double(StackType** arg_stk_base, StackType** arg_stk_end,
}\
} while(0)
-#define STRING_CMP_IC(ambig_flag,s1,ps2,len) do {\
- if (string_cmp_ic(encode, ambig_flag, s1, ps2, len) == 0) \
+#define STRING_CMP_IC(case_fold_flag,s1,ps2,len) do {\
+ if (string_cmp_ic(encode, case_fold_flag, s1, ps2, len) == 0) \
goto fail; \
} while(0)
-static int string_cmp_ic(OnigEncoding enc, int ambig_flag,
+static int string_cmp_ic(OnigEncoding enc, int case_fold_flag,
UChar* s1, UChar** ps2, int mblen)
{
- UChar buf1[ONIGENC_MBC_NORMALIZE_MAXLEN];
- UChar buf2[ONIGENC_MBC_NORMALIZE_MAXLEN];
- UChar *p1, *p2, *end, *s2, *end2;
+ UChar buf1[ONIGENC_MBC_CASE_FOLD_MAXLEN];
+ UChar buf2[ONIGENC_MBC_CASE_FOLD_MAXLEN];
+ UChar *p1, *p2, *end1, *s2, *end2;
int len1, len2;
s2 = *ps2;
- end = s1 + mblen;
+ end1 = s1 + mblen;
end2 = s2 + mblen;
- while (s1 < end) {
- len1 = ONIGENC_MBC_TO_NORMALIZE(enc, ambig_flag, &s1, end, buf1);
- len2 = ONIGENC_MBC_TO_NORMALIZE(enc, ambig_flag, &s2, end2, buf2);
+ while (s1 < end1) {
+ len1 = ONIGENC_MBC_CASE_FOLD(enc, case_fold_flag, &s1, end1, buf1);
+ len2 = ONIGENC_MBC_CASE_FOLD(enc, case_fold_flag, &s2, end2, buf2);
if (len1 != len2) return 0;
p1 = buf1;
p2 = buf2;
@@ -1065,31 +1010,36 @@ static int string_cmp_ic(OnigEncoding enc, int ambig_flag,
}\
} while(0)
-#define STRING_CMP_VALUE_IC(ambig_flag,s1,ps2,len,is_fail) do {\
- if (string_cmp_ic(encode, ambig_flag, s1, ps2, len) == 0) \
+#define STRING_CMP_VALUE_IC(case_fold_flag,s1,ps2,len,is_fail) do {\
+ if (string_cmp_ic(encode, case_fold_flag, s1, ps2, len) == 0) \
is_fail = 1; \
else \
is_fail = 0; \
} while(0)
-#define ON_STR_BEGIN(s) ((s) == str)
-#define ON_STR_END(s) ((s) == end)
-#define IS_EMPTY_STR (str == end)
-
-#define DATA_ENSURE(n) \
- if (s + (n) > end) goto fail
-
+#define IS_EMPTY_STR (str == end)
+#define ON_STR_BEGIN(s) ((s) == str)
+#define ON_STR_END(s) ((s) == end)
+#ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
+#define DATA_ENSURE_CHECK1 (s < right_range)
+#define DATA_ENSURE_CHECK(n) (s + (n) <= right_range)
+#define DATA_ENSURE(n) if (s + (n) > right_range) goto fail
+#else
+#define DATA_ENSURE_CHECK1 (s < end)
#define DATA_ENSURE_CHECK(n) (s + (n) <= end)
+#define DATA_ENSURE(n) if (s + (n) > end) goto fail
+#endif /* USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE */
+
#ifdef USE_CAPTURE_HISTORY
static int
-make_capture_history_tree(OnigCaptureTreeNode* node, StackType** kp,
- StackType* stk_top, UChar* str, regex_t* reg)
+make_capture_history_tree(OnigCaptureTreeNode* node, OnigStackType** kp,
+ OnigStackType* stk_top, UChar* str, regex_t* reg)
{
int n, r;
OnigCaptureTreeNode* child;
- StackType* k = *kp;
+ OnigStackType* k = *kp;
while (k < stk_top) {
if (k->type == STK_MEM_START) {
@@ -1097,7 +1047,7 @@ make_capture_history_tree(OnigCaptureTreeNode* node, StackType** kp,
if (n <= ONIG_MAX_CAPTURE_HISTORY_GROUP &&
BIT_STATUS_AT(reg->capture_history, n) != 0) {
child = history_node_new();
- CHECK_NULL_RETURN_VAL(child, ONIGERR_MEMORY);
+ CHECK_NULL_RETURN_MEMERR(child);
child->group = n;
child->beg = (int )(k->u.mem.pstr - str);
r = history_tree_add_child(node, child);
@@ -1124,7 +1074,7 @@ make_capture_history_tree(OnigCaptureTreeNode* node, StackType** kp,
}
#endif
-#ifdef USE_BACKREF_AT_LEVEL
+#ifdef USE_BACKREF_WITH_LEVEL
static int mem_is_in_memp(int mem, int num, UChar* memp)
{
int i;
@@ -1138,13 +1088,13 @@ static int mem_is_in_memp(int mem, int num, UChar* memp)
}
static int backref_match_at_nested_level(regex_t* reg
- , StackType* top, StackType* stk_base
- , int ignore_case, int ambig_flag
+ , OnigStackType* top, OnigStackType* stk_base
+ , int ignore_case, int case_fold_flag
, int nest, int mem_num, UChar* memp, UChar** s, const UChar* send)
{
UChar *ss, *p, *pstart, *pend = NULL_UCHARP;
int level;
- StackType* k;
+ OnigStackType* k;
level = 0;
k = top;
@@ -1166,7 +1116,7 @@ static int backref_match_at_nested_level(regex_t* reg
ss = *s;
if (ignore_case != 0) {
- if (string_cmp_ic(reg->enc, ambig_flag,
+ if (string_cmp_ic(reg->enc, case_fold_flag,
pstart, &ss, (int )(pend - pstart)) == 0)
return 0; /* or goto next_mem; */
}
@@ -1192,70 +1142,8 @@ static int backref_match_at_nested_level(regex_t* reg
return 0;
}
-#endif /* USE_BACKREF_AT_LEVEL */
-
-
-#ifdef RUBY_PLATFORM
-
-typedef struct {
- int state;
- regex_t* reg;
- MatchArg* msa;
- StackType* stk_base;
-} TrapEnsureArg;
-
-static VALUE
-trap_ensure(VALUE arg)
-{
- TrapEnsureArg* ta = (TrapEnsureArg* )arg;
-
- if (ta->state == 0) { /* trap_exec() is not normal return */
- ONIG_STATE_DEC_THREAD(ta->reg);
- if (! IS_NULL(ta->msa->stack_p) && ta->stk_base != ta->msa->stack_p)
- xfree(ta->stk_base);
-
- MATCH_ARG_FREE(*(ta->msa));
- }
-
- return Qnil;
-}
+#endif /* USE_BACKREF_WITH_LEVEL */
-static VALUE
-trap_exec(VALUE arg)
-{
- TrapEnsureArg* ta;
-
- rb_trap_exec();
-
- ta = (TrapEnsureArg* )arg;
- ta->state = 1; /* normal return */
- return Qnil;
-}
-
-extern void
-onig_exec_trap(regex_t* reg, MatchArg* msa, StackType* stk_base)
-{
- VALUE arg;
- TrapEnsureArg ta;
-
- ta.state = 0;
- ta.reg = reg;
- ta.msa = msa;
- ta.stk_base = stk_base;
- arg = (VALUE )(&ta);
- rb_ensure(trap_exec, arg, trap_ensure, arg);
-}
-
-#define CHECK_INTERRUPT_IN_MATCH_AT do {\
- if (rb_trap_pending) {\
- if (! rb_prohibit_interrupt) {\
- onig_exec_trap(reg, msa, stk_base);\
- }\
- }\
-} while (0)
-#else
-#define CHECK_INTERRUPT_IN_MATCH_AT
-#endif /* RUBY_PLATFORM */
#ifdef ONIG_DEBUG_STATISTICS
@@ -1288,41 +1176,26 @@ static int OpCurr = OP_FINISH;
static int OpPrevTarget = OP_FAIL;
static int MaxStackDepth = 0;
-#define STAT_OP_IN(opcode) do {\
+#define MOP_IN(opcode) do {\
if (opcode == OpPrevTarget) OpPrevCounter[OpCurr]++;\
OpCurr = opcode;\
OpCounter[opcode]++;\
GETTIME(ts);\
-} while (0)
+} while(0)
-#define STAT_OP_OUT do {\
+#define MOP_OUT do {\
GETTIME(te);\
OpTime[OpCurr] += TIMEDIFF(te, ts);\
-} while (0)
-
-#ifdef RUBY_PLATFORM
-
-/*
- * :nodoc:
- */
-static VALUE onig_stat_print(void)
-{
- onig_print_statistics(stderr);
- return Qnil;
-}
-#endif
+} while(0)
-extern void onig_statistics_init(void)
+extern void
+onig_statistics_init(void)
{
int i;
for (i = 0; i < 256; i++) {
OpCounter[i] = OpPrevCounter[i] = 0; OpTime[i] = 0;
}
MaxStackDepth = 0;
-
-#ifdef RUBY_PLATFORM
- rb_define_global_function("onig_stat_print", onig_stat_print, 0);
-#endif
}
extern void
@@ -1341,73 +1214,15 @@ onig_print_statistics(FILE* f)
stk++;\
if (stk - stk_base > MaxStackDepth) \
MaxStackDepth = stk - stk_base;\
-} while (0)
+} while(0)
#else
#define STACK_INC stk++
-#define STAT_OP_IN(opcode)
-#define STAT_OP_OUT
+#define MOP_IN(opcode)
+#define MOP_OUT
#endif
-extern int
-onig_is_in_code_range(const UChar* p, OnigCodePoint code)
-{
- OnigCodePoint n, *data;
- OnigCodePoint low, high, x;
-
- GET_CODE_POINT(n, p);
- data = (OnigCodePoint* )p;
- data++;
-
- for (low = 0, high = n; low < high; ) {
- x = (low + high) >> 1;
- if (code > data[x * 2 + 1])
- low = x + 1;
- else
- high = x;
- }
-
- return ((low < n && code >= data[low * 2]) ? 1 : 0);
-}
-
-static int
-is_code_in_cc(int enclen, OnigCodePoint code, CClassNode* cc)
-{
- int found;
-
- if (enclen > 1 || (code >= SINGLE_BYTE_SIZE)) {
- if (IS_NULL(cc->mbuf)) {
- found = 0;
- }
- else {
- found = (onig_is_in_code_range(cc->mbuf->p, code) != 0 ? 1 : 0);
- }
- }
- else {
- found = (BITSET_AT(cc->bs, code) == 0 ? 0 : 1);
- }
-
- if (IS_CCLASS_NOT(cc))
- return !found;
- else
- return found;
-}
-
-extern int
-onig_is_code_in_cc(OnigEncoding enc, OnigCodePoint code, CClassNode* cc)
-{
- int len;
-
- if (ONIGENC_MBC_MINLEN(enc) > 1) {
- len = 2;
- }
- else {
- len = ONIGENC_CODE_TO_MBCLEN(enc, code);
- }
- return is_code_in_cc(len, code, cc);
-}
-
/* matching region of POSIX API */
typedef int regoff_t;
@@ -1420,8 +1235,11 @@ typedef struct {
/* match data(str - end) from position (sstart). */
/* if sstart == str then set sprev to NULL. */
static int
-match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
- UChar* sprev, MatchArg* msa)
+match_at(regex_t* reg, const UChar* str, const UChar* end,
+#ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
+ const UChar* right_range,
+#endif
+ const UChar* sstart, UChar* sprev, OnigMatchArg* msa)
{
static UChar FinishCode[] = { OP_FINISH };
@@ -1431,15 +1249,15 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
RelAddrType addr;
OnigOptionType option = reg->options;
OnigEncoding encode = reg->enc;
- OnigAmbigType ambig_flag = reg->ambig_flag;
+ OnigCaseFoldType case_fold_flag = reg->case_fold_flag;
UChar *s, *q, *sbegin;
UChar *p = reg->p;
char *alloca_base;
- StackType *stk_alloc, *stk_base, *stk, *stk_end;
- StackType *stkp; /* used as any purpose. */
- StackIndex si;
- StackIndex *repeat_stk;
- StackIndex *mem_start_stk, *mem_end_stk;
+ OnigStackType *stk_alloc, *stk_base, *stk, *stk_end;
+ OnigStackType *stkp; /* used as any purpose. */
+ OnigStackIndex si;
+ OnigStackIndex *repeat_stk;
+ OnigStackIndex *mem_start_stk, *mem_end_stk;
#ifdef USE_COMBINATION_EXPLOSION_CHECK
int scv;
unsigned char* state_check_buff = msa->state_check_buff;
@@ -1450,9 +1268,9 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
STACK_INIT(alloca_base, n, INIT_MATCH_STACK_SIZE);
pop_level = reg->stack_pop_level;
num_mem = reg->num_mem;
- repeat_stk = (StackIndex* )alloca_base;
+ repeat_stk = (OnigStackIndex* )alloca_base;
- mem_start_stk = (StackIndex* )(repeat_stk + reg->num_repeat);
+ mem_start_stk = (OnigStackIndex* )(repeat_stk + reg->num_repeat);
mem_end_stk = mem_start_stk + num_mem;
mem_start_stk--; /* for index start from 1,
mem_start_stk[1]..mem_start_stk[num_mem] */
@@ -1480,13 +1298,13 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
fprintf(stderr, "%4d> \"", (int )(s - str));
bp = buf;
for (i = 0, q = s; i < 7 && q < end; i++) {
- len = enc_len(encode, q);
+ len = enclen(encode, q);
while (len-- > 0) *bp++ = *q++;
}
if (q < end) { xmemcpy(bp, "...\"", 4); bp += 4; }
else { xmemcpy(bp, "\"", 1); bp += 1; }
*bp = 0;
- fputs(buf, stderr);
+ fputs((char* )buf, stderr);
for (i = 0; i < 20 - (bp - buf); i++) fputc(' ', stderr);
onig_print_compiled_byte_code(stderr, p, NULL, encode);
fprintf(stderr, "\n");
@@ -1495,7 +1313,7 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
sbegin = s;
switch (*p++) {
- case OP_END: STAT_OP_IN(OP_END);
+ case OP_END: MOP_IN(OP_END);
n = s - sstart;
if (n > best_len) {
OnigRegion* region;
@@ -1512,7 +1330,7 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
best_len = n;
region = msa->region;
if (region) {
-#ifdef USE_POSIX_REGION_OPTION
+#ifdef USE_POSIX_API_REGION_OPTION
if (IS_POSIX_REGION(msa->options)) {
posix_regmatch_t* rmt = (posix_regmatch_t* )region;
@@ -1535,7 +1353,7 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
}
}
else {
-#endif /* USE_POSIX_REGION_OPTION */
+#endif /* USE_POSIX_API_REGION_OPTION */
region->beg[0] = sstart - str;
region->end[0] = s - str;
for (i = 1; i <= num_mem; i++) {
@@ -1561,7 +1379,7 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
if (IS_NULL(region->history_root)) {
region->history_root = node = history_node_new();
- CHECK_NULL_RETURN_VAL(node, ONIGERR_MEMORY);
+ CHECK_NULL_RETURN_MEMERR(node);
}
else {
node = region->history_root;
@@ -1581,7 +1399,7 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
}
}
#endif /* USE_CAPTURE_HISTORY */
-#ifdef USE_POSIX_REGION_OPTION
+#ifdef USE_POSIX_API_REGION_OPTION
} /* else IS_POSIX_REGION() */
#endif
} /* if (region) */
@@ -1590,14 +1408,14 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
end_best_len:
#endif
- STAT_OP_OUT;
+ MOP_OUT;
if (IS_FIND_CONDITION(option)) {
if (IS_FIND_NOT_EMPTY(option) && s == sstart) {
best_len = ONIG_MISMATCH;
goto fail; /* for retry */
}
- if (IS_FIND_LONGEST(option) && s < end) {
+ if (IS_FIND_LONGEST(option) && DATA_ENSURE_CHECK1) {
goto fail; /* for retry */
}
}
@@ -1606,7 +1424,7 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
goto finish;
break;
- case OP_EXACT1: STAT_OP_IN(OP_EXACT1);
+ case OP_EXACT1: MOP_IN(OP_EXACT1);
#if 0
DATA_ENSURE(1);
if (*p != *s) goto fail;
@@ -1615,19 +1433,19 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
if (*p != *s++) goto fail;
DATA_ENSURE(0);
p++;
- STAT_OP_OUT;
+ MOP_OUT;
break;
- case OP_EXACT1_IC: STAT_OP_IN(OP_EXACT1_IC);
+ case OP_EXACT1_IC: MOP_IN(OP_EXACT1_IC);
{
int len;
- UChar *q, *ss, *sp, lowbuf[ONIGENC_MBC_NORMALIZE_MAXLEN];
+ UChar *q, lowbuf[ONIGENC_MBC_CASE_FOLD_MAXLEN];
DATA_ENSURE(1);
- ss = s;
- sp = p;
-
- len = ONIGENC_MBC_TO_NORMALIZE(encode, ambig_flag, &s, end, lowbuf);
+ len = ONIGENC_MBC_CASE_FOLD(encode,
+ /* DISABLE_CASE_FOLD_MULTI_CHAR(case_fold_flag), */
+ case_fold_flag,
+ &s, end, lowbuf);
DATA_ENSURE(0);
q = lowbuf;
while (len-- > 0) {
@@ -1637,21 +1455,21 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
p++; q++;
}
}
- STAT_OP_OUT;
+ MOP_OUT;
break;
- case OP_EXACT2: STAT_OP_IN(OP_EXACT2);
+ case OP_EXACT2: MOP_IN(OP_EXACT2);
DATA_ENSURE(2);
if (*p != *s) goto fail;
p++; s++;
if (*p != *s) goto fail;
sprev = s;
p++; s++;
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_EXACT3: STAT_OP_IN(OP_EXACT3);
+ case OP_EXACT3: MOP_IN(OP_EXACT3);
DATA_ENSURE(3);
if (*p != *s) goto fail;
p++; s++;
@@ -1660,11 +1478,11 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
if (*p != *s) goto fail;
sprev = s;
p++; s++;
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_EXACT4: STAT_OP_IN(OP_EXACT4);
+ case OP_EXACT4: MOP_IN(OP_EXACT4);
DATA_ENSURE(4);
if (*p != *s) goto fail;
p++; s++;
@@ -1675,11 +1493,11 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
if (*p != *s) goto fail;
sprev = s;
p++; s++;
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_EXACT5: STAT_OP_IN(OP_EXACT5);
+ case OP_EXACT5: MOP_IN(OP_EXACT5);
DATA_ENSURE(5);
if (*p != *s) goto fail;
p++; s++;
@@ -1692,25 +1510,25 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
if (*p != *s) goto fail;
sprev = s;
p++; s++;
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_EXACTN: STAT_OP_IN(OP_EXACTN);
+ case OP_EXACTN: MOP_IN(OP_EXACTN);
GET_LENGTH_INC(tlen, p);
DATA_ENSURE(tlen);
while (tlen-- > 0) {
if (*p++ != *s++) goto fail;
}
sprev = s - 1;
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_EXACTN_IC: STAT_OP_IN(OP_EXACTN_IC);
+ case OP_EXACTN_IC: MOP_IN(OP_EXACTN_IC);
{
int len;
- UChar *ss, *sp, *q, *endp, lowbuf[ONIGENC_MBC_NORMALIZE_MAXLEN];
+ UChar *q, *endp, lowbuf[ONIGENC_MBC_CASE_FOLD_MAXLEN];
GET_LENGTH_INC(tlen, p);
endp = p + tlen;
@@ -1718,35 +1536,33 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
while (p < endp) {
sprev = s;
DATA_ENSURE(1);
- ss = s;
- sp = p;
-
- len = ONIGENC_MBC_TO_NORMALIZE(encode, ambig_flag, &s, end, lowbuf);
+ len = ONIGENC_MBC_CASE_FOLD(encode,
+ /* DISABLE_CASE_FOLD_MULTI_CHAR(case_fold_flag), */
+ case_fold_flag,
+ &s, end, lowbuf);
DATA_ENSURE(0);
q = lowbuf;
while (len-- > 0) {
- if (*p != *q) {
- goto fail;
- }
+ if (*p != *q) goto fail;
p++; q++;
}
}
}
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_EXACTMB2N1: STAT_OP_IN(OP_EXACTMB2N1);
+ case OP_EXACTMB2N1: MOP_IN(OP_EXACTMB2N1);
DATA_ENSURE(2);
if (*p != *s) goto fail;
p++; s++;
if (*p != *s) goto fail;
p++; s++;
- STAT_OP_OUT;
+ MOP_OUT;
break;
- case OP_EXACTMB2N2: STAT_OP_IN(OP_EXACTMB2N2);
+ case OP_EXACTMB2N2: MOP_IN(OP_EXACTMB2N2);
DATA_ENSURE(4);
if (*p != *s) goto fail;
p++; s++;
@@ -1757,11 +1573,11 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
p++; s++;
if (*p != *s) goto fail;
p++; s++;
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_EXACTMB2N3: STAT_OP_IN(OP_EXACTMB2N3);
+ case OP_EXACTMB2N3: MOP_IN(OP_EXACTMB2N3);
DATA_ENSURE(6);
if (*p != *s) goto fail;
p++; s++;
@@ -1776,11 +1592,11 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
p++; s++;
if (*p != *s) goto fail;
p++; s++;
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_EXACTMB2N: STAT_OP_IN(OP_EXACTMB2N);
+ case OP_EXACTMB2N: MOP_IN(OP_EXACTMB2N);
GET_LENGTH_INC(tlen, p);
DATA_ENSURE(tlen * 2);
while (tlen-- > 0) {
@@ -1790,11 +1606,11 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
p++; s++;
}
sprev = s - 2;
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_EXACTMB3N: STAT_OP_IN(OP_EXACTMB3N);
+ case OP_EXACTMB3N: MOP_IN(OP_EXACTMB3N);
GET_LENGTH_INC(tlen, p);
DATA_ENSURE(tlen * 3);
while (tlen-- > 0) {
@@ -1806,11 +1622,11 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
p++; s++;
}
sprev = s - 3;
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_EXACTMBN: STAT_OP_IN(OP_EXACTMBN);
+ case OP_EXACTMBN: MOP_IN(OP_EXACTMBN);
GET_LENGTH_INC(tlen, p); /* mb-len */
GET_LENGTH_INC(tlen2, p); /* string len */
tlen2 *= tlen;
@@ -1820,19 +1636,19 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
p++; s++;
}
sprev = s - tlen;
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_CCLASS: STAT_OP_IN(OP_CCLASS);
+ case OP_CCLASS: MOP_IN(OP_CCLASS);
DATA_ENSURE(1);
if (BITSET_AT(((BitSetRef )p), *s) == 0) goto fail;
p += SIZE_BITSET;
- s += enc_len(encode, s); /* OP_CCLASS can match mb-code. \D, \S */
- STAT_OP_OUT;
+ s += enclen(encode, s); /* OP_CCLASS can match mb-code. \D, \S */
+ MOP_OUT;
break;
- case OP_CCLASS_MB: STAT_OP_IN(OP_CCLASS_MB);
+ case OP_CCLASS_MB: MOP_IN(OP_CCLASS_MB);
if (! ONIGENC_IS_MBC_HEAD(encode, s)) goto fail;
cclass_mb:
@@ -1843,7 +1659,7 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
int mb_len;
DATA_ENSURE(1);
- mb_len = enc_len(encode, s);
+ mb_len = enclen(encode, s);
DATA_ENSURE(mb_len);
ss = s;
s += mb_len;
@@ -1858,10 +1674,10 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
#endif
}
p += tlen;
- STAT_OP_OUT;
+ MOP_OUT;
break;
- case OP_CCLASS_MIX: STAT_OP_IN(OP_CCLASS_MIX);
+ case OP_CCLASS_MIX: MOP_IN(OP_CCLASS_MIX);
DATA_ENSURE(1);
if (ONIGENC_IS_MBC_HEAD(encode, s)) {
p += SIZE_BITSET;
@@ -1876,18 +1692,18 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
p += tlen;
s++;
}
- STAT_OP_OUT;
+ MOP_OUT;
break;
- case OP_CCLASS_NOT: STAT_OP_IN(OP_CCLASS_NOT);
+ case OP_CCLASS_NOT: MOP_IN(OP_CCLASS_NOT);
DATA_ENSURE(1);
if (BITSET_AT(((BitSetRef )p), *s) != 0) goto fail;
p += SIZE_BITSET;
- s += enc_len(encode, s);
- STAT_OP_OUT;
+ s += enclen(encode, s);
+ MOP_OUT;
break;
- case OP_CCLASS_MB_NOT: STAT_OP_IN(OP_CCLASS_MB_NOT);
+ case OP_CCLASS_MB_NOT: MOP_IN(OP_CCLASS_MB_NOT);
DATA_ENSURE(1);
if (! ONIGENC_IS_MBC_HEAD(encode, s)) {
s++;
@@ -1901,9 +1717,9 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
{
OnigCodePoint code;
UChar *ss;
- int mb_len = enc_len(encode, s);
+ int mb_len = enclen(encode, s);
- if (s + mb_len > end) {
+ if (! DATA_ENSURE_CHECK(mb_len)) {
DATA_ENSURE(1);
s = (UChar* )end;
p += tlen;
@@ -1925,10 +1741,10 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
p += tlen;
cc_mb_not_success:
- STAT_OP_OUT;
+ MOP_OUT;
break;
- case OP_CCLASS_MIX_NOT: STAT_OP_IN(OP_CCLASS_MIX_NOT);
+ case OP_CCLASS_MIX_NOT: MOP_IN(OP_CCLASS_MIX_NOT);
DATA_ENSURE(1);
if (ONIGENC_IS_MBC_HEAD(encode, s)) {
p += SIZE_BITSET;
@@ -1943,10 +1759,10 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
p += tlen;
s++;
}
- STAT_OP_OUT;
+ MOP_OUT;
break;
- case OP_CCLASS_NODE: STAT_OP_IN(OP_CCLASS_NODE);
+ case OP_CCLASS_NODE: MOP_IN(OP_CCLASS_NODE);
{
OnigCodePoint code;
void *node;
@@ -1955,49 +1771,49 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
DATA_ENSURE(1);
GET_POINTER_INC(node, p);
- mb_len = enc_len(encode, s);
+ mb_len = enclen(encode, s);
ss = s;
s += mb_len;
DATA_ENSURE(0);
code = ONIGENC_MBC_TO_CODE(encode, ss, s);
- if (is_code_in_cc(mb_len, code, node) == 0) goto fail;
+ if (onig_is_code_in_cc_len(mb_len, code, node) == 0) goto fail;
}
- STAT_OP_OUT;
+ MOP_OUT;
break;
- case OP_ANYCHAR: STAT_OP_IN(OP_ANYCHAR);
+ case OP_ANYCHAR: MOP_IN(OP_ANYCHAR);
DATA_ENSURE(1);
- n = enc_len(encode, s);
+ n = enclen(encode, s);
DATA_ENSURE(n);
if (ONIGENC_IS_MBC_NEWLINE(encode, s, end)) goto fail;
s += n;
- STAT_OP_OUT;
+ MOP_OUT;
break;
- case OP_ANYCHAR_ML: STAT_OP_IN(OP_ANYCHAR_ML);
+ case OP_ANYCHAR_ML: MOP_IN(OP_ANYCHAR_ML);
DATA_ENSURE(1);
- n = enc_len(encode, s);
+ n = enclen(encode, s);
DATA_ENSURE(n);
s += n;
- STAT_OP_OUT;
+ MOP_OUT;
break;
- case OP_ANYCHAR_STAR: STAT_OP_IN(OP_ANYCHAR_STAR);
- while (s < end) {
+ case OP_ANYCHAR_STAR: MOP_IN(OP_ANYCHAR_STAR);
+ while (DATA_ENSURE_CHECK1) {
STACK_PUSH_ALT(p, s, sprev);
- n = enc_len(encode, s);
+ n = enclen(encode, s);
DATA_ENSURE(n);
if (ONIGENC_IS_MBC_NEWLINE(encode, s, end)) goto fail;
sprev = s;
s += n;
}
- STAT_OP_OUT;
+ MOP_OUT;
break;
- case OP_ANYCHAR_ML_STAR: STAT_OP_IN(OP_ANYCHAR_ML_STAR);
- while (s < end) {
+ case OP_ANYCHAR_ML_STAR: MOP_IN(OP_ANYCHAR_ML_STAR);
+ while (DATA_ENSURE_CHECK1) {
STACK_PUSH_ALT(p, s, sprev);
- n = enc_len(encode, s);
+ n = enclen(encode, s);
if (n > 1) {
DATA_ENSURE(n);
sprev = s;
@@ -2008,31 +1824,31 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
s++;
}
}
- STAT_OP_OUT;
+ MOP_OUT;
break;
- case OP_ANYCHAR_STAR_PEEK_NEXT: STAT_OP_IN(OP_ANYCHAR_STAR_PEEK_NEXT);
- while (s < end) {
+ case OP_ANYCHAR_STAR_PEEK_NEXT: MOP_IN(OP_ANYCHAR_STAR_PEEK_NEXT);
+ while (DATA_ENSURE_CHECK1) {
if (*p == *s) {
STACK_PUSH_ALT(p + 1, s, sprev);
}
- n = enc_len(encode, s);
+ n = enclen(encode, s);
DATA_ENSURE(n);
if (ONIGENC_IS_MBC_NEWLINE(encode, s, end)) goto fail;
sprev = s;
s += n;
}
p++;
- STAT_OP_OUT;
+ MOP_OUT;
break;
- case OP_ANYCHAR_ML_STAR_PEEK_NEXT:STAT_OP_IN(OP_ANYCHAR_ML_STAR_PEEK_NEXT);
- while (s < end) {
+ case OP_ANYCHAR_ML_STAR_PEEK_NEXT:MOP_IN(OP_ANYCHAR_ML_STAR_PEEK_NEXT);
+ while (DATA_ENSURE_CHECK1) {
if (*p == *s) {
STACK_PUSH_ALT(p + 1, s, sprev);
}
- n = enc_len(encode, s);
- if (n >1) {
+ n = enclen(encode, s);
+ if (n > 1) {
DATA_ENSURE(n);
sprev = s;
s += n;
@@ -2043,36 +1859,36 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
}
}
p++;
- STAT_OP_OUT;
+ MOP_OUT;
break;
#ifdef USE_COMBINATION_EXPLOSION_CHECK
- case OP_STATE_CHECK_ANYCHAR_STAR: STAT_OP_IN(OP_STATE_CHECK_ANYCHAR_STAR);
+ case OP_STATE_CHECK_ANYCHAR_STAR: MOP_IN(OP_STATE_CHECK_ANYCHAR_STAR);
GET_STATE_CHECK_NUM_INC(mem, p);
- while (s < end) {
+ while (DATA_ENSURE_CHECK1) {
STATE_CHECK_VAL(scv, mem);
if (scv) goto fail;
STACK_PUSH_ALT_WITH_STATE_CHECK(p, s, sprev, mem);
- n = enc_len(encode, s);
+ n = enclen(encode, s);
DATA_ENSURE(n);
if (ONIGENC_IS_MBC_NEWLINE(encode, s, end)) goto fail;
sprev = s;
s += n;
}
- STAT_OP_OUT;
+ MOP_OUT;
break;
case OP_STATE_CHECK_ANYCHAR_ML_STAR:
- STAT_OP_IN(OP_STATE_CHECK_ANYCHAR_ML_STAR);
+ MOP_IN(OP_STATE_CHECK_ANYCHAR_ML_STAR);
GET_STATE_CHECK_NUM_INC(mem, p);
- while (s < end) {
+ while (DATA_ENSURE_CHECK1) {
STATE_CHECK_VAL(scv, mem);
if (scv) goto fail;
STACK_PUSH_ALT_WITH_STATE_CHECK(p, s, sprev, mem);
- n = enc_len(encode, s);
+ n = enclen(encode, s);
if (n > 1) {
DATA_ENSURE(n);
sprev = s;
@@ -2083,29 +1899,29 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
s++;
}
}
- STAT_OP_OUT;
+ MOP_OUT;
break;
#endif /* USE_COMBINATION_EXPLOSION_CHECK */
- case OP_WORD: STAT_OP_IN(OP_WORD);
+ case OP_WORD: MOP_IN(OP_WORD);
DATA_ENSURE(1);
if (! ONIGENC_IS_MBC_WORD(encode, s, end))
goto fail;
- s += enc_len(encode, s);
- STAT_OP_OUT;
+ s += enclen(encode, s);
+ MOP_OUT;
break;
- case OP_NOT_WORD: STAT_OP_IN(OP_NOT_WORD);
+ case OP_NOT_WORD: MOP_IN(OP_NOT_WORD);
DATA_ENSURE(1);
if (ONIGENC_IS_MBC_WORD(encode, s, end))
goto fail;
- s += enc_len(encode, s);
- STAT_OP_OUT;
+ s += enclen(encode, s);
+ MOP_OUT;
break;
- case OP_WORD_BOUND: STAT_OP_IN(OP_WORD_BOUND);
+ case OP_WORD_BOUND: MOP_IN(OP_WORD_BOUND);
if (ON_STR_BEGIN(s)) {
DATA_ENSURE(1);
if (! ONIGENC_IS_MBC_WORD(encode, s, end))
@@ -2120,13 +1936,13 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
== ONIGENC_IS_MBC_WORD(encode, sprev, end))
goto fail;
}
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_NOT_WORD_BOUND: STAT_OP_IN(OP_NOT_WORD_BOUND);
+ case OP_NOT_WORD_BOUND: MOP_IN(OP_NOT_WORD_BOUND);
if (ON_STR_BEGIN(s)) {
- if (DATA_ENSURE_CHECK(1) && ONIGENC_IS_MBC_WORD(encode, s, end))
+ if (DATA_ENSURE_CHECK1 && ONIGENC_IS_MBC_WORD(encode, s, end))
goto fail;
}
else if (ON_STR_END(s)) {
@@ -2138,25 +1954,25 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
!= ONIGENC_IS_MBC_WORD(encode, sprev, end))
goto fail;
}
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
#ifdef USE_WORD_BEGIN_END
- case OP_WORD_BEGIN: STAT_OP_IN(OP_WORD_BEGIN);
- if (DATA_ENSURE_CHECK(1) && ONIGENC_IS_MBC_WORD(encode, s, end)) {
+ case OP_WORD_BEGIN: MOP_IN(OP_WORD_BEGIN);
+ if (DATA_ENSURE_CHECK1 && ONIGENC_IS_MBC_WORD(encode, s, end)) {
if (ON_STR_BEGIN(s) || !ONIGENC_IS_MBC_WORD(encode, sprev, end)) {
- STAT_OP_OUT;
+ MOP_OUT;
continue;
}
}
goto fail;
break;
- case OP_WORD_END: STAT_OP_IN(OP_WORD_END);
+ case OP_WORD_END: MOP_IN(OP_WORD_END);
if (!ON_STR_BEGIN(s) && ONIGENC_IS_MBC_WORD(encode, sprev, end)) {
if (ON_STR_END(s) || !ONIGENC_IS_MBC_WORD(encode, s, end)) {
- STAT_OP_OUT;
+ MOP_OUT;
continue;
}
}
@@ -2164,80 +1980,81 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
break;
#endif
- case OP_BEGIN_BUF: STAT_OP_IN(OP_BEGIN_BUF);
+ case OP_BEGIN_BUF: MOP_IN(OP_BEGIN_BUF);
if (! ON_STR_BEGIN(s)) goto fail;
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_END_BUF: STAT_OP_IN(OP_END_BUF);
+ case OP_END_BUF: MOP_IN(OP_END_BUF);
if (! ON_STR_END(s)) goto fail;
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_BEGIN_LINE: STAT_OP_IN(OP_BEGIN_LINE);
+ case OP_BEGIN_LINE: MOP_IN(OP_BEGIN_LINE);
if (ON_STR_BEGIN(s)) {
if (IS_NOTBOL(msa->options)) goto fail;
- STAT_OP_OUT;
+ MOP_OUT;
continue;
}
else if (ONIGENC_IS_MBC_NEWLINE(encode, sprev, end) && !ON_STR_END(s)) {
- STAT_OP_OUT;
+ MOP_OUT;
continue;
}
goto fail;
break;
- case OP_END_LINE: STAT_OP_IN(OP_END_LINE);
+ case OP_END_LINE: MOP_IN(OP_END_LINE);
if (ON_STR_END(s)) {
#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
if (IS_EMPTY_STR || !ONIGENC_IS_MBC_NEWLINE(encode, sprev, end)) {
#endif
if (IS_NOTEOL(msa->options)) goto fail;
- STAT_OP_OUT;
+ MOP_OUT;
continue;
#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
}
#endif
}
else if (ONIGENC_IS_MBC_NEWLINE(encode, s, end)) {
- STAT_OP_OUT;
+ MOP_OUT;
continue;
}
#ifdef USE_CRNL_AS_LINE_TERMINATOR
else if (ONIGENC_IS_MBC_CRNL(encode, s, end)) {
- STAT_OP_OUT;
+ MOP_OUT;
continue;
}
#endif
goto fail;
break;
- case OP_SEMI_END_BUF: STAT_OP_IN(OP_SEMI_END_BUF);
+ case OP_SEMI_END_BUF: MOP_IN(OP_SEMI_END_BUF);
if (ON_STR_END(s)) {
#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
if (IS_EMPTY_STR || !ONIGENC_IS_MBC_NEWLINE(encode, sprev, end)) {
#endif
- if (IS_NOTEOL(msa->options)) goto fail; /* Is it needed? */
- STAT_OP_OUT;
+ if (IS_NOTEOL(msa->options)) goto fail;
+ MOP_OUT;
continue;
#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
}
#endif
}
else if (ONIGENC_IS_MBC_NEWLINE(encode, s, end) &&
- ON_STR_END(s + enc_len(encode, s))) {
- STAT_OP_OUT;
+ ON_STR_END(s + enclen(encode, s))) {
+ MOP_OUT;
continue;
}
#ifdef USE_CRNL_AS_LINE_TERMINATOR
else if (ONIGENC_IS_MBC_CRNL(encode, s, end)) {
- UChar* ss = s + enc_len(encode, s);
- if (ON_STR_END(ss + enc_len(encode, ss))) {
- STAT_OP_OUT;
+ UChar* ss = s + enclen(encode, s);
+ ss += enclen(encode, ss);
+ if (ON_STR_END(ss)) {
+ MOP_OUT;
continue;
}
}
@@ -2245,79 +2062,79 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
goto fail;
break;
- case OP_BEGIN_POSITION: STAT_OP_IN(OP_BEGIN_POSITION);
+ case OP_BEGIN_POSITION: MOP_IN(OP_BEGIN_POSITION);
if (s != msa->start)
goto fail;
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_MEMORY_START_PUSH: STAT_OP_IN(OP_MEMORY_START_PUSH);
+ case OP_MEMORY_START_PUSH: MOP_IN(OP_MEMORY_START_PUSH);
GET_MEMNUM_INC(mem, p);
STACK_PUSH_MEM_START(mem, s);
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_MEMORY_START: STAT_OP_IN(OP_MEMORY_START);
+ case OP_MEMORY_START: MOP_IN(OP_MEMORY_START);
GET_MEMNUM_INC(mem, p);
- mem_start_stk[mem] = (StackIndex )((void* )s);
- STAT_OP_OUT;
+ mem_start_stk[mem] = (OnigStackIndex )((void* )s);
+ MOP_OUT;
continue;
break;
- case OP_MEMORY_END_PUSH: STAT_OP_IN(OP_MEMORY_END_PUSH);
+ case OP_MEMORY_END_PUSH: MOP_IN(OP_MEMORY_END_PUSH);
GET_MEMNUM_INC(mem, p);
STACK_PUSH_MEM_END(mem, s);
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_MEMORY_END: STAT_OP_IN(OP_MEMORY_END);
+ case OP_MEMORY_END: MOP_IN(OP_MEMORY_END);
GET_MEMNUM_INC(mem, p);
- mem_end_stk[mem] = (StackIndex )((void* )s);
- STAT_OP_OUT;
+ mem_end_stk[mem] = (OnigStackIndex )((void* )s);
+ MOP_OUT;
continue;
break;
#ifdef USE_SUBEXP_CALL
- case OP_MEMORY_END_PUSH_REC: STAT_OP_IN(OP_MEMORY_END_PUSH_REC);
+ case OP_MEMORY_END_PUSH_REC: MOP_IN(OP_MEMORY_END_PUSH_REC);
GET_MEMNUM_INC(mem, p);
STACK_GET_MEM_START(mem, stkp); /* should be before push mem-end. */
STACK_PUSH_MEM_END(mem, s);
mem_start_stk[mem] = GET_STACK_INDEX(stkp);
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_MEMORY_END_REC: STAT_OP_IN(OP_MEMORY_END_REC);
+ case OP_MEMORY_END_REC: MOP_IN(OP_MEMORY_END_REC);
GET_MEMNUM_INC(mem, p);
- mem_end_stk[mem] = (StackIndex )((void* )s);
+ mem_end_stk[mem] = (OnigStackIndex )((void* )s);
STACK_GET_MEM_START(mem, stkp);
if (BIT_STATUS_AT(reg->bt_mem_start, mem))
mem_start_stk[mem] = GET_STACK_INDEX(stkp);
else
- mem_start_stk[mem] = (StackIndex )((void* )stkp->u.mem.pstr);
+ mem_start_stk[mem] = (OnigStackIndex )((void* )stkp->u.mem.pstr);
STACK_PUSH_MEM_END_MARK(mem);
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
#endif
- case OP_BACKREF1: STAT_OP_IN(OP_BACKREF1);
+ case OP_BACKREF1: MOP_IN(OP_BACKREF1);
mem = 1;
goto backref;
break;
- case OP_BACKREF2: STAT_OP_IN(OP_BACKREF2);
+ case OP_BACKREF2: MOP_IN(OP_BACKREF2);
mem = 2;
goto backref;
break;
- case OP_BACKREFN: STAT_OP_IN(OP_BACKREFN);
+ case OP_BACKREFN: MOP_IN(OP_BACKREFN);
GET_MEMNUM_INC(mem, p);
backref:
{
@@ -2342,15 +2159,15 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
DATA_ENSURE(n);
sprev = s;
STRING_CMP(pstart, s, n);
- while (sprev + (len = enc_len(encode, sprev)) < s)
+ while (sprev + (len = enclen(encode, sprev)) < s)
sprev += len;
- STAT_OP_OUT;
+ MOP_OUT;
continue;
}
break;
- case OP_BACKREFN_IC: STAT_OP_IN(OP_BACKREFN_IC);
+ case OP_BACKREFN_IC: MOP_IN(OP_BACKREFN_IC);
GET_MEMNUM_INC(mem, p);
{
int len;
@@ -2373,16 +2190,16 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
n = pend - pstart;
DATA_ENSURE(n);
sprev = s;
- STRING_CMP_IC(ambig_flag, pstart, &s, n);
- while (sprev + (len = enc_len(encode, sprev)) < s)
+ STRING_CMP_IC(case_fold_flag, pstart, &s, n);
+ while (sprev + (len = enclen(encode, sprev)) < s)
sprev += len;
- STAT_OP_OUT;
+ MOP_OUT;
continue;
}
break;
- case OP_BACKREF_MULTI: STAT_OP_IN(OP_BACKREF_MULTI);
+ case OP_BACKREF_MULTI: MOP_IN(OP_BACKREF_MULTI);
{
int len, is_fail;
UChar *pstart, *pend, *swork;
@@ -2409,19 +2226,19 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
STRING_CMP_VALUE(pstart, swork, n, is_fail);
if (is_fail) continue;
s = swork;
- while (sprev + (len = enc_len(encode, sprev)) < s)
+ while (sprev + (len = enclen(encode, sprev)) < s)
sprev += len;
p += (SIZE_MEMNUM * (tlen - i - 1));
break; /* success */
}
if (i == tlen) goto fail;
- STAT_OP_OUT;
+ MOP_OUT;
continue;
}
break;
- case OP_BACKREF_MULTI_IC: STAT_OP_IN(OP_BACKREF_MULTI_IC);
+ case OP_BACKREF_MULTI_IC: MOP_IN(OP_BACKREF_MULTI_IC);
{
int len, is_fail;
UChar *pstart, *pend, *swork;
@@ -2445,23 +2262,23 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
DATA_ENSURE(n);
sprev = s;
swork = s;
- STRING_CMP_VALUE_IC(ambig_flag, pstart, &swork, n, is_fail);
+ STRING_CMP_VALUE_IC(case_fold_flag, pstart, &swork, n, is_fail);
if (is_fail) continue;
s = swork;
- while (sprev + (len = enc_len(encode, sprev)) < s)
+ while (sprev + (len = enclen(encode, sprev)) < s)
sprev += len;
p += (SIZE_MEMNUM * (tlen - i - 1));
break; /* success */
}
if (i == tlen) goto fail;
- STAT_OP_OUT;
+ MOP_OUT;
continue;
}
break;
-#ifdef USE_BACKREF_AT_LEVEL
- case OP_BACKREF_AT_LEVEL:
+#ifdef USE_BACKREF_WITH_LEVEL
+ case OP_BACKREF_WITH_LEVEL:
{
int len;
OnigOptionType ic;
@@ -2472,9 +2289,9 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
GET_LENGTH_INC(tlen, p);
sprev = s;
- if (backref_match_at_nested_level(reg, stk, stk_base, ic, ambig_flag
- , (int )level, (int )tlen, p, &s, end)) {
- while (sprev + (len = enc_len(encode, sprev)) < s)
+ if (backref_match_at_nested_level(reg, stk, stk_base, ic
+ , case_fold_flag, (int )level, (int )tlen, p, &s, end)) {
+ while (sprev + (len = enclen(encode, sprev)) < s)
sprev += len;
p += (SIZE_MEMNUM * tlen);
@@ -2482,35 +2299,37 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
else
goto fail;
- STAT_OP_OUT;
+ MOP_OUT;
continue;
}
break;
#endif
-
- case OP_SET_OPTION_PUSH: STAT_OP_IN(OP_SET_OPTION_PUSH);
+
+#if 0 /* no need: IS_DYNAMIC_OPTION() == 0 */
+ case OP_SET_OPTION_PUSH: MOP_IN(OP_SET_OPTION_PUSH);
GET_OPTION_INC(option, p);
STACK_PUSH_ALT(p, s, sprev);
p += SIZE_OP_SET_OPTION + SIZE_OP_FAIL;
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_SET_OPTION: STAT_OP_IN(OP_SET_OPTION);
+ case OP_SET_OPTION: MOP_IN(OP_SET_OPTION);
GET_OPTION_INC(option, p);
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
+#endif
- case OP_NULL_CHECK_START: STAT_OP_IN(OP_NULL_CHECK_START);
+ case OP_NULL_CHECK_START: MOP_IN(OP_NULL_CHECK_START);
GET_MEMNUM_INC(mem, p); /* mem: null check id */
STACK_PUSH_NULL_CHECK_START(mem, s);
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_NULL_CHECK_END: STAT_OP_IN(OP_NULL_CHECK_END);
+ case OP_NULL_CHECK_END: MOP_IN(OP_NULL_CHECK_END);
{
int isnull;
@@ -2540,12 +2359,12 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
}
}
}
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
-#ifdef USE_INFINITE_REPEAT_MONOMANIAC_MEM_STATUS_CHECK
- case OP_NULL_CHECK_END_MEMST: STAT_OP_IN(OP_NULL_CHECK_END_MEMST);
+#ifdef USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT
+ case OP_NULL_CHECK_END_MEMST: MOP_IN(OP_NULL_CHECK_END_MEMST);
{
int isnull;
@@ -2560,19 +2379,19 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
goto null_check_found;
}
}
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
#endif
#ifdef USE_SUBEXP_CALL
case OP_NULL_CHECK_END_MEMST_PUSH:
- STAT_OP_IN(OP_NULL_CHECK_END_MEMST_PUSH);
+ MOP_IN(OP_NULL_CHECK_END_MEMST_PUSH);
{
int isnull;
GET_MEMNUM_INC(mem, p); /* mem: null check id */
-#ifdef USE_INFINITE_REPEAT_MONOMANIAC_MEM_STATUS_CHECK
+#ifdef USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT
STACK_NULL_CHECK_MEMST_REC(isnull, mem, s, reg);
#else
STACK_NULL_CHECK_REC(isnull, mem, s);
@@ -2589,39 +2408,39 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
STACK_PUSH_NULL_CHECK_END(mem);
}
}
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
#endif
- case OP_JUMP: STAT_OP_IN(OP_JUMP);
+ case OP_JUMP: MOP_IN(OP_JUMP);
GET_RELADDR_INC(addr, p);
p += addr;
- STAT_OP_OUT;
+ MOP_OUT;
CHECK_INTERRUPT_IN_MATCH_AT;
continue;
break;
- case OP_PUSH: STAT_OP_IN(OP_PUSH);
+ case OP_PUSH: MOP_IN(OP_PUSH);
GET_RELADDR_INC(addr, p);
STACK_PUSH_ALT(p + addr, s, sprev);
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
#ifdef USE_COMBINATION_EXPLOSION_CHECK
- case OP_STATE_CHECK_PUSH: STAT_OP_IN(OP_STATE_CHECK_PUSH);
+ case OP_STATE_CHECK_PUSH: MOP_IN(OP_STATE_CHECK_PUSH);
GET_STATE_CHECK_NUM_INC(mem, p);
STATE_CHECK_VAL(scv, mem);
if (scv) goto fail;
GET_RELADDR_INC(addr, p);
STACK_PUSH_ALT_WITH_STATE_CHECK(p + addr, s, sprev, mem);
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_STATE_CHECK_PUSH_OR_JUMP: STAT_OP_IN(OP_STATE_CHECK_PUSH_OR_JUMP);
+ case OP_STATE_CHECK_PUSH_OR_JUMP: MOP_IN(OP_STATE_CHECK_PUSH_OR_JUMP);
GET_STATE_CHECK_NUM_INC(mem, p);
GET_RELADDR_INC(addr, p);
STATE_CHECK_VAL(scv, mem);
@@ -2631,54 +2450,54 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
else {
STACK_PUSH_ALT_WITH_STATE_CHECK(p + addr, s, sprev, mem);
}
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_STATE_CHECK: STAT_OP_IN(OP_STATE_CHECK);
+ case OP_STATE_CHECK: MOP_IN(OP_STATE_CHECK);
GET_STATE_CHECK_NUM_INC(mem, p);
STATE_CHECK_VAL(scv, mem);
if (scv) goto fail;
STACK_PUSH_STATE_CHECK(s, mem);
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
#endif /* USE_COMBINATION_EXPLOSION_CHECK */
- case OP_POP: STAT_OP_IN(OP_POP);
+ case OP_POP: MOP_IN(OP_POP);
STACK_POP_ONE;
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_PUSH_OR_JUMP_EXACT1: STAT_OP_IN(OP_PUSH_OR_JUMP_EXACT1);
+ case OP_PUSH_OR_JUMP_EXACT1: MOP_IN(OP_PUSH_OR_JUMP_EXACT1);
GET_RELADDR_INC(addr, p);
- if (*p == *s && DATA_ENSURE_CHECK(1)) {
+ if (*p == *s && DATA_ENSURE_CHECK1) {
p++;
STACK_PUSH_ALT(p + addr, s, sprev);
- STAT_OP_OUT;
+ MOP_OUT;
continue;
}
p += (addr + 1);
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_PUSH_IF_PEEK_NEXT: STAT_OP_IN(OP_PUSH_IF_PEEK_NEXT);
+ case OP_PUSH_IF_PEEK_NEXT: MOP_IN(OP_PUSH_IF_PEEK_NEXT);
GET_RELADDR_INC(addr, p);
if (*p == *s) {
p++;
STACK_PUSH_ALT(p + addr, s, sprev);
- STAT_OP_OUT;
+ MOP_OUT;
continue;
}
p++;
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_REPEAT: STAT_OP_IN(OP_REPEAT);
+ case OP_REPEAT: MOP_IN(OP_REPEAT);
{
GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
GET_RELADDR_INC(addr, p);
@@ -2691,11 +2510,11 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
STACK_PUSH_ALT(p + addr, s, sprev);
}
}
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_REPEAT_NG: STAT_OP_IN(OP_REPEAT_NG);
+ case OP_REPEAT_NG: MOP_IN(OP_REPEAT_NG);
{
GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
GET_RELADDR_INC(addr, p);
@@ -2709,11 +2528,11 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
p += addr;
}
}
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_REPEAT_INC: STAT_OP_IN(OP_REPEAT_INC);
+ case OP_REPEAT_INC: MOP_IN(OP_REPEAT_INC);
GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
si = repeat_stk[mem];
stkp = STACK_AT(si);
@@ -2731,19 +2550,19 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
p = stkp->u.repeat.pcode;
}
STACK_PUSH_REPEAT_INC(si);
- STAT_OP_OUT;
+ MOP_OUT;
CHECK_INTERRUPT_IN_MATCH_AT;
continue;
break;
- case OP_REPEAT_INC_SG: STAT_OP_IN(OP_REPEAT_INC_SG);
+ case OP_REPEAT_INC_SG: MOP_IN(OP_REPEAT_INC_SG);
GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
STACK_GET_REPEAT(mem, stkp);
si = GET_STACK_INDEX(stkp);
goto repeat_inc;
break;
- case OP_REPEAT_INC_NG: STAT_OP_IN(OP_REPEAT_INC_NG);
+ case OP_REPEAT_INC_NG: MOP_IN(OP_REPEAT_INC_NG);
GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
si = repeat_stk[mem];
stkp = STACK_AT(si);
@@ -2765,68 +2584,68 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
else if (stkp->u.repeat.count == reg->repeat_range[mem].upper) {
STACK_PUSH_REPEAT_INC(si);
}
- STAT_OP_OUT;
+ MOP_OUT;
CHECK_INTERRUPT_IN_MATCH_AT;
continue;
break;
- case OP_REPEAT_INC_NG_SG: STAT_OP_IN(OP_REPEAT_INC_NG_SG);
+ case OP_REPEAT_INC_NG_SG: MOP_IN(OP_REPEAT_INC_NG_SG);
GET_MEMNUM_INC(mem, p); /* mem: OP_REPEAT ID */
STACK_GET_REPEAT(mem, stkp);
si = GET_STACK_INDEX(stkp);
goto repeat_inc_ng;
break;
- case OP_PUSH_POS: STAT_OP_IN(OP_PUSH_POS);
+ case OP_PUSH_POS: MOP_IN(OP_PUSH_POS);
STACK_PUSH_POS(s, sprev);
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_POP_POS: STAT_OP_IN(OP_POP_POS);
+ case OP_POP_POS: MOP_IN(OP_POP_POS);
{
STACK_POS_END(stkp);
s = stkp->u.state.pstr;
sprev = stkp->u.state.pstr_prev;
}
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_PUSH_POS_NOT: STAT_OP_IN(OP_PUSH_POS_NOT);
+ case OP_PUSH_POS_NOT: MOP_IN(OP_PUSH_POS_NOT);
GET_RELADDR_INC(addr, p);
STACK_PUSH_POS_NOT(p + addr, s, sprev);
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_FAIL_POS: STAT_OP_IN(OP_FAIL_POS);
+ case OP_FAIL_POS: MOP_IN(OP_FAIL_POS);
STACK_POP_TIL_POS_NOT;
goto fail;
break;
- case OP_PUSH_STOP_BT: STAT_OP_IN(OP_PUSH_STOP_BT);
+ case OP_PUSH_STOP_BT: MOP_IN(OP_PUSH_STOP_BT);
STACK_PUSH_STOP_BT;
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_POP_STOP_BT: STAT_OP_IN(OP_POP_STOP_BT);
+ case OP_POP_STOP_BT: MOP_IN(OP_POP_STOP_BT);
STACK_STOP_BT_END;
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_LOOK_BEHIND: STAT_OP_IN(OP_LOOK_BEHIND);
+ case OP_LOOK_BEHIND: MOP_IN(OP_LOOK_BEHIND);
GET_LENGTH_INC(tlen, p);
s = (UChar* )ONIGENC_STEP_BACK(encode, str, s, (int )tlen);
if (IS_NULL(s)) goto fail;
sprev = (UChar* )onigenc_get_prev_char_head(encode, str, s);
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_PUSH_LOOK_BEHIND_NOT: STAT_OP_IN(OP_PUSH_LOOK_BEHIND_NOT);
+ case OP_PUSH_LOOK_BEHIND_NOT: MOP_IN(OP_PUSH_LOOK_BEHIND_NOT);
GET_RELADDR_INC(addr, p);
GET_LENGTH_INC(tlen, p);
q = (UChar* )ONIGENC_STEP_BACK(encode, str, s, (int )tlen);
@@ -2841,28 +2660,28 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
s = q;
sprev = (UChar* )onigenc_get_prev_char_head(encode, str, s);
}
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_FAIL_LOOK_BEHIND_NOT: STAT_OP_IN(OP_FAIL_LOOK_BEHIND_NOT);
+ case OP_FAIL_LOOK_BEHIND_NOT: MOP_IN(OP_FAIL_LOOK_BEHIND_NOT);
STACK_POP_TIL_LOOK_BEHIND_NOT;
goto fail;
break;
#ifdef USE_SUBEXP_CALL
- case OP_CALL: STAT_OP_IN(OP_CALL);
+ case OP_CALL: MOP_IN(OP_CALL);
GET_ABSADDR_INC(addr, p);
STACK_PUSH_CALL_FRAME(p);
p = reg->p + addr;
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
- case OP_RETURN: STAT_OP_IN(OP_RETURN);
+ case OP_RETURN: MOP_IN(OP_RETURN);
STACK_RETURN(p);
STACK_PUSH_RETURN;
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
#endif
@@ -2872,9 +2691,9 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
break;
fail:
- STAT_OP_OUT;
+ MOP_OUT;
/* fall */
- case OP_FAIL: STAT_OP_IN(OP_FAIL);
+ case OP_FAIL: MOP_IN(OP_FAIL);
STACK_POP;
p = stk->u.state.pcode;
s = stk->u.state.pstr;
@@ -2887,7 +2706,7 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, const UChar* sstart,
}
#endif
- STAT_OP_OUT;
+ MOP_OUT;
continue;
break;
@@ -2943,32 +2762,25 @@ slow_search(OnigEncoding enc, UChar* target, UChar* target_end,
if (t == target_end)
return s;
}
- s += enc_len(enc, s);
+ s += enclen(enc, s);
}
return (UChar* )NULL;
}
static int
-str_lower_case_match(OnigEncoding enc, int ambig_flag,
+str_lower_case_match(OnigEncoding enc, int case_fold_flag,
const UChar* t, const UChar* tend,
const UChar* p, const UChar* end)
{
int lowlen;
- UChar *q, lowbuf[ONIGENC_MBC_NORMALIZE_MAXLEN];
- const UChar* tsave;
- const UChar* psave;
-
- tsave = t;
- psave = p;
+ UChar *q, lowbuf[ONIGENC_MBC_CASE_FOLD_MAXLEN];
while (t < tend) {
- lowlen = ONIGENC_MBC_TO_NORMALIZE(enc, ambig_flag, &p, end, lowbuf);
+ lowlen = ONIGENC_MBC_CASE_FOLD(enc, case_fold_flag, &p, end, lowbuf);
q = lowbuf;
while (lowlen > 0) {
- if (*t++ != *q++) {
- return 0;
- }
+ if (*t++ != *q++) return 0;
lowlen--;
}
}
@@ -2977,7 +2789,7 @@ str_lower_case_match(OnigEncoding enc, int ambig_flag,
}
static UChar*
-slow_search_ic(OnigEncoding enc, int ambig_flag,
+slow_search_ic(OnigEncoding enc, int case_fold_flag,
UChar* target, UChar* target_end,
const UChar* text, const UChar* text_end, UChar* text_range)
{
@@ -2991,10 +2803,11 @@ slow_search_ic(OnigEncoding enc, int ambig_flag,
s = (UChar* )text;
while (s < end) {
- if (str_lower_case_match(enc, ambig_flag, target, target_end, s, text_end))
+ if (str_lower_case_match(enc, case_fold_flag, target, target_end,
+ s, text_end))
return s;
- s += enc_len(enc, s);
+ s += enclen(enc, s);
}
return (UChar* )NULL;
@@ -3033,7 +2846,7 @@ slow_search_backward(OnigEncoding enc, UChar* target, UChar* target_end,
}
static UChar*
-slow_search_backward_ic(OnigEncoding enc, int ambig_flag,
+slow_search_backward_ic(OnigEncoding enc, int case_fold_flag,
UChar* target, UChar* target_end,
const UChar* text, const UChar* adjust_text,
const UChar* text_end, const UChar* text_start)
@@ -3048,7 +2861,7 @@ slow_search_backward_ic(OnigEncoding enc, int ambig_flag,
s = ONIGENC_LEFT_ADJUST_CHAR_HEAD(enc, adjust_text, s);
while (s >= text) {
- if (str_lower_case_match(enc, ambig_flag,
+ if (str_lower_case_match(enc, case_fold_flag,
target, target_end, s, text_end))
return s;
@@ -3084,15 +2897,14 @@ bm_search_notrev(regex_t* reg, const UChar* target, const UChar* target_end,
while (s < end) {
p = se = s + tlen1;
t = tail;
- while (t >= target && *p == *t) {
- p--; t--;
+ while (*p == *t) {
+ if (t == target) return (UChar* )s;
+ p--; t--;
}
- if (t < target) return (UChar* )s;
-
skip = reg->map[*se];
t = s;
do {
- s += enc_len(reg->enc, s);
+ s += enclen(reg->enc, s);
} while ((s - t) < skip && s < end);
}
}
@@ -3100,15 +2912,14 @@ bm_search_notrev(regex_t* reg, const UChar* target, const UChar* target_end,
while (s < end) {
p = se = s + tlen1;
t = tail;
- while (t >= target && *p == *t) {
- p--; t--;
+ while (*p == *t) {
+ if (t == target) return (UChar* )s;
+ p--; t--;
}
- if (t < target) return (UChar* )s;
-
skip = reg->int_map[*se];
t = s;
do {
- s += enc_len(reg->enc, s);
+ s += enclen(reg->enc, s);
} while ((s - t) < skip && s < end);
}
}
@@ -3133,10 +2944,10 @@ bm_search(regex_t* reg, const UChar* target, const UChar* target_end,
while (s < end) {
p = s;
t = tail;
- while (t >= target && *p == *t) {
+ while (*p == *t) {
+ if (t == target) return (UChar* )p;
p--; t--;
}
- if (t < target) return (UChar* )(p + 1);
s += reg->map[*s];
}
}
@@ -3144,10 +2955,10 @@ bm_search(regex_t* reg, const UChar* target, const UChar* target_end,
while (s < end) {
p = s;
t = tail;
- while (t >= target && *p == *t) {
+ while (*p == *t) {
+ if (t == target) return (UChar* )p;
p--; t--;
}
- if (t < target) return (UChar* )(p + 1);
s += reg->int_map[*s];
}
}
@@ -3155,7 +2966,8 @@ bm_search(regex_t* reg, const UChar* target, const UChar* target_end,
}
static int
-set_bm_backward_skip(UChar* s, UChar* end, OnigEncoding enc, int** skip)
+set_bm_backward_skip(UChar* s, UChar* end, OnigEncoding enc ARG_UNUSED,
+ int** skip)
{
int i, len;
@@ -3213,7 +3025,7 @@ map_search(OnigEncoding enc, UChar map[],
while (s < text_range) {
if (map[*s]) return (UChar* )s;
- s += enc_len(enc, s);
+ s += enclen(enc, s);
}
return (UChar* )NULL;
}
@@ -3239,7 +3051,7 @@ onig_match(regex_t* reg, const UChar* str, const UChar* end, const UChar* at, On
{
int r;
UChar *prev;
- MatchArg msa;
+ OnigMatchArg msa;
#if defined(USE_RECOMPILE_API) && defined(USE_MULTI_THREAD_SYSTEM)
start:
@@ -3275,7 +3087,7 @@ onig_match(regex_t* reg, const UChar* str, const UChar* end, const UChar* at, On
#endif
if (region
-#ifdef USE_POSIX_REGION_OPTION
+#ifdef USE_POSIX_API_REGION_OPTION
&& !IS_POSIX_REGION(option)
#endif
) {
@@ -3286,7 +3098,11 @@ onig_match(regex_t* reg, const UChar* str, const UChar* end, const UChar* at, On
if (r == 0) {
prev = (UChar* )onigenc_get_prev_char_head(reg->enc, str, at);
- r = match_at(reg, str, end, at, prev, &msa);
+ r = match_at(reg, str, end,
+#ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
+ end,
+#endif
+ at, prev, &msa);
}
MATCH_ARG_FREE(msa);
@@ -3312,7 +3128,7 @@ forward_search_range(regex_t* reg, const UChar* str, const UChar* end, UChar* s,
}
else {
UChar *q = p + reg->dmin;
- while (p < q) p += enc_len(reg->enc, p);
+ while (p < q) p += enclen(reg->enc, p);
}
}
@@ -3322,7 +3138,7 @@ forward_search_range(regex_t* reg, const UChar* str, const UChar* end, UChar* s,
p = slow_search(reg->enc, reg->exact, reg->exact_end, p, end, range);
break;
case ONIG_OPTIMIZE_EXACT_IC:
- p = slow_search_ic(reg->enc, reg->ambig_flag,
+ p = slow_search_ic(reg->enc, reg->case_fold_flag,
reg->exact, reg->exact_end, p, end, range);
break;
@@ -3343,7 +3159,7 @@ forward_search_range(regex_t* reg, const UChar* str, const UChar* end, UChar* s,
if (p - reg->dmin < s) {
retry_gate:
pprev = p;
- p += enc_len(reg->enc, p);
+ p += enclen(reg->enc, p);
goto retry;
}
@@ -3362,10 +3178,12 @@ forward_search_range(regex_t* reg, const UChar* str, const UChar* end, UChar* s,
case ANCHOR_END_LINE:
if (ON_STR_END(p)) {
+#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
prev = (UChar* )onigenc_get_prev_char_head(reg->enc,
(pprev ? pprev : str), p);
if (prev && ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end))
goto retry_gate;
+#endif
}
else if (! ONIGENC_IS_MBC_NEWLINE(reg->enc, p, end)
#ifdef USE_CRNL_AS_LINE_TERMINATOR
@@ -3443,7 +3261,7 @@ backward_search_range(regex_t* reg, const UChar* str, const UChar* end,
break;
case ONIG_OPTIMIZE_EXACT_IC:
- p = slow_search_backward_ic(reg->enc, reg->ambig_flag,
+ p = slow_search_backward_ic(reg->enc, reg->case_fold_flag,
reg->exact, reg->exact_end,
range, adjrange, end, p);
break;
@@ -3484,12 +3302,14 @@ backward_search_range(regex_t* reg, const UChar* str, const UChar* end,
case ANCHOR_END_LINE:
if (ON_STR_END(p)) {
+#ifndef USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE
prev = onigenc_get_prev_char_head(reg->enc, adjrange, p);
if (IS_NULL(prev)) goto fail;
if (ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end)) {
p = prev;
goto retry;
}
+#endif
}
else if (! ONIGENC_IS_MBC_NEWLINE(reg->enc, p, end)
#ifdef USE_CRNL_AS_LINE_TERMINATOR
@@ -3532,8 +3352,11 @@ onig_search(regex_t* reg, const UChar* str, const UChar* end,
{
int r;
UChar *s, *prev;
- MatchArg msa;
+ OnigMatchArg msa;
const UChar *orig_start = start;
+#ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
+ const UChar *orig_range = range;
+#endif
#if defined(USE_RECOMPILE_API) && defined(USE_MULTI_THREAD_SYSTEM)
start:
@@ -3567,7 +3390,7 @@ onig_search(regex_t* reg, const UChar* str, const UChar* end,
#endif
if (region
-#ifdef USE_POSIX_REGION_OPTION
+#ifdef USE_POSIX_API_REGION_OPTION
&& !IS_POSIX_REGION(option)
#endif
) {
@@ -3577,8 +3400,32 @@ onig_search(regex_t* reg, const UChar* str, const UChar* end,
if (start > end || start < str) goto mismatch_no_msa;
+
+#ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
+#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
+#define MATCH_AND_RETURN_CHECK(upper_range) \
+ r = match_at(reg, str, end, (upper_range), s, prev, &msa); \
+ if (r != ONIG_MISMATCH) {\
+ if (r >= 0) {\
+ if (! IS_FIND_LONGEST(reg->options)) {\
+ goto match;\
+ }\
+ }\
+ else goto finish; /* error */ \
+ }
+#else
+#define MATCH_AND_RETURN_CHECK(upper_range) \
+ r = match_at(reg, str, end, (upper_range), s, prev, &msa); \
+ if (r != ONIG_MISMATCH) {\
+ if (r >= 0) {\
+ goto match;\
+ }\
+ else goto finish; /* error */ \
+ }
+#endif /* USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE */
+#else
#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
-#define MATCH_AND_RETURN_CHECK \
+#define MATCH_AND_RETURN_CHECK(none) \
r = match_at(reg, str, end, s, prev, &msa);\
if (r != ONIG_MISMATCH) {\
if (r >= 0) {\
@@ -3589,7 +3436,7 @@ onig_search(regex_t* reg, const UChar* str, const UChar* end,
else goto finish; /* error */ \
}
#else
-#define MATCH_AND_RETURN_CHECK \
+#define MATCH_AND_RETURN_CHECK(none) \
r = match_at(reg, str, end, s, prev, &msa);\
if (r != ONIG_MISMATCH) {\
if (r >= 0) {\
@@ -3597,7 +3444,9 @@ onig_search(regex_t* reg, const UChar* str, const UChar* end,
}\
else goto finish; /* error */ \
}
-#endif
+#endif /* USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE */
+#endif /* USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE */
+
/* anchor optimize: resume search range */
if (reg->anchor != 0 && str < end) {
@@ -3700,10 +3549,10 @@ onig_search(regex_t* reg, const UChar* str, const UChar* end,
MATCH_ARG_INIT(msa, option, region, start);
#ifdef USE_COMBINATION_EXPLOSION_CHECK
- msa.state_check_buff = (void* )0;
- msa.state_check_buff_size = 0;
+ msa.state_check_buff = (void* )0;
+ msa.state_check_buff_size = 0; /* NO NEED, for valgrind */
#endif
- MATCH_AND_RETURN_CHECK;
+ MATCH_AND_RETURN_CHECK(end);
goto mismatch;
}
goto mismatch_no_msa;
@@ -3754,9 +3603,9 @@ onig_search(regex_t* reg, const UChar* str, const UChar* end,
prev = low_prev;
}
while (s <= high) {
- MATCH_AND_RETURN_CHECK;
+ MATCH_AND_RETURN_CHECK(orig_range);
prev = s;
- s += enc_len(reg->enc, s);
+ s += enclen(reg->enc, s);
}
} while (s < range);
goto mismatch;
@@ -3767,13 +3616,13 @@ onig_search(regex_t* reg, const UChar* str, const UChar* end,
if ((reg->anchor & ANCHOR_ANYCHAR_STAR) != 0) {
do {
- MATCH_AND_RETURN_CHECK;
+ MATCH_AND_RETURN_CHECK(orig_range);
prev = s;
- s += enc_len(reg->enc, s);
+ s += enclen(reg->enc, s);
while (!ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end) && s < range) {
prev = s;
- s += enc_len(reg->enc, s);
+ s += enclen(reg->enc, s);
}
} while (s < range);
goto mismatch;
@@ -3782,16 +3631,21 @@ onig_search(regex_t* reg, const UChar* str, const UChar* end,
}
do {
- MATCH_AND_RETURN_CHECK;
+ MATCH_AND_RETURN_CHECK(orig_range);
prev = s;
- s += enc_len(reg->enc, s);
+ s += enclen(reg->enc, s);
} while (s < range);
if (s == range) { /* because empty match with /$/. */
- MATCH_AND_RETURN_CHECK;
+ MATCH_AND_RETURN_CHECK(orig_range);
}
}
else { /* backward search */
+#ifdef USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE
+ if (orig_start < end)
+ orig_start += enclen(reg->enc, orig_start); /* is upper range */
+#endif
+
if (reg->optimize != ONIG_OPTIMIZE_NONE) {
UChar *low, *high, *adjrange, *sch_start;
@@ -3814,7 +3668,7 @@ onig_search(regex_t* reg, const UChar* str, const UChar* end,
while (s >= low) {
prev = onigenc_get_prev_char_head(reg->enc, str, s);
- MATCH_AND_RETURN_CHECK;
+ MATCH_AND_RETURN_CHECK(orig_start);
s = prev;
}
} while (s >= range);
@@ -3842,7 +3696,7 @@ onig_search(regex_t* reg, const UChar* str, const UChar* end,
do {
prev = onigenc_get_prev_char_head(reg->enc, str, s);
- MATCH_AND_RETURN_CHECK;
+ MATCH_AND_RETURN_CHECK(orig_start);
s = prev;
} while (s >= range);
}
@@ -3865,7 +3719,7 @@ onig_search(regex_t* reg, const UChar* str, const UChar* end,
/* If result is mismatch and no FIND_NOT_EMPTY option,
then the region is not setted in match_at(). */
if (IS_FIND_NOT_EMPTY(reg->options) && region
-#ifdef USE_POSIX_REGION_OPTION
+#ifdef USE_POSIX_API_REGION_OPTION
&& !IS_POSIX_REGION(option)
#endif
) {
@@ -3906,10 +3760,10 @@ onig_get_options(regex_t* reg)
return reg->options;
}
-extern OnigAmbigType
-onig_get_ambig_flag(regex_t* reg)
+extern OnigCaseFoldType
+onig_get_case_fold_flag(regex_t* reg)
{
- return reg->ambig_flag;
+ return reg->case_fold_flag;
}
extern OnigSyntaxType*
diff --git a/ext/mbstring/oniguruma/regext.c b/ext/mbstring/oniguruma/regext.c
index f5ad1f35a2..b1b957b40c 100644
--- a/ext/mbstring/oniguruma/regext.c
+++ b/ext/mbstring/oniguruma/regext.c
@@ -2,7 +2,7 @@
regext.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2006 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2008 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -100,7 +100,7 @@ conv_encoding(OnigEncoding from, OnigEncoding to, const UChar* s, const UChar* e
if (to == ONIG_ENCODING_UTF16_BE) {
if (from == ONIG_ENCODING_ASCII || from == ONIG_ENCODING_ISO_8859_1) {
*conv = (UChar* )xmalloc(len * 2);
- CHECK_NULL_RETURN_VAL(*conv, ONIGERR_MEMORY);
+ CHECK_NULL_RETURN_MEMERR(*conv);
*conv_end = *conv + (len * 2);
conv_ext0be(s, end, *conv);
return 0;
@@ -108,7 +108,7 @@ conv_encoding(OnigEncoding from, OnigEncoding to, const UChar* s, const UChar* e
else if (from == ONIG_ENCODING_UTF16_LE) {
swap16:
*conv = (UChar* )xmalloc(len);
- CHECK_NULL_RETURN_VAL(*conv, ONIGERR_MEMORY);
+ CHECK_NULL_RETURN_MEMERR(*conv);
*conv_end = *conv + len;
conv_swap2bytes(s, end, *conv);
return 0;
@@ -117,7 +117,7 @@ conv_encoding(OnigEncoding from, OnigEncoding to, const UChar* s, const UChar* e
else if (to == ONIG_ENCODING_UTF16_LE) {
if (from == ONIG_ENCODING_ASCII || from == ONIG_ENCODING_ISO_8859_1) {
*conv = (UChar* )xmalloc(len * 2);
- CHECK_NULL_RETURN_VAL(*conv, ONIGERR_MEMORY);
+ CHECK_NULL_RETURN_MEMERR(*conv);
*conv_end = *conv + (len * 2);
conv_ext0le(s, end, *conv);
return 0;
@@ -129,7 +129,7 @@ conv_encoding(OnigEncoding from, OnigEncoding to, const UChar* s, const UChar* e
if (to == ONIG_ENCODING_UTF32_BE) {
if (from == ONIG_ENCODING_ASCII || from == ONIG_ENCODING_ISO_8859_1) {
*conv = (UChar* )xmalloc(len * 4);
- CHECK_NULL_RETURN_VAL(*conv, ONIGERR_MEMORY);
+ CHECK_NULL_RETURN_MEMERR(*conv);
*conv_end = *conv + (len * 4);
conv_ext0be32(s, end, *conv);
return 0;
@@ -137,7 +137,7 @@ conv_encoding(OnigEncoding from, OnigEncoding to, const UChar* s, const UChar* e
else if (from == ONIG_ENCODING_UTF32_LE) {
swap32:
*conv = (UChar* )xmalloc(len);
- CHECK_NULL_RETURN_VAL(*conv, ONIGERR_MEMORY);
+ CHECK_NULL_RETURN_MEMERR(*conv);
*conv_end = *conv + len;
conv_swap4bytes(s, end, *conv);
return 0;
@@ -146,7 +146,7 @@ conv_encoding(OnigEncoding from, OnigEncoding to, const UChar* s, const UChar* e
else if (to == ONIG_ENCODING_UTF32_LE) {
if (from == ONIG_ENCODING_ASCII || from == ONIG_ENCODING_ISO_8859_1) {
*conv = (UChar* )xmalloc(len * 4);
- CHECK_NULL_RETURN_VAL(*conv, ONIGERR_MEMORY);
+ CHECK_NULL_RETURN_MEMERR(*conv);
*conv_end = *conv + (len * 4);
conv_ext0le32(s, end, *conv);
return 0;
@@ -178,17 +178,24 @@ onig_new_deluxe(regex_t** reg, const UChar* pattern, const UChar* pattern_end,
cpat_end = (UChar* )pattern_end;
}
- r = onig_alloc_init(reg, ci->option, ci->ambig_flag, ci->target_enc,
- ci->syntax);
+ *reg = (regex_t* )xmalloc(sizeof(regex_t));
+ if (IS_NULL(*reg)) {
+ r = ONIGERR_MEMORY;
+ goto err2;
+ }
+
+ r = onig_reg_init(*reg, ci->option, ci->case_fold_flag, ci->target_enc,
+ ci->syntax);
if (r) goto err;
r = onig_compile(*reg, cpat, cpat_end, einfo);
if (r) {
+ err:
onig_free(*reg);
*reg = NULL;
}
- err:
+ err2:
if (cpat != pattern) xfree(cpat);
return r;
diff --git a/ext/mbstring/oniguruma/reggnu.c b/ext/mbstring/oniguruma/reggnu.c
index 248957c9d9..4bd18c45e1 100644
--- a/ext/mbstring/oniguruma/reggnu.c
+++ b/ext/mbstring/oniguruma/reggnu.c
@@ -2,7 +2,7 @@
reggnu.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2006 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2008 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -85,7 +85,7 @@ re_compile_pattern(const char* pattern, int size, regex_t* reg, char* ebuf)
OnigErrorInfo einfo;
r = onig_compile(reg, (UChar* )pattern, (UChar* )(pattern + size), &einfo);
- if (r != 0) {
+ if (r != ONIG_NORMAL) {
if (IS_NOT_NULL(ebuf))
(void )onig_error_code_to_str((UChar* )ebuf, r, &einfo);
}
@@ -108,7 +108,7 @@ re_recompile_pattern(const char* pattern, int size, regex_t* reg, char* ebuf)
r = onig_recompile(reg, (UChar* )pattern, (UChar* )(pattern + size),
reg->options, enc, OnigDefaultSyntax, &einfo);
- if (r != 0) {
+ if (r != ONIG_NORMAL) {
if (IS_NOT_NULL(ebuf))
(void )onig_error_code_to_str((UChar* )ebuf, r, &einfo);
}
@@ -125,10 +125,13 @@ re_free_pattern(regex_t* reg)
extern int
re_alloc_pattern(regex_t** reg)
{
- return onig_alloc_init(reg, ONIG_OPTION_DEFAULT,
- ONIGENC_AMBIGUOUS_MATCH_DEFAULT,
- OnigEncDefaultCharEncoding,
- OnigDefaultSyntax);
+ *reg = (regex_t* )xmalloc(sizeof(regex_t));
+ if (IS_NULL(*reg)) return ONIGERR_MEMORY;
+
+ return onig_reg_init(*reg, ONIG_OPTION_DEFAULT,
+ ONIGENC_CASE_FOLD_DEFAULT,
+ OnigEncDefaultCharEncoding,
+ OnigDefaultSyntax);
}
extern void
@@ -138,18 +141,8 @@ re_set_casetable(const char* table)
}
extern void
-#ifdef ONIG_RUBY_M17N
-re_mbcinit(OnigEncoding enc)
-#else
re_mbcinit(int mb_code)
-#endif
{
-#ifdef ONIG_RUBY_M17N
-
- onigenc_set_default_encoding(enc);
-
-#else
-
OnigEncoding enc;
switch (mb_code) {
@@ -171,5 +164,4 @@ re_mbcinit(int mb_code)
}
onigenc_set_default_encoding(enc);
-#endif
}
diff --git a/ext/mbstring/oniguruma/regint.h b/ext/mbstring/oniguruma/regint.h
index d6819d8f94..a0ce4912d8 100644
--- a/ext/mbstring/oniguruma/regint.h
+++ b/ext/mbstring/oniguruma/regint.h
@@ -4,7 +4,7 @@
regint.h - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2007 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2008 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -56,64 +56,77 @@
/* config */
/* spec. config */
-/* #define USE_UNICODE_FULL_RANGE_CTYPE */ /* --> move to regenc.h */
#define USE_NAMED_GROUP
#define USE_SUBEXP_CALL
-#define USE_INFINITE_REPEAT_MONOMANIAC_MEM_STATUS_CHECK /* /(?:()|())*\2/ */
+#define USE_BACKREF_WITH_LEVEL /* \k<name+n>, \k<name-n> */
+#define USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT /* /(?:()|())*\2/ */
#define USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE /* /\n$/ =~ "\n" */
#define USE_WARNING_REDUNDANT_NESTED_REPEAT_OPERATOR
/* #define USE_RECOMPILE_API */
-/* treat \r\n as line terminator.
- !!! NO SUPPORT !!!
- use this configuration on your own responsibility */
-/* #define USE_CRNL_AS_LINE_TERMINATOR */
+/* !!! moved to regenc.h. */ /* #define USE_CRNL_AS_LINE_TERMINATOR */
/* internal config */
-#define USE_RECYCLE_NODE
+#define USE_PARSE_TREE_NODE_RECYCLE
#define USE_OP_PUSH_OR_JUMP_EXACT
-#define USE_QUANTIFIER_PEEK_NEXT
-#define USE_ST_HASH_TABLE
+#define USE_QTFR_PEEK_NEXT
+#define USE_ST_LIBRARY
#define USE_SHARED_CCLASS_TABLE
#define INIT_MATCH_STACK_SIZE 160
#define DEFAULT_MATCH_STACK_LIMIT_SIZE 0 /* unlimited */
-/* interface to external system */
-#ifdef NOT_RUBY /* given from Makefile */
+#if defined(__GNUC__)
+# define ARG_UNUSED __attribute__ ((unused))
+#else
+# define ARG_UNUSED
+#endif
+
+/* */
+/* escape other system UChar definition */
#include "config.h"
-#define USE_BACKREF_AT_LEVEL
+#ifdef ONIG_ESCAPE_UCHAR_COLLISION
+#undef ONIG_ESCAPE_UCHAR_COLLISION
+#endif
+
+#define USE_WORD_BEGIN_END /* "\<", "\>" */
#define USE_CAPTURE_HISTORY
#define USE_VARIABLE_META_CHARS
-#define USE_WORD_BEGIN_END /* "\<": word-begin, "\>": word-end */
-#define USE_POSIX_REGION_OPTION /* needed for POSIX API support */
+#define USE_POSIX_API_REGION_OPTION
#define USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
/* #define USE_COMBINATION_EXPLOSION_CHECK */ /* (X*)* */
+
/* #define USE_MULTI_THREAD_SYSTEM */
-#define THREAD_SYSTEM_INIT /* depend on thread system */
-#define THREAD_SYSTEM_END /* depend on thread system */
-#define THREAD_ATOMIC_START /* depend on thread system */
-#define THREAD_ATOMIC_END /* depend on thread system */
-#define THREAD_PASS /* depend on thread system */
+#define THREAD_SYSTEM_INIT /* depend on thread system */
+#define THREAD_SYSTEM_END /* depend on thread system */
+#define THREAD_ATOMIC_START /* depend on thread system */
+#define THREAD_ATOMIC_END /* depend on thread system */
+#define THREAD_PASS /* depend on thread system */
#define xmalloc malloc
#define xrealloc realloc
#define xcalloc calloc
#define xfree free
-#else
-#include "ruby.h"
-#include "rubysig.h" /* for DEFER_INTS, ENABLE_INTS */
-
-#define USE_COMBINATION_EXPLOSION_CHECK /* (X*)* */
-#define USE_MULTI_THREAD_SYSTEM
-#define THREAD_SYSTEM_INIT
-#define THREAD_SYSTEM_END
-#define THREAD_ATOMIC_START DEFER_INTS
-#define THREAD_ATOMIC_END ENABLE_INTS
-#define THREAD_PASS rb_thread_schedule()
-#define DEFAULT_WARN_FUNCTION onig_rb_warn
-#define DEFAULT_VERB_WARN_FUNCTION onig_rb_warning
+#define CHECK_INTERRUPT_IN_MATCH_AT
-#endif /* else NOT_RUBY */
+#define st_init_table onig_st_init_table
+#define st_init_table_with_size onig_st_init_table_with_size
+#define st_init_numtable onig_st_init_numtable
+#define st_init_numtable_with_size onig_st_init_numtable_with_size
+#define st_init_strtable onig_st_init_strtable
+#define st_init_strtable_with_size onig_st_init_strtable_with_size
+#define st_delete onig_st_delete
+#define st_delete_safe onig_st_delete_safe
+#define st_insert onig_st_insert
+#define st_lookup onig_st_lookup
+#define st_foreach onig_st_foreach
+#define st_add_direct onig_st_add_direct
+#define st_free_table onig_st_free_table
+#define st_cleanup_safe onig_st_cleanup_safe
+#define st_copy onig_st_copy
+#define st_nothing_key_clone onig_st_nothing_key_clone
+#define st_nothing_key_free onig_st_nothing_key_free
+/* */
+#define onig_st_is_member st_is_member
#define STATE_CHECK_STRING_THRESHOLD_LEN 7
#define STATE_CHECK_BUFF_MAX_SIZE 0x4000
@@ -122,17 +135,16 @@
#define xmemset memset
#define xmemcpy memcpy
#define xmemmove memmove
+
#if defined(_WIN32) && !defined(__GNUC__)
#define xalloca _alloca
-#if _MSC_VER < 1500
-#ifndef vsnprintf
-#define vsnprintf _vsnprintf
-#endif
-#endif
+#define xvsnprintf _vsnprintf
#else
#define xalloca alloca
+#define xvsnprintf vsnprintf
#endif
+
#if defined(USE_RECOMPILE_API) && defined(USE_MULTI_THREAD_SYSTEM)
#define ONIG_STATE_INC(reg) (reg)->state++
#define ONIG_STATE_DEC(reg) (reg)->state--
@@ -154,60 +166,6 @@
#define ONIG_STATE_DEC_THREAD(reg) /* Nothing */
#endif /* USE_RECOMPILE_API && USE_MULTI_THREAD_SYSTEM */
-
-#define onig_st_is_member st_is_member
-
-#ifdef NOT_RUBY
-
-#define st_init_table onig_st_init_table
-#define st_init_table_with_size onig_st_init_table_with_size
-#define st_init_numtable onig_st_init_numtable
-#define st_init_numtable_with_size onig_st_init_numtable_with_size
-#define st_init_strtable onig_st_init_strtable
-#define st_init_strtable_with_size onig_st_init_strtable_with_size
-#define st_init_strend_table_with_size onig_st_init_strend_table_with_size
-#define st_delete onig_st_delete
-#define st_delete_safe onig_st_delete_safe
-#define st_insert onig_st_insert
-#define st_insert_strend onig_st_insert_strend
-#define st_lookup onig_st_lookup
-#define st_lookup_strend onig_st_lookup_strend
-#define st_foreach onig_st_foreach
-#define st_add_direct onig_st_add_direct
-#define st_add_direct_strend onig_st_add_direct_strend
-#define st_free_table onig_st_free_table
-#define st_cleanup_safe onig_st_cleanup_safe
-#define st_copy onig_st_copy
-#define st_nothing_key_clone onig_st_nothing_key_clone
-#define st_nothing_key_free onig_st_nothing_key_free
-
-#else /* NOT_RUBY */
-
-#define onig_st_init_table st_init_table
-#define onig_st_init_table_with_size st_init_table_with_size
-#define onig_st_init_numtable st_init_numtable
-#define onig_st_init_numtable_with_size st_init_numtable_with_size
-#define onig_st_init_strtable st_init_strtable
-#define onig_st_init_strtable_with_size st_init_strtable_with_size
-#define onig_st_init_strend_table_with_size st_init_strend_table_with_size
-#define onig_st_delete st_delete
-#define onig_st_delete_safe st_delete_safe
-#define onig_st_insert st_insert
-#define onig_st_insert_strend st_insert_strend
-#define onig_st_lookup st_lookup
-#define onig_st_lookup_strend st_lookup_strend
-#define onig_st_foreach st_foreach
-#define onig_st_add_direct st_add_direct
-#define onig_st_add_direct_strend st_add_direct_strend
-#define onig_st_free_table st_free_table
-#define onig_st_cleanup_safe st_cleanup_safe
-#define onig_st_copy st_copy
-#define onig_st_nothing_key_clone st_nothing_key_clone
-#define onig_st_nothing_key_free st_nothing_key_free
-
-#endif /* NOT_RUBY */
-
-
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
@@ -238,7 +196,6 @@
#endif
#include "regenc.h"
-#include "oniguruma.h"
#ifdef MIN
#undef MIN
@@ -252,10 +209,23 @@
#define IS_NULL(p) (((void*)(p)) == (void*)0)
#define IS_NOT_NULL(p) (((void*)(p)) != (void*)0)
#define CHECK_NULL_RETURN(p) if (IS_NULL(p)) return NULL
-#define CHECK_NULL_RETURN_VAL(p,val) if (IS_NULL(p)) return (val)
+#define CHECK_NULL_RETURN_MEMERR(p) if (IS_NULL(p)) return ONIGERR_MEMORY
#define NULL_UCHARP ((UChar* )0)
-#ifndef PLATFORM_UNALIGNED_WORD_ACCESS
+#ifdef PLATFORM_UNALIGNED_WORD_ACCESS
+
+#define PLATFORM_GET_INC(val,p,type) do{\
+ val = *(type* )p;\
+ (p) += sizeof(type);\
+} while(0)
+
+#else
+
+#define PLATFORM_GET_INC(val,p,type) do{\
+ xmemcpy(&val, (p), sizeof(type));\
+ (p) += sizeof(type);\
+} while(0)
+
/* sizeof(OnigCodePoint) */
#define WORD_ALIGNMENT_SIZE SIZEOF_LONG
@@ -270,86 +240,6 @@
(addr) -= ((unsigned int )(addr) % WORD_ALIGNMENT_SIZE);\
} while (0)
-
-#define B_SHIFT 8
-#define B_MASK 0xff
-
-#define SERIALIZE_2BYTE_INT(i,p) do {\
- *(p) = ((i) >> B_SHIFT) & B_MASK;\
- *((p)+1) = (i) & B_MASK;\
-} while (0)
-
-#define SERIALIZE_4BYTE_INT(i,p) do {\
- *(p) = ((i) >> B_SHIFT*3) & B_MASK;\
- *((p)+1) = ((i) >> B_SHIFT*2) & B_MASK;\
- *((p)+2) = ((i) >> B_SHIFT ) & B_MASK;\
- *((p)+3) = (i) & B_MASK;\
-} while (0)
-
-#define SERIALIZE_8BYTE_INT(i,p) do {\
- *(p) = ((i) >> B_SHIFT*7) & B_MASK;\
- *((p)+1) = ((i) >> B_SHIFT*6) & B_MASK;\
- *((p)+2) = ((i) >> B_SHIFT*5) & B_MASK;\
- *((p)+3) = ((i) >> B_SHIFT*4) & B_MASK;\
- *((p)+4) = ((i) >> B_SHIFT*3) & B_MASK;\
- *((p)+5) = ((i) >> B_SHIFT*2) & B_MASK;\
- *((p)+6) = ((i) >> B_SHIFT ) & B_MASK;\
- *((p)+7) = (i) & B_MASK;\
-} while (0)
-
-#define GET_2BYTE_INT_INC(type,i,p) do {\
- (i) = (type )(((unsigned int )(*(p)) << B_SHIFT) | (unsigned int )((p)[1]));\
- (p) += 2;\
-} while (0)
-
-#define GET_4BYTE_INT_INC(type,i,p) do {\
- (i) = (type )(((unsigned int )((p)[0]) << B_SHIFT*3) | \
- ((unsigned int )((p)[1]) << B_SHIFT*2) | \
- ((unsigned int )((p)[2]) << B_SHIFT ) | \
- ((unsigned int )((p)[3]) )); \
- (p) += 4;\
-} while (0)
-
-#define GET_8BYTE_INT_INC(type,i,p) do {\
- (i) = (type )(((unsigned long )((p)[0]) << B_SHIFT*7) | \
- ((unsigned long )((p)[1]) << B_SHIFT*6) | \
- ((unsigned long )((p)[2]) << B_SHIFT*5) | \
- ((unsigned long )((p)[3]) << B_SHIFT*4) | \
- ((unsigned long )((p)[4]) << B_SHIFT*3) | \
- ((unsigned long )((p)[5]) << B_SHIFT*2) | \
- ((unsigned long )((p)[6]) << B_SHIFT ) | \
- ((unsigned long )((p)[7]) )); \
- (p) += 8;\
-} while (0)
-
-#if SIZEOF_SHORT == 2
-#define GET_SHORT_INC(i,p) GET_2BYTE_INT_INC(short,i,p)
-#define SERIALIZE_SHORT(i,p) SERIALIZE_2BYTE_INT(i,p)
-#elif SIZEOF_SHORT == 4
-#define GET_SHORT_INC(i,p) GET_4BYTE_INT_INC(short,i,p)
-#define SERIALIZE_SHORT(i,p) SERIALIZE_4BYTE_INT(i,p)
-#elif SIZEOF_SHORT == 8
-#define GET_SHORT_INC(i,p) GET_8BYTE_INT_INC(short,i,p)
-#define SERIALIZE_SHORT(i,p) SERIALIZE_8BYTE_INT(i,p)
-#endif
-
-#if SIZEOF_INT == 2
-#define GET_INT_INC(i,p) GET_2BYTE_INT_INC(int,i,p)
-#define GET_UINT_INC(i,p) GET_2BYTE_INT_INC(unsigned,i,p)
-#define SERIALIZE_INT(i,p) SERIALIZE_2BYTE_INT(i,p)
-#define SERIALIZE_UINT(i,p) SERIALIZE_2BYTE_INT(i,p)
-#elif SIZEOF_INT == 4
-#define GET_INT_INC(i,p) GET_4BYTE_INT_INC(int,i,p)
-#define GET_UINT_INC(i,p) GET_4BYTE_INT_INC(unsigned,i,p)
-#define SERIALIZE_INT(i,p) SERIALIZE_4BYTE_INT(i,p)
-#define SERIALIZE_UINT(i,p) SERIALIZE_4BYTE_INT(i,p)
-#elif SIZEOF_INT == 8
-#define GET_INT_INC(i,p) GET_8BYTE_INT_INC(int,i,p)
-#define GET_UINT_INC(i,p) GET_8BYTE_INT_INC(unsigned,i,p)
-#define SERIALIZE_INT(i,p) SERIALIZE_8BYTE_INT(i,p)
-#define SERIALIZE_UINT(i,p) SERIALIZE_8BYTE_INT(i,p)
-#endif
-
#endif /* PLATFORM_UNALIGNED_WORD_ACCESS */
/* stack pop level */
@@ -372,17 +262,17 @@ typedef unsigned int BitStatusType;
#define BIT_STATUS_CLEAR(stats) (stats) = 0
#define BIT_STATUS_ON_ALL(stats) (stats) = ~((BitStatusType )0)
#define BIT_STATUS_AT(stats,n) \
- ((n) < BIT_STATUS_BITS_NUM ? ((stats) & (1 << n)) : ((stats) & 1))
+ ((n) < (int )BIT_STATUS_BITS_NUM ? ((stats) & (1 << n)) : ((stats) & 1))
#define BIT_STATUS_ON_AT(stats,n) do {\
- if ((n) < BIT_STATUS_BITS_NUM)\
+ if ((n) < (int )BIT_STATUS_BITS_NUM) \
(stats) |= (1 << (n));\
else\
(stats) |= 1;\
} while (0)
#define BIT_STATUS_ON_AT_SIMPLE(stats,n) do {\
- if ((n) < BIT_STATUS_BITS_NUM)\
+ if ((n) < (int )BIT_STATUS_BITS_NUM)\
(stats) |= (1 << (n));\
} while (0)
@@ -401,7 +291,6 @@ typedef unsigned int BitStatusType;
#define IS_EXTEND(option) ((option) & ONIG_OPTION_EXTEND)
#define IS_FIND_LONGEST(option) ((option) & ONIG_OPTION_FIND_LONGEST)
#define IS_FIND_NOT_EMPTY(option) ((option) & ONIG_OPTION_FIND_NOT_EMPTY)
-#define IS_POSIXLINE(option) (IS_SINGLELINE(option) && IS_MULTILINE(option))
#define IS_FIND_CONDITION(option) ((option) & \
(ONIG_OPTION_FIND_LONGEST | ONIG_OPTION_FIND_NOT_EMPTY))
#define IS_NOTBOL(option) ((option) & ONIG_OPTION_NOTBOL)
@@ -415,6 +304,9 @@ typedef unsigned int BitStatusType;
/* ignore-case and multibyte status are included in compiled code. */
#define IS_DYNAMIC_OPTION(option) 0
+#define DISABLE_CASE_FOLD_MULTI_CHAR(case_fold_flag) \
+ ((case_fold_flag) & ~INTERNAL_ONIGENC_CASE_FOLD_MULTI_CHAR)
+
#define REPEAT_INFINITE -1
#define IS_REPEAT_INFINITE(n) ((n) == REPEAT_INFINITE)
@@ -436,7 +328,7 @@ typedef Bits* BitSetRef;
#define BITSET_CLEAR(bs) do {\
int i;\
- for (i = 0; i < BITSET_SIZE; i++) { (bs)[i] = 0; }\
+ for (i = 0; i < (int )BITSET_SIZE; i++) { (bs)[i] = 0; } \
} while (0)
#define BS_ROOM(bs,pos) (bs)[pos / BITS_IN_ROOM]
@@ -603,7 +495,7 @@ enum OpCode {
OP_BACKREFN_IC,
OP_BACKREF_MULTI,
OP_BACKREF_MULTI_IC,
- OP_BACKREF_AT_LEVEL, /* \k<xxx+n>, \k<xxx-n> */
+ OP_BACKREF_WITH_LEVEL, /* \k<xxx+n>, \k<xxx-n> */
OP_MEMORY_START,
OP_MEMORY_START_PUSH, /* push back-tracker to stack */
@@ -612,9 +504,6 @@ enum OpCode {
OP_MEMORY_END,
OP_MEMORY_END_REC, /* push marker to stack */
- OP_SET_OPTION_PUSH, /* set option and push recover option */
- OP_SET_OPTION, /* set option */
-
OP_FAIL, /* pop stack and move */
OP_JUMP,
OP_PUSH,
@@ -649,7 +538,11 @@ enum OpCode {
OP_STATE_CHECK_PUSH_OR_JUMP, /* check ok -> push, else jump */
OP_STATE_CHECK, /* check only */
OP_STATE_CHECK_ANYCHAR_STAR,
- OP_STATE_CHECK_ANYCHAR_ML_STAR
+ OP_STATE_CHECK_ANYCHAR_ML_STAR,
+
+ /* no need: IS_DYNAMIC_OPTION() == 0 */
+ OP_SET_OPTION_PUSH, /* set option and push recover option */
+ OP_SET_OPTION /* set option */
};
typedef int RelAddrType;
@@ -672,22 +565,6 @@ typedef void* PointerType;
#define SIZE_POINTER sizeof(PointerType)
-#ifdef PLATFORM_UNALIGNED_WORD_ACCESS
-
-#define PLATFORM_GET_INC(val,p,type) do{\
- val = *(type* )p;\
- (p) += sizeof(type);\
-} while(0)
-
-#else
-
-#define PLATFORM_GET_INC(val,p,type) do{\
- xmemcpy(&val, (p), sizeof(type));\
- (p) += sizeof(type);\
-} while(0)
-
-#endif /* PLATFORM_UNALIGNED_WORD_ACCESS */
-
#define GET_RELADDR_INC(addr,p) PLATFORM_GET_INC(addr, p, RelAddrType)
#define GET_ABSADDR_INC(addr,p) PLATFORM_GET_INC(addr, p, AbsAddrType)
#define GET_LENGTH_INC(len,p) PLATFORM_GET_INC(len, p, LengthType)
@@ -745,15 +622,15 @@ typedef void* PointerType;
#define SIZE_OP_STATE_CHECK_ANYCHAR_STAR (SIZE_OPCODE + SIZE_STATE_CHECK_NUM)
#endif
-#define MC_ESC(enc) (enc)->meta_char_table.esc
-#define MC_ANYCHAR(enc) (enc)->meta_char_table.anychar
-#define MC_ANYTIME(enc) (enc)->meta_char_table.anytime
-#define MC_ZERO_OR_ONE_TIME(enc) (enc)->meta_char_table.zero_or_one_time
-#define MC_ONE_OR_MORE_TIME(enc) (enc)->meta_char_table.one_or_more_time
-#define MC_ANYCHAR_ANYTIME(enc) (enc)->meta_char_table.anychar_anytime
+#define MC_ESC(syn) (syn)->meta_char_table.esc
+#define MC_ANYCHAR(syn) (syn)->meta_char_table.anychar
+#define MC_ANYTIME(syn) (syn)->meta_char_table.anytime
+#define MC_ZERO_OR_ONE_TIME(syn) (syn)->meta_char_table.zero_or_one_time
+#define MC_ONE_OR_MORE_TIME(syn) (syn)->meta_char_table.one_or_more_time
+#define MC_ANYCHAR_ANYTIME(syn) (syn)->meta_char_table.anychar_anytime
-#define IS_MC_ESC_CODE(code, enc, syn) \
- ((code) == MC_ESC(enc) && \
+#define IS_MC_ESC_CODE(code, syn) \
+ ((code) == MC_ESC(syn) && \
!IS_SYNTAX_OP2((syn), ONIG_SYN_OP2_INEFFECTIVE_ESCAPE))
@@ -782,22 +659,96 @@ typedef void* PointerType;
ONIG_SYN_CONTEXT_INVALID_REPEAT_OPS | ONIG_SYN_ALLOW_INVALID_INTERVAL | \
ONIG_SYN_BACKSLASH_ESCAPE_IN_CC | ONIG_SYN_ALLOW_DOUBLE_RANGE_OP_IN_CC )
+
+#define NCCLASS_FLAGS(cc) ((cc)->flags)
+#define NCCLASS_FLAG_SET(cc,flag) (NCCLASS_FLAGS(cc) |= (flag))
+#define NCCLASS_FLAG_CLEAR(cc,flag) (NCCLASS_FLAGS(cc) &= ~(flag))
+#define IS_NCCLASS_FLAG_ON(cc,flag) ((NCCLASS_FLAGS(cc) & (flag)) != 0)
+
/* cclass node */
-#define FLAG_CCLASS_NOT 1
-#define FLAG_CCLASS_SHARE (1<<1)
+#define FLAG_NCCLASS_NOT (1<<0)
+#define FLAG_NCCLASS_SHARE (1<<1)
-#define CCLASS_SET_NOT(cc) (cc)->flags |= FLAG_CCLASS_NOT
-#define CCLASS_CLEAR_NOT(cc) (cc)->flags &= ~FLAG_CCLASS_NOT
-#define CCLASS_SET_SHARE(cc) (cc)->flags |= FLAG_CCLASS_SHARE
-#define IS_CCLASS_NOT(cc) (((cc)->flags & FLAG_CCLASS_NOT) != 0)
-#define IS_CCLASS_SHARE(cc) (((cc)->flags & FLAG_CCLASS_SHARE) != 0)
+#define NCCLASS_SET_NOT(nd) NCCLASS_FLAG_SET(nd, FLAG_NCCLASS_NOT)
+#define NCCLASS_SET_SHARE(nd) NCCLASS_FLAG_SET(nd, FLAG_NCCLASS_SHARE)
+#define NCCLASS_CLEAR_NOT(nd) NCCLASS_FLAG_CLEAR(nd, FLAG_NCCLASS_NOT)
+#define IS_NCCLASS_NOT(nd) IS_NCCLASS_FLAG_ON(nd, FLAG_NCCLASS_NOT)
+#define IS_NCCLASS_SHARE(nd) IS_NCCLASS_FLAG_ON(nd, FLAG_NCCLASS_SHARE)
typedef struct {
- int flags;
+ int type;
+ /* struct _Node* next; */
+ /* unsigned int flags; */
+} NodeBase;
+
+typedef struct {
+ NodeBase base;
+ unsigned int flags;
BitSet bs;
- BBuf* mbuf; /* multi-byte info or NULL */
+ BBuf* mbuf; /* multi-byte info or NULL */
} CClassNode;
+typedef long OnigStackIndex;
+
+typedef struct _OnigStackType {
+ unsigned int type;
+ union {
+ struct {
+ UChar *pcode; /* byte code position */
+ UChar *pstr; /* string position */
+ UChar *pstr_prev; /* previous char position of pstr */
+#ifdef USE_COMBINATION_EXPLOSION_CHECK
+ unsigned int state_check;
+#endif
+ } state;
+ struct {
+ int count; /* for OP_REPEAT_INC, OP_REPEAT_INC_NG */
+ UChar *pcode; /* byte code position (head of repeated target) */
+ int num; /* repeat id */
+ } repeat;
+ struct {
+ OnigStackIndex si; /* index of stack */
+ } repeat_inc;
+ struct {
+ int num; /* memory num */
+ UChar *pstr; /* start/end position */
+ /* Following information is setted, if this stack type is MEM-START */
+ OnigStackIndex start; /* prev. info (for backtrack "(...)*" ) */
+ OnigStackIndex end; /* prev. info (for backtrack "(...)*" ) */
+ } mem;
+ struct {
+ int num; /* null check id */
+ UChar *pstr; /* start position */
+ } null_check;
+#ifdef USE_SUBEXP_CALL
+ struct {
+ UChar *ret_addr; /* byte code position */
+ int num; /* null check id */
+ UChar *pstr; /* string position */
+ } call_frame;
+#endif
+ } u;
+} OnigStackType;
+
+typedef struct {
+ void* stack_p;
+ int stack_n;
+ OnigOptionType options;
+ OnigRegion* region;
+ const UChar* start; /* search start position (for \G: BEGIN_POSITION) */
+#ifdef USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE
+ int best_len; /* for ONIG_OPTION_FIND_LONGEST */
+ UChar* best_s;
+#endif
+#ifdef USE_COMBINATION_EXPLOSION_CHECK
+ void* state_check_buff;
+ int state_check_buff_size;
+#endif
+} OnigMatchArg;
+
+
+#define IS_CODE_SB_WORD(enc,code) \
+ (ONIGENC_IS_CODE_ASCII(code) && ONIGENC_IS_CODE_WORD(enc,code))
#ifdef ONIG_DEBUG
@@ -820,11 +771,38 @@ extern void onig_print_statistics P_((FILE* f));
extern UChar* onig_error_code_to_format P_((int code));
extern void onig_snprintf_with_pattern PV_((UChar buf[], int bufsize, OnigEncoding enc, UChar* pat, UChar* pat_end, const UChar *fmt, ...));
extern int onig_bbuf_init P_((BBuf* buf, int size));
-extern int onig_alloc_init P_((regex_t** reg, OnigOptionType option, OnigAmbigType ambig_flag, OnigEncoding enc, OnigSyntaxType* syntax));
extern int onig_compile P_((regex_t* reg, const UChar* pattern, const UChar* pattern_end, OnigErrorInfo* einfo));
extern void onig_chain_reduce P_((regex_t* reg));
extern void onig_chain_link_add P_((regex_t* to, regex_t* add));
extern void onig_transfer P_((regex_t* to, regex_t* from));
extern int onig_is_code_in_cc P_((OnigEncoding enc, OnigCodePoint code, CClassNode* cc));
+extern int onig_is_code_in_cc_len P_((int enclen, OnigCodePoint code, CClassNode* cc));
+
+/* strend hash */
+typedef void hash_table_type;
+typedef unsigned long hash_data_type;
+
+extern hash_table_type* onig_st_init_strend_table_with_size P_((int size));
+extern int onig_st_lookup_strend P_((hash_table_type* table, const UChar* str_key, const UChar* end_key, hash_data_type *value));
+extern int onig_st_insert_strend P_((hash_table_type* table, const UChar* str_key, const UChar* end_key, hash_data_type value));
+
+/* encoding property management */
+#define PROPERTY_LIST_ADD_PROP(Name, CR) \
+ r = onigenc_property_list_add_property((UChar* )Name, CR,\
+ &PropertyNameTable, &PropertyList, &PropertyListNum,\
+ &PropertyListSize);\
+ if (r != 0) goto end
+
+#define PROPERTY_LIST_INIT_CHECK \
+ if (PropertyInited == 0) {\
+ int r = onigenc_property_list_init(init_property_list);\
+ if (r != 0) return r;\
+ }
+
+extern int onigenc_property_list_add_property P_((UChar* name, const OnigCodePoint* prop, hash_table_type **table, const OnigCodePoint*** plist, int *pnum, int *psize));
+
+typedef int (*ONIGENC_INIT_PROPERTY_LIST_FUNC_TYPE)(void);
+
+extern int onigenc_property_list_init P_((ONIGENC_INIT_PROPERTY_LIST_FUNC_TYPE));
#endif /* REGINT_H */
diff --git a/ext/mbstring/oniguruma/regparse.c b/ext/mbstring/oniguruma/regparse.c
index abf2cc1cb5..01131300c6 100644
--- a/ext/mbstring/oniguruma/regparse.c
+++ b/ext/mbstring/oniguruma/regparse.c
@@ -2,7 +2,7 @@
regparse.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2007 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2008 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -28,9 +28,13 @@
*/
#include "regparse.h"
+#include "st.h"
#define WARN_BUFSIZE 256
+#define CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS
+
+
OnigSyntaxType OnigSyntaxRuby = {
(( SYN_GNU_REGEX_OP | ONIG_SYN_OP_QMARK_NON_GREEDY |
ONIG_SYN_OP_ESC_OCTAL3 | ONIG_SYN_OP_ESC_X_HEX2 |
@@ -41,6 +45,8 @@ OnigSyntaxType OnigSyntaxRuby = {
ONIG_SYN_OP2_OPTION_RUBY |
ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP | ONIG_SYN_OP2_ESC_K_NAMED_BACKREF |
ONIG_SYN_OP2_ESC_G_SUBEXP_CALL |
+ ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY |
+ ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT |
ONIG_SYN_OP2_PLUS_POSSESSIVE_REPEAT |
ONIG_SYN_OP2_CCLASS_SET_OP | ONIG_SYN_OP2_ESC_CAPITAL_C_BAR_CONTROL |
ONIG_SYN_OP2_ESC_CAPITAL_M_BAR_META | ONIG_SYN_OP2_ESC_V_VTAB |
@@ -54,25 +60,20 @@ OnigSyntaxType OnigSyntaxRuby = {
ONIG_SYN_WARN_CC_OP_NOT_ESCAPED |
ONIG_SYN_WARN_REDUNDANT_NESTED_REPEAT )
, ONIG_OPTION_NONE
+ ,
+ {
+ (OnigCodePoint )'\\' /* esc */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
+ }
};
OnigSyntaxType* OnigDefaultSyntax = ONIG_SYNTAX_RUBY;
-extern void onig_null_warn(const char* s) { }
-
-#ifdef RUBY_PLATFORM
-extern void
-onig_rb_warn(const char* s)
-{
- rb_warn("%s", s);
-}
-
-extern void
-onig_rb_warning(const char* s)
-{
- rb_warning("%s", s);
-}
-#endif
+extern void onig_null_warn(const char* s ARG_UNUSED) { }
#ifdef DEFAULT_WARN_FUNCTION
static OnigWarnFunc onig_warn = (OnigWarnFunc )DEFAULT_WARN_FUNCTION;
@@ -112,7 +113,7 @@ bbuf_clone(BBuf** rto, BBuf* from)
BBuf *to;
*rto = to = (BBuf* )xmalloc(sizeof(BBuf));
- CHECK_NULL_RETURN_VAL(to, ONIGERR_MEMORY);
+ CHECK_NULL_RETURN_MEMERR(to);
r = BBUF_INIT(to, from->alloc);
if (r != 0) return r;
to->used = from->used;
@@ -120,6 +121,9 @@ bbuf_clone(BBuf** rto, BBuf* from)
return 0;
}
+#define BACKREF_REL_TO_ABS(rel_no, env) \
+ ((env)->num_mem + 1 + (rel_no))
+
#define ONOFF(v,f,negative) (negative) ? ((v) &= ~(f)) : ((v) |= (f))
#define MBCODE_START_POS(enc) \
@@ -139,7 +143,7 @@ bbuf_clone(BBuf** rto, BBuf* from)
#define BITSET_IS_EMPTY(bs,empty) do {\
int i;\
empty = 1;\
- for (i = 0; i < BITSET_SIZE; i++) {\
+ for (i = 0; i < (int )BITSET_SIZE; i++) {\
if ((bs)[i] != 0) {\
empty = 0; break;\
}\
@@ -160,9 +164,7 @@ static void
bitset_set_all(BitSetRef bs)
{
int i;
- for (i = 0; i < BITSET_SIZE; i++) {
- bs[i] = ~((Bits )0);
- }
+ for (i = 0; i < BITSET_SIZE; i++) { bs[i] = ~((Bits )0); }
}
#endif
@@ -170,45 +172,35 @@ static void
bitset_invert(BitSetRef bs)
{
int i;
- for (i = 0; i < BITSET_SIZE; i++) {
- bs[i] = ~(bs[i]);
- }
+ for (i = 0; i < (int )BITSET_SIZE; i++) { bs[i] = ~(bs[i]); }
}
static void
bitset_invert_to(BitSetRef from, BitSetRef to)
{
int i;
- for (i = 0; i < BITSET_SIZE; i++) {
- to[i] = ~(from[i]);
- }
+ for (i = 0; i < (int )BITSET_SIZE; i++) { to[i] = ~(from[i]); }
}
static void
bitset_and(BitSetRef dest, BitSetRef bs)
{
int i;
- for (i = 0; i < BITSET_SIZE; i++) {
- dest[i] &= bs[i];
- }
+ for (i = 0; i < (int )BITSET_SIZE; i++) { dest[i] &= bs[i]; }
}
static void
bitset_or(BitSetRef dest, BitSetRef bs)
{
int i;
- for (i = 0; i < BITSET_SIZE; i++) {
- dest[i] |= bs[i];
- }
+ for (i = 0; i < (int )BITSET_SIZE; i++) { dest[i] |= bs[i]; }
}
static void
bitset_copy(BitSetRef dest, BitSetRef bs)
{
int i;
- for (i = 0; i < BITSET_SIZE; i++) {
- dest[i] = bs[i];
- }
+ for (i = 0; i < (int )BITSET_SIZE; i++) { dest[i] = bs[i]; }
}
extern int
@@ -223,8 +215,8 @@ onig_strncmp(const UChar* s1, const UChar* s2, int n)
return 0;
}
-static void
-k_strcpy(UChar* dest, const UChar* src, const UChar* end)
+extern void
+onig_strcpy(UChar* dest, const UChar* src, const UChar* end)
{
int len = end - src;
if (len > 0) {
@@ -233,6 +225,7 @@ k_strcpy(UChar* dest, const UChar* src, const UChar* end)
}
}
+#ifdef USE_NAMED_GROUP
static UChar*
strdup_with_null(OnigEncoding enc, UChar* s, UChar* end)
{
@@ -251,7 +244,7 @@ strdup_with_null(OnigEncoding enc, UChar* s, UChar* end)
return r;
}
-
+#endif
/* scan pattern methods */
#define PEND_VALUE 0
@@ -273,7 +266,7 @@ strdup_with_null(OnigEncoding enc, UChar* s, UChar* end)
#define PPEEK_IS(c) (PPEEK == (OnigCodePoint )c)
static UChar*
-k_strcat_capa(UChar* dest, UChar* dest_end, const UChar* src, const UChar* src_end,
+strcat_capa(UChar* dest, UChar* dest_end, const UChar* src, const UChar* src_end,
int capa)
{
UChar* r;
@@ -284,7 +277,7 @@ k_strcat_capa(UChar* dest, UChar* dest_end, const UChar* src, const UChar* src_e
r = (UChar* )xmalloc(capa + 1);
CHECK_NULL_RETURN(r);
- k_strcpy(r + (dest_end - dest), src, src_end);
+ onig_strcpy(r + (dest_end - dest), src, src_end);
return r;
}
@@ -297,78 +290,23 @@ strcat_capa_from_static(UChar* dest, UChar* dest_end,
r = (UChar* )xmalloc(capa + 1);
CHECK_NULL_RETURN(r);
- k_strcpy(r, dest, dest_end);
- k_strcpy(r + (dest_end - dest), src, src_end);
+ onig_strcpy(r, dest, dest_end);
+ onig_strcpy(r + (dest_end - dest), src, src_end);
return r;
}
-#ifdef USE_NAMED_GROUP
-
-#define INIT_NAME_BACKREFS_ALLOC_NUM 8
-
-typedef struct {
- UChar* name;
- int name_len; /* byte length */
- int back_num; /* number of backrefs */
- int back_alloc;
- int back_ref1;
- int* back_refs;
-} NameEntry;
-
-#ifdef USE_ST_HASH_TABLE
-#include "st.h"
+#ifdef USE_ST_LIBRARY
typedef struct {
- unsigned char* s;
- unsigned char* end;
-} st_strend_key;
-
-static int strend_cmp(st_strend_key*, st_strend_key*);
-static int strend_hash(st_strend_key*);
-
-static struct st_hash_type type_strend_hash = {
- strend_cmp,
- strend_hash,
-};
-
-static st_table*
-onig_st_init_strend_table_with_size(int size)
-{
- return onig_st_init_table_with_size(&type_strend_hash, size);
-}
-
-static int
-onig_st_lookup_strend(st_table *table, const UChar* str_key, const UChar* end_key, st_data_t *value)
-{
- st_strend_key key;
-
- key.s = (unsigned char* )str_key;
- key.end = (unsigned char* )end_key;
-
- return onig_st_lookup(table, (st_data_t )(&key), value);
-}
-
-static int
-onig_st_insert_strend(st_table *table, const UChar* str_key, const UChar* end_key, st_data_t value)
-{
- st_strend_key* key;
- int result;
-
- key = (st_strend_key* )xmalloc(sizeof(st_strend_key));
- key->s = (unsigned char* )str_key;
- key->end = (unsigned char* )end_key;
- result = onig_st_insert(table, (st_data_t )key, value);
- if (result) {
- xfree(key);
- }
- return result;
-}
+ UChar* s;
+ UChar* end;
+} st_str_end_key;
static int
-strend_cmp(st_strend_key* x, st_strend_key* y)
+str_end_cmp(st_str_end_key* x, st_str_end_key* y)
{
- unsigned char *p, *q;
+ UChar *p, *q;
int c;
if ((x->end - x->s) != (y->end - y->s))
@@ -387,12 +325,11 @@ strend_cmp(st_strend_key* x, st_strend_key* y)
}
static int
-strend_hash(st_strend_key* x)
+str_end_hash(st_str_end_key* x)
{
- int val;
- unsigned char *p;
+ UChar *p;
+ int val = 0;
- val = 0;
p = x->s;
while (p < x->end) {
val = val * 997 + (int )*p++;
@@ -401,6 +338,65 @@ strend_hash(st_strend_key* x)
return val + (val >> 5);
}
+extern hash_table_type*
+onig_st_init_strend_table_with_size(int size)
+{
+ static struct st_hash_type hashType = {
+ str_end_cmp,
+ str_end_hash,
+ };
+
+ return (hash_table_type* )
+ onig_st_init_table_with_size(&hashType, size);
+}
+
+extern int
+onig_st_lookup_strend(hash_table_type* table, const UChar* str_key,
+ const UChar* end_key, hash_data_type *value)
+{
+ st_str_end_key key;
+
+ key.s = (UChar* )str_key;
+ key.end = (UChar* )end_key;
+
+ return onig_st_lookup(table, (st_data_t )(&key), value);
+}
+
+extern int
+onig_st_insert_strend(hash_table_type* table, const UChar* str_key,
+ const UChar* end_key, hash_data_type value)
+{
+ st_str_end_key* key;
+ int result;
+
+ key = (st_str_end_key* )xmalloc(sizeof(st_str_end_key));
+ key->s = (UChar* )str_key;
+ key->end = (UChar* )end_key;
+ result = onig_st_insert(table, (st_data_t )key, value);
+ if (result) {
+ xfree(key);
+ }
+ return result;
+}
+
+#endif /* USE_ST_LIBRARY */
+
+
+#ifdef USE_NAMED_GROUP
+
+#define INIT_NAME_BACKREFS_ALLOC_NUM 8
+
+typedef struct {
+ UChar* name;
+ int name_len; /* byte length */
+ int back_num; /* number of backrefs */
+ int back_alloc;
+ int back_ref1;
+ int* back_refs;
+} NameEntry;
+
+#ifdef USE_ST_LIBRARY
+
typedef st_table NameTable;
typedef st_data_t HashDataType; /* 1.6 st.h doesn't define st_data_t type */
@@ -441,10 +437,10 @@ onig_print_names(FILE* fp, regex_t* reg)
}
return 0;
}
-#endif
+#endif /* ONIG_DEBUG */
static int
-i_free_name_entry(UChar* key, NameEntry* e, void* arg)
+i_free_name_entry(UChar* key, NameEntry* e, void* arg ARG_UNUSED)
{
xfree(e->name);
if (IS_NOT_NULL(e->back_refs)) xfree(e->back_refs);
@@ -501,10 +497,9 @@ typedef struct {
} INamesArg;
static int
-i_names(UChar* key, NameEntry* e, INamesArg* arg)
+i_names(UChar* key ARG_UNUSED, NameEntry* e, INamesArg* arg)
{
int r = (*(arg->func))(e->name,
- /*e->name + onigenc_str_bytelen_null(arg->enc, e->name), */
e->name + e->name_len,
e->back_num,
(e->back_num > 1 ? e->back_refs : &(e->back_ref1)),
@@ -518,8 +513,7 @@ i_names(UChar* key, NameEntry* e, INamesArg* arg)
extern int
onig_foreach_name(regex_t* reg,
- int (*func)(const UChar*, const UChar*,int,int*,regex_t*,void*),
- void* arg)
+ int (*func)(const UChar*, const UChar*,int,int*,regex_t*,void*), void* arg)
{
INamesArg narg;
NameTable* t = (NameTable* )reg->name_table;
@@ -536,7 +530,7 @@ onig_foreach_name(regex_t* reg,
}
static int
-i_renumber_name(UChar* key, NameEntry* e, GroupNumRemap* map)
+i_renumber_name(UChar* key ARG_UNUSED, NameEntry* e, GroupNumRemap* map)
{
int i;
@@ -575,7 +569,7 @@ onig_number_of_names(regex_t* reg)
return 0;
}
-#else /* USE_ST_HASH_TABLE */
+#else /* USE_ST_LIBRARY */
#define INIT_NAMES_ALLOC_NUM 8
@@ -585,7 +579,6 @@ typedef struct {
int alloc;
} NameTable;
-
#ifdef ONIG_DEBUG
extern int
onig_print_names(FILE* fp, regex_t* reg)
@@ -683,8 +676,7 @@ name_find(regex_t* reg, UChar* name, UChar* name_end)
extern int
onig_foreach_name(regex_t* reg,
- int (*func)(const UChar*, const UChar*,int,int*,regex_t*,void*),
- void* arg)
+ int (*func)(const UChar*, const UChar*,int,int*,regex_t*,void*), void* arg)
{
int i, r;
NameEntry* e;
@@ -713,7 +705,7 @@ onig_number_of_names(regex_t* reg)
return 0;
}
-#endif /* else USE_ST_HASH_TABLE */
+#endif /* else USE_ST_LIBRARY */
static int
name_add(regex_t* reg, UChar* name, UChar* name_end, int backref, ScanEnv* env)
@@ -727,16 +719,18 @@ name_add(regex_t* reg, UChar* name, UChar* name_end, int backref, ScanEnv* env)
e = name_find(reg, name, name_end);
if (IS_NULL(e)) {
-#ifdef USE_ST_HASH_TABLE
+#ifdef USE_ST_LIBRARY
if (IS_NULL(t)) {
t = onig_st_init_strend_table_with_size(5);
reg->name_table = (void* )t;
}
e = (NameEntry* )xmalloc(sizeof(NameEntry));
- CHECK_NULL_RETURN_VAL(e, ONIGERR_MEMORY);
+ CHECK_NULL_RETURN_MEMERR(e);
e->name = strdup_with_null(reg->enc, name, name_end);
- if (IS_NULL(e->name)) return ONIGERR_MEMORY;
+ if (IS_NULL(e->name)) {
+ xfree(e); return ONIGERR_MEMORY;
+ }
onig_st_insert_strend(t, e->name, (e->name + (name_end - name)),
(HashDataType )e);
@@ -750,7 +744,7 @@ name_add(regex_t* reg, UChar* name, UChar* name_end, int backref, ScanEnv* env)
if (IS_NULL(t)) {
alloc = INIT_NAMES_ALLOC_NUM;
t = (NameTable* )xmalloc(sizeof(NameTable));
- CHECK_NULL_RETURN_VAL(t, ONIGERR_MEMORY);
+ CHECK_NULL_RETURN_MEMERR(t);
t->e = NULL;
t->alloc = 0;
t->num = 0;
@@ -769,7 +763,7 @@ name_add(regex_t* reg, UChar* name, UChar* name_end, int backref, ScanEnv* env)
alloc = t->alloc * 2;
t->e = (NameEntry* )xrealloc(t->e, sizeof(NameEntry) * alloc);
- CHECK_NULL_RETURN_VAL(t->e, ONIGERR_MEMORY);
+ CHECK_NULL_RETURN_MEMERR(t->e);
t->alloc = alloc;
clear:
@@ -784,6 +778,7 @@ name_add(regex_t* reg, UChar* name, UChar* name_end, int backref, ScanEnv* env)
e = &(t->e[t->num]);
t->num++;
e->name = strdup_with_null(reg->enc, name, name_end);
+ if (IS_NULL(e->name)) return ONIGERR_MEMORY;
e->name_len = name_end - name;
#endif
}
@@ -803,7 +798,7 @@ name_add(regex_t* reg, UChar* name, UChar* name_end, int backref, ScanEnv* env)
if (e->back_num == 2) {
alloc = INIT_NAME_BACKREFS_ALLOC_NUM;
e->back_refs = (int* )xmalloc(sizeof(int) * alloc);
- CHECK_NULL_RETURN_VAL(e->back_refs, ONIGERR_MEMORY);
+ CHECK_NULL_RETURN_MEMERR(e->back_refs);
e->back_alloc = alloc;
e->back_refs[0] = e->back_ref1;
e->back_refs[1] = backref;
@@ -812,7 +807,7 @@ name_add(regex_t* reg, UChar* name, UChar* name_end, int backref, ScanEnv* env)
if (e->back_num > e->back_alloc) {
alloc = e->back_alloc * 2;
e->back_refs = (int* )xrealloc(e->back_refs, sizeof(int) * alloc);
- CHECK_NULL_RETURN_VAL(e->back_refs, ONIGERR_MEMORY);
+ CHECK_NULL_RETURN_MEMERR(e->back_refs);
e->back_alloc = alloc;
}
e->back_refs[e->back_num - 1] = backref;
@@ -826,9 +821,8 @@ extern int
onig_name_to_group_numbers(regex_t* reg, const UChar* name,
const UChar* name_end, int** nums)
{
- NameEntry* e;
+ NameEntry* e = name_find(reg, name, name_end);
- e = name_find(reg, name, name_end);
if (IS_NULL(e)) return ONIGERR_UNDEFINED_NAME_REFERENCE;
switch (e->back_num) {
@@ -886,8 +880,7 @@ onig_name_to_backref_number(regex_t* reg, const UChar* name,
extern int
onig_foreach_name(regex_t* reg,
- int (*func)(const UChar*, const UChar*,int,int*,regex_t*,void*),
- void* arg)
+ int (*func)(const UChar*, const UChar*,int,int*,regex_t*,void*), void* arg)
{
return ONIG_NO_SUPPORT_CONFIG;
}
@@ -928,12 +921,12 @@ scan_env_clear(ScanEnv* env)
BIT_STATUS_CLEAR(env->bt_mem_start);
BIT_STATUS_CLEAR(env->bt_mem_end);
BIT_STATUS_CLEAR(env->backrefed_mem);
- env->error = (UChar* )NULL;
- env->error_end = (UChar* )NULL;
- env->num_call = 0;
- env->num_mem = 0;
+ env->error = (UChar* )NULL;
+ env->error_end = (UChar* )NULL;
+ env->num_call = 0;
+ env->num_mem = 0;
#ifdef USE_NAMED_GROUP
- env->num_named = 0;
+ env->num_named = 0;
#endif
env->mem_alloc = 0;
env->mem_nodes_dynamic = (Node** )NULL;
@@ -968,7 +961,7 @@ scan_env_add_mem_entry(ScanEnv* env)
alloc = env->mem_alloc * 2;
p = (Node** )xrealloc(env->mem_nodes_dynamic, sizeof(Node*) * alloc);
}
- CHECK_NULL_RETURN_VAL(p, ONIGERR_MEMORY);
+ CHECK_NULL_RETURN_MEMERR(p);
for (i = env->num_mem + 1; i < alloc; i++)
p[i] = NULL_NODE;
@@ -993,7 +986,7 @@ scan_env_set_mem_node(ScanEnv* env, int num, Node* node)
}
-#ifdef USE_RECYCLE_NODE
+#ifdef USE_PARSE_TREE_NODE_RECYCLE
typedef struct _FreeNode {
struct _FreeNode* next;
} FreeNode;
@@ -1008,20 +1001,20 @@ onig_node_free(Node* node)
if (IS_NULL(node)) return ;
switch (NTYPE(node)) {
- case N_STRING:
- if (IS_NOT_NULL(NSTRING(node).s) && NSTRING(node).s != NSTRING(node).buf) {
- xfree(NSTRING(node).s);
+ case NT_STR:
+ if (NSTR(node)->capa != 0 &&
+ IS_NOT_NULL(NSTR(node)->s) && NSTR(node)->s != NSTR(node)->buf) {
+ xfree(NSTR(node)->s);
}
break;
- case N_LIST:
- case N_ALT:
- onig_node_free(NCONS(node).left);
- /* onig_node_free(NCONS(node).right); */
+ case NT_LIST:
+ case NT_ALT:
+ onig_node_free(NCAR(node));
{
- Node* next_node = NCONS(node).right;
+ Node* next_node = NCDR(node);
-#ifdef USE_RECYCLE_NODE
+#ifdef USE_PARSE_TREE_NODE_RECYCLE
{
FreeNode* n = (FreeNode* )node;
@@ -1033,46 +1026,43 @@ onig_node_free(Node* node)
#else
xfree(node);
#endif
-
node = next_node;
goto start;
}
break;
- case N_CCLASS:
+ case NT_CCLASS:
{
- CClassNode* cc = &(NCCLASS(node));
-
- if (IS_CCLASS_SHARE(cc))
- return ;
+ CClassNode* cc = NCCLASS(node);
+ if (IS_NCCLASS_SHARE(cc)) return ;
if (cc->mbuf)
bbuf_free(cc->mbuf);
}
break;
- case N_QUANTIFIER:
- if (NQUANTIFIER(node).target)
- onig_node_free(NQUANTIFIER(node).target);
+ case NT_QTFR:
+ if (NQTFR(node)->target)
+ onig_node_free(NQTFR(node)->target);
break;
- case N_EFFECT:
- if (NEFFECT(node).target)
- onig_node_free(NEFFECT(node).target);
+ case NT_ENCLOSE:
+ if (NENCLOSE(node)->target)
+ onig_node_free(NENCLOSE(node)->target);
break;
- case N_BACKREF:
- if (IS_NOT_NULL(NBACKREF(node).back_dynamic))
- xfree(NBACKREF(node).back_dynamic);
+ case NT_BREF:
+ if (IS_NOT_NULL(NBREF(node)->back_dynamic))
+ xfree(NBREF(node)->back_dynamic);
break;
- case N_ANCHOR:
- if (NANCHOR(node).target)
- onig_node_free(NANCHOR(node).target);
+ case NT_ANCHOR:
+ if (NANCHOR(node)->target)
+ onig_node_free(NANCHOR(node)->target);
break;
}
-#ifdef USE_RECYCLE_NODE
+#ifdef USE_PARSE_TREE_NODE_RECYCLE
{
FreeNode* n = (FreeNode* )node;
@@ -1086,7 +1076,7 @@ onig_node_free(Node* node)
#endif
}
-#ifdef USE_RECYCLE_NODE
+#ifdef USE_PARSE_TREE_NODE_RECYCLE
extern int
onig_free_node_list(void)
{
@@ -1108,7 +1098,7 @@ node_new(void)
{
Node* node;
-#ifdef USE_RECYCLE_NODE
+#ifdef USE_PARSE_TREE_NODE_RECYCLE
THREAD_ATOMIC_START;
if (IS_NOT_NULL(FreeNodeList)) {
node = (Node* )FreeNodeList;
@@ -1120,6 +1110,7 @@ node_new(void)
#endif
node = (Node* )xmalloc(sizeof(Node));
+ /* xmemset(node, 0, sizeof(Node)); */
return node;
}
@@ -1128,6 +1119,7 @@ static void
initialize_cclass(CClassNode* cc)
{
BITSET_CLEAR(cc->bs);
+ /* cc->base.flags = 0; */
cc->flags = 0;
cc->mbuf = NULL;
}
@@ -1137,53 +1129,55 @@ node_new_cclass(void)
{
Node* node = node_new();
CHECK_NULL_RETURN(node);
- node->type = N_CCLASS;
- initialize_cclass(&(NCCLASS(node)));
+ SET_NTYPE(node, NT_CCLASS);
+ initialize_cclass(NCCLASS(node));
return node;
}
static Node*
-node_new_cclass_by_codepoint_range(int not,
- const OnigCodePoint sbr[], const OnigCodePoint mbr[])
+node_new_cclass_by_codepoint_range(int not, OnigCodePoint sb_out,
+ const OnigCodePoint ranges[])
{
+ int n, i;
CClassNode* cc;
- int n, i, j;
+ OnigCodePoint j;
- Node* node = node_new();
+ Node* node = node_new_cclass();
CHECK_NULL_RETURN(node);
- node->type = N_CCLASS;
- cc = &(NCCLASS(node));
- cc->flags = 0;
- if (not != 0) CCLASS_SET_NOT(cc);
+ cc = NCCLASS(node);
+ if (not != 0) NCCLASS_SET_NOT(cc);
BITSET_CLEAR(cc->bs);
- if (IS_NOT_NULL(sbr)) {
- n = ONIGENC_CODE_RANGE_NUM(sbr);
+ if (sb_out > 0 && IS_NOT_NULL(ranges)) {
+ n = ONIGENC_CODE_RANGE_NUM(ranges);
for (i = 0; i < n; i++) {
- for (j = ONIGENC_CODE_RANGE_FROM(sbr, i);
- j <= (int )ONIGENC_CODE_RANGE_TO(sbr, i); j++) {
+ for (j = ONIGENC_CODE_RANGE_FROM(ranges, i);
+ j <= (OnigCodePoint )ONIGENC_CODE_RANGE_TO(ranges, i); j++) {
+ if (j >= sb_out) goto sb_end;
+
BITSET_SET_BIT(cc->bs, j);
}
}
}
- if (IS_NULL(mbr)) {
+ sb_end:
+ if (IS_NULL(ranges)) {
is_null:
cc->mbuf = NULL;
}
else {
BBuf* bbuf;
- n = ONIGENC_CODE_RANGE_NUM(mbr);
+ n = ONIGENC_CODE_RANGE_NUM(ranges);
if (n == 0) goto is_null;
bbuf = (BBuf* )xmalloc(sizeof(BBuf));
- CHECK_NULL_RETURN_VAL(bbuf, NULL);
+ CHECK_NULL_RETURN(bbuf);
bbuf->alloc = n + 1;
bbuf->used = n + 1;
- bbuf->p = (UChar* )((void* )mbr);
+ bbuf->p = (UChar* )((void* )ranges);
cc->mbuf = bbuf;
}
@@ -1192,12 +1186,14 @@ node_new_cclass_by_codepoint_range(int not,
}
static Node*
-node_new_ctype(int type)
+node_new_ctype(int type, int not)
{
Node* node = node_new();
CHECK_NULL_RETURN(node);
- node->type = N_CTYPE;
- NCTYPE(node).type = type;
+
+ SET_NTYPE(node, NT_CTYPE);
+ NCTYPE(node)->ctype = type;
+ NCTYPE(node)->not = not;
return node;
}
@@ -1206,7 +1202,8 @@ node_new_anychar(void)
{
Node* node = node_new();
CHECK_NULL_RETURN(node);
- node->type = N_ANYCHAR;
+
+ SET_NTYPE(node, NT_CANY);
return node;
}
@@ -1215,9 +1212,10 @@ node_new_list(Node* left, Node* right)
{
Node* node = node_new();
CHECK_NULL_RETURN(node);
- node->type = N_LIST;
- NCONS(node).left = left;
- NCONS(node).right = right;
+
+ SET_NTYPE(node, NT_LIST);
+ NCAR(node) = left;
+ NCDR(node) = right;
return node;
}
@@ -1227,14 +1225,33 @@ onig_node_new_list(Node* left, Node* right)
return node_new_list(left, right);
}
-static Node*
-node_new_alt(Node* left, Node* right)
+extern Node*
+onig_node_list_add(Node* list, Node* x)
+{
+ Node *n;
+
+ n = onig_node_new_list(x, NULL);
+ if (IS_NULL(n)) return NULL_NODE;
+
+ if (IS_NOT_NULL(list)) {
+ while (IS_NOT_NULL(NCDR(list)))
+ list = NCDR(list);
+
+ NCDR(list) = n;
+ }
+
+ return n;
+}
+
+extern Node*
+onig_node_new_alt(Node* left, Node* right)
{
Node* node = node_new();
CHECK_NULL_RETURN(node);
- node->type = N_ALT;
- NCONS(node).left = left;
- NCONS(node).right = right;
+
+ SET_NTYPE(node, NT_ALT);
+ NCAR(node) = left;
+ NCDR(node) = right;
return node;
}
@@ -1243,16 +1260,17 @@ onig_node_new_anchor(int type)
{
Node* node = node_new();
CHECK_NULL_RETURN(node);
- node->type = N_ANCHOR;
- NANCHOR(node).type = type;
- NANCHOR(node).target = NULL;
- NANCHOR(node).char_len = -1;
+
+ SET_NTYPE(node, NT_ANCHOR);
+ NANCHOR(node)->type = type;
+ NANCHOR(node)->target = NULL;
+ NANCHOR(node)->char_len = -1;
return node;
}
static Node*
node_new_backref(int back_num, int* backrefs, int by_name,
-#ifdef USE_BACKREF_AT_LEVEL
+#ifdef USE_BACKREF_WITH_LEVEL
int exist_level, int nest_level,
#endif
ScanEnv* env)
@@ -1261,31 +1279,32 @@ node_new_backref(int back_num, int* backrefs, int by_name,
Node* node = node_new();
CHECK_NULL_RETURN(node);
- node->type = N_BACKREF;
- NBACKREF(node).state = 0;
- NBACKREF(node).back_num = back_num;
- NBACKREF(node).back_dynamic = (int* )NULL;
+
+ SET_NTYPE(node, NT_BREF);
+ NBREF(node)->state = 0;
+ NBREF(node)->back_num = back_num;
+ NBREF(node)->back_dynamic = (int* )NULL;
if (by_name != 0)
- NBACKREF(node).state |= NST_NAME_REF;
+ NBREF(node)->state |= NST_NAME_REF;
-#ifdef USE_BACKREF_AT_LEVEL
+#ifdef USE_BACKREF_WITH_LEVEL
if (exist_level != 0) {
- NBACKREF(node).state |= NST_NEST_LEVEL;
- NBACKREF(node).nest_level = nest_level;
+ NBREF(node)->state |= NST_NEST_LEVEL;
+ NBREF(node)->nest_level = nest_level;
}
#endif
for (i = 0; i < back_num; i++) {
if (backrefs[i] <= env->num_mem &&
IS_NULL(SCANENV_MEM_NODES(env)[backrefs[i]])) {
- NBACKREF(node).state |= NST_RECURSION; /* /...(\1).../ */
+ NBREF(node)->state |= NST_RECURSION; /* /...(\1).../ */
break;
}
}
if (back_num <= NODE_BACKREFS_SIZE) {
for (i = 0; i < back_num; i++)
- NBACKREF(node).back_static[i] = backrefs[i];
+ NBREF(node)->back_static[i] = backrefs[i];
}
else {
int* p = (int* )xmalloc(sizeof(int) * back_num);
@@ -1293,7 +1312,7 @@ node_new_backref(int back_num, int* backrefs, int by_name,
onig_node_free(node);
return NULL;
}
- NBACKREF(node).back_dynamic = p;
+ NBREF(node)->back_dynamic = p;
for (i = 0; i < back_num; i++)
p[i] = backrefs[i];
}
@@ -1302,17 +1321,17 @@ node_new_backref(int back_num, int* backrefs, int by_name,
#ifdef USE_SUBEXP_CALL
static Node*
-node_new_call(UChar* name, UChar* name_end)
+node_new_call(UChar* name, UChar* name_end, int gnum)
{
Node* node = node_new();
CHECK_NULL_RETURN(node);
- node->type = N_CALL;
- NCALL(node).state = 0;
- NCALL(node).ref_num = CALLNODE_REFNUM_UNDEF;
- NCALL(node).target = NULL_NODE;
- NCALL(node).name = name;
- NCALL(node).name_end = name_end;
+ SET_NTYPE(node, NT_CALL);
+ NCALL(node)->state = 0;
+ NCALL(node)->target = NULL_NODE;
+ NCALL(node)->name = name;
+ NCALL(node)->name_end = name_end;
+ NCALL(node)->group_num = gnum; /* call by number if gnum != 0 */
return node;
}
#endif
@@ -1322,58 +1341,60 @@ node_new_quantifier(int lower, int upper, int by_number)
{
Node* node = node_new();
CHECK_NULL_RETURN(node);
- node->type = N_QUANTIFIER;
- NQUANTIFIER(node).state = 0;
- NQUANTIFIER(node).target = NULL;
- NQUANTIFIER(node).lower = lower;
- NQUANTIFIER(node).upper = upper;
- NQUANTIFIER(node).greedy = 1;
- NQUANTIFIER(node).target_empty_info = NQ_TARGET_ISNOT_EMPTY;
- NQUANTIFIER(node).head_exact = NULL_NODE;
- NQUANTIFIER(node).next_head_exact = NULL_NODE;
- NQUANTIFIER(node).is_refered = 0;
+
+ SET_NTYPE(node, NT_QTFR);
+ NQTFR(node)->state = 0;
+ NQTFR(node)->target = NULL;
+ NQTFR(node)->lower = lower;
+ NQTFR(node)->upper = upper;
+ NQTFR(node)->greedy = 1;
+ NQTFR(node)->target_empty_info = NQ_TARGET_ISNOT_EMPTY;
+ NQTFR(node)->head_exact = NULL_NODE;
+ NQTFR(node)->next_head_exact = NULL_NODE;
+ NQTFR(node)->is_refered = 0;
if (by_number != 0)
- NQUANTIFIER(node).state |= NST_BY_NUMBER;
+ NQTFR(node)->state |= NST_BY_NUMBER;
#ifdef USE_COMBINATION_EXPLOSION_CHECK
- NQUANTIFIER(node).comb_exp_check_num = 0;
+ NQTFR(node)->comb_exp_check_num = 0;
#endif
return node;
}
static Node*
-node_new_effect(int type)
+node_new_enclose(int type)
{
Node* node = node_new();
CHECK_NULL_RETURN(node);
- node->type = N_EFFECT;
- NEFFECT(node).type = type;
- NEFFECT(node).state = 0;
- NEFFECT(node).regnum = 0;
- NEFFECT(node).option = 0;
- NEFFECT(node).target = NULL;
- NEFFECT(node).call_addr = -1;
- NEFFECT(node).opt_count = 0;
+
+ SET_NTYPE(node, NT_ENCLOSE);
+ NENCLOSE(node)->type = type;
+ NENCLOSE(node)->state = 0;
+ NENCLOSE(node)->regnum = 0;
+ NENCLOSE(node)->option = 0;
+ NENCLOSE(node)->target = NULL;
+ NENCLOSE(node)->call_addr = -1;
+ NENCLOSE(node)->opt_count = 0;
return node;
}
extern Node*
-onig_node_new_effect(int type)
+onig_node_new_enclose(int type)
{
- return node_new_effect(type);
+ return node_new_enclose(type);
}
static Node*
-node_new_effect_memory(OnigOptionType option, int is_named)
+node_new_enclose_memory(OnigOptionType option, int is_named)
{
- Node* node = node_new_effect(EFFECT_MEMORY);
+ Node* node = node_new_enclose(ENCLOSE_MEMORY);
CHECK_NULL_RETURN(node);
if (is_named != 0)
- SET_EFFECT_STATUS(node, NST_NAMED_GROUP);
+ SET_ENCLOSE_STATUS(node, NST_NAMED_GROUP);
#ifdef USE_SUBEXP_CALL
- NEFFECT(node).option = option;
+ NENCLOSE(node)->option = option;
#endif
return node;
}
@@ -1381,9 +1402,9 @@ node_new_effect_memory(OnigOptionType option, int is_named)
static Node*
node_new_option(OnigOptionType option)
{
- Node* node = node_new_effect(EFFECT_OPTION);
+ Node* node = node_new_enclose(ENCLOSE_OPTION);
CHECK_NULL_RETURN(node);
- NEFFECT(node).option = option;
+ NENCLOSE(node)->option = option;
return node;
}
@@ -1393,36 +1414,43 @@ onig_node_str_cat(Node* node, const UChar* s, const UChar* end)
int addlen = end - s;
if (addlen > 0) {
- int len = NSTRING(node).end - NSTRING(node).s;
+ int len = NSTR(node)->end - NSTR(node)->s;
- if (NSTRING(node).capa > 0 || (len + addlen > NODE_STR_BUF_SIZE - 1)) {
+ if (NSTR(node)->capa > 0 || (len + addlen > NODE_STR_BUF_SIZE - 1)) {
UChar* p;
int capa = len + addlen + NODE_STR_MARGIN;
- if (capa <= NSTRING(node).capa) {
- k_strcpy(NSTRING(node).s + len, s, end);
+ if (capa <= NSTR(node)->capa) {
+ onig_strcpy(NSTR(node)->s + len, s, end);
}
else {
- if (NSTRING(node).s == NSTRING(node).buf)
- p = strcat_capa_from_static(NSTRING(node).s, NSTRING(node).end,
+ if (NSTR(node)->s == NSTR(node)->buf)
+ p = strcat_capa_from_static(NSTR(node)->s, NSTR(node)->end,
s, end, capa);
else
- p = k_strcat_capa(NSTRING(node).s, NSTRING(node).end, s, end, capa);
+ p = strcat_capa(NSTR(node)->s, NSTR(node)->end, s, end, capa);
- CHECK_NULL_RETURN_VAL(p, ONIGERR_MEMORY);
- NSTRING(node).s = p;
- NSTRING(node).capa = capa;
+ CHECK_NULL_RETURN_MEMERR(p);
+ NSTR(node)->s = p;
+ NSTR(node)->capa = capa;
}
}
else {
- k_strcpy(NSTRING(node).s + len, s, end);
+ onig_strcpy(NSTR(node)->s + len, s, end);
}
- NSTRING(node).end = NSTRING(node).s + len + addlen;
+ NSTR(node)->end = NSTR(node)->s + len + addlen;
}
return 0;
}
+extern int
+onig_node_str_set(Node* node, const UChar* s, const UChar* end)
+{
+ onig_node_str_clear(node);
+ return onig_node_str_cat(node, s, end);
+}
+
static int
node_str_cat_char(Node* node, UChar c)
{
@@ -1435,26 +1463,25 @@ node_str_cat_char(Node* node, UChar c)
extern void
onig_node_conv_to_str_node(Node* node, int flag)
{
- node->type = N_STRING;
-
- NSTRING(node).flag = flag;
- NSTRING(node).capa = 0;
- NSTRING(node).s = NSTRING(node).buf;
- NSTRING(node).end = NSTRING(node).buf;
+ SET_NTYPE(node, NT_STR);
+ NSTR(node)->flag = flag;
+ NSTR(node)->capa = 0;
+ NSTR(node)->s = NSTR(node)->buf;
+ NSTR(node)->end = NSTR(node)->buf;
}
extern void
onig_node_str_clear(Node* node)
{
- if (NSTRING(node).capa != 0 &&
- IS_NOT_NULL(NSTRING(node).s) && NSTRING(node).s != NSTRING(node).buf) {
- xfree(NSTRING(node).s);
+ if (NSTR(node)->capa != 0 &&
+ IS_NOT_NULL(NSTR(node)->s) && NSTR(node)->s != NSTR(node)->buf) {
+ xfree(NSTR(node)->s);
}
- NSTRING(node).capa = 0;
- NSTRING(node).flag = 0;
- NSTRING(node).s = NSTRING(node).buf;
- NSTRING(node).end = NSTRING(node).buf;
+ NSTR(node)->capa = 0;
+ NSTR(node)->flag = 0;
+ NSTR(node)->s = NSTR(node)->buf;
+ NSTR(node)->end = NSTR(node)->buf;
}
static Node*
@@ -1463,11 +1490,11 @@ node_new_str(const UChar* s, const UChar* end)
Node* node = node_new();
CHECK_NULL_RETURN(node);
- node->type = N_STRING;
- NSTRING(node).capa = 0;
- NSTRING(node).flag = 0;
- NSTRING(node).s = NSTRING(node).buf;
- NSTRING(node).end = NSTRING(node).buf;
+ SET_NTYPE(node, NT_STR);
+ NSTR(node)->capa = 0;
+ NSTR(node)->flag = 0;
+ NSTR(node)->s = NSTR(node)->buf;
+ NSTR(node)->end = NSTR(node)->buf;
if (onig_node_str_cat(node, s, end)) {
onig_node_free(node);
return NULL;
@@ -1481,7 +1508,6 @@ onig_node_new_str(const UChar* s, const UChar* end)
return node_new_str(s, end);
}
-#ifdef NUMBERED_CHAR_IS_NOT_CASE_AMBIG
static Node*
node_new_str_raw(UChar* s, UChar* end)
{
@@ -1489,7 +1515,6 @@ node_new_str_raw(UChar* s, UChar* end)
NSTRING_SET_RAW(node);
return node;
}
-#endif
static Node*
node_new_empty(void)
@@ -1498,12 +1523,12 @@ node_new_empty(void)
}
static Node*
-node_new_str_char(UChar c)
+node_new_str_raw_char(UChar c)
{
UChar p[1];
p[0] = c;
- return node_new_str(p, p + 1);
+ return node_new_str_raw(p, p + 1);
}
static Node*
@@ -1528,7 +1553,7 @@ static int
str_node_can_be_split(StrNode* sn, OnigEncoding enc)
{
if (sn->end > sn->s) {
- return ((enc_len(enc, sn->s) < sn->end - sn->s) ? 1 : 0);
+ return ((enclen(enc, sn->s) < sn->end - sn->s) ? 1 : 0);
}
return 0;
}
@@ -1651,7 +1676,7 @@ new_code_range(BBuf** pbuf)
BBuf* bbuf;
bbuf = *pbuf = (BBuf* )xmalloc(sizeof(BBuf));
- CHECK_NULL_RETURN_VAL(*pbuf, ONIGERR_MEMORY);
+ CHECK_NULL_RETURN_MEMERR(*pbuf);
r = BBUF_INIT(*pbuf, INIT_MULTI_BYTE_RANGE_SIZE);
if (r) return r;
@@ -1952,10 +1977,10 @@ and_cclass(CClassNode* dest, CClassNode* cc, OnigEncoding enc)
BitSetRef bsr1, bsr2;
BitSet bs1, bs2;
- not1 = IS_CCLASS_NOT(dest);
+ not1 = IS_NCCLASS_NOT(dest);
bsr1 = dest->bs;
buf1 = dest->mbuf;
- not2 = IS_CCLASS_NOT(cc);
+ not2 = IS_NCCLASS_NOT(cc);
bsr2 = cc->bs;
buf2 = cc->mbuf;
@@ -2010,10 +2035,10 @@ or_cclass(CClassNode* dest, CClassNode* cc, OnigEncoding enc)
BitSetRef bsr1, bsr2;
BitSet bs1, bs2;
- not1 = IS_CCLASS_NOT(dest);
+ not1 = IS_NCCLASS_NOT(dest);
bsr1 = dest->bs;
buf1 = dest->mbuf;
- not2 = IS_CCLASS_NOT(cc);
+ not2 = IS_NCCLASS_NOT(cc);
bsr2 = cc->bs;
buf2 = cc->mbuf;
@@ -2066,13 +2091,13 @@ conv_backslash_value(int c, ScanEnv* env)
{
if (IS_SYNTAX_OP(env->syntax, ONIG_SYN_OP_ESC_CONTROL_CHARS)) {
switch (c) {
- case 'n': return '\n';
- case 't': return '\t';
- case 'r': return '\r';
- case 'f': return '\f';
- case 'a': return '\007';
- case 'b': return '\010';
- case 'e': return '\033';
+ case 'n': return '\n';
+ case 't': return '\t';
+ case 'r': return '\r';
+ case 'f': return '\f';
+ case 'a': return '\007';
+ case 'b': return '\010';
+ case 'e': return '\033';
case 'v':
if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_ESC_V_VTAB))
return '\v';
@@ -2089,26 +2114,26 @@ static int
is_invalid_quantifier_target(Node* node)
{
switch (NTYPE(node)) {
- case N_ANCHOR:
+ case NT_ANCHOR:
return 1;
break;
- case N_EFFECT:
- if (NEFFECT(node).type == EFFECT_OPTION)
- return is_invalid_quantifier_target(NEFFECT(node).target);
+ case NT_ENCLOSE:
+ /* allow enclosed elements */
+ /* return is_invalid_quantifier_target(NENCLOSE(node)->target); */
break;
- case N_LIST: /* ex. (?:\G\A)* */
+ case NT_LIST:
do {
- if (! is_invalid_quantifier_target(NCONS(node).left)) return 0;
- } while (IS_NOT_NULL(node = NCONS(node).right));
+ if (! is_invalid_quantifier_target(NCAR(node))) return 0;
+ } while (IS_NOT_NULL(node = NCDR(node)));
return 0;
break;
- case N_ALT: /* ex. (?:abc|\A)* */
+ case NT_ALT:
do {
- if (is_invalid_quantifier_target(NCONS(node).left)) return 1;
- } while (IS_NOT_NULL(node = NCONS(node).right));
+ if (is_invalid_quantifier_target(NCAR(node))) return 1;
+ } while (IS_NOT_NULL(node = NCDR(node)));
break;
default:
@@ -2119,24 +2144,24 @@ is_invalid_quantifier_target(Node* node)
/* ?:0, *:1, +:2, ??:3, *?:4, +?:5 */
static int
-popular_quantifier_num(QuantifierNode* qf)
+popular_quantifier_num(QtfrNode* q)
{
- if (qf->greedy) {
- if (qf->lower == 0) {
- if (qf->upper == 1) return 0;
- else if (IS_REPEAT_INFINITE(qf->upper)) return 1;
+ if (q->greedy) {
+ if (q->lower == 0) {
+ if (q->upper == 1) return 0;
+ else if (IS_REPEAT_INFINITE(q->upper)) return 1;
}
- else if (qf->lower == 1) {
- if (IS_REPEAT_INFINITE(qf->upper)) return 2;
+ else if (q->lower == 1) {
+ if (IS_REPEAT_INFINITE(q->upper)) return 2;
}
}
else {
- if (qf->lower == 0) {
- if (qf->upper == 1) return 3;
- else if (IS_REPEAT_INFINITE(qf->upper)) return 4;
+ if (q->lower == 0) {
+ if (q->upper == 1) return 3;
+ else if (IS_REPEAT_INFINITE(q->upper)) return 4;
}
- else if (qf->lower == 1) {
- if (IS_REPEAT_INFINITE(qf->upper)) return 5;
+ else if (q->lower == 1) {
+ if (IS_REPEAT_INFINITE(q->upper)) return 5;
}
}
return -1;
@@ -2166,16 +2191,17 @@ extern void
onig_reduce_nested_quantifier(Node* pnode, Node* cnode)
{
int pnum, cnum;
- QuantifierNode *p, *c;
+ QtfrNode *p, *c;
- p = &(NQUANTIFIER(pnode));
- c = &(NQUANTIFIER(cnode));
+ p = NQTFR(pnode);
+ c = NQTFR(cnode);
pnum = popular_quantifier_num(p);
cnum = popular_quantifier_num(c);
+ if (pnum < 0 || cnum < 0) return ;
switch(ReduceTypeTable[cnum][pnum]) {
case RQ_DEL:
- *p = *c;
+ *pnode = *cnode;
break;
case RQ_A:
p->target = c->target;
@@ -2262,7 +2288,7 @@ typedef struct {
int ref1;
int* refs;
int by_name;
-#ifdef USE_BACKREF_AT_LEVEL
+#ifdef USE_BACKREF_WITH_LEVEL
int exist_level;
int level; /* \k<name+n> */
#endif
@@ -2270,8 +2296,10 @@ typedef struct {
struct {
UChar* name;
UChar* name_end;
+ int gnum;
} call;
struct {
+ int ctype;
int not;
} prop;
} u;
@@ -2346,7 +2374,7 @@ fetch_range_quantifier(UChar** src, UChar* end, OnigToken* tok, ScanEnv* env)
if (PEND) goto invalid;
PFETCH(c);
if (IS_SYNTAX_OP(env->syntax, ONIG_SYN_OP_ESC_BRACE_INTERVAL)) {
- if (c != MC_ESC(enc)) goto invalid;
+ if (c != MC_ESC(env->syntax)) goto invalid;
PFETCH(c);
}
if (c != '}') goto invalid;
@@ -2389,7 +2417,7 @@ fetch_escaped_value(UChar** src, UChar* end, ScanEnv* env)
if (c != '-') return ONIGERR_META_CODE_SYNTAX;
if (PEND) return ONIGERR_END_PATTERN_AT_META;
PFETCH(c);
- if (c == MC_ESC(enc)) {
+ if (c == MC_ESC(env->syntax)) {
v = fetch_escaped_value(&p, end, env);
if (v < 0) return v;
c = (OnigCodePoint )v;
@@ -2419,7 +2447,7 @@ fetch_escaped_value(UChar** src, UChar* end, ScanEnv* env)
c = 0177;
}
else {
- if (c == MC_ESC(enc)) {
+ if (c == MC_ESC(env->syntax)) {
v = fetch_escaped_value(&p, end, env);
if (v < 0) return v;
c = (OnigCodePoint )v;
@@ -2444,23 +2472,47 @@ fetch_escaped_value(UChar** src, UChar* end, ScanEnv* env)
static int fetch_token(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env);
+static OnigCodePoint
+get_name_end_code_point(OnigCodePoint start)
+{
+ switch (start) {
+ case '<': return (OnigCodePoint )'>'; break;
+ case '\'': return (OnigCodePoint )'\''; break;
+ default:
+ break;
+ }
+
+ return (OnigCodePoint )0;
+}
+
#ifdef USE_NAMED_GROUP
-#ifdef USE_BACKREF_AT_LEVEL
+#ifdef USE_BACKREF_WITH_LEVEL
/*
\k<name+n>, \k<name-n>
+ \k<num+n>, \k<num-n>
+ \k<-num+n>, \k<-num-n>
*/
static int
-fetch_name_with_level(UChar** src, UChar* end, UChar** rname_end
- , ScanEnv* env, int* level)
+fetch_name_with_level(OnigCodePoint start_code, UChar** src, UChar* end,
+ UChar** rname_end, ScanEnv* env,
+ int* rback_num, int* rlevel)
{
- int r, exist_level = 0;
+ int r, sign, is_num, exist_level;
+ OnigCodePoint end_code;
OnigCodePoint c = 0;
- OnigCodePoint first_code;
OnigEncoding enc = env->enc;
UChar *name_end;
+ UChar *pnum_head;
UChar *p = *src;
PFETCH_READY;
+ *rback_num = 0;
+ is_num = exist_level = 0;
+ sign = 1;
+ pnum_head = *src;
+
+ end_code = get_name_end_code_point(start_code);
+
name_end = end;
r = 0;
if (PEND) {
@@ -2468,11 +2520,18 @@ fetch_name_with_level(UChar** src, UChar* end, UChar** rname_end
}
else {
PFETCH(c);
- first_code = c;
- if (c == '>')
+ if (c == end_code)
return ONIGERR_EMPTY_GROUP_NAME;
- if (!ONIGENC_IS_CODE_WORD(enc, c)) {
+ if (ONIGENC_IS_CODE_DIGIT(enc, c)) {
+ is_num = 1;
+ }
+ else if (c == '-') {
+ is_num = 2;
+ sign = -1;
+ pnum_head = p;
+ }
+ else if (!ONIGENC_IS_CODE_WORD(enc, c)) {
r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
}
}
@@ -2480,43 +2539,58 @@ fetch_name_with_level(UChar** src, UChar* end, UChar** rname_end
while (!PEND) {
name_end = p;
PFETCH(c);
- if (c == '>' || c == ')' || c == '+' || c == '-') break;
+ if (c == end_code || c == ')' || c == '+' || c == '-') {
+ if (is_num == 2) r = ONIGERR_INVALID_GROUP_NAME;
+ break;
+ }
- if (!ONIGENC_IS_CODE_WORD(enc, c)) {
+ if (is_num != 0) {
+ if (ONIGENC_IS_CODE_DIGIT(enc, c)) {
+ is_num = 1;
+ }
+ else {
+ r = ONIGERR_INVALID_GROUP_NAME;
+ is_num = 0;
+ }
+ }
+ else if (!ONIGENC_IS_CODE_WORD(enc, c)) {
r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
}
}
- if (c != '>') {
+ if (r == 0 && c != end_code) {
if (c == '+' || c == '-') {
- int num;
+ int level;
int flag = (c == '-' ? -1 : 1);
PFETCH(c);
if (! ONIGENC_IS_CODE_DIGIT(enc, c)) goto err;
PUNFETCH;
- num = onig_scan_unsigned_number(&p, end, enc);
- if (num < 0) return ONIGERR_TOO_BIG_NUMBER;
- *level = (num * flag);
+ level = onig_scan_unsigned_number(&p, end, enc);
+ if (level < 0) return ONIGERR_TOO_BIG_NUMBER;
+ *rlevel = (level * flag);
exist_level = 1;
PFETCH(c);
- if (c == '>')
- goto first_check;
+ if (c == end_code)
+ goto end;
}
err:
r = ONIGERR_INVALID_GROUP_NAME;
name_end = end;
}
- else {
- first_check:
- if (ONIGENC_IS_CODE_ASCII(first_code) &&
- ONIGENC_IS_CODE_UPPER(enc, first_code))
- r = ONIGERR_INVALID_GROUP_NAME;
- }
+ end:
if (r == 0) {
+ if (is_num != 0) {
+ *rback_num = onig_scan_unsigned_number(&pnum_head, name_end, enc);
+ if (*rback_num < 0) return ONIGERR_TOO_BIG_NUMBER;
+ else if (*rback_num == 0) goto err;
+
+ *rback_num *= sign;
+ }
+
*rname_end = name_end;
*src = p;
return (exist_level ? 1 : 0);
@@ -2526,33 +2600,40 @@ fetch_name_with_level(UChar** src, UChar* end, UChar** rname_end
return r;
}
}
-#endif /* USE_BACKREF_AT_LEVEL */
+#endif /* USE_BACKREF_WITH_LEVEL */
/*
def: 0 -> define name (don't allow number name)
1 -> reference name (allow number name)
*/
static int
-fetch_name(UChar** src, UChar* end, UChar** rname_end, ScanEnv* env, int ref)
+fetch_name(OnigCodePoint start_code, UChar** src, UChar* end,
+ UChar** rname_end, ScanEnv* env, int* rback_num, int ref)
{
- int r, is_num;
+ int r, is_num, sign;
+ OnigCodePoint end_code;
OnigCodePoint c = 0;
- OnigCodePoint first_code;
OnigEncoding enc = env->enc;
UChar *name_end;
+ UChar *pnum_head;
UChar *p = *src;
PFETCH_READY;
+ *rback_num = 0;
+
+ end_code = get_name_end_code_point(start_code);
+
name_end = end;
+ pnum_head = *src;
r = 0;
is_num = 0;
+ sign = 1;
if (PEND) {
return ONIGERR_EMPTY_GROUP_NAME;
}
else {
PFETCH(c);
- first_code = c;
- if (c == '>')
+ if (c == end_code)
return ONIGERR_EMPTY_GROUP_NAME;
if (ONIGENC_IS_CODE_DIGIT(enc, c)) {
@@ -2560,6 +2641,18 @@ fetch_name(UChar** src, UChar* end, UChar** rname_end, ScanEnv* env, int ref)
is_num = 1;
else {
r = ONIGERR_INVALID_GROUP_NAME;
+ is_num = 0;
+ }
+ }
+ else if (c == '-') {
+ if (ref == 1) {
+ is_num = 2;
+ sign = -1;
+ pnum_head = p;
+ }
+ else {
+ r = ONIGERR_INVALID_GROUP_NAME;
+ is_num = 0;
}
}
else if (!ONIGENC_IS_CODE_WORD(enc, c)) {
@@ -2567,74 +2660,137 @@ fetch_name(UChar** src, UChar* end, UChar** rname_end, ScanEnv* env, int ref)
}
}
- while (!PEND) {
- name_end = p;
- PFETCH(c);
- if (c == '>' || c == ')') break;
+ if (r == 0) {
+ while (!PEND) {
+ name_end = p;
+ PFETCH(c);
+ if (c == end_code || c == ')') {
+ if (is_num == 2) r = ONIGERR_INVALID_GROUP_NAME;
+ break;
+ }
- if (is_num == 1) {
- if (! ONIGENC_IS_CODE_DIGIT(enc, c)) {
- if (!ONIGENC_IS_CODE_WORD(enc, c))
- r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
- else
- r = ONIGERR_INVALID_GROUP_NAME;
+ if (is_num != 0) {
+ if (ONIGENC_IS_CODE_DIGIT(enc, c)) {
+ is_num = 1;
+ }
+ else {
+ if (!ONIGENC_IS_CODE_WORD(enc, c))
+ r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
+ else
+ r = ONIGERR_INVALID_GROUP_NAME;
+
+ is_num = 0;
+ }
}
- }
- else {
- if (!ONIGENC_IS_CODE_WORD(enc, c)) {
- r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
+ else {
+ if (!ONIGENC_IS_CODE_WORD(enc, c)) {
+ r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
+ }
}
}
- }
- if (c != '>') {
- r = ONIGERR_INVALID_GROUP_NAME;
- name_end = end;
- }
- else {
- if (ONIGENC_IS_CODE_ASCII(first_code) &&
- ONIGENC_IS_CODE_UPPER(enc, first_code))
+ if (c != end_code) {
r = ONIGERR_INVALID_GROUP_NAME;
- }
+ name_end = end;
+ }
+
+ if (is_num != 0) {
+ *rback_num = onig_scan_unsigned_number(&pnum_head, name_end, enc);
+ if (*rback_num < 0) return ONIGERR_TOO_BIG_NUMBER;
+ else if (*rback_num == 0) {
+ r = ONIGERR_INVALID_GROUP_NAME;
+ goto err;
+ }
+
+ *rback_num *= sign;
+ }
- if (r == 0) {
*rname_end = name_end;
*src = p;
return 0;
}
else {
+ while (!PEND) {
+ name_end = p;
+ PFETCH(c);
+ if (c == end_code || c == ')')
+ break;
+ }
+ if (PEND)
+ name_end = end;
+
+ err:
onig_scan_env_set_error_string(env, r, *src, name_end);
return r;
}
}
#else
static int
-fetch_name(UChar** src, UChar* end, UChar** rname_end, ScanEnv* env, int ref)
+fetch_name(OnigCodePoint start_code, UChar** src, UChar* end,
+ UChar** rname_end, ScanEnv* env, int* rback_num, int ref)
{
- int r, len;
+ int r, is_num, sign;
+ OnigCodePoint end_code;
OnigCodePoint c = 0;
UChar *name_end;
OnigEncoding enc = env->enc;
+ UChar *pnum_head;
UChar *p = *src;
PFETCH_READY;
+ *rback_num = 0;
+
+ end_code = get_name_end_code_point(start_code);
+
+ *rname_end = name_end = end;
r = 0;
+ pnum_head = *src;
+ is_num = 0;
+ sign = 1;
+
+ if (PEND) {
+ return ONIGERR_EMPTY_GROUP_NAME;
+ }
+ else {
+ PFETCH(c);
+ if (c == end_code)
+ return ONIGERR_EMPTY_GROUP_NAME;
+
+ if (ONIGENC_IS_CODE_DIGIT(enc, c)) {
+ is_num = 1;
+ }
+ else if (c == '-') {
+ is_num = 2;
+ sign = -1;
+ pnum_head = p;
+ }
+ else {
+ r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
+ }
+ }
+
while (!PEND) {
name_end = p;
- if (enc_len(enc, p) > 1)
- r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
PFETCH(c);
- if (c == '>' || c == ')') break;
+ if (c == end_code || c == ')') break;
if (! ONIGENC_IS_CODE_DIGIT(enc, c))
r = ONIGERR_INVALID_CHAR_IN_GROUP_NAME;
}
- if (c != '>') {
+ if (r == 0 && c != end_code) {
r = ONIGERR_INVALID_GROUP_NAME;
name_end = end;
}
if (r == 0) {
+ *rback_num = onig_scan_unsigned_number(&pnum_head, name_end, enc);
+ if (*rback_num < 0) return ONIGERR_TOO_BIG_NUMBER;
+ else if (*rback_num == 0) {
+ r = ONIGERR_INVALID_GROUP_NAME;
+ goto err;
+ }
+ *rback_num *= sign;
+
*rname_end = name_end;
*src = p;
return 0;
@@ -2645,7 +2801,7 @@ fetch_name(UChar** src, UChar* end, UChar** rname_end, ScanEnv* env, int ref)
return r;
}
}
-#endif
+#endif /* USE_NAMED_GROUP */
static void
CC_ESC_WARN(ScanEnv* env, UChar *c)
@@ -2663,7 +2819,7 @@ CC_ESC_WARN(ScanEnv* env, UChar *c)
}
static void
-CCEND_ESC_WARN(ScanEnv* env, UChar* c)
+CLOSE_BRACKET_WITHOUT_ESC_WARN(ScanEnv* env, UChar* c)
{
if (onig_warn == onig_null_warn) return ;
@@ -2687,12 +2843,12 @@ find_str_position(OnigCodePoint s[], int n, UChar* from, UChar* to,
while (p < to) {
x = ONIGENC_MBC_TO_CODE(enc, p, to);
- q = p + enc_len(enc, p);
+ q = p + enclen(enc, p);
if (x == s[0]) {
for (i = 1; i < n && q < to; i++) {
x = ONIGENC_MBC_TO_CODE(enc, q, to);
if (x != s[i]) break;
- q += enc_len(enc, q);
+ q += enclen(enc, q);
}
if (i >= n) {
if (IS_NOT_NULL(next))
@@ -2707,7 +2863,7 @@ find_str_position(OnigCodePoint s[], int n, UChar* from, UChar* to,
static int
str_exist_check_with_esc(OnigCodePoint s[], int n, UChar* from, UChar* to,
- OnigCodePoint bad, OnigEncoding enc)
+ OnigCodePoint bad, OnigEncoding enc, OnigSyntaxType* syn)
{
int i, in_esc;
OnigCodePoint x;
@@ -2718,24 +2874,24 @@ str_exist_check_with_esc(OnigCodePoint s[], int n, UChar* from, UChar* to,
while (p < to) {
if (in_esc) {
in_esc = 0;
- p += enc_len(enc, p);
+ p += enclen(enc, p);
}
else {
x = ONIGENC_MBC_TO_CODE(enc, p, to);
- q = p + enc_len(enc, p);
+ q = p + enclen(enc, p);
if (x == s[0]) {
for (i = 1; i < n && q < to; i++) {
x = ONIGENC_MBC_TO_CODE(enc, q, to);
if (x != s[i]) break;
- q += enc_len(enc, q);
+ q += enclen(enc, q);
}
if (i >= n) return 1;
- p += enc_len(enc, p);
+ p += enclen(enc, p);
}
else {
x = ONIGENC_MBC_TO_CODE(enc, p, to);
if (x == bad) return 0;
- else if (x == MC_ESC(enc)) in_esc = 1;
+ else if (x == MC_ESC(syn)) in_esc = 1;
p = q;
}
}
@@ -2771,7 +2927,7 @@ fetch_token_in_cc(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
else if (c == '-') {
tok->type = TK_CC_RANGE;
}
- else if (c == MC_ESC(enc)) {
+ else if (c == MC_ESC(syn)) {
if (! IS_SYNTAX_BV(syn, ONIG_SYN_BACKSLASH_ESCAPE_IN_CC))
goto end;
@@ -2783,37 +2939,45 @@ fetch_token_in_cc(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
switch (c) {
case 'w':
tok->type = TK_CHAR_TYPE;
- tok->u.subtype = CTYPE_WORD;
+ tok->u.prop.ctype = ONIGENC_CTYPE_WORD;
+ tok->u.prop.not = 0;
break;
case 'W':
tok->type = TK_CHAR_TYPE;
- tok->u.subtype = CTYPE_NOT_WORD;
+ tok->u.prop.ctype = ONIGENC_CTYPE_WORD;
+ tok->u.prop.not = 1;
break;
case 'd':
tok->type = TK_CHAR_TYPE;
- tok->u.subtype = CTYPE_DIGIT;
+ tok->u.prop.ctype = ONIGENC_CTYPE_DIGIT;
+ tok->u.prop.not = 0;
break;
case 'D':
tok->type = TK_CHAR_TYPE;
- tok->u.subtype = CTYPE_NOT_DIGIT;
+ tok->u.prop.ctype = ONIGENC_CTYPE_DIGIT;
+ tok->u.prop.not = 1;
break;
case 's':
tok->type = TK_CHAR_TYPE;
- tok->u.subtype = CTYPE_WHITE_SPACE;
+ tok->u.prop.ctype = ONIGENC_CTYPE_SPACE;
+ tok->u.prop.not = 0;
break;
case 'S':
tok->type = TK_CHAR_TYPE;
- tok->u.subtype = CTYPE_NOT_WHITE_SPACE;
+ tok->u.prop.ctype = ONIGENC_CTYPE_SPACE;
+ tok->u.prop.not = 1;
break;
case 'h':
if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_H_XDIGIT)) break;
tok->type = TK_CHAR_TYPE;
- tok->u.subtype = CTYPE_XDIGIT;
+ tok->u.prop.ctype = ONIGENC_CTYPE_XDIGIT;
+ tok->u.prop.not = 0;
break;
case 'H':
if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_H_XDIGIT)) break;
tok->type = TK_CHAR_TYPE;
- tok->u.subtype = CTYPE_NOT_XDIGIT;
+ tok->u.prop.ctype = ONIGENC_CTYPE_XDIGIT;
+ tok->u.prop.not = 1;
break;
case 'p':
@@ -2850,7 +3014,7 @@ fetch_token_in_cc(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
return ONIGERR_TOO_LONG_WIDE_CHAR_VALUE;
}
- if (p > prev + enc_len(enc, prev) && !PEND && (PPEEK_IS('}'))) {
+ if (p > prev + enclen(enc, prev) && !PEND && (PPEEK_IS('}'))) {
PINC;
tok->type = TK_CODE_POINT;
tok->base = 16;
@@ -2922,7 +3086,7 @@ fetch_token_in_cc(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
tok->backp = p; /* point at '[' is readed */
PINC;
if (str_exist_check_with_esc(send, 2, p, end,
- (OnigCodePoint )']', enc)) {
+ (OnigCodePoint )']', enc, syn)) {
tok->type = TK_POSIX_BRACKET_OPEN;
}
else {
@@ -2975,7 +3139,7 @@ fetch_token(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
tok->backp = p;
PFETCH(c);
- if (IS_MC_ESC_CODE(c, enc, syn)) {
+ if (IS_MC_ESC_CODE(c, syn)) {
if (PEND) return ONIGERR_END_PATTERN_AT_ESCAPE;
tok->backp = p;
@@ -3062,13 +3226,15 @@ fetch_token(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
case 'w':
if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_W_WORD)) break;
tok->type = TK_CHAR_TYPE;
- tok->u.subtype = CTYPE_WORD;
+ tok->u.prop.ctype = ONIGENC_CTYPE_WORD;
+ tok->u.prop.not = 0;
break;
case 'W':
if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_W_WORD)) break;
tok->type = TK_CHAR_TYPE;
- tok->u.subtype = CTYPE_NOT_WORD;
+ tok->u.prop.ctype = ONIGENC_CTYPE_WORD;
+ tok->u.prop.not = 1;
break;
case 'b':
@@ -3100,37 +3266,43 @@ fetch_token(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
case 's':
if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_S_WHITE_SPACE)) break;
tok->type = TK_CHAR_TYPE;
- tok->u.subtype = CTYPE_WHITE_SPACE;
+ tok->u.prop.ctype = ONIGENC_CTYPE_SPACE;
+ tok->u.prop.not = 0;
break;
case 'S':
if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_S_WHITE_SPACE)) break;
tok->type = TK_CHAR_TYPE;
- tok->u.subtype = CTYPE_NOT_WHITE_SPACE;
+ tok->u.prop.ctype = ONIGENC_CTYPE_SPACE;
+ tok->u.prop.not = 1;
break;
case 'd':
if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_D_DIGIT)) break;
tok->type = TK_CHAR_TYPE;
- tok->u.subtype = CTYPE_DIGIT;
+ tok->u.prop.ctype = ONIGENC_CTYPE_DIGIT;
+ tok->u.prop.not = 0;
break;
case 'D':
if (! IS_SYNTAX_OP(syn, ONIG_SYN_OP_ESC_D_DIGIT)) break;
tok->type = TK_CHAR_TYPE;
- tok->u.subtype = CTYPE_NOT_DIGIT;
+ tok->u.prop.ctype = ONIGENC_CTYPE_DIGIT;
+ tok->u.prop.not = 1;
break;
case 'h':
if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_H_XDIGIT)) break;
tok->type = TK_CHAR_TYPE;
- tok->u.subtype = CTYPE_XDIGIT;
+ tok->u.prop.ctype = ONIGENC_CTYPE_XDIGIT;
+ tok->u.prop.not = 0;
break;
case 'H':
if (! IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_H_XDIGIT)) break;
tok->type = TK_CHAR_TYPE;
- tok->u.subtype = CTYPE_NOT_XDIGIT;
+ tok->u.prop.ctype = ONIGENC_CTYPE_XDIGIT;
+ tok->u.prop.not = 1;
break;
case 'A':
@@ -3182,7 +3354,7 @@ fetch_token(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
return ONIGERR_TOO_LONG_WIDE_CHAR_VALUE;
}
- if ((p > prev + enc_len(enc, prev)) && !PEND && PPEEK_IS('}')) {
+ if ((p > prev + enclen(enc, prev)) && !PEND && PPEEK_IS('}')) {
PINC;
tok->type = TK_CODE_POINT;
tok->u.code = (OnigCodePoint )num;
@@ -3240,7 +3412,7 @@ fetch_token(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
tok->u.backref.num = 1;
tok->u.backref.ref1 = num;
tok->u.backref.by_name = 0;
-#ifdef USE_BACKREF_AT_LEVEL
+#ifdef USE_BACKREF_WITH_LEVEL
tok->u.backref.exist_level = 0;
#endif
break;
@@ -3276,46 +3448,67 @@ fetch_token(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
case 'k':
if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_K_NAMED_BACKREF)) {
PFETCH(c);
- if (c == '<') {
+ if (c == '<' || c == '\'') {
UChar* name_end;
int* backs;
+ int back_num;
prev = p;
-#ifdef USE_BACKREF_AT_LEVEL
+#ifdef USE_BACKREF_WITH_LEVEL
name_end = NULL_UCHARP; /* no need. escape gcc warning. */
- r = fetch_name_with_level(&p, end, &name_end, env, &tok->u.backref.level);
+ r = fetch_name_with_level((OnigCodePoint )c, &p, end, &name_end,
+ env, &back_num, &tok->u.backref.level);
if (r == 1) tok->u.backref.exist_level = 1;
else tok->u.backref.exist_level = 0;
#else
- r = fetch_name(&p, end, &name_end, env, 1);
+ r = fetch_name(&p, end, &name_end, env, &back_num, 1);
#endif
if (r < 0) return r;
- num = onig_name_to_group_numbers(env->reg, prev, name_end, &backs);
- if (num <= 0) {
- onig_scan_env_set_error_string(env,
- ONIGERR_UNDEFINED_NAME_REFERENCE, prev, name_end);
- return ONIGERR_UNDEFINED_NAME_REFERENCE;
- }
- if (IS_SYNTAX_BV(syn, ONIG_SYN_STRICT_CHECK_BACKREF)) {
- int i;
- for (i = 0; i < num; i++) {
- if (backs[i] > env->num_mem ||
- IS_NULL(SCANENV_MEM_NODES(env)[backs[i]]))
+ if (back_num != 0) {
+ if (back_num < 0) {
+ back_num = BACKREF_REL_TO_ABS(back_num, env);
+ if (back_num <= 0)
return ONIGERR_INVALID_BACKREF;
}
- }
- tok->type = TK_BACKREF;
- tok->u.backref.by_name = 1;
- if (num == 1) {
+ if (IS_SYNTAX_BV(syn, ONIG_SYN_STRICT_CHECK_BACKREF)) {
+ if (back_num > env->num_mem ||
+ IS_NULL(SCANENV_MEM_NODES(env)[back_num]))
+ return ONIGERR_INVALID_BACKREF;
+ }
+ tok->type = TK_BACKREF;
+ tok->u.backref.by_name = 0;
tok->u.backref.num = 1;
- tok->u.backref.ref1 = backs[0];
+ tok->u.backref.ref1 = back_num;
}
else {
- tok->u.backref.num = num;
- tok->u.backref.refs = backs;
+ num = onig_name_to_group_numbers(env->reg, prev, name_end, &backs);
+ if (num <= 0) {
+ onig_scan_env_set_error_string(env,
+ ONIGERR_UNDEFINED_NAME_REFERENCE, prev, name_end);
+ return ONIGERR_UNDEFINED_NAME_REFERENCE;
+ }
+ if (IS_SYNTAX_BV(syn, ONIG_SYN_STRICT_CHECK_BACKREF)) {
+ int i;
+ for (i = 0; i < num; i++) {
+ if (backs[i] > env->num_mem ||
+ IS_NULL(SCANENV_MEM_NODES(env)[backs[i]]))
+ return ONIGERR_INVALID_BACKREF;
+ }
+ }
+
+ tok->type = TK_BACKREF;
+ tok->u.backref.by_name = 1;
+ if (num == 1) {
+ tok->u.backref.num = 1;
+ tok->u.backref.ref1 = backs[0];
+ }
+ else {
+ tok->u.backref.num = num;
+ tok->u.backref.refs = backs;
+ }
}
}
else
@@ -3328,16 +3521,18 @@ fetch_token(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
case 'g':
if (IS_SYNTAX_OP2(syn, ONIG_SYN_OP2_ESC_G_SUBEXP_CALL)) {
PFETCH(c);
- if (c == '<') {
+ if (c == '<' || c == '\'') {
+ int gnum;
UChar* name_end;
prev = p;
- r = fetch_name(&p, end, &name_end, env, 1);
+ r = fetch_name((OnigCodePoint )c, &p, end, &name_end, env, &gnum, 1);
if (r < 0) return r;
tok->type = TK_CALL;
tok->u.call.name = prev;
tok->u.call.name_end = name_end;
+ tok->u.call.gnum = gnum;
}
else
PUNFETCH;
@@ -3380,7 +3575,7 @@ fetch_token(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
tok->u.code = (OnigCodePoint )num;
}
else { /* string */
- p = tok->backp + enc_len(enc, tok->backp);
+ p = tok->backp + enclen(enc, tok->backp);
}
break;
}
@@ -3392,15 +3587,15 @@ fetch_token(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
#ifdef USE_VARIABLE_META_CHARS
if ((c != ONIG_INEFFECTIVE_META_CHAR) &&
IS_SYNTAX_OP(syn, ONIG_SYN_OP_VARIABLE_META_CHARACTERS)) {
- if (c == MC_ANYCHAR(enc))
+ if (c == MC_ANYCHAR(syn))
goto any_char;
- else if (c == MC_ANYTIME(enc))
+ else if (c == MC_ANYTIME(syn))
goto anytime;
- else if (c == MC_ZERO_OR_ONE_TIME(enc))
+ else if (c == MC_ZERO_OR_ONE_TIME(syn))
goto zero_or_one_time;
- else if (c == MC_ONE_OR_MORE_TIME(enc))
+ else if (c == MC_ONE_OR_MORE_TIME(syn))
goto one_or_more_time;
- else if (c == MC_ANYCHAR_ANYTIME(enc)) {
+ else if (c == MC_ANYCHAR_ANYTIME(syn)) {
tok->type = TK_ANYCHAR_ANYTIME;
goto out;
}
@@ -3477,7 +3672,7 @@ fetch_token(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
while (1) {
if (PEND) return ONIGERR_END_PATTERN_IN_GROUP;
PFETCH(c);
- if (c == MC_ESC(enc)) {
+ if (c == MC_ESC(syn)) {
if (!PEND) PFETCH(c);
}
else {
@@ -3519,7 +3714,7 @@ fetch_token(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
case ']':
if (*src > env->pattern) /* /].../ is allowed. */
- CCEND_ESC_WARN(env, (UChar* )"]");
+ CLOSE_BRACKET_WITHOUT_ESC_WARN(env, (UChar* )"]");
break;
case '#':
@@ -3553,24 +3748,36 @@ fetch_token(OnigToken* tok, UChar** src, UChar* end, ScanEnv* env)
}
static int
-add_ctype_to_cc_by_range(CClassNode* cc, int ctype, int not, OnigEncoding enc,
- const OnigCodePoint sbr[], const OnigCodePoint mbr[])
+add_ctype_to_cc_by_range(CClassNode* cc, int ctype ARG_UNUSED, int not,
+ OnigEncoding enc ARG_UNUSED,
+ OnigCodePoint sb_out, const OnigCodePoint mbr[])
{
int i, r;
OnigCodePoint j;
- int nsb = ONIGENC_CODE_RANGE_NUM(sbr);
- int nmb = ONIGENC_CODE_RANGE_NUM(mbr);
+ int n = ONIGENC_CODE_RANGE_NUM(mbr);
if (not == 0) {
- for (i = 0; i < nsb; i++) {
- for (j = ONIGENC_CODE_RANGE_FROM(sbr, i);
- j <= ONIGENC_CODE_RANGE_TO(sbr, i); j++) {
+ for (i = 0; i < n; i++) {
+ for (j = ONIGENC_CODE_RANGE_FROM(mbr, i);
+ j <= ONIGENC_CODE_RANGE_TO(mbr, i); j++) {
+ if (j >= sb_out) {
+ if (j == ONIGENC_CODE_RANGE_TO(mbr, i)) i++;
+ else if (j > ONIGENC_CODE_RANGE_FROM(mbr, i)) {
+ r = add_code_range_to_buf(&(cc->mbuf), j,
+ ONIGENC_CODE_RANGE_TO(mbr, i));
+ if (r != 0) return r;
+ i++;
+ }
+
+ goto sb_end;
+ }
BITSET_SET_BIT(cc->bs, j);
}
}
- for (i = 0; i < nmb; i++) {
+ sb_end:
+ for ( ; i < n; i++) {
r = add_code_range_to_buf(&(cc->mbuf),
ONIGENC_CODE_RANGE_FROM(mbr, i),
ONIGENC_CODE_RANGE_TO(mbr, i));
@@ -3580,24 +3787,24 @@ add_ctype_to_cc_by_range(CClassNode* cc, int ctype, int not, OnigEncoding enc,
else {
OnigCodePoint prev = 0;
- if (ONIGENC_MBC_MINLEN(enc) == 1) {
- for (i = 0; i < nsb; i++) {
- for (j = prev;
- j < ONIGENC_CODE_RANGE_FROM(sbr, i); j++) {
- BITSET_SET_BIT(cc->bs, j);
- }
- prev = ONIGENC_CODE_RANGE_TO(sbr, i) + 1;
- }
- if (prev < 0x7f) {
- for (j = prev; j < 0x7f; j++) {
- BITSET_SET_BIT(cc->bs, j);
- }
+ for (i = 0; i < n; i++) {
+ for (j = prev;
+ j < ONIGENC_CODE_RANGE_FROM(mbr, i); j++) {
+ if (j >= sb_out) {
+ goto sb_end2;
+ }
+ BITSET_SET_BIT(cc->bs, j);
}
-
- prev = 0x80;
+ prev = ONIGENC_CODE_RANGE_TO(mbr, i) + 1;
+ }
+ for (j = prev; j < sb_out; j++) {
+ BITSET_SET_BIT(cc->bs, j);
}
- for (i = 0; i < nmb; i++) {
+ sb_end2:
+ prev = sb_out;
+
+ for (i = 0; i < n; i++) {
if (prev < ONIGENC_CODE_RANGE_FROM(mbr, i)) {
r = add_code_range_to_buf(&(cc->mbuf), prev,
ONIGENC_CODE_RANGE_FROM(mbr, i) - 1);
@@ -3618,12 +3825,13 @@ static int
add_ctype_to_cc(CClassNode* cc, int ctype, int not, ScanEnv* env)
{
int c, r;
- const OnigCodePoint *sbr, *mbr;
+ const OnigCodePoint *ranges;
+ OnigCodePoint sb_out;
OnigEncoding enc = env->enc;
- r = ONIGENC_GET_CTYPE_CODE_RANGE(enc, ctype, &sbr, &mbr);
+ r = ONIGENC_GET_CTYPE_CODE_RANGE(enc, ctype, &sb_out, &ranges);
if (r == 0) {
- return add_ctype_to_cc_by_range(cc, ctype, not, env->enc, sbr, mbr);
+ return add_ctype_to_cc_by_range(cc, ctype, not, env->enc, sb_out, ranges);
}
else if (r != ONIG_NO_SUPPORT_CONFIG) {
return r;
@@ -3677,13 +3885,13 @@ add_ctype_to_cc(CClassNode* cc, int ctype, int not, ScanEnv* env)
case ONIGENC_CTYPE_WORD:
if (not == 0) {
for (c = 0; c < SINGLE_BYTE_SIZE; c++) {
- if (ONIGENC_IS_CODE_SB_WORD(enc, c)) BITSET_SET_BIT(cc->bs, c);
+ if (IS_CODE_SB_WORD(enc, c)) BITSET_SET_BIT(cc->bs, c);
}
ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
}
else {
for (c = 0; c < SINGLE_BYTE_SIZE; c++) {
- if ((ONIGENC_CODE_TO_MBCLEN(enc, c) > 0) /* 0: invalid code point */
+ if ((ONIGENC_CODE_TO_MBCLEN(enc, c) > 0) /* check invalid code point */
&& ! ONIGENC_IS_CODE_WORD(enc, c))
BITSET_SET_BIT(cc->bs, c);
}
@@ -3699,61 +3907,10 @@ add_ctype_to_cc(CClassNode* cc, int ctype, int not, ScanEnv* env)
}
static int
-parse_ctype_to_enc_ctype(int pctype, int* not)
-{
- int ctype;
-
- switch (pctype) {
- case CTYPE_WORD:
- ctype = ONIGENC_CTYPE_WORD;
- *not = 0;
- break;
- case CTYPE_NOT_WORD:
- ctype = ONIGENC_CTYPE_WORD;
- *not = 1;
- break;
- case CTYPE_WHITE_SPACE:
- ctype = ONIGENC_CTYPE_SPACE;
- *not = 0;
- break;
- case CTYPE_NOT_WHITE_SPACE:
- ctype = ONIGENC_CTYPE_SPACE;
- *not = 1;
- break;
- case CTYPE_DIGIT:
- ctype = ONIGENC_CTYPE_DIGIT;
- *not = 0;
- break;
- case CTYPE_NOT_DIGIT:
- ctype = ONIGENC_CTYPE_DIGIT;
- *not = 1;
- break;
- case CTYPE_XDIGIT:
- ctype = ONIGENC_CTYPE_XDIGIT;
- *not = 0;
- break;
- case CTYPE_NOT_XDIGIT:
- ctype = ONIGENC_CTYPE_XDIGIT;
- *not = 1;
- break;
- default:
- return ONIGERR_PARSER_BUG;
- break;
- }
- return ctype;
-}
-
-typedef struct {
- UChar *name;
- int ctype;
- short int len;
-} PosixBracketEntryType;
-
-static int
parse_posix_bracket(CClassNode* cc, UChar** src, UChar* end, ScanEnv* env)
{
#define POSIX_BRACKET_CHECK_LIMIT_LENGTH 20
-#define POSIX_BRACKET_NAME_MAX_LEN 6
+#define POSIX_BRACKET_NAME_MIN_LEN 4
static PosixBracketEntryType PBS[] = {
{ (UChar* )"alnum", ONIGENC_CTYPE_ALNUM, 5 },
@@ -3769,7 +3926,8 @@ parse_posix_bracket(CClassNode* cc, UChar** src, UChar* end, ScanEnv* env)
{ (UChar* )"upper", ONIGENC_CTYPE_UPPER, 5 },
{ (UChar* )"xdigit", ONIGENC_CTYPE_XDIGIT, 6 },
{ (UChar* )"ascii", ONIGENC_CTYPE_ASCII, 5 },
- { (UChar* )NULL, -1, 0 }
+ { (UChar* )"word", ONIGENC_CTYPE_WORD, 4 },
+ { (UChar* )NULL, -1, 0 }
};
PosixBracketEntryType *pb;
@@ -3786,7 +3944,7 @@ parse_posix_bracket(CClassNode* cc, UChar** src, UChar* end, ScanEnv* env)
else
not = 0;
- if (onigenc_strlen(enc, p, end) < POSIX_BRACKET_NAME_MAX_LEN + 2)
+ if (onigenc_strlen(enc, p, end) < POSIX_BRACKET_NAME_MIN_LEN + 3)
goto not_posix_bracket;
for (pb = PBS; IS_NOT_NULL(pb->name); pb++) {
@@ -3820,86 +3978,39 @@ parse_posix_bracket(CClassNode* cc, UChar** src, UChar* end, ScanEnv* env)
}
}
- return 1; /* 1: is not POSIX bracket, but no error. */
-}
-
-static int
-property_name_to_ctype(UChar* p, UChar* end, OnigEncoding enc)
-{
- static PosixBracketEntryType PBS[] = {
- { (UChar* )"Alnum", ONIGENC_CTYPE_ALNUM, 5 },
- { (UChar* )"Alpha", ONIGENC_CTYPE_ALPHA, 5 },
- { (UChar* )"Blank", ONIGENC_CTYPE_BLANK, 5 },
- { (UChar* )"Cntrl", ONIGENC_CTYPE_CNTRL, 5 },
- { (UChar* )"Digit", ONIGENC_CTYPE_DIGIT, 5 },
- { (UChar* )"Graph", ONIGENC_CTYPE_GRAPH, 5 },
- { (UChar* )"Lower", ONIGENC_CTYPE_LOWER, 5 },
- { (UChar* )"Print", ONIGENC_CTYPE_PRINT, 5 },
- { (UChar* )"Punct", ONIGENC_CTYPE_PUNCT, 5 },
- { (UChar* )"Space", ONIGENC_CTYPE_SPACE, 5 },
- { (UChar* )"Upper", ONIGENC_CTYPE_UPPER, 5 },
- { (UChar* )"XDigit", ONIGENC_CTYPE_XDIGIT, 6 },
- { (UChar* )"ASCII", ONIGENC_CTYPE_ASCII, 5 },
- { (UChar* )NULL, -1, 0 }
- };
-
- PosixBracketEntryType *pb;
- int len;
-
- len = onigenc_strlen(enc, p, end);
- for (pb = PBS; IS_NOT_NULL(pb->name); pb++) {
- if (len == pb->len &&
- onigenc_with_ascii_strncmp(enc, p, end, pb->name, pb->len) == 0)
- return pb->ctype;
- }
-
- return -1;
+ return 1; /* 1: is not POSIX bracket, but no error. */
}
static int
fetch_char_property_to_ctype(UChar** src, UChar* end, ScanEnv* env)
{
- int ctype;
+ int r;
OnigCodePoint c;
OnigEncoding enc = env->enc;
UChar *prev, *start, *p = *src;
PFETCH_READY;
- /* 'IsXXXX' => 'XXXX' */
- if (!PEND &&
- IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_CHAR_PROPERTY_PREFIX_IS)) {
- c = PPEEK;
- if (c == 'I') {
- PINC;
- if (! PEND) {
- c = PPEEK;
- if (c == 's')
- PINC;
- else
- PUNFETCH;
- }
- }
- }
-
+ r = 0;
start = prev = p;
while (!PEND) {
prev = p;
PFETCH(c);
if (c == '}') {
- ctype = property_name_to_ctype(start, prev, enc);
- if (ctype < 0) break;
+ r = ONIGENC_PROPERTY_NAME_TO_CTYPE(enc, start, prev);
+ if (r < 0) break;
*src = p;
- return ctype;
+ return r;
}
- else if (c == '(' || c == ')' || c == '{' || c == '|')
+ else if (c == '(' || c == ')' || c == '{' || c == '|') {
+ r = ONIGERR_INVALID_CHAR_PROPERTY_NAME;
break;
+ }
}
- onig_scan_env_set_error_string(env, ONIGERR_INVALID_CHAR_PROPERTY_NAME,
- *src, prev);
- return ONIGERR_INVALID_CHAR_PROPERTY_NAME;
+ onig_scan_env_set_error_string(env, r, *src, prev);
+ return r;
}
static int
@@ -3913,11 +4024,11 @@ parse_char_property(Node** np, OnigToken* tok, UChar** src, UChar* end,
if (ctype < 0) return ctype;
*np = node_new_cclass();
- CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
- cc = &(NCCLASS(*np));
+ CHECK_NULL_RETURN_MEMERR(*np);
+ cc = NCCLASS(*np);
r = add_ctype_to_cc(cc, ctype, 0, env);
if (r != 0) return r;
- if (tok->u.prop.not != 0) CCLASS_SET_NOT(cc);
+ if (tok->u.prop.not != 0) NCCLASS_SET_NOT(cc);
return 0;
}
@@ -3981,7 +4092,7 @@ next_state_val(CClassNode* cc, OnigCodePoint *vs, OnigCodePoint v,
if (intype == *type) {
if (intype == CCV_SB) {
if (*vs > 0xff || v > 0xff)
- return ONIGERR_INVALID_WIDE_CHAR_VALUE;
+ return ONIGERR_INVALID_CODE_POINT_VALUE;
if (*vs > v) {
if (IS_SYNTAX_BV(env->syntax, ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC))
@@ -4036,10 +4147,11 @@ next_state_val(CClassNode* cc, OnigCodePoint *vs, OnigCodePoint v,
static int
code_exist_check(OnigCodePoint c, UChar* from, UChar* end, int ignore_escaped,
- OnigEncoding enc)
+ ScanEnv* env)
{
int in_esc;
OnigCodePoint code;
+ OnigEncoding enc = env->enc;
UChar* p = from;
PFETCH_READY;
@@ -4051,7 +4163,7 @@ code_exist_check(OnigCodePoint c, UChar* from, UChar* end, int ignore_escaped,
else {
PFETCH(code);
if (code == c) return 1;
- if (code == MC_ESC(enc)) in_esc = 1;
+ if (code == MC_ESC(env->syntax)) in_esc = 1;
}
}
return 0;
@@ -4086,7 +4198,7 @@ parse_char_class(Node** np, OnigToken* tok, UChar** src, UChar* end,
if (r < 0) return r;
if (r == TK_CC_CLOSE) {
if (! code_exist_check((OnigCodePoint )']',
- *src, env->pattern_end, 1, env->enc))
+ *src, env->pattern_end, 1, env))
return ONIGERR_EMPTY_CHAR_CLASS;
CC_ESC_WARN(env, (UChar* )"]");
@@ -4094,8 +4206,8 @@ parse_char_class(Node** np, OnigToken* tok, UChar** src, UChar* end,
}
*np = node = node_new_cclass();
- CHECK_NULL_RETURN_VAL(node, ONIGERR_MEMORY);
- cc = &(NCCLASS(node));
+ CHECK_NULL_RETURN_MEMERR(node);
+ cc = NCCLASS(node);
and_start = 0;
state = CCS_START;
@@ -4108,6 +4220,10 @@ parse_char_class(Node** np, OnigToken* tok, UChar** src, UChar* end,
if (len > 1) {
in_type = CCV_CODE_POINT;
}
+ else if (len < 0) {
+ r = len;
+ goto err;
+ }
else {
sb_char:
in_type = CCV_SB;
@@ -4141,7 +4257,7 @@ parse_char_class(Node** np, OnigToken* tok, UChar** src, UChar* end,
goto err;
}
- len = enc_len(env->enc, buf);
+ len = enclen(env->enc, buf);
if (i < len) {
r = ONIGERR_TOO_SHORT_MULTI_BYTE_STRING;
goto err;
@@ -4202,12 +4318,8 @@ parse_char_class(Node** np, OnigToken* tok, UChar** src, UChar* end,
break;
case TK_CHAR_TYPE:
- {
- int ctype, not;
- ctype = parse_ctype_to_enc_ctype(tok->u.subtype, &not);
- r = add_ctype_to_cc(cc, ctype, not, env);
- if (r != 0) return r;
- }
+ r = add_ctype_to_cc(cc, tok->u.prop.ctype, tok->u.prop.not, env);
+ if (r != 0) return r;
next_class:
r = next_state_class(cc, &vs, &val_type, &state, env);
@@ -4287,7 +4399,7 @@ parse_char_class(Node** np, OnigToken* tok, UChar** src, UChar* end,
r = parse_char_class(&anode, tok, &p, end, env);
if (r != 0) goto cc_open_err;
- acc = &(NCCLASS(anode));
+ acc = NCCLASS(anode);
r = or_cclass(cc, acc, env->enc);
onig_node_free(anode);
@@ -4352,10 +4464,10 @@ parse_char_class(Node** np, OnigToken* tok, UChar** src, UChar* end,
}
if (neg != 0)
- CCLASS_SET_NOT(cc);
+ NCCLASS_SET_NOT(cc);
else
- CCLASS_CLEAR_NOT(cc);
- if (IS_CCLASS_NOT(cc) &&
+ NCCLASS_CLEAR_NOT(cc);
+ if (IS_NCCLASS_NOT(cc) &&
IS_SYNTAX_BV(env->syntax, ONIG_SYN_NOT_NEWLINE_IN_NEGATIVE_CC)) {
int is_empty;
@@ -4378,7 +4490,7 @@ parse_char_class(Node** np, OnigToken* tok, UChar** src, UChar* end,
return 0;
err:
- if (cc != &(NCCLASS(*np)))
+ if (cc != NCCLASS(*np))
bbuf_free(cc->mbuf);
onig_node_free(*np);
return r;
@@ -4388,15 +4500,19 @@ static int parse_subexp(Node** top, OnigToken* tok, int term,
UChar** src, UChar* end, ScanEnv* env);
static int
-parse_effect(Node** np, OnigToken* tok, int term, UChar** src, UChar* end,
- ScanEnv* env)
+parse_enclose(Node** np, OnigToken* tok, int term, UChar** src, UChar* end,
+ ScanEnv* env)
{
int r, num;
- int list_capture;
Node *target;
OnigOptionType option;
- OnigEncoding enc = env->enc;
OnigCodePoint c;
+ OnigEncoding enc = env->enc;
+
+#ifdef USE_NAMED_GROUP
+ int list_capture;
+#endif
+
UChar* p = *src;
PFETCH_READY;
@@ -4428,9 +4544,19 @@ parse_effect(Node** np, OnigToken* tok, int term, UChar** src, UChar* end,
*np = onig_node_new_anchor(ANCHOR_PREC_READ_NOT);
break;
case '>': /* (?>...) stop backtrack */
- *np = node_new_effect(EFFECT_STOP_BACKTRACK);
+ *np = node_new_enclose(ENCLOSE_STOP_BACKTRACK);
break;
+#ifdef USE_NAMED_GROUP
+ case '\'':
+ if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP)) {
+ goto named_group1;
+ }
+ else
+ return ONIGERR_UNDEFINED_GROUP_OPTION;
+ break;
+#endif
+
case '<': /* look behind (?<=...), (?<!...) */
PFETCH(c);
if (c == '=')
@@ -4438,35 +4564,45 @@ parse_effect(Node** np, OnigToken* tok, int term, UChar** src, UChar* end,
else if (c == '!')
*np = onig_node_new_anchor(ANCHOR_LOOK_BEHIND_NOT);
#ifdef USE_NAMED_GROUP
- else if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP)) {
- UChar *name;
- UChar *name_end;
+ else {
+ if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP)) {
+ UChar *name;
+ UChar *name_end;
- PUNFETCH;
- list_capture = 0;
+ PUNFETCH;
+ c = '<';
- named_group:
- name = p;
- r = fetch_name(&p, end, &name_end, env, 0);
- if (r < 0) return r;
+ named_group1:
+ list_capture = 0;
- num = scan_env_add_mem_entry(env);
- if (num < 0) return num;
- if (list_capture != 0 && num >= BIT_STATUS_BITS_NUM)
- return ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY;
+ named_group2:
+ name = p;
+ r = fetch_name((OnigCodePoint )c, &p, end, &name_end, env, &num, 0);
+ if (r < 0) return r;
- r = name_add(env->reg, name, name_end, num, env);
- if (r != 0) return r;
- *np = node_new_effect_memory(env->option, 1);
- CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
- NEFFECT(*np).regnum = num;
- if (list_capture != 0)
- BIT_STATUS_ON_AT_SIMPLE(env->capture_history, num);
- env->num_named++;
+ num = scan_env_add_mem_entry(env);
+ if (num < 0) return num;
+ if (list_capture != 0 && num >= (int )BIT_STATUS_BITS_NUM)
+ return ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY;
+
+ r = name_add(env->reg, name, name_end, num, env);
+ if (r != 0) return r;
+ *np = node_new_enclose_memory(env->option, 1);
+ CHECK_NULL_RETURN_MEMERR(*np);
+ NENCLOSE(*np)->regnum = num;
+ if (list_capture != 0)
+ BIT_STATUS_ON_AT_SIMPLE(env->capture_history, num);
+ env->num_named++;
+ }
+ else {
+ return ONIGERR_UNDEFINED_GROUP_OPTION;
+ }
}
-#endif
- else
+#else
+ else {
return ONIGERR_UNDEFINED_GROUP_OPTION;
+ }
+#endif
break;
case '@':
@@ -4474,25 +4610,25 @@ parse_effect(Node** np, OnigToken* tok, int term, UChar** src, UChar* end,
#ifdef USE_NAMED_GROUP
if (IS_SYNTAX_OP2(env->syntax, ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP)) {
PFETCH(c);
- if (c == '<') {
+ if (c == '<' || c == '\'') {
list_capture = 1;
- goto named_group; /* (?@<name>...) */
+ goto named_group2; /* (?@<name>...) */
}
PUNFETCH;
}
#endif
- *np = node_new_effect_memory(env->option, 0);
- CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
+ *np = node_new_enclose_memory(env->option, 0);
+ CHECK_NULL_RETURN_MEMERR(*np);
num = scan_env_add_mem_entry(env);
if (num < 0) {
onig_node_free(*np);
return num;
}
- else if (num >= BIT_STATUS_BITS_NUM) {
+ else if (num >= (int )BIT_STATUS_BITS_NUM) {
onig_node_free(*np);
return ONIGERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY;
}
- NEFFECT(*np).regnum = num;
+ NENCLOSE(*np)->regnum = num;
BIT_STATUS_ON_AT_SIMPLE(env->capture_history, num);
}
else {
@@ -4545,7 +4681,7 @@ parse_effect(Node** np, OnigToken* tok, int term, UChar** src, UChar* end,
if (c == ')') {
*np = node_new_option(option);
- CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
+ CHECK_NULL_RETURN_MEMERR(*np);
*src = p;
return 2; /* option only */
}
@@ -4559,8 +4695,8 @@ parse_effect(Node** np, OnigToken* tok, int term, UChar** src, UChar* end,
env->option = prev;
if (r < 0) return r;
*np = node_new_option(option);
- CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
- NEFFECT(*np).target = target;
+ CHECK_NULL_RETURN_MEMERR(*np);
+ NENCLOSE(*np)->target = target;
*src = p;
return 0;
}
@@ -4579,26 +4715,26 @@ parse_effect(Node** np, OnigToken* tok, int term, UChar** src, UChar* end,
if (ONIG_IS_OPTION_ON(env->option, ONIG_OPTION_DONT_CAPTURE_GROUP))
goto group;
- *np = node_new_effect_memory(env->option, 0);
- CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
+ *np = node_new_enclose_memory(env->option, 0);
+ CHECK_NULL_RETURN_MEMERR(*np);
num = scan_env_add_mem_entry(env);
if (num < 0) return num;
- NEFFECT(*np).regnum = num;
+ NENCLOSE(*np)->regnum = num;
}
- CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
+ CHECK_NULL_RETURN_MEMERR(*np);
r = fetch_token(tok, &p, end, env);
if (r < 0) return r;
r = parse_subexp(&target, tok, term, &p, end, env);
if (r < 0) return r;
- if (NTYPE(*np) == N_ANCHOR)
- NANCHOR(*np).target = target;
+ if (NTYPE(*np) == NT_ANCHOR)
+ NANCHOR(*np)->target = target;
else {
- NEFFECT(*np).target = target;
- if (NEFFECT(*np).type == EFFECT_MEMORY) {
+ NENCLOSE(*np)->target = target;
+ if (NENCLOSE(*np)->type == ENCLOSE_MEMORY) {
/* Don't move this to previous of parse_subexp() */
- r = scan_env_set_mem_node(env, NEFFECT(*np).regnum, *np);
+ r = scan_env_set_mem_node(env, NENCLOSE(*np)->regnum, *np);
if (r != 0) return r;
}
}
@@ -4618,17 +4754,17 @@ static const char* ReduceQStr[] = {
static int
set_quantifier(Node* qnode, Node* target, int group, ScanEnv* env)
{
- QuantifierNode* qn;
+ QtfrNode* qn;
- qn = &(NQUANTIFIER(qnode));
+ qn = NQTFR(qnode);
if (qn->lower == 1 && qn->upper == 1) {
return 1;
}
switch (NTYPE(target)) {
- case N_STRING:
+ case NT_STR:
if (! group) {
- StrNode* sn = &(NSTRING(target));
+ StrNode* sn = NSTR(target);
if (str_node_can_be_split(sn, env->enc)) {
Node* n = str_node_split_last_char(sn, env->enc);
if (IS_NOT_NULL(n)) {
@@ -4639,10 +4775,10 @@ set_quantifier(Node* qnode, Node* target, int group, ScanEnv* env)
}
break;
- case N_QUANTIFIER:
+ case NT_QTFR:
{ /* check redundant double repeat. */
/* verbose warn (?:.?)? etc... but not warn (.?)? etc... */
- QuantifierNode* qnt = &(NQUANTIFIER(target));
+ QtfrNode* qnt = NQTFR(target);
int nestq_num = popular_quantifier_num(qn);
int targetq_num = popular_quantifier_num(qnt);
@@ -4705,6 +4841,7 @@ set_quantifier(Node* qnode, Node* target, int group, ScanEnv* env)
return 0;
}
+
#ifdef USE_SHARED_CCLASS_TABLE
#define THRESHOLD_RANGE_NUM_FOR_SHARE_CCLASS 8
@@ -4728,17 +4865,17 @@ static int type_cclass_cmp(type_cclass_key* x, type_cclass_key* y)
static int type_cclass_hash(type_cclass_key* key)
{
int i, val;
- unsigned char *p;
+ UChar *p;
val = 0;
- p = (unsigned char* )&(key->enc);
- for (i = 0; i < sizeof(key->enc); i++) {
+ p = (UChar* )&(key->enc);
+ for (i = 0; i < (int )sizeof(key->enc); i++) {
val = val * 997 + (int )*p++;
}
- p = (unsigned char* )(&key->type);
- for (i = 0; i < sizeof(key->type); i++) {
+ p = (UChar* )(&key->type);
+ for (i = 0; i < (int )sizeof(key->type); i++) {
val = val * 997 + (int )*p++;
}
@@ -4755,10 +4892,10 @@ static st_table* OnigTypeCClassTable;
static int
-i_free_shared_class(type_cclass_key* key, Node* node, void* arg)
+i_free_shared_class(type_cclass_key* key, Node* node, void* arg ARG_UNUSED)
{
if (IS_NOT_NULL(node)) {
- CClassNode* cc = &(NCCLASS(node));
+ CClassNode* cc = NCCLASS(node);
if (IS_NOT_NULL(cc->mbuf)) xfree(cc->mbuf);
xfree(node);
}
@@ -4782,6 +4919,118 @@ onig_free_shared_cclass_table(void)
#endif /* USE_SHARED_CCLASS_TABLE */
+#ifndef CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS
+static int
+clear_not_flag_cclass(CClassNode* cc, OnigEncoding enc)
+{
+ BBuf *tbuf;
+ int r;
+
+ if (IS_NCCLASS_NOT(cc)) {
+ bitset_invert(cc->bs);
+
+ if (! ONIGENC_IS_SINGLEBYTE(enc)) {
+ r = not_code_range_buf(enc, cc->mbuf, &tbuf);
+ if (r != 0) return r;
+
+ bbuf_free(cc->mbuf);
+ cc->mbuf = tbuf;
+ }
+
+ NCCLASS_CLEAR_NOT(cc);
+ }
+
+ return 0;
+}
+#endif /* CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS */
+
+typedef struct {
+ ScanEnv* env;
+ CClassNode* cc;
+ Node* alt_root;
+ Node** ptail;
+} IApplyCaseFoldArg;
+
+static int
+i_apply_case_fold(OnigCodePoint from, OnigCodePoint to[],
+ int to_len, void* arg)
+{
+ IApplyCaseFoldArg* iarg;
+ ScanEnv* env;
+ CClassNode* cc;
+ BitSetRef bs;
+
+ iarg = (IApplyCaseFoldArg* )arg;
+ env = iarg->env;
+ cc = iarg->cc;
+ bs = cc->bs;
+
+ if (to_len == 1) {
+ int is_in = onig_is_code_in_cc(env->enc, from, cc);
+#ifdef CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS
+ if ((is_in != 0 && !IS_NCCLASS_NOT(cc)) ||
+ (is_in == 0 && IS_NCCLASS_NOT(cc))) {
+ if (ONIGENC_MBC_MINLEN(env->enc) > 1 || *to >= SINGLE_BYTE_SIZE) {
+ add_code_range(&(cc->mbuf), env, *to, *to);
+ }
+ else {
+ BITSET_SET_BIT(bs, *to);
+ }
+ }
+#else
+ if (is_in != 0) {
+ if (ONIGENC_MBC_MINLEN(env->enc) > 1 || *to >= SINGLE_BYTE_SIZE) {
+ if (IS_NCCLASS_NOT(cc)) clear_not_flag_cclass(cc, env->enc);
+ add_code_range(&(cc->mbuf), env, *to, *to);
+ }
+ else {
+ if (IS_NCCLASS_NOT(cc)) {
+ BITSET_CLEAR_BIT(bs, *to);
+ }
+ else
+ BITSET_SET_BIT(bs, *to);
+ }
+ }
+#endif /* CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS */
+ }
+ else {
+ int r, i, len;
+ UChar buf[ONIGENC_CODE_TO_MBC_MAXLEN];
+ Node *snode = NULL_NODE;
+
+ if (onig_is_code_in_cc(env->enc, from, cc)
+#ifdef CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS
+ && !IS_NCCLASS_NOT(cc)
+#endif
+ ) {
+ for (i = 0; i < to_len; i++) {
+ len = ONIGENC_CODE_TO_MBC(env->enc, to[i], buf);
+ if (i == 0) {
+ snode = onig_node_new_str(buf, buf + len);
+ CHECK_NULL_RETURN_MEMERR(snode);
+
+ /* char-class expanded multi-char only
+ compare with string folded at match time. */
+ NSTRING_SET_AMBIG(snode);
+ }
+ else {
+ r = onig_node_str_cat(snode, buf, buf + len);
+ if (r < 0) {
+ onig_node_free(snode);
+ return r;
+ }
+ }
+ }
+
+ *(iarg->ptail) = onig_node_new_alt(snode, NULL_NODE);
+ CHECK_NULL_RETURN_MEMERR(*(iarg->ptail));
+ iarg->ptail = &(NCDR((*(iarg->ptail))));
+ }
+ }
+
+ return 0;
+}
+
static int
parse_exp(Node** np, OnigToken* tok, int term,
UChar** src, UChar* end, ScanEnv* env)
@@ -4791,7 +5040,7 @@ parse_exp(Node** np, OnigToken* tok, int term,
Node** targetp;
*np = NULL;
- if (tok->type == term)
+ if (tok->type == (enum TokenSyms )term)
goto end_of_token;
switch (tok->type) {
@@ -4803,20 +5052,20 @@ parse_exp(Node** np, OnigToken* tok, int term,
break;
case TK_SUBEXP_OPEN:
- r = parse_effect(np, tok, TK_SUBEXP_CLOSE, src, end, env);
+ r = parse_enclose(np, tok, TK_SUBEXP_CLOSE, src, end, env);
if (r < 0) return r;
if (r == 1) group = 1;
else if (r == 2) { /* option only */
Node* target;
OnigOptionType prev = env->option;
- env->option = NEFFECT(*np).option;
+ env->option = NENCLOSE(*np)->option;
r = fetch_token(tok, src, end, env);
if (r < 0) return r;
r = parse_subexp(&target, tok, term, src, end, env);
env->option = prev;
if (r < 0) return r;
- NEFFECT(*np).target = target;
+ NENCLOSE(*np)->target = target;
return tok->type;
}
break;
@@ -4833,7 +5082,7 @@ parse_exp(Node** np, OnigToken* tok, int term,
tk_byte:
{
*np = node_new_str(tok->backp, *src);
- CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
+ CHECK_NULL_RETURN_MEMERR(*np);
while (1) {
r = fetch_token(tok, src, end, env);
@@ -4853,13 +5102,14 @@ parse_exp(Node** np, OnigToken* tok, int term,
case TK_RAW_BYTE:
tk_raw_byte:
{
- *np = node_new_str_char((UChar )tok->u.c);
- CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
+ *np = node_new_str_raw_char((UChar )tok->u.c);
+ CHECK_NULL_RETURN_MEMERR(*np);
len = 1;
while (1) {
if (len >= ONIGENC_MBC_MINLEN(env->enc)) {
- if (len == enc_len(env->enc, NSTRING(*np).s)) {
+ if (len == enclen(env->enc, NSTR(*np)->s)) {
r = fetch_token(tok, src, end, env);
+ NSTRING_CLEAR_RAW(*np);
goto string_end;
}
}
@@ -4867,12 +5117,14 @@ parse_exp(Node** np, OnigToken* tok, int term,
r = fetch_token(tok, src, end, env);
if (r < 0) return r;
if (r != TK_RAW_BYTE) {
+ /* Don't use this, it is wrong for little endian encodings. */
#ifdef USE_PAD_TO_SHORT_BYTE_CHAR
int rem;
if (len < ONIGENC_MBC_MINLEN(env->enc)) {
rem = ONIGENC_MBC_MINLEN(env->enc) - len;
- (void )node_str_head_pad(&NSTRING(*np), rem, (UChar )0);
- if (len + rem == enc_len(env->enc, NSTRING(*np).s)) {
+ (void )node_str_head_pad(NSTR(*np), rem, (UChar )0);
+ if (len + rem == enclen(env->enc, NSTR(*np)->s)) {
+ NSTRING_CLEAR_RAW(*np);
goto string_end;
}
}
@@ -4898,7 +5150,7 @@ parse_exp(Node** np, OnigToken* tok, int term,
#else
*np = node_new_str(buf, buf + num);
#endif
- CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
+ CHECK_NULL_RETURN_MEMERR(*np);
}
break;
@@ -4907,7 +5159,7 @@ parse_exp(Node** np, OnigToken* tok, int term,
OnigCodePoint end_op[2];
UChar *qstart, *qend, *nextp;
- end_op[0] = (OnigCodePoint )MC_ESC(env->enc);
+ end_op[0] = (OnigCodePoint )MC_ESC(env->syntax);
end_op[1] = (OnigCodePoint )'E';
qstart = *src;
qend = find_str_position(end_op, 2, qstart, end, &nextp, env->enc);
@@ -4915,35 +5167,31 @@ parse_exp(Node** np, OnigToken* tok, int term,
nextp = qend = end;
}
*np = node_new_str(qstart, qend);
- CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
+ CHECK_NULL_RETURN_MEMERR(*np);
*src = nextp;
}
break;
case TK_CHAR_TYPE:
{
- switch (tok->u.subtype) {
- case CTYPE_WORD:
- case CTYPE_NOT_WORD:
- *np = node_new_ctype(tok->u.subtype);
- CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
+ switch (tok->u.prop.ctype) {
+ case ONIGENC_CTYPE_WORD:
+ *np = node_new_ctype(tok->u.prop.ctype, tok->u.prop.not);
+ CHECK_NULL_RETURN_MEMERR(*np);
break;
- case CTYPE_WHITE_SPACE:
- case CTYPE_NOT_WHITE_SPACE:
- case CTYPE_DIGIT:
- case CTYPE_NOT_DIGIT:
- case CTYPE_XDIGIT:
- case CTYPE_NOT_XDIGIT:
+ case ONIGENC_CTYPE_SPACE:
+ case ONIGENC_CTYPE_DIGIT:
+ case ONIGENC_CTYPE_XDIGIT:
{
CClassNode* cc;
- int ctype, not;
#ifdef USE_SHARED_CCLASS_TABLE
- const OnigCodePoint *sbr, *mbr;
+ const OnigCodePoint *mbr;
+ OnigCodePoint sb_out;
- ctype = parse_ctype_to_enc_ctype(tok->u.subtype, &not);
- r = ONIGENC_GET_CTYPE_CODE_RANGE(env->enc, ctype, &sbr, &mbr);
+ r = ONIGENC_GET_CTYPE_CODE_RANGE(env->enc, tok->u.prop.ctype,
+ &sb_out, &mbr);
if (r == 0 &&
ONIGENC_CODE_RANGE_NUM(mbr)
>= THRESHOLD_RANGE_NUM_FOR_SHARE_CCLASS) {
@@ -4951,8 +5199,8 @@ parse_exp(Node** np, OnigToken* tok, int term,
type_cclass_key* new_key;
key.enc = env->enc;
- key.not = not;
- key.type = ctype;
+ key.not = tok->u.prop.not;
+ key.type = tok->u.prop.ctype;
THREAD_ATOMIC_START;
@@ -4972,15 +5220,17 @@ parse_exp(Node** np, OnigToken* tok, int term,
}
}
- *np = node_new_cclass_by_codepoint_range(not, sbr, mbr);
+ *np = node_new_cclass_by_codepoint_range(tok->u.prop.not,
+ sb_out, mbr);
if (IS_NULL(*np)) {
THREAD_ATOMIC_END;
return ONIGERR_MEMORY;
}
- CCLASS_SET_SHARE(&(NCCLASS(*np)));
+ cc = NCCLASS(*np);
+ NCCLASS_SET_SHARE(cc);
new_key = (type_cclass_key* )xmalloc(sizeof(type_cclass_key));
- xmemcpy(new_key, &key, sizeof(type_cclass_key));
+ xmemcpy(new_key, &key, sizeof(type_cclass_key));
onig_st_add_direct(OnigTypeCClassTable, (st_data_t )new_key,
(st_data_t )*np);
@@ -4988,12 +5238,11 @@ parse_exp(Node** np, OnigToken* tok, int term,
}
else {
#endif
- ctype = parse_ctype_to_enc_ctype(tok->u.subtype, &not);
*np = node_new_cclass();
- CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
- cc = &(NCCLASS(*np));
- add_ctype_to_cc(cc, ctype, 0, env);
- if (not != 0) CCLASS_SET_NOT(cc);
+ CHECK_NULL_RETURN_MEMERR(*np);
+ cc = NCCLASS(*np);
+ add_ctype_to_cc(cc, tok->u.prop.ctype, 0, env);
+ if (tok->u.prop.not != 0) NCCLASS_SET_NOT(cc);
#ifdef USE_SHARED_CCLASS_TABLE
}
#endif
@@ -5019,55 +5268,44 @@ parse_exp(Node** np, OnigToken* tok, int term,
r = parse_char_class(np, tok, src, end, env);
if (r != 0) return r;
- cc = &(NCCLASS(*np));
-
+ cc = NCCLASS(*np);
if (IS_IGNORECASE(env->option)) {
- int i, n, in_cc;
- const OnigPairAmbigCodes* ccs;
- BitSetRef bs = cc->bs;
- OnigAmbigType amb;
-
- for (amb = 0x01; amb <= ONIGENC_AMBIGUOUS_MATCH_LIMIT; amb <<= 1) {
- if ((amb & env->ambig_flag) == 0) continue;
-
- n = ONIGENC_GET_ALL_PAIR_AMBIG_CODES(env->enc, amb, &ccs);
- for (i = 0; i < n; i++) {
- in_cc = onig_is_code_in_cc(env->enc, ccs[i].from, cc);
-
- if ((in_cc != 0 && !IS_CCLASS_NOT(cc)) ||
- (in_cc == 0 && IS_CCLASS_NOT(cc))) {
- if (ONIGENC_MBC_MINLEN(env->enc) > 1 ||
- ccs[i].from >= SINGLE_BYTE_SIZE) {
- /* if (cc->not) clear_not_flag_cclass(cc, env->enc); */
- add_code_range(&(cc->mbuf), env, ccs[i].to, ccs[i].to);
- }
- else {
- if (BITSET_AT(bs, ccs[i].from)) {
- /* /(?i:[^A-C])/.match("a") ==> fail. */
- BITSET_SET_BIT(bs, ccs[i].to);
- }
- if (BITSET_AT(bs, ccs[i].to)) {
- BITSET_SET_BIT(bs, ccs[i].from);
- }
- }
- }
+ IApplyCaseFoldArg iarg;
+
+ iarg.env = env;
+ iarg.cc = cc;
+ iarg.alt_root = NULL_NODE;
+ iarg.ptail = &(iarg.alt_root);
+
+ r = ONIGENC_APPLY_ALL_CASE_FOLD(env->enc, env->case_fold_flag,
+ i_apply_case_fold, &iarg);
+ if (r != 0) {
+ onig_node_free(iarg.alt_root);
+ return r;
+ }
+ if (IS_NOT_NULL(iarg.alt_root)) {
+ Node* work = onig_node_new_alt(*np, iarg.alt_root);
+ if (IS_NULL(work)) {
+ onig_node_free(iarg.alt_root);
+ return ONIGERR_MEMORY;
}
- }
+ *np = work;
+ }
}
}
break;
case TK_ANYCHAR:
*np = node_new_anychar();
- CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
+ CHECK_NULL_RETURN_MEMERR(*np);
break;
case TK_ANYCHAR_ANYTIME:
*np = node_new_anychar();
- CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
+ CHECK_NULL_RETURN_MEMERR(*np);
qn = node_new_quantifier(0, REPEAT_INFINITE, 0);
- CHECK_NULL_RETURN_VAL(qn, ONIGERR_MEMORY);
- NQUANTIFIER(qn).target = *np;
+ CHECK_NULL_RETURN_MEMERR(qn);
+ NQTFR(qn)->target = *np;
*np = qn;
break;
@@ -5076,19 +5314,28 @@ parse_exp(Node** np, OnigToken* tok, int term,
*np = node_new_backref(len,
(len > 1 ? tok->u.backref.refs : &(tok->u.backref.ref1)),
tok->u.backref.by_name,
-#ifdef USE_BACKREF_AT_LEVEL
+#ifdef USE_BACKREF_WITH_LEVEL
tok->u.backref.exist_level,
tok->u.backref.level,
#endif
env);
- CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
+ CHECK_NULL_RETURN_MEMERR(*np);
break;
#ifdef USE_SUBEXP_CALL
case TK_CALL:
- *np = node_new_call(tok->u.call.name, tok->u.call.name_end);
- CHECK_NULL_RETURN_VAL(*np, ONIGERR_MEMORY);
- env->num_call++;
+ {
+ int gnum = tok->u.call.gnum;
+
+ if (gnum < 0) {
+ gnum = BACKREF_REL_TO_ABS(gnum, env);
+ if (gnum <= 0)
+ return ONIGERR_INVALID_BACKREF;
+ }
+ *np = node_new_call(tok->u.call.name, tok->u.call.name_end, gnum);
+ CHECK_NULL_RETURN_MEMERR(*np);
+ env->num_call++;
+ }
break;
#endif
@@ -5127,31 +5374,46 @@ parse_exp(Node** np, OnigToken* tok, int term,
return ONIGERR_TARGET_OF_REPEAT_OPERATOR_INVALID;
qn = node_new_quantifier(tok->u.repeat.lower, tok->u.repeat.upper,
- (r == TK_INTERVAL ? 1 : 0));
- CHECK_NULL_RETURN_VAL(qn, ONIGERR_MEMORY);
- NQUANTIFIER(qn).greedy = tok->u.repeat.greedy;
+ (r == TK_INTERVAL ? 1 : 0));
+ CHECK_NULL_RETURN_MEMERR(qn);
+ NQTFR(qn)->greedy = tok->u.repeat.greedy;
r = set_quantifier(qn, *targetp, group, env);
- if (r < 0) return r;
-
+ if (r < 0) {
+ onig_node_free(qn);
+ return r;
+ }
+
if (tok->u.repeat.possessive != 0) {
Node* en;
- en = node_new_effect(EFFECT_STOP_BACKTRACK);
- CHECK_NULL_RETURN_VAL(en, ONIGERR_MEMORY);
- NEFFECT(en).target = qn;
+ en = node_new_enclose(ENCLOSE_STOP_BACKTRACK);
+ if (IS_NULL(en)) {
+ onig_node_free(qn);
+ return ONIGERR_MEMORY;
+ }
+ NENCLOSE(en)->target = qn;
qn = en;
}
if (r == 0) {
*targetp = qn;
}
+ else if (r == 1) {
+ onig_node_free(qn);
+ }
else if (r == 2) { /* split case: /abc+/ */
Node *tmp;
*targetp = node_new_list(*targetp, NULL);
- CHECK_NULL_RETURN_VAL(*targetp, ONIGERR_MEMORY);
- tmp = NCONS(*targetp).right = node_new_list(qn, NULL);
- CHECK_NULL_RETURN_VAL(tmp, ONIGERR_MEMORY);
- targetp = &(NCONS(tmp).left);
+ if (IS_NULL(*targetp)) {
+ onig_node_free(qn);
+ return ONIGERR_MEMORY;
+ }
+ tmp = NCDR(*targetp) = node_new_list(qn, NULL);
+ if (IS_NULL(tmp)) {
+ onig_node_free(qn);
+ return ONIGERR_MEMORY;
+ }
+ targetp = &(NCAR(tmp));
}
goto re_entry;
}
@@ -5176,19 +5438,19 @@ parse_branch(Node** top, OnigToken* tok, int term,
}
else {
*top = node_new_list(node, NULL);
- headp = &(NCONS(*top).right);
+ headp = &(NCDR(*top));
while (r != TK_EOT && r != term && r != TK_ALT) {
r = parse_exp(&node, tok, term, src, end, env);
if (r < 0) return r;
- if (NTYPE(node) == N_LIST) {
+ if (NTYPE(node) == NT_LIST) {
*headp = node;
- while (IS_NOT_NULL(NCONS(node).right)) node = NCONS(node).right;
- headp = &(NCONS(node).right);
+ while (IS_NOT_NULL(NCDR(node))) node = NCDR(node);
+ headp = &(NCDR(node));
}
else {
*headp = node_new_list(node, NULL);
- headp = &(NCONS(*headp).right);
+ headp = &(NCDR(*headp));
}
}
}
@@ -5215,19 +5477,19 @@ parse_subexp(Node** top, OnigToken* tok, int term,
*top = node;
}
else if (r == TK_ALT) {
- *top = node_new_alt(node, NULL);
- headp = &(NCONS(*top).right);
+ *top = onig_node_new_alt(node, NULL);
+ headp = &(NCDR(*top));
while (r == TK_ALT) {
r = fetch_token(tok, src, end, env);
if (r < 0) return r;
r = parse_branch(&node, tok, term, src, end, env);
if (r < 0) return r;
- *headp = node_new_alt(node, NULL);
- headp = &(NCONS(*headp).right);
+ *headp = onig_node_new_alt(node, NULL);
+ headp = &(NCDR(*headp));
}
- if (tok->type != term)
+ if (tok->type != (enum TokenSyms )term)
goto err;
}
else {
@@ -5255,8 +5517,8 @@ parse_regexp(Node** top, UChar** src, UChar* end, ScanEnv* env)
}
extern int
-onig_parse_make_tree(Node** root, const UChar* pattern, const UChar* end, regex_t* reg,
- ScanEnv* env)
+onig_parse_make_tree(Node** root, const UChar* pattern, const UChar* end,
+ regex_t* reg, ScanEnv* env)
{
int r;
UChar* p;
@@ -5266,13 +5528,13 @@ onig_parse_make_tree(Node** root, const UChar* pattern, const UChar* end, regex_
#endif
scan_env_clear(env);
- env->option = reg->options;
- env->ambig_flag = reg->ambig_flag;
- env->enc = reg->enc;
- env->syntax = reg->syntax;
- env->pattern = (UChar* )pattern;
- env->pattern_end = (UChar* )end;
- env->reg = reg;
+ env->option = reg->options;
+ env->case_fold_flag = reg->case_fold_flag;
+ env->enc = reg->enc;
+ env->syntax = reg->syntax;
+ env->pattern = (UChar* )pattern;
+ env->pattern_end = (UChar* )end;
+ env->reg = reg;
*root = NULL;
p = (UChar* )pattern;
@@ -5282,7 +5544,7 @@ onig_parse_make_tree(Node** root, const UChar* pattern, const UChar* end, regex_
}
extern void
-onig_scan_env_set_error_string(ScanEnv* env, int ecode,
+onig_scan_env_set_error_string(ScanEnv* env, int ecode ARG_UNUSED,
UChar* arg, UChar* arg_end)
{
env->error = arg;
diff --git a/ext/mbstring/oniguruma/regparse.h b/ext/mbstring/oniguruma/regparse.h
index b25618a33f..0c5c2c936c 100644
--- a/ext/mbstring/oniguruma/regparse.h
+++ b/ext/mbstring/oniguruma/regparse.h
@@ -32,47 +32,61 @@
#include "regint.h"
/* node type */
-#define N_STRING (1<< 0)
-#define N_CCLASS (1<< 1)
-#define N_CTYPE (1<< 2)
-#define N_ANYCHAR (1<< 3)
-#define N_BACKREF (1<< 4)
-#define N_QUANTIFIER (1<< 5)
-#define N_EFFECT (1<< 6)
-#define N_ANCHOR (1<< 7)
-#define N_LIST (1<< 8)
-#define N_ALT (1<< 9)
-#define N_CALL (1<<10)
+#define NT_STR 0
+#define NT_CCLASS 1
+#define NT_CTYPE 2
+#define NT_CANY 3
+#define NT_BREF 4
+#define NT_QTFR 5
+#define NT_ENCLOSE 6
+#define NT_ANCHOR 7
+#define NT_LIST 8
+#define NT_ALT 9
+#define NT_CALL 10
+
+/* node type bit */
+#define NTYPE2BIT(type) (1<<(type))
+
+#define BIT_NT_STR NTYPE2BIT(NT_STR)
+#define BIT_NT_CCLASS NTYPE2BIT(NT_CCLASS)
+#define BIT_NT_CTYPE NTYPE2BIT(NT_CTYPE)
+#define BIT_NT_CANY NTYPE2BIT(NT_CANY)
+#define BIT_NT_BREF NTYPE2BIT(NT_BREF)
+#define BIT_NT_QTFR NTYPE2BIT(NT_QTFR)
+#define BIT_NT_ENCLOSE NTYPE2BIT(NT_ENCLOSE)
+#define BIT_NT_ANCHOR NTYPE2BIT(NT_ANCHOR)
+#define BIT_NT_LIST NTYPE2BIT(NT_LIST)
+#define BIT_NT_ALT NTYPE2BIT(NT_ALT)
+#define BIT_NT_CALL NTYPE2BIT(NT_CALL)
#define IS_NODE_TYPE_SIMPLE(type) \
- (((type) & (N_STRING | N_CCLASS | N_CTYPE | N_ANYCHAR | N_BACKREF)) != 0)
-
-#define NTYPE(node) ((node)->type)
-#define NCONS(node) ((node)->u.cons)
-#define NSTRING(node) ((node)->u.str)
-#define NCCLASS(node) ((node)->u.cclass)
-#define NCTYPE(node) ((node)->u.ctype)
-#define NQUANTIFIER(node) ((node)->u.quantifier)
-#define NANCHOR(node) ((node)->u.anchor)
-#define NBACKREF(node) ((node)->u.backref)
-#define NEFFECT(node) ((node)->u.effect)
-#define NCALL(node) ((node)->u.call)
-
-#define CTYPE_WORD (1<<0)
-#define CTYPE_NOT_WORD (1<<1)
-#define CTYPE_WHITE_SPACE (1<<2)
-#define CTYPE_NOT_WHITE_SPACE (1<<3)
-#define CTYPE_DIGIT (1<<4)
-#define CTYPE_NOT_DIGIT (1<<5)
-#define CTYPE_XDIGIT (1<<6)
-#define CTYPE_NOT_XDIGIT (1<<7)
+ ((NTYPE2BIT(type) & (BIT_NT_STR | BIT_NT_CCLASS | BIT_NT_CTYPE |\
+ BIT_NT_CANY | BIT_NT_BREF)) != 0)
+
+#define NTYPE(node) ((node)->u.base.type)
+#define SET_NTYPE(node, ntype) (node)->u.base.type = (ntype)
+
+#define NSTR(node) (&((node)->u.str))
+#define NCCLASS(node) (&((node)->u.cclass))
+#define NCTYPE(node) (&((node)->u.ctype))
+#define NBREF(node) (&((node)->u.bref))
+#define NQTFR(node) (&((node)->u.qtfr))
+#define NENCLOSE(node) (&((node)->u.enclose))
+#define NANCHOR(node) (&((node)->u.anchor))
+#define NCONS(node) (&((node)->u.cons))
+#define NCALL(node) (&((node)->u.call))
+
+#define NCAR(node) (NCONS(node)->car)
+#define NCDR(node) (NCONS(node)->cdr)
+
+
#define ANCHOR_ANYCHAR_STAR_MASK (ANCHOR_ANYCHAR_STAR | ANCHOR_ANYCHAR_STAR_ML)
#define ANCHOR_END_BUF_MASK (ANCHOR_END_BUF | ANCHOR_SEMI_END_BUF)
-#define EFFECT_MEMORY (1<<0)
-#define EFFECT_OPTION (1<<1)
-#define EFFECT_STOP_BACKTRACK (1<<2)
+#define ENCLOSE_MEMORY (1<<0)
+#define ENCLOSE_OPTION (1<<1)
+#define ENCLOSE_STOP_BACKTRACK (1<<2)
#define NODE_STR_MARGIN 16
#define NODE_STR_BUF_SIZE 24 /* sizeof(CClassNode) - sizeof(int)*4 */
@@ -80,17 +94,18 @@
#define NSTR_RAW (1<<0) /* by backslashed number */
#define NSTR_AMBIG (1<<1)
-#define NSTR_AMBIG_REDUCE (1<<2)
+#define NSTR_DONT_GET_OPT_INFO (1<<2)
#define NSTRING_LEN(node) ((node)->u.str.end - (node)->u.str.s)
#define NSTRING_SET_RAW(node) (node)->u.str.flag |= NSTR_RAW
#define NSTRING_CLEAR_RAW(node) (node)->u.str.flag &= ~NSTR_RAW
#define NSTRING_SET_AMBIG(node) (node)->u.str.flag |= NSTR_AMBIG
-#define NSTRING_SET_AMBIG_REDUCE(node) (node)->u.str.flag |= NSTR_AMBIG_REDUCE
+#define NSTRING_SET_DONT_GET_OPT_INFO(node) \
+ (node)->u.str.flag |= NSTR_DONT_GET_OPT_INFO
#define NSTRING_IS_RAW(node) (((node)->u.str.flag & NSTR_RAW) != 0)
#define NSTRING_IS_AMBIG(node) (((node)->u.str.flag & NSTR_AMBIG) != 0)
-#define NSTRING_IS_AMBIG_REDUCE(node) \
- (((node)->u.str.flag & NSTR_AMBIG_REDUCE) != 0)
+#define NSTRING_IS_DONT_GET_OPT_INFO(node) \
+ (((node)->u.str.flag & NSTR_DONT_GET_OPT_INFO) != 0)
#define BACKREFS_P(br) \
(IS_NOT_NULL((br)->back_dynamic) ? (br)->back_dynamic : (br)->back_static);
@@ -100,39 +115,6 @@
#define NQ_TARGET_IS_EMPTY_MEM 2
#define NQ_TARGET_IS_EMPTY_REC 3
-
-typedef struct {
- UChar* s;
- UChar* end;
- unsigned int flag;
- int capa; /* (allocated size - 1) or 0: use buf[] */
- UChar buf[NODE_STR_BUF_SIZE];
-} StrNode;
-
-/* move to regint.h */
-#if 0
-typedef struct {
- int flags;
- BitSet bs;
- BBuf* mbuf; /* multi-byte info or NULL */
-} CClassNode;
-#endif
-
-typedef struct {
- int state;
- struct _Node* target;
- int lower;
- int upper;
- int greedy;
- int target_empty_info;
- struct _Node* head_exact;
- struct _Node* next_head_exact;
- int is_refered; /* include called node. don't eliminate even if {0} */
-#ifdef USE_COMBINATION_EXPLOSION_CHECK
- int comb_exp_check_num; /* 1,2,3...: check, 0: no check */
-#endif
-} QuantifierNode;
-
/* status bits */
#define NST_MIN_FIXED (1<<0)
#define NST_MAX_FIXED (1<<1)
@@ -150,105 +132,142 @@ typedef struct {
#define NST_NEST_LEVEL (1<<13)
#define NST_BY_NUMBER (1<<14) /* {n,m} */
-#define SET_EFFECT_STATUS(node,f) (node)->u.effect.state |= (f)
-#define CLEAR_EFFECT_STATUS(node,f) (node)->u.effect.state &= ~(f)
-
-#define IS_EFFECT_CALLED(en) (((en)->state & NST_CALLED) != 0)
-#define IS_EFFECT_ADDR_FIXED(en) (((en)->state & NST_ADDR_FIXED) != 0)
-#define IS_EFFECT_RECURSION(en) (((en)->state & NST_RECURSION) != 0)
-#define IS_EFFECT_MARK1(en) (((en)->state & NST_MARK1) != 0)
-#define IS_EFFECT_MARK2(en) (((en)->state & NST_MARK2) != 0)
-#define IS_EFFECT_MIN_FIXED(en) (((en)->state & NST_MIN_FIXED) != 0)
-#define IS_EFFECT_MAX_FIXED(en) (((en)->state & NST_MAX_FIXED) != 0)
-#define IS_EFFECT_CLEN_FIXED(en) (((en)->state & NST_CLEN_FIXED) != 0)
-#define IS_EFFECT_STOP_BT_SIMPLE_REPEAT(en) \
+#define SET_ENCLOSE_STATUS(node,f) (node)->u.enclose.state |= (f)
+#define CLEAR_ENCLOSE_STATUS(node,f) (node)->u.enclose.state &= ~(f)
+
+#define IS_ENCLOSE_CALLED(en) (((en)->state & NST_CALLED) != 0)
+#define IS_ENCLOSE_ADDR_FIXED(en) (((en)->state & NST_ADDR_FIXED) != 0)
+#define IS_ENCLOSE_RECURSION(en) (((en)->state & NST_RECURSION) != 0)
+#define IS_ENCLOSE_MARK1(en) (((en)->state & NST_MARK1) != 0)
+#define IS_ENCLOSE_MARK2(en) (((en)->state & NST_MARK2) != 0)
+#define IS_ENCLOSE_MIN_FIXED(en) (((en)->state & NST_MIN_FIXED) != 0)
+#define IS_ENCLOSE_MAX_FIXED(en) (((en)->state & NST_MAX_FIXED) != 0)
+#define IS_ENCLOSE_CLEN_FIXED(en) (((en)->state & NST_CLEN_FIXED) != 0)
+#define IS_ENCLOSE_STOP_BT_SIMPLE_REPEAT(en) \
(((en)->state & NST_STOP_BT_SIMPLE_REPEAT) != 0)
-#define IS_EFFECT_NAMED_GROUP(en) (((en)->state & NST_NAMED_GROUP) != 0)
+#define IS_ENCLOSE_NAMED_GROUP(en) (((en)->state & NST_NAMED_GROUP) != 0)
#define SET_CALL_RECURSION(node) (node)->u.call.state |= NST_RECURSION
#define IS_CALL_RECURSION(cn) (((cn)->state & NST_RECURSION) != 0)
#define IS_CALL_NAME_REF(cn) (((cn)->state & NST_NAME_REF) != 0)
#define IS_BACKREF_NAME_REF(bn) (((bn)->state & NST_NAME_REF) != 0)
#define IS_BACKREF_NEST_LEVEL(bn) (((bn)->state & NST_NEST_LEVEL) != 0)
-#define IS_QUANTIFIER_IN_REPEAT(qn) (((qn)->state & NST_IN_REPEAT) != 0)
-#define IS_QUANTIFIER_BY_NUMBER(qn) (((qn)->state & NST_BY_NUMBER) != 0)
+#define IS_QUANTIFIER_IN_REPEAT(qn) (((qn)->state & NST_IN_REPEAT) != 0)
+#define IS_QUANTIFIER_BY_NUMBER(qn) (((qn)->state & NST_BY_NUMBER) != 0)
+
+#define CALLNODE_REFNUM_UNDEF -1
typedef struct {
+ NodeBase base;
+ UChar* s;
+ UChar* end;
+ unsigned int flag;
+ int capa; /* (allocated size - 1) or 0: use buf[] */
+ UChar buf[NODE_STR_BUF_SIZE];
+} StrNode;
+
+typedef struct {
+ NodeBase base;
+ int state;
+ struct _Node* target;
+ int lower;
+ int upper;
+ int greedy;
+ int target_empty_info;
+ struct _Node* head_exact;
+ struct _Node* next_head_exact;
+ int is_refered; /* include called node. don't eliminate even if {0} */
+#ifdef USE_COMBINATION_EXPLOSION_CHECK
+ int comb_exp_check_num; /* 1,2,3...: check, 0: no check */
+#endif
+} QtfrNode;
+
+typedef struct {
+ NodeBase base;
int state;
int type;
int regnum;
OnigOptionType option;
- struct _Node* target;
- AbsAddrType call_addr;
+ struct _Node* target;
+ AbsAddrType call_addr;
/* for multiple call reference */
OnigDistance min_len; /* min length (byte) */
OnigDistance max_len; /* max length (byte) */
- int char_len; /* character length */
- int opt_count; /* referenced count in optimize_node_left() */
-} EffectNode;
-
-#define CALLNODE_REFNUM_UNDEF -1
+ int char_len; /* character length */
+ int opt_count; /* referenced count in optimize_node_left() */
+} EncloseNode;
#ifdef USE_SUBEXP_CALL
typedef struct {
- int offset;
+ int offset;
struct _Node* target;
} UnsetAddr;
typedef struct {
- int num;
- int alloc;
+ int num;
+ int alloc;
UnsetAddr* us;
} UnsetAddrList;
typedef struct {
+ NodeBase base;
int state;
- int ref_num;
+ int group_num;
UChar* name;
UChar* name_end;
- struct _Node* target; /* EffectNode : EFFECT_MEMORY */
+ struct _Node* target; /* EncloseNode : ENCLOSE_MEMORY */
UnsetAddrList* unset_addr_list;
} CallNode;
#endif
typedef struct {
- int state;
- int back_num;
- int back_static[NODE_BACKREFS_SIZE];
- int* back_dynamic;
- int nest_level;
-} BackrefNode;
+ NodeBase base;
+ int state;
+ int back_num;
+ int back_static[NODE_BACKREFS_SIZE];
+ int* back_dynamic;
+ int nest_level;
+} BRefNode;
typedef struct {
+ NodeBase base;
int type;
struct _Node* target;
int char_len;
} AnchorNode;
+typedef struct {
+ NodeBase base;
+ struct _Node* car;
+ struct _Node* cdr;
+} ConsAltNode;
+
+typedef struct {
+ NodeBase base;
+ int ctype;
+ int not;
+} CtypeNode;
+
typedef struct _Node {
- int type;
union {
- StrNode str;
- CClassNode cclass;
- QuantifierNode quantifier;
- EffectNode effect;
+ NodeBase base;
+ StrNode str;
+ CClassNode cclass;
+ QtfrNode qtfr;
+ EncloseNode enclose;
+ BRefNode bref;
+ AnchorNode anchor;
+ ConsAltNode cons;
+ CtypeNode ctype;
#ifdef USE_SUBEXP_CALL
- CallNode call;
+ CallNode call;
#endif
- BackrefNode backref;
- AnchorNode anchor;
- struct {
- struct _Node* left;
- struct _Node* right;
- } cons;
- struct {
- int type;
- } ctype;
} u;
} Node;
+
#define NULL_NODE ((Node* )0)
#define SCANENV_MEMNODES_SIZE 8
@@ -257,30 +276,30 @@ typedef struct _Node {
(senv)->mem_nodes_dynamic : (senv)->mem_nodes_static)
typedef struct {
- OnigOptionType option;
- OnigAmbigType ambig_flag;
- OnigEncoding enc;
- OnigSyntaxType* syntax;
- BitStatusType capture_history;
- BitStatusType bt_mem_start;
- BitStatusType bt_mem_end;
- BitStatusType backrefed_mem;
- UChar* pattern;
- UChar* pattern_end;
- UChar* error;
- UChar* error_end;
- regex_t* reg; /* for reg->names only */
- int num_call;
+ OnigOptionType option;
+ OnigCaseFoldType case_fold_flag;
+ OnigEncoding enc;
+ OnigSyntaxType* syntax;
+ BitStatusType capture_history;
+ BitStatusType bt_mem_start;
+ BitStatusType bt_mem_end;
+ BitStatusType backrefed_mem;
+ UChar* pattern;
+ UChar* pattern_end;
+ UChar* error;
+ UChar* error_end;
+ regex_t* reg; /* for reg->names only */
+ int num_call;
#ifdef USE_SUBEXP_CALL
- UnsetAddrList* unset_addr_list;
+ UnsetAddrList* unset_addr_list;
#endif
- int num_mem;
+ int num_mem;
#ifdef USE_NAMED_GROUP
- int num_named;
+ int num_named;
#endif
- int mem_alloc;
- Node* mem_nodes_static[SCANENV_MEMNODES_SIZE];
- Node** mem_nodes_dynamic;
+ int mem_alloc;
+ Node* mem_nodes_static[SCANENV_MEMNODES_SIZE];
+ Node** mem_nodes_dynamic;
#ifdef USE_COMBINATION_EXPLOSION_CHECK
int num_comb_exp_check;
int comb_exp_max_regnum;
@@ -294,7 +313,6 @@ typedef struct {
#define IS_SYNTAX_OP2(syn, opm) (((syn)->op2 & (opm)) != 0)
#define IS_SYNTAX_BV(syn, bvm) (((syn)->behavior & (bvm)) != 0)
-
#ifdef USE_NAMED_GROUP
typedef struct {
int new_val;
@@ -304,20 +322,25 @@ extern int onig_renumber_name_table P_((regex_t* reg, GroupNumRemap* map));
#endif
extern int onig_strncmp P_((const UChar* s1, const UChar* s2, int n));
+extern void onig_strcpy P_((UChar* dest, const UChar* src, const UChar* end));
extern void onig_scan_env_set_error_string P_((ScanEnv* env, int ecode, UChar* arg, UChar* arg_end));
extern int onig_scan_unsigned_number P_((UChar** src, const UChar* end, OnigEncoding enc));
extern void onig_reduce_nested_quantifier P_((Node* pnode, Node* cnode));
extern void onig_node_conv_to_str_node P_((Node* node, int raw));
extern int onig_node_str_cat P_((Node* node, const UChar* s, const UChar* end));
+extern int onig_node_str_set P_((Node* node, const UChar* s, const UChar* end));
extern void onig_node_free P_((Node* node));
-extern Node* onig_node_new_effect P_((int type));
+extern Node* onig_node_new_enclose P_((int type));
extern Node* onig_node_new_anchor P_((int type));
extern Node* onig_node_new_str P_((const UChar* s, const UChar* end));
extern Node* onig_node_new_list P_((Node* left, Node* right));
+extern Node* onig_node_list_add P_((Node* list, Node* x));
+extern Node* onig_node_new_alt P_((Node* left, Node* right));
extern void onig_node_str_clear P_((Node* node));
extern int onig_free_node_list P_((void));
extern int onig_names_free P_((regex_t* reg));
extern int onig_parse_make_tree P_((Node** root, const UChar* pattern, const UChar* end, regex_t* reg, ScanEnv* env));
+extern int onig_free_shared_cclass_table P_((void));
#ifdef ONIG_DEBUG
#ifdef USE_NAMED_GROUP
diff --git a/ext/mbstring/oniguruma/regposerr.c b/ext/mbstring/oniguruma/regposerr.c
index e54b5c4089..56f75abfc1 100644
--- a/ext/mbstring/oniguruma/regposerr.c
+++ b/ext/mbstring/oniguruma/regposerr.c
@@ -2,7 +2,7 @@
regposerr.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2005 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2007 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,6 +36,12 @@
# include <strings.h>
#endif
+#if defined(__GNUC__)
+# define ARG_UNUSED __attribute__ ((unused))
+#else
+# define ARG_UNUSED
+#endif
+
static char* ESTRING[] = {
NULL,
"failed to match", /* REG_NOMATCH */
@@ -63,13 +69,15 @@ static char* ESTRING[] = {
extern size_t
-regerror(int posix_ecode, const regex_t* reg, char* buf, size_t size)
+regerror(int posix_ecode, const regex_t* reg ARG_UNUSED, char* buf,
+ size_t size)
{
char* s;
char tbuf[35];
size_t len;
- if (posix_ecode > 0 && posix_ecode < sizeof(ESTRING) / sizeof(ESTRING[0])) {
+ if (posix_ecode > 0
+ && posix_ecode < (int )(sizeof(ESTRING) / sizeof(ESTRING[0]))) {
s = ESTRING[posix_ecode];
}
else if (posix_ecode == 0) {
diff --git a/ext/mbstring/oniguruma/regposix.c b/ext/mbstring/oniguruma/regposix.c
index a3bacf722e..7d1857cf2d 100644
--- a/ext/mbstring/oniguruma/regposix.c
+++ b/ext/mbstring/oniguruma/regposix.c
@@ -2,7 +2,7 @@
regposix.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2006 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2008 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -102,7 +102,7 @@ onig2posix_error_code(int code)
{ ONIGERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED, REG_BADPAT },
{ ONIGERR_TOO_BIG_WIDE_CHAR_VALUE, REG_EONIG_BADWC },
{ ONIGERR_TOO_LONG_WIDE_CHAR_VALUE, REG_EONIG_BADWC },
- { ONIGERR_INVALID_WIDE_CHAR_VALUE, REG_EONIG_BADWC },
+ { ONIGERR_INVALID_CODE_POINT_VALUE, REG_EONIG_BADWC },
{ ONIGERR_EMPTY_GROUP_NAME, REG_BADPAT },
{ ONIGERR_INVALID_GROUP_NAME, REG_BADPAT },
{ ONIGERR_INVALID_CHAR_IN_GROUP_NAME, REG_BADPAT },
@@ -122,7 +122,7 @@ onig2posix_error_code(int code)
if (code >= 0) return 0;
- for (i = 0; i < sizeof(o2p) / sizeof(o2p[0]); i++) {
+ for (i = 0; i < (int )(sizeof(o2p) / sizeof(o2p[0])); i++) {
if (code == o2p[i].onig_err)
return o2p[i].posix_err;
}
@@ -273,9 +273,9 @@ typedef struct {
void* arg;
} i_wrap;
-static int i_wrapper(const unsigned char* name, const unsigned char* name_end,
- int ng, int* gs,
- onig_regex_t* reg, void* arg)
+static int
+i_wrapper(const UChar* name, const UChar* name_end, int ng, int* gs,
+ onig_regex_t* reg ARG_UNUSED, void* arg)
{
i_wrap* warg = (i_wrap* )arg;
diff --git a/ext/mbstring/oniguruma/regsyntax.c b/ext/mbstring/oniguruma/regsyntax.c
index 9114e39e6b..ade5b55f77 100644
--- a/ext/mbstring/oniguruma/regsyntax.c
+++ b/ext/mbstring/oniguruma/regsyntax.c
@@ -34,6 +34,15 @@ OnigSyntaxType OnigSyntaxASIS = {
, ONIG_SYN_OP2_INEFFECTIVE_ESCAPE
, 0
, ONIG_OPTION_NONE
+ ,
+ {
+ (OnigCodePoint )'\\' /* esc */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
+ }
};
OnigSyntaxType OnigSyntaxPosixBasic = {
@@ -42,6 +51,15 @@ OnigSyntaxType OnigSyntaxPosixBasic = {
, 0
, 0
, ( ONIG_OPTION_SINGLELINE | ONIG_OPTION_MULTILINE )
+ ,
+ {
+ (OnigCodePoint )'\\' /* esc */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
+ }
};
OnigSyntaxType OnigSyntaxPosixExtended = {
@@ -54,6 +72,15 @@ OnigSyntaxType OnigSyntaxPosixExtended = {
ONIG_SYN_ALLOW_UNMATCHED_CLOSE_SUBEXP |
ONIG_SYN_ALLOW_DOUBLE_RANGE_OP_IN_CC )
, ( ONIG_OPTION_SINGLELINE | ONIG_OPTION_MULTILINE )
+ ,
+ {
+ (OnigCodePoint )'\\' /* esc */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
+ }
};
OnigSyntaxType OnigSyntaxEmacs = {
@@ -66,6 +93,15 @@ OnigSyntaxType OnigSyntaxEmacs = {
, ONIG_SYN_OP2_ESC_GNU_BUF_ANCHOR
, ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC
, ONIG_OPTION_NONE
+ ,
+ {
+ (OnigCodePoint )'\\' /* esc */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
+ }
};
OnigSyntaxType OnigSyntaxGrep = {
@@ -79,6 +115,15 @@ OnigSyntaxType OnigSyntaxGrep = {
, 0
, ( ONIG_SYN_ALLOW_EMPTY_RANGE_IN_CC | ONIG_SYN_NOT_NEWLINE_IN_NEGATIVE_CC )
, ONIG_OPTION_NONE
+ ,
+ {
+ (OnigCodePoint )'\\' /* esc */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
+ }
};
OnigSyntaxType OnigSyntaxGnuRegex = {
@@ -86,6 +131,15 @@ OnigSyntaxType OnigSyntaxGnuRegex = {
, 0
, SYN_GNU_REGEX_BV
, ONIG_OPTION_NONE
+ ,
+ {
+ (OnigCodePoint )'\\' /* esc */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
+ }
};
OnigSyntaxType OnigSyntaxJava = {
@@ -100,6 +154,15 @@ OnigSyntaxType OnigSyntaxJava = {
ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY )
, ( SYN_GNU_REGEX_BV | ONIG_SYN_DIFFERENT_LEN_ALT_LOOK_BEHIND )
, ONIG_OPTION_SINGLELINE
+ ,
+ {
+ (OnigCodePoint )'\\' /* esc */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
+ }
};
OnigSyntaxType OnigSyntaxPerl = {
@@ -111,10 +174,18 @@ OnigSyntaxType OnigSyntaxPerl = {
, ( ONIG_SYN_OP2_ESC_CAPITAL_Q_QUOTE |
ONIG_SYN_OP2_QMARK_GROUP_EFFECT | ONIG_SYN_OP2_OPTION_PERL |
ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY |
- ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT |
- ONIG_SYN_OP2_CHAR_PROPERTY_PREFIX_IS )
+ ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT )
, SYN_GNU_REGEX_BV
, ONIG_OPTION_SINGLELINE
+ ,
+ {
+ (OnigCodePoint )'\\' /* esc */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
+ }
};
/* Perl + named group */
@@ -128,7 +199,6 @@ OnigSyntaxType OnigSyntaxPerl_NG = {
ONIG_SYN_OP2_QMARK_GROUP_EFFECT | ONIG_SYN_OP2_OPTION_PERL |
ONIG_SYN_OP2_ESC_P_BRACE_CHAR_PROPERTY |
ONIG_SYN_OP2_ESC_P_BRACE_CIRCUMFLEX_NOT |
- ONIG_SYN_OP2_CHAR_PROPERTY_PREFIX_IS |
ONIG_SYN_OP2_QMARK_LT_NAMED_GROUP |
ONIG_SYN_OP2_ESC_K_NAMED_BACKREF |
ONIG_SYN_OP2_ESC_G_SUBEXP_CALL )
@@ -136,6 +206,15 @@ OnigSyntaxType OnigSyntaxPerl_NG = {
ONIG_SYN_CAPTURE_ONLY_NAMED_GROUP |
ONIG_SYN_ALLOW_MULTIPLEX_DEFINITION_NAME )
, ONIG_OPTION_SINGLELINE
+ ,
+ {
+ (OnigCodePoint )'\\' /* esc */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar '.' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anytime '*' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* zero or one time '?' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* one or more time '+' */
+ , (OnigCodePoint )ONIG_INEFFECTIVE_META_CHAR /* anychar anytime */
+ }
};
@@ -205,7 +284,7 @@ onig_get_syntax_options(OnigSyntaxType* syntax)
}
#ifdef USE_VARIABLE_META_CHARS
-extern int onig_set_meta_char(OnigEncoding enc,
+extern int onig_set_meta_char(OnigSyntaxType* enc,
unsigned int what, OnigCodePoint code)
{
switch (what) {
diff --git a/ext/mbstring/oniguruma/regversion.c b/ext/mbstring/oniguruma/regversion.c
index 5fad0cc18c..113fbaedc6 100644
--- a/ext/mbstring/oniguruma/regversion.c
+++ b/ext/mbstring/oniguruma/regversion.c
@@ -2,7 +2,7 @@
regversion.c - Oniguruma (regular expression library)
**********************************************************************/
/*-
- * Copyright (c) 2002-2006 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
+ * Copyright (c) 2002-2008 K.Kosako <sndgk393 AT ybb DOT ne DOT jp>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -27,6 +27,7 @@
* SUCH DAMAGE.
*/
+#include "config.h"
#include "oniguruma.h"
#include <stdio.h>
@@ -47,7 +48,7 @@ onig_copyright(void)
{
static char s[58];
- sprintf(s, "Oniguruma %d.%d.%d : Copyright (C) 2002-2006 K.Kosako",
+ sprintf(s, "Oniguruma %d.%d.%d : Copyright (C) 2002-2008 K.Kosako",
ONIGURUMA_VERSION_MAJOR,
ONIGURUMA_VERSION_MINOR,
ONIGURUMA_VERSION_TEENY);
diff --git a/ext/mbstring/oniguruma/st.c b/ext/mbstring/oniguruma/st.c
index 2324da2635..022880ae36 100644
--- a/ext/mbstring/oniguruma/st.c
+++ b/ext/mbstring/oniguruma/st.c
@@ -2,7 +2,6 @@
/* static char sccsid[] = "@(#) st.c 5.1 89/12/14 Crucible"; */
-#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -11,22 +10,7 @@
#include <malloc.h>
#endif
-#ifdef NOT_RUBY
#include "regint.h"
-#else
-#ifdef RUBY_PLATFORM
-#define xmalloc ruby_xmalloc
-#define xcalloc ruby_xcalloc
-#define xrealloc ruby_xrealloc
-#define xfree ruby_xfree
-
-void *xmalloc(long);
-void *xcalloc(long, long);
-void *xrealloc(void *, long);
-void xfree(void *);
-#endif
-#endif
-
#include "st.h"
typedef struct st_table_entry st_table_entry;
@@ -467,8 +451,13 @@ st_delete_safe(table, key, value, never)
}
static int
+#if defined(__GNUC__)
+delete_never(st_data_t key __attribute__ ((unused)), st_data_t value,
+ st_data_t never)
+#else
delete_never(key, value, never)
st_data_t key, value, never;
+#endif
{
if (value == never) return ST_DELETE;
return ST_CONTINUE;
diff --git a/ext/mbstring/oniguruma/st.h b/ext/mbstring/oniguruma/st.h
index da65e7fef8..6f93870214 100644
--- a/ext/mbstring/oniguruma/st.h
+++ b/ext/mbstring/oniguruma/st.h
@@ -6,7 +6,12 @@
#define ST_INCLUDED
+#ifdef _WIN32
+# include <windows.h>
+typedef ULONG_PTR st_data_t;
+#else
typedef unsigned long st_data_t;
+#endif
#define ST_DATA_T_DEFINED
typedef struct st_table st_table;
diff --git a/ext/mbstring/oniguruma/testc.c b/ext/mbstring/oniguruma/testc.c
new file mode 100644
index 0000000000..6a8c77896d
--- /dev/null
+++ b/ext/mbstring/oniguruma/testc.c
@@ -0,0 +1,863 @@
+/*
+ * This program was generated by testconv.rb.
+ */
+#include "config.h"
+#ifdef ONIG_ESCAPE_UCHAR_COLLISION
+#undef ONIG_ESCAPE_UCHAR_COLLISION
+#endif
+#include <stdio.h>
+
+#ifdef POSIX_TEST
+#include "onigposix.h"
+#else
+#include "oniguruma.h"
+#endif
+
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# include <strings.h>
+#endif
+
+#define SLEN(s) strlen(s)
+
+static int nsucc = 0;
+static int nfail = 0;
+static int nerror = 0;
+
+static FILE* err_file;
+
+#ifndef POSIX_TEST
+static OnigRegion* region;
+#endif
+
+static void xx(char* pattern, char* str, int from, int to, int mem, int not)
+{
+ int r;
+
+#ifdef POSIX_TEST
+ regex_t reg;
+ char buf[200];
+ regmatch_t pmatch[25];
+
+ r = regcomp(&reg, pattern, REG_EXTENDED | REG_NEWLINE);
+ if (r) {
+ regerror(r, &reg, buf, sizeof(buf));
+ fprintf(err_file, "ERROR: %s\n", buf);
+ nerror++;
+ return ;
+ }
+
+ r = regexec(&reg, str, reg.re_nsub + 1, pmatch, 0);
+ if (r != 0 && r != REG_NOMATCH) {
+ regerror(r, &reg, buf, sizeof(buf));
+ fprintf(err_file, "ERROR: %s\n", buf);
+ nerror++;
+ return ;
+ }
+
+ if (r == REG_NOMATCH) {
+ if (not) {
+ fprintf(stdout, "OK(N): /%s/ '%s'\n", pattern, str);
+ nsucc++;
+ }
+ else {
+ fprintf(stdout, "FAIL: /%s/ '%s'\n", pattern, str);
+ nfail++;
+ }
+ }
+ else {
+ if (not) {
+ fprintf(stdout, "FAIL(N): /%s/ '%s'\n", pattern, str);
+ nfail++;
+ }
+ else {
+ if (pmatch[mem].rm_so == from && pmatch[mem].rm_eo == to) {
+ fprintf(stdout, "OK: /%s/ '%s'\n", pattern, str);
+ nsucc++;
+ }
+ else {
+ fprintf(stdout, "FAIL: /%s/ '%s' %d-%d : %d-%d\n", pattern, str,
+ from, to, pmatch[mem].rm_so, pmatch[mem].rm_eo);
+ nfail++;
+ }
+ }
+ }
+ regfree(&reg);
+
+#else
+ regex_t* reg;
+ OnigErrorInfo einfo;
+
+ r = onig_new(&reg, (UChar* )pattern, (UChar* )(pattern + SLEN(pattern)),
+ ONIG_OPTION_DEFAULT, ONIG_ENCODING_EUC_JP, ONIG_SYNTAX_DEFAULT, &einfo);
+ if (r) {
+ char s[ONIG_MAX_ERROR_MESSAGE_LEN];
+ onig_error_code_to_str((UChar* )s, r, &einfo);
+ fprintf(err_file, "ERROR: %s\n", s);
+ nerror++;
+ return ;
+ }
+
+ r = onig_search(reg, (UChar* )str, (UChar* )(str + SLEN(str)),
+ (UChar* )str, (UChar* )(str + SLEN(str)),
+ region, ONIG_OPTION_NONE);
+ if (r < ONIG_MISMATCH) {
+ char s[ONIG_MAX_ERROR_MESSAGE_LEN];
+ onig_error_code_to_str((UChar* )s, r);
+ fprintf(err_file, "ERROR: %s\n", s);
+ nerror++;
+ return ;
+ }
+
+ if (r == ONIG_MISMATCH) {
+ if (not) {
+ fprintf(stdout, "OK(N): /%s/ '%s'\n", pattern, str);
+ nsucc++;
+ }
+ else {
+ fprintf(stdout, "FAIL: /%s/ '%s'\n", pattern, str);
+ nfail++;
+ }
+ }
+ else {
+ if (not) {
+ fprintf(stdout, "FAIL(N): /%s/ '%s'\n", pattern, str);
+ nfail++;
+ }
+ else {
+ if (region->beg[mem] == from && region->end[mem] == to) {
+ fprintf(stdout, "OK: /%s/ '%s'\n", pattern, str);
+ nsucc++;
+ }
+ else {
+ fprintf(stdout, "FAIL: /%s/ '%s' %d-%d : %d-%d\n", pattern, str,
+ from, to, region->beg[mem], region->end[mem]);
+ nfail++;
+ }
+ }
+ }
+ onig_free(reg);
+#endif
+}
+
+static void x2(char* pattern, char* str, int from, int to)
+{
+ xx(pattern, str, from, to, 0, 0);
+}
+
+static void x3(char* pattern, char* str, int from, int to, int mem)
+{
+ xx(pattern, str, from, to, mem, 0);
+}
+
+static void n(char* pattern, char* str)
+{
+ xx(pattern, str, 0, 0, 0, 1);
+}
+
+extern int main(int argc, char* argv[])
+{
+ err_file = stdout;
+
+#ifdef POSIX_TEST
+ reg_set_encoding(REG_POSIX_ENCODING_EUC_JP);
+#else
+ region = onig_region_new();
+#endif
+
+ x2("", "", 0, 0);
+ x2("^", "", 0, 0);
+ x2("$", "", 0, 0);
+ x2("\\G", "", 0, 0);
+ x2("\\A", "", 0, 0);
+ x2("\\Z", "", 0, 0);
+ x2("\\z", "", 0, 0);
+ x2("^$", "", 0, 0);
+ x2("\\ca", "\001", 0, 1);
+ x2("\\C-b", "\002", 0, 1);
+ x2("\\c\\\\", "\034", 0, 1);
+ x2("q[\\c\\\\]", "q\034", 0, 2);
+ x2("", "a", 0, 0);
+ x2("a", "a", 0, 1);
+ x2("\\x61", "a", 0, 1);
+ x2("aa", "aa", 0, 2);
+ x2("aaa", "aaa", 0, 3);
+ x2("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0, 35);
+ x2("ab", "ab", 0, 2);
+ x2("b", "ab", 1, 2);
+ x2("bc", "abc", 1, 3);
+ x2("(?i:#RET#)", "#INS##RET#", 5, 10);
+ x2("\\17", "\017", 0, 1);
+ x2("\\x1f", "\x1f", 0, 1);
+ x2("a(?#....\\\\JJJJ)b", "ab", 0, 2);
+ x2("(?x) G (o O(?-x)oO) g L", "GoOoOgLe", 0, 7);
+ x2(".", "a", 0, 1);
+ n(".", "");
+ x2("..", "ab", 0, 2);
+ x2("\\w", "e", 0, 1);
+ n("\\W", "e");
+ x2("\\s", " ", 0, 1);
+ x2("\\S", "b", 0, 1);
+ x2("\\d", "4", 0, 1);
+ n("\\D", "4");
+ x2("\\b", "z ", 0, 0);
+ x2("\\b", " z", 1, 1);
+ x2("\\B", "zz ", 1, 1);
+ x2("\\B", "z ", 2, 2);
+ x2("\\B", " z", 0, 0);
+ x2("[ab]", "b", 0, 1);
+ n("[ab]", "c");
+ x2("[a-z]", "t", 0, 1);
+ n("[^a]", "a");
+ x2("[^a]", "\n", 0, 1);
+ x2("[]]", "]", 0, 1);
+ n("[^]]", "]");
+ x2("[\\^]+", "0^^1", 1, 3);
+ x2("[b-]", "b", 0, 1);
+ x2("[b-]", "-", 0, 1);
+ x2("[\\w]", "z", 0, 1);
+ n("[\\w]", " ");
+ x2("[\\W]", "b$", 1, 2);
+ x2("[\\d]", "5", 0, 1);
+ n("[\\d]", "e");
+ x2("[\\D]", "t", 0, 1);
+ n("[\\D]", "3");
+ x2("[\\s]", " ", 0, 1);
+ n("[\\s]", "a");
+ x2("[\\S]", "b", 0, 1);
+ n("[\\S]", " ");
+ x2("[\\w\\d]", "2", 0, 1);
+ n("[\\w\\d]", " ");
+ x2("[[:upper:]]", "B", 0, 1);
+ x2("[*[:xdigit:]+]", "+", 0, 1);
+ x2("[*[:xdigit:]+]", "GHIKK-9+*", 6, 7);
+ x2("[*[:xdigit:]+]", "-@^+", 3, 4);
+ n("[[:upper]]", "A");
+ x2("[[:upper]]", ":", 0, 1);
+ x2("[\\044-\\047]", "\046", 0, 1);
+ x2("[\\x5a-\\x5c]", "\x5b", 0, 1);
+ x2("[\\x6A-\\x6D]", "\x6c", 0, 1);
+ n("[\\x6A-\\x6D]", "\x6E");
+ n("^[0-9A-F]+ 0+ UNDEF ", "75F 00000000 SECT14A notype () External | _rb_apply");
+ x2("[\\[]", "[", 0, 1);
+ x2("[\\]]", "]", 0, 1);
+ x2("[&]", "&", 0, 1);
+ x2("[[ab]]", "b", 0, 1);
+ x2("[[ab]c]", "c", 0, 1);
+ n("[[^a]]", "a");
+ n("[^[a]]", "a");
+ x2("[[ab]&&bc]", "b", 0, 1);
+ n("[[ab]&&bc]", "a");
+ n("[[ab]&&bc]", "c");
+ x2("[a-z&&b-y&&c-x]", "w", 0, 1);
+ n("[^a-z&&b-y&&c-x]", "w");
+ x2("[[^a&&a]&&a-z]", "b", 0, 1);
+ n("[[^a&&a]&&a-z]", "a");
+ x2("[[^a-z&&bcdef]&&[^c-g]]", "h", 0, 1);
+ n("[[^a-z&&bcdef]&&[^c-g]]", "c");
+ x2("[^[^abc]&&[^cde]]", "c", 0, 1);
+ x2("[^[^abc]&&[^cde]]", "e", 0, 1);
+ n("[^[^abc]&&[^cde]]", "f");
+ x2("[a-&&-a]", "-", 0, 1);
+ n("[a\\-&&\\-a]", "&");
+ n("\\wabc", " abc");
+ x2("a\\Wbc", "a bc", 0, 4);
+ x2("a.b.c", "aabbc", 0, 5);
+ x2(".\\wb\\W..c", "abb bcc", 0, 7);
+ x2("\\s\\wzzz", " zzzz", 0, 5);
+ x2("aa.b", "aabb", 0, 4);
+ n(".a", "ab");
+ x2(".a", "aa", 0, 2);
+ x2("^a", "a", 0, 1);
+ x2("^a$", "a", 0, 1);
+ x2("^\\w$", "a", 0, 1);
+ n("^\\w$", " ");
+ x2("^\\wab$", "zab", 0, 3);
+ x2("^\\wabcdef$", "zabcdef", 0, 7);
+ x2("^\\w...def$", "zabcdef", 0, 7);
+ x2("\\w\\w\\s\\Waaa\\d", "aa aaa4", 0, 8);
+ x2("\\A\\Z", "", 0, 0);
+ x2("\\Axyz", "xyz", 0, 3);
+ x2("xyz\\Z", "xyz", 0, 3);
+ x2("xyz\\z", "xyz", 0, 3);
+ x2("a\\Z", "a", 0, 1);
+ x2("\\Gaz", "az", 0, 2);
+ n("\\Gz", "bza");
+ n("az\\G", "az");
+ n("az\\A", "az");
+ n("a\\Az", "az");
+ x2("\\^\\$", "^$", 0, 2);
+ x2("^x?y", "xy", 0, 2);
+ x2("^(x?y)", "xy", 0, 2);
+ x2("\\w", "_", 0, 1);
+ n("\\W", "_");
+ x2("(?=z)z", "z", 0, 1);
+ n("(?=z).", "a");
+ x2("(?!z)a", "a", 0, 1);
+ n("(?!z)a", "z");
+ x2("(?i:a)", "a", 0, 1);
+ x2("(?i:a)", "A", 0, 1);
+ x2("(?i:A)", "a", 0, 1);
+ n("(?i:A)", "b");
+ x2("(?i:[A-Z])", "a", 0, 1);
+ x2("(?i:[f-m])", "H", 0, 1);
+ x2("(?i:[f-m])", "h", 0, 1);
+ n("(?i:[f-m])", "e");
+ x2("(?i:[A-c])", "D", 0, 1);
+ n("(?i:[^a-z])", "A");
+ n("(?i:[^a-z])", "a");
+ x2("(?i:[!-k])", "Z", 0, 1);
+ x2("(?i:[!-k])", "7", 0, 1);
+ x2("(?i:[T-}])", "b", 0, 1);
+ x2("(?i:[T-}])", "{", 0, 1);
+ x2("(?i:\\?a)", "?A", 0, 2);
+ x2("(?i:\\*A)", "*a", 0, 2);
+ n(".", "\n");
+ x2("(?m:.)", "\n", 0, 1);
+ x2("(?m:a.)", "a\n", 0, 2);
+ x2("(?m:.b)", "a\nb", 1, 3);
+ x2(".*abc", "dddabdd\nddabc", 8, 13);
+ x2("(?m:.*abc)", "dddabddabc", 0, 10);
+ n("(?i)(?-i)a", "A");
+ n("(?i)(?-i:a)", "A");
+ x2("a?", "", 0, 0);
+ x2("a?", "b", 0, 0);
+ x2("a?", "a", 0, 1);
+ x2("a*", "", 0, 0);
+ x2("a*", "a", 0, 1);
+ x2("a*", "aaa", 0, 3);
+ x2("a*", "baaaa", 0, 0);
+ n("a+", "");
+ x2("a+", "a", 0, 1);
+ x2("a+", "aaaa", 0, 4);
+ x2("a+", "aabbb", 0, 2);
+ x2("a+", "baaaa", 1, 5);
+ x2(".?", "", 0, 0);
+ x2(".?", "f", 0, 1);
+ x2(".?", "\n", 0, 0);
+ x2(".*", "", 0, 0);
+ x2(".*", "abcde", 0, 5);
+ x2(".+", "z", 0, 1);
+ x2(".+", "zdswer\n", 0, 6);
+ x2("(.*)a\\1f", "babfbac", 0, 4);
+ x2("(.*)a\\1f", "bacbabf", 3, 7);
+ x2("((.*)a\\2f)", "bacbabf", 3, 7);
+ x2("(.*)a\\1f", "baczzzzzz\nbazz\nzzzzbabf", 19, 23);
+ x2("a|b", "a", 0, 1);
+ x2("a|b", "b", 0, 1);
+ x2("|a", "a", 0, 0);
+ x2("(|a)", "a", 0, 0);
+ x2("ab|bc", "ab", 0, 2);
+ x2("ab|bc", "bc", 0, 2);
+ x2("z(?:ab|bc)", "zbc", 0, 3);
+ x2("a(?:ab|bc)c", "aabc", 0, 4);
+ x2("ab|(?:ac|az)", "az", 0, 2);
+ x2("a|b|c", "dc", 1, 2);
+ x2("a|b|cd|efg|h|ijk|lmn|o|pq|rstuvwx|yz", "pqr", 0, 2);
+ n("a|b|cd|efg|h|ijk|lmn|o|pq|rstuvwx|yz", "mn");
+ x2("a|^z", "ba", 1, 2);
+ x2("a|^z", "za", 0, 1);
+ x2("a|\\Gz", "bza", 2, 3);
+ x2("a|\\Gz", "za", 0, 1);
+ x2("a|\\Az", "bza", 2, 3);
+ x2("a|\\Az", "za", 0, 1);
+ x2("a|b\\Z", "ba", 1, 2);
+ x2("a|b\\Z", "b", 0, 1);
+ x2("a|b\\z", "ba", 1, 2);
+ x2("a|b\\z", "b", 0, 1);
+ x2("\\w|\\s", " ", 0, 1);
+ n("\\w|\\w", " ");
+ x2("\\w|%", "%", 0, 1);
+ x2("\\w|[&$]", "&", 0, 1);
+ x2("[b-d]|[^e-z]", "a", 0, 1);
+ x2("(?:a|[c-f])|bz", "dz", 0, 1);
+ x2("(?:a|[c-f])|bz", "bz", 0, 2);
+ x2("abc|(?=zz)..f", "zzf", 0, 3);
+ x2("abc|(?!zz)..f", "abf", 0, 3);
+ x2("(?=za)..a|(?=zz)..a", "zza", 0, 3);
+ n("(?>a|abd)c", "abdc");
+ x2("(?>abd|a)c", "abdc", 0, 4);
+ x2("a?|b", "a", 0, 1);
+ x2("a?|b", "b", 0, 0);
+ x2("a?|b", "", 0, 0);
+ x2("a*|b", "aa", 0, 2);
+ x2("a*|b*", "ba", 0, 0);
+ x2("a*|b*", "ab", 0, 1);
+ x2("a+|b*", "", 0, 0);
+ x2("a+|b*", "bbb", 0, 3);
+ x2("a+|b*", "abbb", 0, 1);
+ n("a+|b+", "");
+ x2("(a|b)?", "b", 0, 1);
+ x2("(a|b)*", "ba", 0, 2);
+ x2("(a|b)+", "bab", 0, 3);
+ x2("(ab|ca)+", "caabbc", 0, 4);
+ x2("(ab|ca)+", "aabca", 1, 5);
+ x2("(ab|ca)+", "abzca", 0, 2);
+ x2("(a|bab)+", "ababa", 0, 5);
+ x2("(a|bab)+", "ba", 1, 2);
+ x2("(a|bab)+", "baaaba", 1, 4);
+ x2("(?:a|b)(?:a|b)", "ab", 0, 2);
+ x2("(?:a*|b*)(?:a*|b*)", "aaabbb", 0, 3);
+ x2("(?:a*|b*)(?:a+|b+)", "aaabbb", 0, 6);
+ x2("(?:a+|b+){2}", "aaabbb", 0, 6);
+ x2("h{0,}", "hhhh", 0, 4);
+ x2("(?:a+|b+){1,2}", "aaabbb", 0, 6);
+ n("ax{2}*a", "0axxxa1");
+ n("a.{0,2}a", "0aXXXa0");
+ n("a.{0,2}?a", "0aXXXa0");
+ n("a.{0,2}?a", "0aXXXXa0");
+ x2("^a{2,}?a$", "aaa", 0, 3);
+ x2("^[a-z]{2,}?$", "aaa", 0, 3);
+ x2("(?:a+|\\Ab*)cc", "cc", 0, 2);
+ n("(?:a+|\\Ab*)cc", "abcc");
+ x2("(?:^a+|b+)*c", "aabbbabc", 6, 8);
+ x2("(?:^a+|b+)*c", "aabbbbc", 0, 7);
+ x2("a|(?i)c", "C", 0, 1);
+ x2("(?i)c|a", "C", 0, 1);
+ x2("(?i)c|a", "A", 0, 1);
+ x2("(?i:c)|a", "C", 0, 1);
+ n("(?i:c)|a", "A");
+ x2("[abc]?", "abc", 0, 1);
+ x2("[abc]*", "abc", 0, 3);
+ x2("[^abc]*", "abc", 0, 0);
+ n("[^abc]+", "abc");
+ x2("a?\?", "aaa", 0, 0);
+ x2("ba?\?b", "bab", 0, 3);
+ x2("a*?", "aaa", 0, 0);
+ x2("ba*?", "baa", 0, 1);
+ x2("ba*?b", "baab", 0, 4);
+ x2("a+?", "aaa", 0, 1);
+ x2("ba+?", "baa", 0, 2);
+ x2("ba+?b", "baab", 0, 4);
+ x2("(?:a?)?\?", "a", 0, 0);
+ x2("(?:a?\?)?", "a", 0, 0);
+ x2("(?:a?)+?", "aaa", 0, 1);
+ x2("(?:a+)?\?", "aaa", 0, 0);
+ x2("(?:a+)?\?b", "aaab", 0, 4);
+ x2("(?:ab)?{2}", "", 0, 0);
+ x2("(?:ab)?{2}", "ababa", 0, 4);
+ x2("(?:ab)*{0}", "ababa", 0, 0);
+ x2("(?:ab){3,}", "abababab", 0, 8);
+ n("(?:ab){3,}", "abab");
+ x2("(?:ab){2,4}", "ababab", 0, 6);
+ x2("(?:ab){2,4}", "ababababab", 0, 8);
+ x2("(?:ab){2,4}?", "ababababab", 0, 4);
+ x2("(?:ab){,}", "ab{,}", 0, 5);
+ x2("(?:abc)+?{2}", "abcabcabc", 0, 6);
+ x2("(?:X*)(?i:xa)", "XXXa", 0, 4);
+ x2("(d+)([^abc]z)", "dddz", 0, 4);
+ x2("([^abc]*)([^abc]z)", "dddz", 0, 4);
+ x2("(\\w+)(\\wz)", "dddz", 0, 4);
+ x3("(a)", "a", 0, 1, 1);
+ x3("(ab)", "ab", 0, 2, 1);
+ x2("((ab))", "ab", 0, 2);
+ x3("((ab))", "ab", 0, 2, 1);
+ x3("((ab))", "ab", 0, 2, 2);
+ x3("((((((((((((((((((((ab))))))))))))))))))))", "ab", 0, 2, 20);
+ x3("(ab)(cd)", "abcd", 0, 2, 1);
+ x3("(ab)(cd)", "abcd", 2, 4, 2);
+ x3("()(a)bc(def)ghijk", "abcdefghijk", 3, 6, 3);
+ x3("(()(a)bc(def)ghijk)", "abcdefghijk", 3, 6, 4);
+ x2("(^a)", "a", 0, 1);
+ x3("(a)|(a)", "ba", 1, 2, 1);
+ x3("(^a)|(a)", "ba", 1, 2, 2);
+ x3("(a?)", "aaa", 0, 1, 1);
+ x3("(a*)", "aaa", 0, 3, 1);
+ x3("(a*)", "", 0, 0, 1);
+ x3("(a+)", "aaaaaaa", 0, 7, 1);
+ x3("(a+|b*)", "bbbaa", 0, 3, 1);
+ x3("(a+|b?)", "bbbaa", 0, 1, 1);
+ x3("(abc)?", "abc", 0, 3, 1);
+ x3("(abc)*", "abc", 0, 3, 1);
+ x3("(abc)+", "abc", 0, 3, 1);
+ x3("(xyz|abc)+", "abc", 0, 3, 1);
+ x3("([xyz][abc]|abc)+", "abc", 0, 3, 1);
+ x3("((?i:abc))", "AbC", 0, 3, 1);
+ x2("(abc)(?i:\\1)", "abcABC", 0, 6);
+ x3("((?m:a.c))", "a\nc", 0, 3, 1);
+ x3("((?=az)a)", "azb", 0, 1, 1);
+ x3("abc|(.abd)", "zabd", 0, 4, 1);
+ x2("(?:abc)|(ABC)", "abc", 0, 3);
+ x3("(?i:(abc))|(zzz)", "ABC", 0, 3, 1);
+ x3("a*(.)", "aaaaz", 4, 5, 1);
+ x3("a*?(.)", "aaaaz", 0, 1, 1);
+ x3("a*?(c)", "aaaac", 4, 5, 1);
+ x3("[bcd]a*(.)", "caaaaz", 5, 6, 1);
+ x3("(\\Abb)cc", "bbcc", 0, 2, 1);
+ n("(\\Abb)cc", "zbbcc");
+ x3("(^bb)cc", "bbcc", 0, 2, 1);
+ n("(^bb)cc", "zbbcc");
+ x3("cc(bb$)", "ccbb", 2, 4, 1);
+ n("cc(bb$)", "ccbbb");
+ n("(\\1)", "");
+ n("\\1(a)", "aa");
+ n("(a(b)\\1)\\2+", "ababb");
+ n("(?:(?:\\1|z)(a))+$", "zaa");
+ x2("(?:(?:\\1|z)(a))+$", "zaaa", 0, 4);
+ x2("(a)(?=\\1)", "aa", 0, 1);
+ n("(a)$|\\1", "az");
+ x2("(a)\\1", "aa", 0, 2);
+ n("(a)\\1", "ab");
+ x2("(a?)\\1", "aa", 0, 2);
+ x2("(a?\?)\\1", "aa", 0, 0);
+ x2("(a*)\\1", "aaaaa", 0, 4);
+ x3("(a*)\\1", "aaaaa", 0, 2, 1);
+ x2("a(b*)\\1", "abbbb", 0, 5);
+ x2("a(b*)\\1", "ab", 0, 1);
+ x2("(a*)(b*)\\1\\2", "aaabbaaabb", 0, 10);
+ x2("(a*)(b*)\\2", "aaabbbb", 0, 7);
+ x2("(((((((a*)b))))))c\\7", "aaabcaaa", 0, 8);
+ x3("(((((((a*)b))))))c\\7", "aaabcaaa", 0, 3, 7);
+ x2("(a)(b)(c)\\2\\1\\3", "abcbac", 0, 6);
+ x2("([a-d])\\1", "cc", 0, 2);
+ x2("(\\w\\d\\s)\\1", "f5 f5 ", 0, 6);
+ n("(\\w\\d\\s)\\1", "f5 f5");
+ x2("(who|[a-c]{3})\\1", "whowho", 0, 6);
+ x2("...(who|[a-c]{3})\\1", "abcwhowho", 0, 9);
+ x2("(who|[a-c]{3})\\1", "cbccbc", 0, 6);
+ x2("(^a)\\1", "aa", 0, 2);
+ n("(^a)\\1", "baa");
+ n("(a$)\\1", "aa");
+ n("(ab\\Z)\\1", "ab");
+ x2("(a*\\Z)\\1", "a", 1, 1);
+ x2(".(a*\\Z)\\1", "ba", 1, 2);
+ x3("(.(abc)\\2)", "zabcabc", 0, 7, 1);
+ x3("(.(..\\d.)\\2)", "z12341234", 0, 9, 1);
+ x2("((?i:az))\\1", "AzAz", 0, 4);
+ n("((?i:az))\\1", "Azaz");
+ x2("(?<=a)b", "ab", 1, 2);
+ n("(?<=a)b", "bb");
+ x2("(?<=a|b)b", "bb", 1, 2);
+ x2("(?<=a|bc)b", "bcb", 2, 3);
+ x2("(?<=a|bc)b", "ab", 1, 2);
+ x2("(?<=a|bc||defghij|klmnopq|r)z", "rz", 1, 2);
+ x2("(a)\\g<1>", "aa", 0, 2);
+ x2("(?<!a)b", "cb", 1, 2);
+ n("(?<!a)b", "ab");
+ x2("(?<!a|bc)b", "bbb", 0, 1);
+ n("(?<!a|bc)z", "bcz");
+ x2("(?<name1>a)", "a", 0, 1);
+ x2("(?<name_2>ab)\\g<name_2>", "abab", 0, 4);
+ x2("(?<name_3>.zv.)\\k<name_3>", "azvbazvb", 0, 8);
+ x2("(?<=\\g<ab>)|-\\zEND (?<ab>XyZ)", "XyZ", 3, 3);
+ x2("(?<n>|a\\g<n>)+", "", 0, 0);
+ x2("(?<n>|\\(\\g<n>\\))+$", "()(())", 0, 6);
+ x3("\\g<n>(?<n>.){0}", "X", 0, 1, 1);
+ x2("\\g<n>(abc|df(?<n>.YZ){2,8}){0}", "XYZ", 0, 3);
+ x2("\\A(?<n>(a\\g<n>)|)\\z", "aaaa", 0, 4);
+ x2("(?<n>|\\g<m>\\g<n>)\\z|\\zEND (?<m>a|(b)\\g<m>)", "bbbbabba", 0, 8);
+ x2("(?<name1240>\\w+\\sx)a+\\k<name1240>", " fg xaaaaaaaafg x", 2, 18);
+ x3("(z)()()(?<_9>a)\\g<_9>", "zaa", 2, 3, 1);
+ x2("(.)(((?<_>a)))\\k<_>", "zaa", 0, 3);
+ x2("((?<name1>\\d)|(?<name2>\\w))(\\k<name1>|\\k<name2>)", "ff", 0, 2);
+ x2("(?:(?<x>)|(?<x>efg))\\k<x>", "", 0, 0);
+ x2("(?:(?<x>abc)|(?<x>efg))\\k<x>", "abcefgefg", 3, 9);
+ n("(?:(?<x>abc)|(?<x>efg))\\k<x>", "abcefg");
+ x2("(?:(?<n1>.)|(?<n1>..)|(?<n1>...)|(?<n1>....)|(?<n1>.....)|(?<n1>......)|(?<n1>.......)|(?<n1>........)|(?<n1>.........)|(?<n1>..........)|(?<n1>...........)|(?<n1>............)|(?<n1>.............)|(?<n1>..............))\\k<n1>$", "a-pyumpyum", 2, 10);
+ x3("(?:(?<n1>.)|(?<n1>..)|(?<n1>...)|(?<n1>....)|(?<n1>.....)|(?<n1>......)|(?<n1>.......)|(?<n1>........)|(?<n1>.........)|(?<n1>..........)|(?<n1>...........)|(?<n1>............)|(?<n1>.............)|(?<n1>..............))\\k<n1>$", "xxxxabcdefghijklmnabcdefghijklmn", 4, 18, 14);
+ x3("(?<name1>)(?<name2>)(?<name3>)(?<name4>)(?<name5>)(?<name6>)(?<name7>)(?<name8>)(?<name9>)(?<name10>)(?<name11>)(?<name12>)(?<name13>)(?<name14>)(?<name15>)(?<name16>aaa)(?<name17>)$", "aaa", 0, 3, 16);
+ x2("(?<foo>a|\\(\\g<foo>\\))", "a", 0, 1);
+ x2("(?<foo>a|\\(\\g<foo>\\))", "((((((a))))))", 0, 13);
+ x3("(?<foo>a|\\(\\g<foo>\\))", "((((((((a))))))))", 0, 17, 1);
+ x2("\\g<bar>|\\zEND(?<bar>.*abc$)", "abcxxxabc", 0, 9);
+ x2("\\g<1>|\\zEND(.a.)", "bac", 0, 3);
+ x3("\\g<_A>\\g<_A>|\\zEND(.a.)(?<_A>.b.)", "xbxyby", 3, 6, 1);
+ x2("\\A(?:\\g<pon>|\\g<pan>|\\zEND (?<pan>a|c\\g<pon>c)(?<pon>b|d\\g<pan>d))$", "cdcbcdc", 0, 7);
+ x2("\\A(?<n>|a\\g<m>)\\z|\\zEND (?<m>\\g<n>)", "aaaa", 0, 4);
+ x2("(?<n>(a|b\\g<n>c){3,5})", "baaaaca", 1, 5);
+ x2("(?<n>(a|b\\g<n>c){3,5})", "baaaacaaaaa", 0, 10);
+ x2("(?<pare>\\(([^\\(\\)]++|\\g<pare>)*+\\))", "((a))", 0, 5);
+ x2("()*\\1", "", 0, 0);
+ x2("(?:()|())*\\1\\2", "", 0, 0);
+ x3("(?:\\1a|())*", "a", 0, 0, 1);
+ x2("x((.)*)*x", "0x1x2x3", 1, 6);
+ x2("x((.)*)*x(?i:\\1)\\Z", "0x1x2x1X2", 1, 9);
+ x2("(?:()|()|()|()|()|())*\\2\\5", "", 0, 0);
+ x2("(?:()|()|()|(x)|()|())*\\2b\\5", "b", 0, 1);
+ x2("\\xED\\xF2", "\xed\xf2", 0, 2);
+ x2("", "", 0, 0);
+ x2("", "", 0, 2);
+ n("", "");
+ x2("", "", 0, 4);
+ x2("", "", 0, 6);
+ x2("", "", 0, 70);
+ x2("", "", 2, 4);
+ x2("", "", 2, 6);
+ x2("\\xca\\xb8", "\xca\xb8", 0, 2);
+ x2(".", "", 0, 2);
+ x2("..", "", 0, 4);
+ x2("\\w", "", 0, 2);
+ n("\\W", "");
+ x2("[\\W]", "$", 2, 3);
+ x2("\\S", "", 0, 2);
+ x2("\\S", "", 0, 2);
+ x2("\\b", " ", 0, 0);
+ x2("\\b", " ", 1, 1);
+ x2("\\B", " ", 2, 2);
+ x2("\\B", " ", 3, 3);
+ x2("\\B", " ", 0, 0);
+ x2("[]", "", 0, 2);
+ n("[ʤ]", "");
+ x2("[-]", "", 0, 2);
+ n("[^]", "");
+ x2("[\\w]", "", 0, 2);
+ n("[\\d]", "");
+ x2("[\\D]", "", 0, 2);
+ n("[\\s]", "");
+ x2("[\\S]", "", 0, 2);
+ x2("[\\w\\d]", "", 0, 2);
+ x2("[\\w\\d]", " ", 3, 5);
+ n("\\w", " ");
+ x2("\\W", " ", 0, 5);
+ x2("..", "", 0, 10);
+ x2(".\\w\\W..", " ", 0, 13);
+ x2("\\s\\w", " ", 0, 9);
+ x2(".", "", 0, 8);
+ n(".", "");
+ x2(".", "", 0, 4);
+ x2("^", "", 0, 2);
+ x2("^$", "", 0, 2);
+ x2("^\\w$", "", 0, 2);
+ x2("^\\w$", "z", 0, 11);
+ x2("^\\w...$", "z", 0, 13);
+ x2("\\w\\w\\s\\W\\d", "a 4", 0, 12);
+ x2("\\A", "", 0, 6);
+ x2("\\Z", "", 0, 6);
+ x2("\\z", "", 0, 6);
+ x2("\\Z", "\n", 0, 6);
+ x2("\\Gݤ", "ݤ", 0, 4);
+ n("\\G", "");
+ n("Ȥ\\G", "Ȥ");
+ n("ޤ\\A", "ޤ");
+ n("\\A", "ޤ");
+ x2("(?=)", "", 0, 2);
+ n("(?=).", "");
+ x2("(?!)", "", 0, 2);
+ n("(?!)", "");
+ x2("(?i:)", "", 0, 2);
+ x2("(?i:֤)", "֤", 0, 4);
+ n("(?i:)", "");
+ x2("(?m:.)", "\n", 0, 3);
+ x2("(?m:.)", "\n", 2, 5);
+ x2("?", "", 0, 0);
+ x2("?", "", 0, 0);
+ x2("?", "", 0, 2);
+ x2("*", "", 0, 0);
+ x2("*", "", 0, 2);
+ x2("*", "һһ", 0, 6);
+ x2("*", "", 0, 0);
+ n("+", "");
+ x2("+", "", 0, 2);
+ x2("+", "", 0, 8);
+ x2("+", "", 0, 4);
+ x2("+", "", 2, 10);
+ x2(".?", "", 0, 2);
+ x2(".*", "ѤԤפ", 0, 8);
+ x2(".+", "", 0, 2);
+ x2(".+", "\n", 0, 8);
+ x2("|", "", 0, 2);
+ x2("|", "", 0, 2);
+ x2("|", "", 0, 4);
+ x2("|", "", 0, 4);
+ x2("(?:|)", "򤫤", 0, 6);
+ x2("(?:|)", "򤭤", 0, 8);
+ x2("|(?:|)", "", 0, 4);
+ x2("||", "", 2, 4);
+ x2("|||||||||ĤƤȤʤ|̤", "", 0, 6);
+ n("|||||||||ĤƤȤʤ|̤", "");
+ x2("|^", "֤", 2, 4);
+ x2("|^", "", 0, 2);
+ x2("|\\G", "ֵ", 4, 6);
+ x2("|\\G", "ֵ", 0, 2);
+ x2("|\\A", "bֵ", 3, 5);
+ x2("|\\A", "", 0, 2);
+ x2("|\\Z", "ֵ", 2, 4);
+ x2("|\\Z", "", 0, 2);
+ x2("|\\Z", "\n", 0, 2);
+ x2("|\\z", "ֵ", 2, 4);
+ x2("|\\z", "", 0, 2);
+ x2("\\w|\\s", "", 0, 2);
+ x2("\\w|%", "%", 0, 1);
+ x2("\\w|[&$]", "&", 0, 2);
+ x2("[-]", "", 0, 2);
+ x2("[-]|[^-]", "", 0, 2);
+ x2("[-]|[^-]", "", 0, 2);
+ x2("[^]", "\n", 0, 1);
+ x2("(?:|[-])|", "", 0, 2);
+ x2("(?:|[-])|", "", 0, 4);
+ x2("|(?=)..", "", 0, 6);
+ x2("|(?!)..", "", 0, 6);
+ x2("(?=)..|(?=)..", "", 0, 6);
+ x2("(?<=|)", "", 4, 6);
+ n("(?>|)", "");
+ x2("(?>|)", "", 0, 8);
+ x2("?|", "", 0, 2);
+ x2("?|", "", 0, 0);
+ x2("?|", "", 0, 0);
+ x2("*|", "", 0, 4);
+ x2("*|*", "", 0, 0);
+ x2("*|*", "", 0, 2);
+ x2("[a]*|*", "a", 0, 3);
+ x2("+|*", "", 0, 0);
+ x2("+|*", "", 0, 6);
+ x2("+|*", "", 0, 2);
+ x2("+|*", "a", 0, 0);
+ n("+|+", "");
+ x2("(|)?", "", 0, 2);
+ x2("(|)*", "", 0, 4);
+ x2("(|)+", "", 0, 6);
+ x2("(|)+", "", 0, 8);
+ x2("(|)+", "", 4, 12);
+ x2("(|)+", "", 2, 10);
+ x2("(|)+", "򤦤", 0, 4);
+ x2("(|)+", "$$zzzz򤦤", 6, 10);
+ x2("(|)+", "", 0, 10);
+ x2("(|)+", "", 2, 4);
+ x2("(|)+", "", 2, 8);
+ x2("(?:|)(?:|)", "", 0, 4);
+ x2("(?:*|*)(?:*|*)", "", 0, 6);
+ x2("(?:*|*)(?:+|+)", "", 0, 12);
+ x2("(?:+|+){2}", "", 0, 12);
+ x2("(?:+|+){1,2}", "", 0, 12);
+ x2("(?:+|\\A*)", "", 0, 4);
+ n("(?:+|\\A*)", "");
+ x2("(?:^+|+)*", "", 12, 16);
+ x2("(?:^+|+)*", "", 0, 14);
+ x2("{0,}", "", 0, 8);
+ x2("|(?i)c", "C", 0, 1);
+ x2("(?i)c|", "C", 0, 1);
+ x2("(?i:)|a", "a", 0, 1);
+ n("(?i:)|a", "A");
+ x2("[]?", "", 0, 2);
+ x2("[]*", "", 0, 6);
+ x2("[^]*", "", 0, 0);
+ n("[^]+", "");
+ x2("?\?", "", 0, 0);
+ x2("?\?", "", 0, 6);
+ x2("*?", "", 0, 0);
+ x2("*?", "", 0, 2);
+ x2("*?", "", 0, 8);
+ x2("+?", "", 0, 2);
+ x2("+?", "", 0, 4);
+ x2("+?", "", 0, 8);
+ x2("(?:ŷ?)?\?", "ŷ", 0, 0);
+ x2("(?:ŷ?\?)?", "ŷ", 0, 0);
+ x2("(?:̴?)+?", "̴̴̴", 0, 2);
+ x2("(?:+)?\?", "", 0, 0);
+ x2("(?:+)?\?", "", 0, 8);
+ x2("(?:)?{2}", "", 0, 0);
+ x2("(?:)?{2}", "ֵֵ", 0, 8);
+ x2("(?:)*{0}", "ֵֵ", 0, 0);
+ x2("(?:){3,}", "ֵֵֵ", 0, 16);
+ n("(?:){3,}", "ֵ");
+ x2("(?:){2,4}", "ֵֵ", 0, 12);
+ x2("(?:){2,4}", "ֵֵֵֵ", 0, 16);
+ x2("(?:){2,4}?", "ֵֵֵֵ", 0, 8);
+ x2("(?:){,}", "{,}", 0, 7);
+ x2("(?:)+?{2}", "", 0, 12);
+ x3("()", "", 0, 2, 1);
+ x3("(п)", "п", 0, 4, 1);
+ x2("(())", "", 0, 4);
+ x3("(())", "", 0, 4, 1);
+ x3("(())", "", 0, 4, 2);
+ x3("((((((((((((((((((((̻))))))))))))))))))))", "̻", 0, 4, 20);
+ x3("()()", "", 0, 4, 1);
+ x3("()()", "", 4, 8, 2);
+ x3("()()()", "", 6, 12, 3);
+ x3("(()()())", "", 6, 12, 4);
+ x3(".*(ե)󡦥(()奿)", "ե󡦥ޥ󥷥奿", 10, 18, 2);
+ x2("(^)", "", 0, 2);
+ x3("()|()", "", 2, 4, 1);
+ x3("(^)|()", "", 2, 4, 2);
+ x3("(?)", "", 0, 2, 1);
+ x3("(*)", "ޤޤ", 0, 6, 1);
+ x3("(*)", "", 0, 0, 1);
+ x3("(+)", "", 0, 14, 1);
+ x3("(+|*)", "դդդؤ", 0, 6, 1);
+ x3("(+|?)", "", 0, 2, 1);
+ x3("()?", "", 0, 6, 1);
+ x3("()*", "", 0, 6, 1);
+ x3("()+", "", 0, 6, 1);
+ x3("(|)+", "", 0, 6, 1);
+ x3("([ʤˤ][]|)+", "", 0, 6, 1);
+ x3("((?i:))", "", 0, 6, 1);
+ x3("((?m:.))", "\n", 0, 5, 1);
+ x3("((?=))", "", 0, 2, 1);
+ x3("|(.)", "󤢤", 0, 8, 1);
+ x3("*(.)", "", 8, 10, 1);
+ x3("*?(.)", "", 0, 2, 1);
+ x3("*?()", "", 8, 10, 1);
+ x3("[]*(.)", "", 10, 12, 1);
+ x3("(\\A)", "", 0, 4, 1);
+ n("(\\A)", "󤤤");
+ x3("(^)", "", 0, 4, 1);
+ n("(^)", "󤤤");
+ x3("($)", "", 4, 8, 1);
+ n("($)", "");
+ x2("(̵)\\1", "̵̵", 0, 4);
+ n("(̵)\\1", "̵");
+ x2("(?)\\1", "", 0, 4);
+ x2("(?\?)\\1", "", 0, 0);
+ x2("(*)\\1", "", 0, 8);
+ x3("(*)\\1", "", 0, 4, 1);
+ x2("(*)\\1", "", 0, 10);
+ x2("(*)\\1", "", 0, 2);
+ x2("(*)(*)\\1\\2", "", 0, 20);
+ x2("(*)(*)\\2", "", 0, 14);
+ x3("(*)(*)\\2", "", 6, 10, 2);
+ x2("(((((((*)))))))\\7", "ݤݤݤڤԤݤݤ", 0, 16);
+ x3("(((((((*)))))))\\7", "ݤݤݤڤԤݤݤ", 0, 6, 7);
+ x2("()()()\\2\\1\\3", "ϤҤդҤϤ", 0, 12);
+ x2("([-])\\1", "", 0, 4);
+ x2("(\\w\\d\\s)\\1", "5 5 ", 0, 8);
+ n("(\\w\\d\\s)\\1", "5 5");
+ x2("(ï|[-]{3})\\1", "ïï", 0, 8);
+ x2("...(ï|[-]{3})\\1", "aïï", 0, 13);
+ x2("(ï|[-]{3})\\1", "", 0, 12);
+ x2("(^)\\1", "", 0, 4);
+ n("(^)\\1", "");
+ n("($)\\1", "");
+ n("(\\Z)\\1", "");
+ x2("(*\\Z)\\1", "", 2, 2);
+ x2(".(*\\Z)\\1", "", 2, 4);
+ x3("(.(䤤)\\2)", "z䤤䤤", 0, 13, 1);
+ x3("(.(..\\d.)\\2)", "12341234", 0, 10, 1);
+ x2("((?i:v))\\1", "vv", 0, 10);
+ x2("(?<>|\\(\\g<>\\))", "(((((())))))", 0, 14);
+ x2("\\A(?:\\g<_1>|\\g<_2>|\\zλ (?<_1>|\\g<_2>)(?<_2>|\\g<_1>))$", "߼", 0, 26);
+ x2("[[Ҥ]]", "", 0, 2);
+ x2("[[]]", "", 0, 2);
+ n("[[^]]", "");
+ n("[^[]]", "");
+ x2("[^[^]]", "", 0, 2);
+ x2("[[]&&]", "", 0, 2);
+ n("[[]&&]", "");
+ n("[[]&&]", "");
+ x2("[-&&-&&-]", "", 0, 2);
+ n("[^-&&-&&-]", "");
+ x2("[[^&&]&&-]", "", 0, 2);
+ n("[[^&&]&&-]", "");
+ x2("[[^-&&]&&[^-]]", "", 0, 2);
+ n("[[^-&&]&&[^-]]", "");
+ x2("[^[^]&&[^]]", "", 0, 2);
+ x2("[^[^]&&[^]]", "", 0, 2);
+ n("[^[^]&&[^]]", "");
+ x2("[-&&-]", "-", 0, 1);
+ x2("[^[^a-z]&&[^bcdefg]q-w]", "", 0, 2);
+ x2("[^[^a-z]&&[^bcdefg]g-w]", "f", 0, 1);
+ x2("[^[^a-z]&&[^bcdefg]g-w]", "g", 0, 1);
+ n("[^[^a-z]&&[^bcdefg]g-w]", "2");
+ x2("a<b>СΥ<\\/b>", "a<b>СΥ</b>", 0, 32);
+ x2(".<b>СΥ<\\/b>", "a<b>СΥ</b>", 0, 32);
+ fprintf(stdout,
+ "\nRESULT SUCC: %d, FAIL: %d, ERROR: %d (by Oniguruma %s)\n",
+ nsucc, nfail, nerror, onig_version());
+
+#ifndef POSIX_TEST
+ onig_region_free(region, 1);
+ onig_end();
+#endif
+
+ return ((nfail == 0 && nerror == 0) ? 0 : -1);
+}
diff --git a/ext/mbstring/oniguruma/testu.c b/ext/mbstring/oniguruma/testu.c
new file mode 100644
index 0000000000..5652988ca9
--- /dev/null
+++ b/ext/mbstring/oniguruma/testu.c
@@ -0,0 +1,911 @@
+/*
+ * This program was generated by testconv.rb.
+ */
+#include<stdio.h>
+
+#ifdef POSIX_TEST
+#include "onigposix.h"
+#else
+#include "oniguruma.h"
+#endif
+
+static int nsucc = 0;
+static int nfail = 0;
+static int nerror = 0;
+
+static FILE* err_file;
+
+#ifndef POSIX_TEST
+static OnigRegion* region;
+static OnigEncoding ENC;
+#endif
+
+#define ulen(p) onigenc_str_bytelen_null(ENC, (UChar* )p)
+
+static void uconv(char* from, char* to, int len)
+{
+ int i;
+ unsigned char c;
+ char *q;
+
+ q = to;
+
+ for (i = 0; i < len; i += 2) {
+ c = (unsigned char )from[i];
+ if (c == 0) {
+ c = (unsigned char )from[i+1];
+ if (c < 0x20 || c >= 0x7f || c == 0x5c || c == 0x22) {
+ sprintf(q, "\\%03o", c);
+ q += 4;
+ }
+ else {
+ sprintf(q, "%c", c);
+ q++;
+ }
+ }
+ else {
+ sprintf(q, "\\%03o", c);
+ q += 4;
+ c = (unsigned char )from[i+1];
+ sprintf(q, "\\%03o", c);
+ q += 4;
+ }
+ }
+
+ *q = 0;
+}
+
+static void xx(char* pattern, char* str, int from, int to, int mem, int not)
+{
+ int r;
+ char cpat[4000], cstr[4000];
+
+#ifdef POSIX_TEST
+ regex_t reg;
+ char buf[200];
+ regmatch_t pmatch[20];
+
+ uconv(pattern, cpat, ulen(pattern));
+ uconv(str, cstr, ulen(str));
+
+ r = regcomp(&reg, pattern, REG_EXTENDED | REG_NEWLINE);
+ if (r) {
+ regerror(r, &reg, buf, sizeof(buf));
+ fprintf(err_file, "ERROR: %s\n", buf);
+ nerror++;
+ return ;
+ }
+
+ r = regexec(&reg, str, reg.re_nsub + 1, pmatch, 0);
+ if (r != 0 && r != REG_NOMATCH) {
+ regerror(r, &reg, buf, sizeof(buf));
+ fprintf(err_file, "ERROR: %s\n", buf);
+ nerror++;
+ return ;
+ }
+
+ if (r == REG_NOMATCH) {
+ if (not) {
+ fprintf(stdout, "OK(N): /%s/ '%s'\n", cpat, cstr);
+ nsucc++;
+ }
+ else {
+ fprintf(stdout, "FAIL: /%s/ '%s'\n", cpat, cstr);
+ nfail++;
+ }
+ }
+ else {
+ if (not) {
+ fprintf(stdout, "FAIL(N): /%s/ '%s'\n", cpat, cstr);
+ nfail++;
+ }
+ else {
+ if (pmatch[mem].rm_so == from && pmatch[mem].rm_eo == to) {
+ fprintf(stdout, "OK: /%s/ '%s'\n", cpat, cstr);
+ nsucc++;
+ }
+ else {
+ fprintf(stdout, "FAIL: /%s/ '%s' %d-%d : %d-%d\n", cpat, cstr,
+ from, to, pmatch[mem].rm_so, pmatch[mem].rm_eo);
+ nfail++;
+ }
+ }
+ }
+ regfree(&reg);
+
+#else
+ regex_t* reg;
+ OnigCompileInfo ci;
+ OnigErrorInfo einfo;
+
+ uconv(pattern, cpat, ulen(pattern));
+ uconv(str, cstr, ulen(str));
+
+#if 0
+ r = onig_new(&reg, (UChar* )pattern, (UChar* )(pattern + ulen(pattern)),
+ ONIG_OPTION_DEFAULT, ENC, ONIG_SYNTAX_DEFAULT, &einfo);
+#else
+ ci.num_of_elements = 5;
+ ci.pattern_enc = ENC;
+ ci.target_enc = ENC;
+ ci.syntax = ONIG_SYNTAX_DEFAULT;
+ ci.option = ONIG_OPTION_DEFAULT;
+ ci.case_fold_flag = ONIGENC_CASE_FOLD_DEFAULT;
+
+ r = onig_new_deluxe(&reg, (UChar* )pattern,
+ (UChar* )(pattern + ulen(pattern)),
+ &ci, &einfo);
+#endif
+
+ if (r) {
+ char s[ONIG_MAX_ERROR_MESSAGE_LEN];
+ onig_error_code_to_str(s, r, &einfo);
+ fprintf(err_file, "ERROR: %s\n", s);
+ nerror++;
+ return ;
+ }
+
+ r = onig_search(reg, (UChar* )str, (UChar* )(str + ulen(str)),
+ (UChar* )str, (UChar* )(str + ulen(str)),
+ region, ONIG_OPTION_NONE);
+ if (r < ONIG_MISMATCH) {
+ char s[ONIG_MAX_ERROR_MESSAGE_LEN];
+ onig_error_code_to_str(s, r);
+ fprintf(err_file, "ERROR: %s\n", s);
+ nerror++;
+ return ;
+ }
+
+ if (r == ONIG_MISMATCH) {
+ if (not) {
+ fprintf(stdout, "OK(N): /%s/ '%s'\n", cpat, cstr);
+ nsucc++;
+ }
+ else {
+ fprintf(stdout, "FAIL: /%s/ '%s'\n", cpat, cstr);
+ nfail++;
+ }
+ }
+ else {
+ if (not) {
+ fprintf(stdout, "FAIL(N): /%s/ '%s'\n", cpat, cstr);
+ nfail++;
+ }
+ else {
+ if (region->beg[mem] == from && region->end[mem] == to) {
+ fprintf(stdout, "OK: /%s/ '%s'\n", cpat, cstr);
+ nsucc++;
+ }
+ else {
+ fprintf(stdout, "FAIL: /%s/ '%s' %d-%d : %d-%d\n", cpat, cstr,
+ from, to, region->beg[mem], region->end[mem]);
+ nfail++;
+ }
+ }
+ }
+ onig_free(reg);
+#endif
+}
+
+static void x2(char* pattern, char* str, int from, int to)
+{
+ xx(pattern, str, from, to, 0, 0);
+}
+
+static void x3(char* pattern, char* str, int from, int to, int mem)
+{
+ xx(pattern, str, from, to, mem, 0);
+}
+
+static void n(char* pattern, char* str)
+{
+ xx(pattern, str, 0, 0, 0, 1);
+}
+
+extern int main(int argc, char* argv[])
+{
+ err_file = stdout;
+
+#ifndef POSIX_TEST
+ region = onig_region_new();
+#endif
+#ifdef POSIX_TEST
+ reg_set_encoding(REG_POSIX_ENCODING_UTF16_BE);
+#else
+ ENC = ONIG_ENCODING_UTF16_BE;
+#endif
+ x2("\000\000", "\000\000", 0, 0);
+ x2("\000^\000\000", "\000\000", 0, 0);
+ x2("\000$\000\000", "\000\000", 0, 0);
+ x2("\000\134\000G\000\000", "\000\000", 0, 0);
+ x2("\000\134\000A\000\000", "\000\000", 0, 0);
+ x2("\000\134\000Z\000\000", "\000\000", 0, 0);
+ x2("\000\134\000z\000\000", "\000\000", 0, 0);
+ x2("\000^\000$\000\000", "\000\000", 0, 0);
+ x2("\000\134\000c\000a\000\000", "\000\001\000\000", 0, 2);
+ x2("\000\134\000C\000-\000b\000\000", "\000\002\000\000", 0, 2);
+ x2("\000\134\000c\000\134\000\134\000\000", "\000\034\000\000", 0, 2);
+ x2("\000q\000[\000\134\000c\000\134\000\134\000]\000\000", "\000q\000\034\000\000", 0, 4);
+ x2("\000\000", "\000a\000\000", 0, 0);
+ x2("\000a\000\000", "\000a\000\000", 0, 2);
+ x2("\000\134\000x\0000\0000\000\134\000x\0006\0001\000\000", "\000a\000\000", 0, 2);
+ x2("\000a\000a\000\000", "\000a\000a\000\000", 0, 4);
+ x2("\000a\000a\000a\000\000", "\000a\000a\000a\000\000", 0, 6);
+ x2("\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000\000", "\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000a\000\000", 0, 70);
+ x2("\000a\000b\000\000", "\000a\000b\000\000", 0, 4);
+ x2("\000b\000\000", "\000a\000b\000\000", 2, 4);
+ x2("\000b\000c\000\000", "\000a\000b\000c\000\000", 2, 6);
+ x2("\000(\000?\000i\000:\000#\000R\000E\000T\000#\000)\000\000", "\000#\000I\000N\000S\000#\000#\000R\000E\000T\000#\000\000", 10, 20);
+ x2("\000\134\0000\0000\0000\000\134\0001\0007\000\000", "\000\017\000\000", 0, 2);
+ x2("\000\134\000x\0000\0000\000\134\000x\0001\000f\000\000", "\000\037\000\000", 0, 2);
+ x2("\000a\000(\000?\000#\000.\000.\000.\000.\000\134\000\134\000J\000J\000J\000J\000)\000b\000\000", "\000a\000b\000\000", 0, 4);
+ x2("\000(\000?\000x\000)\000 \000 \000G\000 \000(\000o\000 \000O\000(\000?\000-\000x\000)\000o\000O\000)\000 \000g\000 \000L\000\000", "\000G\000o\000O\000o\000O\000g\000L\000e\000\000", 0, 14);
+ x2("\000.\000\000", "\000a\000\000", 0, 2);
+ n("\000.\000\000", "\000\000");
+ x2("\000.\000.\000\000", "\000a\000b\000\000", 0, 4);
+ x2("\000\134\000w\000\000", "\000e\000\000", 0, 2);
+ n("\000\134\000W\000\000", "\000e\000\000");
+ x2("\000\134\000s\000\000", "\000 \000\000", 0, 2);
+ x2("\000\134\000S\000\000", "\000b\000\000", 0, 2);
+ x2("\000\134\000d\000\000", "\0004\000\000", 0, 2);
+ n("\000\134\000D\000\000", "\0004\000\000");
+ x2("\000\134\000b\000\000", "\000z\000 \000\000", 0, 0);
+ x2("\000\134\000b\000\000", "\000 \000z\000\000", 2, 2);
+ x2("\000\134\000B\000\000", "\000z\000z\000 \000\000", 2, 2);
+ x2("\000\134\000B\000\000", "\000z\000 \000\000", 4, 4);
+ x2("\000\134\000B\000\000", "\000 \000z\000\000", 0, 0);
+ x2("\000[\000a\000b\000]\000\000", "\000b\000\000", 0, 2);
+ n("\000[\000a\000b\000]\000\000", "\000c\000\000");
+ x2("\000[\000a\000-\000z\000]\000\000", "\000t\000\000", 0, 2);
+ n("\000[\000^\000a\000]\000\000", "\000a\000\000");
+ x2("\000[\000^\000a\000]\000\000", "\000\012\000\000", 0, 2);
+ x2("\000[\000]\000]\000\000", "\000]\000\000", 0, 2);
+ n("\000[\000^\000]\000]\000\000", "\000]\000\000");
+ x2("\000[\000\134\000^\000]\000+\000\000", "\0000\000^\000^\0001\000\000", 2, 6);
+ x2("\000[\000b\000-\000]\000\000", "\000b\000\000", 0, 2);
+ x2("\000[\000b\000-\000]\000\000", "\000-\000\000", 0, 2);
+ x2("\000[\000\134\000w\000]\000\000", "\000z\000\000", 0, 2);
+ n("\000[\000\134\000w\000]\000\000", "\000 \000\000");
+ x2("\000[\000\134\000W\000]\000\000", "\000b\000$\000\000", 2, 4);
+ x2("\000[\000\134\000d\000]\000\000", "\0005\000\000", 0, 2);
+ n("\000[\000\134\000d\000]\000\000", "\000e\000\000");
+ x2("\000[\000\134\000D\000]\000\000", "\000t\000\000", 0, 2);
+ n("\000[\000\134\000D\000]\000\000", "\0003\000\000");
+ x2("\000[\000\134\000s\000]\000\000", "\000 \000\000", 0, 2);
+ n("\000[\000\134\000s\000]\000\000", "\000a\000\000");
+ x2("\000[\000\134\000S\000]\000\000", "\000b\000\000", 0, 2);
+ n("\000[\000\134\000S\000]\000\000", "\000 \000\000");
+ x2("\000[\000\134\000w\000\134\000d\000]\000\000", "\0002\000\000", 0, 2);
+ n("\000[\000\134\000w\000\134\000d\000]\000\000", "\000 \000\000");
+ x2("\000[\000[\000:\000u\000p\000p\000e\000r\000:\000]\000]\000\000", "\000B\000\000", 0, 2);
+ x2("\000[\000*\000[\000:\000x\000d\000i\000g\000i\000t\000:\000]\000+\000]\000\000", "\000+\000\000", 0, 2);
+ x2("\000[\000*\000[\000:\000x\000d\000i\000g\000i\000t\000:\000]\000+\000]\000\000", "\000G\000H\000I\000K\000K\000-\0009\000+\000*\000\000", 12, 14);
+ x2("\000[\000*\000[\000:\000x\000d\000i\000g\000i\000t\000:\000]\000+\000]\000\000", "\000-\000@\000^\000+\000\000", 6, 8);
+ n("\000[\000[\000:\000u\000p\000p\000e\000r\000]\000]\000\000", "\000A\000\000");
+ x2("\000[\000[\000:\000u\000p\000p\000e\000r\000]\000]\000\000", "\000:\000\000", 0, 2);
+ x2("\000[\000\134\0000\0000\0000\000\134\0000\0004\0004\000-\000\134\0000\0000\0000\000\134\0000\0004\0007\000]\000\000", "\000&\000\000", 0, 2);
+ x2("\000[\000\134\000x\0000\0000\000\134\000x\0005\000a\000-\000\134\000x\0000\0000\000\134\000x\0005\000c\000]\000\000", "\000[\000\000", 0, 2);
+ x2("\000[\000\134\000x\0000\0000\000\134\000x\0006\000A\000-\000\134\000x\0000\0000\000\134\000x\0006\000D\000]\000\000", "\000l\000\000", 0, 2);
+ n("\000[\000\134\000x\0000\0000\000\134\000x\0006\000A\000-\000\134\000x\0000\0000\000\134\000x\0006\000D\000]\000\000", "\000n\000\000");
+ n("\000^\000[\0000\000-\0009\000A\000-\000F\000]\000+\000 \0000\000+\000 \000U\000N\000D\000E\000F\000 \000\000", "\0007\0005\000F\000 \0000\0000\0000\0000\0000\0000\0000\0000\000 \000S\000E\000C\000T\0001\0004\000A\000 \000n\000o\000t\000y\000p\000e\000 \000(\000)\000 \000 \000 \000 \000E\000x\000t\000e\000r\000n\000a\000l\000 \000 \000 \000 \000|\000 \000_\000r\000b\000_\000a\000p\000p\000l\000y\000\000");
+ x2("\000[\000\134\000[\000]\000\000", "\000[\000\000", 0, 2);
+ x2("\000[\000\134\000]\000]\000\000", "\000]\000\000", 0, 2);
+ x2("\000[\000&\000]\000\000", "\000&\000\000", 0, 2);
+ x2("\000[\000[\000a\000b\000]\000]\000\000", "\000b\000\000", 0, 2);
+ x2("\000[\000[\000a\000b\000]\000c\000]\000\000", "\000c\000\000", 0, 2);
+ n("\000[\000[\000^\000a\000]\000]\000\000", "\000a\000\000");
+ n("\000[\000^\000[\000a\000]\000]\000\000", "\000a\000\000");
+ x2("\000[\000[\000a\000b\000]\000&\000&\000b\000c\000]\000\000", "\000b\000\000", 0, 2);
+ n("\000[\000[\000a\000b\000]\000&\000&\000b\000c\000]\000\000", "\000a\000\000");
+ n("\000[\000[\000a\000b\000]\000&\000&\000b\000c\000]\000\000", "\000c\000\000");
+ x2("\000[\000a\000-\000z\000&\000&\000b\000-\000y\000&\000&\000c\000-\000x\000]\000\000", "\000w\000\000", 0, 2);
+ n("\000[\000^\000a\000-\000z\000&\000&\000b\000-\000y\000&\000&\000c\000-\000x\000]\000\000", "\000w\000\000");
+ x2("\000[\000[\000^\000a\000&\000&\000a\000]\000&\000&\000a\000-\000z\000]\000\000", "\000b\000\000", 0, 2);
+ n("\000[\000[\000^\000a\000&\000&\000a\000]\000&\000&\000a\000-\000z\000]\000\000", "\000a\000\000");
+ x2("\000[\000[\000^\000a\000-\000z\000&\000&\000b\000c\000d\000e\000f\000]\000&\000&\000[\000^\000c\000-\000g\000]\000]\000\000", "\000h\000\000", 0, 2);
+ n("\000[\000[\000^\000a\000-\000z\000&\000&\000b\000c\000d\000e\000f\000]\000&\000&\000[\000^\000c\000-\000g\000]\000]\000\000", "\000c\000\000");
+ x2("\000[\000^\000[\000^\000a\000b\000c\000]\000&\000&\000[\000^\000c\000d\000e\000]\000]\000\000", "\000c\000\000", 0, 2);
+ x2("\000[\000^\000[\000^\000a\000b\000c\000]\000&\000&\000[\000^\000c\000d\000e\000]\000]\000\000", "\000e\000\000", 0, 2);
+ n("\000[\000^\000[\000^\000a\000b\000c\000]\000&\000&\000[\000^\000c\000d\000e\000]\000]\000\000", "\000f\000\000");
+ x2("\000[\000a\000-\000&\000&\000-\000a\000]\000\000", "\000-\000\000", 0, 2);
+ n("\000[\000a\000\134\000-\000&\000&\000\134\000-\000a\000]\000\000", "\000&\000\000");
+ n("\000\134\000w\000a\000b\000c\000\000", "\000 \000a\000b\000c\000\000");
+ x2("\000a\000\134\000W\000b\000c\000\000", "\000a\000 \000b\000c\000\000", 0, 8);
+ x2("\000a\000.\000b\000.\000c\000\000", "\000a\000a\000b\000b\000c\000\000", 0, 10);
+ x2("\000.\000\134\000w\000b\000\134\000W\000.\000.\000c\000\000", "\000a\000b\000b\000 \000b\000c\000c\000\000", 0, 14);
+ x2("\000\134\000s\000\134\000w\000z\000z\000z\000\000", "\000 \000z\000z\000z\000z\000\000", 0, 10);
+ x2("\000a\000a\000.\000b\000\000", "\000a\000a\000b\000b\000\000", 0, 8);
+ n("\000.\000a\000\000", "\000a\000b\000\000");
+ x2("\000.\000a\000\000", "\000a\000a\000\000", 0, 4);
+ x2("\000^\000a\000\000", "\000a\000\000", 0, 2);
+ x2("\000^\000a\000$\000\000", "\000a\000\000", 0, 2);
+ x2("\000^\000\134\000w\000$\000\000", "\000a\000\000", 0, 2);
+ n("\000^\000\134\000w\000$\000\000", "\000 \000\000");
+ x2("\000^\000\134\000w\000a\000b\000$\000\000", "\000z\000a\000b\000\000", 0, 6);
+ x2("\000^\000\134\000w\000a\000b\000c\000d\000e\000f\000$\000\000", "\000z\000a\000b\000c\000d\000e\000f\000\000", 0, 14);
+ x2("\000^\000\134\000w\000.\000.\000.\000d\000e\000f\000$\000\000", "\000z\000a\000b\000c\000d\000e\000f\000\000", 0, 14);
+ x2("\000\134\000w\000\134\000w\000\134\000s\000\134\000W\000a\000a\000a\000\134\000d\000\000", "\000a\000a\000 \000 \000a\000a\000a\0004\000\000", 0, 16);
+ x2("\000\134\000A\000\134\000Z\000\000", "\000\000", 0, 0);
+ x2("\000\134\000A\000x\000y\000z\000\000", "\000x\000y\000z\000\000", 0, 6);
+ x2("\000x\000y\000z\000\134\000Z\000\000", "\000x\000y\000z\000\000", 0, 6);
+ x2("\000x\000y\000z\000\134\000z\000\000", "\000x\000y\000z\000\000", 0, 6);
+ x2("\000a\000\134\000Z\000\000", "\000a\000\000", 0, 2);
+ x2("\000\134\000G\000a\000z\000\000", "\000a\000z\000\000", 0, 4);
+ n("\000\134\000G\000z\000\000", "\000b\000z\000a\000\000");
+ n("\000a\000z\000\134\000G\000\000", "\000a\000z\000\000");
+ n("\000a\000z\000\134\000A\000\000", "\000a\000z\000\000");
+ n("\000a\000\134\000A\000z\000\000", "\000a\000z\000\000");
+ x2("\000\134\000^\000\134\000$\000\000", "\000^\000$\000\000", 0, 4);
+ x2("\000^\000x\000?\000y\000\000", "\000x\000y\000\000", 0, 4);
+ x2("\000^\000(\000x\000?\000y\000)\000\000", "\000x\000y\000\000", 0, 4);
+ x2("\000\134\000w\000\000", "\000_\000\000", 0, 2);
+ n("\000\134\000W\000\000", "\000_\000\000");
+ x2("\000(\000?\000=\000z\000)\000z\000\000", "\000z\000\000", 0, 2);
+ n("\000(\000?\000=\000z\000)\000.\000\000", "\000a\000\000");
+ x2("\000(\000?\000!\000z\000)\000a\000\000", "\000a\000\000", 0, 2);
+ n("\000(\000?\000!\000z\000)\000a\000\000", "\000z\000\000");
+ x2("\000(\000?\000i\000:\000a\000)\000\000", "\000a\000\000", 0, 2);
+ x2("\000(\000?\000i\000:\000a\000)\000\000", "\000A\000\000", 0, 2);
+ x2("\000(\000?\000i\000:\000A\000)\000\000", "\000a\000\000", 0, 2);
+ n("\000(\000?\000i\000:\000A\000)\000\000", "\000b\000\000");
+ x2("\000(\000?\000i\000:\000[\000A\000-\000Z\000]\000)\000\000", "\000a\000\000", 0, 2);
+ x2("\000(\000?\000i\000:\000[\000f\000-\000m\000]\000)\000\000", "\000H\000\000", 0, 2);
+ x2("\000(\000?\000i\000:\000[\000f\000-\000m\000]\000)\000\000", "\000h\000\000", 0, 2);
+ n("\000(\000?\000i\000:\000[\000f\000-\000m\000]\000)\000\000", "\000e\000\000");
+ x2("\000(\000?\000i\000:\000[\000A\000-\000c\000]\000)\000\000", "\000D\000\000", 0, 2);
+ n("\000(\000?\000i\000:\000[\000^\000a\000-\000z\000]\000)\000\000", "\000A\000\000");
+ n("\000(\000?\000i\000:\000[\000^\000a\000-\000z\000]\000)\000\000", "\000a\000\000");
+ x2("\000(\000?\000i\000:\000[\000!\000-\000k\000]\000)\000\000", "\000Z\000\000", 0, 2);
+ x2("\000(\000?\000i\000:\000[\000!\000-\000k\000]\000)\000\000", "\0007\000\000", 0, 2);
+ x2("\000(\000?\000i\000:\000[\000T\000-\000}\000]\000)\000\000", "\000b\000\000", 0, 2);
+ x2("\000(\000?\000i\000:\000[\000T\000-\000}\000]\000)\000\000", "\000{\000\000", 0, 2);
+ x2("\000(\000?\000i\000:\000\134\000?\000a\000)\000\000", "\000?\000A\000\000", 0, 4);
+ x2("\000(\000?\000i\000:\000\134\000*\000A\000)\000\000", "\000*\000a\000\000", 0, 4);
+ n("\000.\000\000", "\000\012\000\000");
+ x2("\000(\000?\000m\000:\000.\000)\000\000", "\000\012\000\000", 0, 2);
+ x2("\000(\000?\000m\000:\000a\000.\000)\000\000", "\000a\000\012\000\000", 0, 4);
+ x2("\000(\000?\000m\000:\000.\000b\000)\000\000", "\000a\000\012\000b\000\000", 2, 6);
+ x2("\000.\000*\000a\000b\000c\000\000", "\000d\000d\000d\000a\000b\000d\000d\000\012\000d\000d\000a\000b\000c\000\000", 16, 26);
+ x2("\000(\000?\000m\000:\000.\000*\000a\000b\000c\000)\000\000", "\000d\000d\000d\000a\000b\000d\000d\000a\000b\000c\000\000", 0, 20);
+ n("\000(\000?\000i\000)\000(\000?\000-\000i\000)\000a\000\000", "\000A\000\000");
+ n("\000(\000?\000i\000)\000(\000?\000-\000i\000:\000a\000)\000\000", "\000A\000\000");
+ x2("\000a\000?\000\000", "\000\000", 0, 0);
+ x2("\000a\000?\000\000", "\000b\000\000", 0, 0);
+ x2("\000a\000?\000\000", "\000a\000\000", 0, 2);
+ x2("\000a\000*\000\000", "\000\000", 0, 0);
+ x2("\000a\000*\000\000", "\000a\000\000", 0, 2);
+ x2("\000a\000*\000\000", "\000a\000a\000a\000\000", 0, 6);
+ x2("\000a\000*\000\000", "\000b\000a\000a\000a\000a\000\000", 0, 0);
+ n("\000a\000+\000\000", "\000\000");
+ x2("\000a\000+\000\000", "\000a\000\000", 0, 2);
+ x2("\000a\000+\000\000", "\000a\000a\000a\000a\000\000", 0, 8);
+ x2("\000a\000+\000\000", "\000a\000a\000b\000b\000b\000\000", 0, 4);
+ x2("\000a\000+\000\000", "\000b\000a\000a\000a\000a\000\000", 2, 10);
+ x2("\000.\000?\000\000", "\000\000", 0, 0);
+ x2("\000.\000?\000\000", "\000f\000\000", 0, 2);
+ x2("\000.\000?\000\000", "\000\012\000\000", 0, 0);
+ x2("\000.\000*\000\000", "\000\000", 0, 0);
+ x2("\000.\000*\000\000", "\000a\000b\000c\000d\000e\000\000", 0, 10);
+ x2("\000.\000+\000\000", "\000z\000\000", 0, 2);
+ x2("\000.\000+\000\000", "\000z\000d\000s\000w\000e\000r\000\012\000\000", 0, 12);
+ x2("\000(\000.\000*\000)\000a\000\134\0001\000f\000\000", "\000b\000a\000b\000f\000b\000a\000c\000\000", 0, 8);
+ x2("\000(\000.\000*\000)\000a\000\134\0001\000f\000\000", "\000b\000a\000c\000b\000a\000b\000f\000\000", 6, 14);
+ x2("\000(\000(\000.\000*\000)\000a\000\134\0002\000f\000)\000\000", "\000b\000a\000c\000b\000a\000b\000f\000\000", 6, 14);
+ x2("\000(\000.\000*\000)\000a\000\134\0001\000f\000\000", "\000b\000a\000c\000z\000z\000z\000z\000z\000z\000\012\000b\000a\000z\000z\000\012\000z\000z\000z\000z\000b\000a\000b\000f\000\000", 38, 46);
+ x2("\000a\000|\000b\000\000", "\000a\000\000", 0, 2);
+ x2("\000a\000|\000b\000\000", "\000b\000\000", 0, 2);
+ x2("\000|\000a\000\000", "\000a\000\000", 0, 0);
+ x2("\000(\000|\000a\000)\000\000", "\000a\000\000", 0, 0);
+ x2("\000a\000b\000|\000b\000c\000\000", "\000a\000b\000\000", 0, 4);
+ x2("\000a\000b\000|\000b\000c\000\000", "\000b\000c\000\000", 0, 4);
+ x2("\000z\000(\000?\000:\000a\000b\000|\000b\000c\000)\000\000", "\000z\000b\000c\000\000", 0, 6);
+ x2("\000a\000(\000?\000:\000a\000b\000|\000b\000c\000)\000c\000\000", "\000a\000a\000b\000c\000\000", 0, 8);
+ x2("\000a\000b\000|\000(\000?\000:\000a\000c\000|\000a\000z\000)\000\000", "\000a\000z\000\000", 0, 4);
+ x2("\000a\000|\000b\000|\000c\000\000", "\000d\000c\000\000", 2, 4);
+ x2("\000a\000|\000b\000|\000c\000d\000|\000e\000f\000g\000|\000h\000|\000i\000j\000k\000|\000l\000m\000n\000|\000o\000|\000p\000q\000|\000r\000s\000t\000u\000v\000w\000x\000|\000y\000z\000\000", "\000p\000q\000r\000\000", 0, 4);
+ n("\000a\000|\000b\000|\000c\000d\000|\000e\000f\000g\000|\000h\000|\000i\000j\000k\000|\000l\000m\000n\000|\000o\000|\000p\000q\000|\000r\000s\000t\000u\000v\000w\000x\000|\000y\000z\000\000", "\000m\000n\000\000");
+ x2("\000a\000|\000^\000z\000\000", "\000b\000a\000\000", 2, 4);
+ x2("\000a\000|\000^\000z\000\000", "\000z\000a\000\000", 0, 2);
+ x2("\000a\000|\000\134\000G\000z\000\000", "\000b\000z\000a\000\000", 4, 6);
+ x2("\000a\000|\000\134\000G\000z\000\000", "\000z\000a\000\000", 0, 2);
+ x2("\000a\000|\000\134\000A\000z\000\000", "\000b\000z\000a\000\000", 4, 6);
+ x2("\000a\000|\000\134\000A\000z\000\000", "\000z\000a\000\000", 0, 2);
+ x2("\000a\000|\000b\000\134\000Z\000\000", "\000b\000a\000\000", 2, 4);
+ x2("\000a\000|\000b\000\134\000Z\000\000", "\000b\000\000", 0, 2);
+ x2("\000a\000|\000b\000\134\000z\000\000", "\000b\000a\000\000", 2, 4);
+ x2("\000a\000|\000b\000\134\000z\000\000", "\000b\000\000", 0, 2);
+ x2("\000\134\000w\000|\000\134\000s\000\000", "\000 \000\000", 0, 2);
+ n("\000\134\000w\000|\000\134\000w\000\000", "\000 \000\000");
+ x2("\000\134\000w\000|\000%\000\000", "\000%\000\000", 0, 2);
+ x2("\000\134\000w\000|\000[\000&\000$\000]\000\000", "\000&\000\000", 0, 2);
+ x2("\000[\000b\000-\000d\000]\000|\000[\000^\000e\000-\000z\000]\000\000", "\000a\000\000", 0, 2);
+ x2("\000(\000?\000:\000a\000|\000[\000c\000-\000f\000]\000)\000|\000b\000z\000\000", "\000d\000z\000\000", 0, 2);
+ x2("\000(\000?\000:\000a\000|\000[\000c\000-\000f\000]\000)\000|\000b\000z\000\000", "\000b\000z\000\000", 0, 4);
+ x2("\000a\000b\000c\000|\000(\000?\000=\000z\000z\000)\000.\000.\000f\000\000", "\000z\000z\000f\000\000", 0, 6);
+ x2("\000a\000b\000c\000|\000(\000?\000!\000z\000z\000)\000.\000.\000f\000\000", "\000a\000b\000f\000\000", 0, 6);
+ x2("\000(\000?\000=\000z\000a\000)\000.\000.\000a\000|\000(\000?\000=\000z\000z\000)\000.\000.\000a\000\000", "\000z\000z\000a\000\000", 0, 6);
+ n("\000(\000?\000>\000a\000|\000a\000b\000d\000)\000c\000\000", "\000a\000b\000d\000c\000\000");
+ x2("\000(\000?\000>\000a\000b\000d\000|\000a\000)\000c\000\000", "\000a\000b\000d\000c\000\000", 0, 8);
+ x2("\000a\000?\000|\000b\000\000", "\000a\000\000", 0, 2);
+ x2("\000a\000?\000|\000b\000\000", "\000b\000\000", 0, 0);
+ x2("\000a\000?\000|\000b\000\000", "\000\000", 0, 0);
+ x2("\000a\000*\000|\000b\000\000", "\000a\000a\000\000", 0, 4);
+ x2("\000a\000*\000|\000b\000*\000\000", "\000b\000a\000\000", 0, 0);
+ x2("\000a\000*\000|\000b\000*\000\000", "\000a\000b\000\000", 0, 2);
+ x2("\000a\000+\000|\000b\000*\000\000", "\000\000", 0, 0);
+ x2("\000a\000+\000|\000b\000*\000\000", "\000b\000b\000b\000\000", 0, 6);
+ x2("\000a\000+\000|\000b\000*\000\000", "\000a\000b\000b\000b\000\000", 0, 2);
+ n("\000a\000+\000|\000b\000+\000\000", "\000\000");
+ x2("\000(\000a\000|\000b\000)\000?\000\000", "\000b\000\000", 0, 2);
+ x2("\000(\000a\000|\000b\000)\000*\000\000", "\000b\000a\000\000", 0, 4);
+ x2("\000(\000a\000|\000b\000)\000+\000\000", "\000b\000a\000b\000\000", 0, 6);
+ x2("\000(\000a\000b\000|\000c\000a\000)\000+\000\000", "\000c\000a\000a\000b\000b\000c\000\000", 0, 8);
+ x2("\000(\000a\000b\000|\000c\000a\000)\000+\000\000", "\000a\000a\000b\000c\000a\000\000", 2, 10);
+ x2("\000(\000a\000b\000|\000c\000a\000)\000+\000\000", "\000a\000b\000z\000c\000a\000\000", 0, 4);
+ x2("\000(\000a\000|\000b\000a\000b\000)\000+\000\000", "\000a\000b\000a\000b\000a\000\000", 0, 10);
+ x2("\000(\000a\000|\000b\000a\000b\000)\000+\000\000", "\000b\000a\000\000", 2, 4);
+ x2("\000(\000a\000|\000b\000a\000b\000)\000+\000\000", "\000b\000a\000a\000a\000b\000a\000\000", 2, 8);
+ x2("\000(\000?\000:\000a\000|\000b\000)\000(\000?\000:\000a\000|\000b\000)\000\000", "\000a\000b\000\000", 0, 4);
+ x2("\000(\000?\000:\000a\000*\000|\000b\000*\000)\000(\000?\000:\000a\000*\000|\000b\000*\000)\000\000", "\000a\000a\000a\000b\000b\000b\000\000", 0, 6);
+ x2("\000(\000?\000:\000a\000*\000|\000b\000*\000)\000(\000?\000:\000a\000+\000|\000b\000+\000)\000\000", "\000a\000a\000a\000b\000b\000b\000\000", 0, 12);
+ x2("\000(\000?\000:\000a\000+\000|\000b\000+\000)\000{\0002\000}\000\000", "\000a\000a\000a\000b\000b\000b\000\000", 0, 12);
+ x2("\000h\000{\0000\000,\000}\000\000", "\000h\000h\000h\000h\000\000", 0, 8);
+ x2("\000(\000?\000:\000a\000+\000|\000b\000+\000)\000{\0001\000,\0002\000}\000\000", "\000a\000a\000a\000b\000b\000b\000\000", 0, 12);
+ n("\000a\000x\000{\0002\000}\000*\000a\000\000", "\0000\000a\000x\000x\000x\000a\0001\000\000");
+ n("\000a\000.\000{\0000\000,\0002\000}\000a\000\000", "\0000\000a\000X\000X\000X\000a\0000\000\000");
+ n("\000a\000.\000{\0000\000,\0002\000}\000?\000a\000\000", "\0000\000a\000X\000X\000X\000a\0000\000\000");
+ n("\000a\000.\000{\0000\000,\0002\000}\000?\000a\000\000", "\0000\000a\000X\000X\000X\000X\000a\0000\000\000");
+ x2("\000^\000a\000{\0002\000,\000}\000?\000a\000$\000\000", "\000a\000a\000a\000\000", 0, 6);
+ x2("\000^\000[\000a\000-\000z\000]\000{\0002\000,\000}\000?\000$\000\000", "\000a\000a\000a\000\000", 0, 6);
+ x2("\000(\000?\000:\000a\000+\000|\000\134\000A\000b\000*\000)\000c\000c\000\000", "\000c\000c\000\000", 0, 4);
+ n("\000(\000?\000:\000a\000+\000|\000\134\000A\000b\000*\000)\000c\000c\000\000", "\000a\000b\000c\000c\000\000");
+ x2("\000(\000?\000:\000^\000a\000+\000|\000b\000+\000)\000*\000c\000\000", "\000a\000a\000b\000b\000b\000a\000b\000c\000\000", 12, 16);
+ x2("\000(\000?\000:\000^\000a\000+\000|\000b\000+\000)\000*\000c\000\000", "\000a\000a\000b\000b\000b\000b\000c\000\000", 0, 14);
+ x2("\000a\000|\000(\000?\000i\000)\000c\000\000", "\000C\000\000", 0, 2);
+ x2("\000(\000?\000i\000)\000c\000|\000a\000\000", "\000C\000\000", 0, 2);
+ x2("\000(\000?\000i\000)\000c\000|\000a\000\000", "\000A\000\000", 0, 2);
+ x2("\000(\000?\000i\000:\000c\000)\000|\000a\000\000", "\000C\000\000", 0, 2);
+ n("\000(\000?\000i\000:\000c\000)\000|\000a\000\000", "\000A\000\000");
+ x2("\000[\000a\000b\000c\000]\000?\000\000", "\000a\000b\000c\000\000", 0, 2);
+ x2("\000[\000a\000b\000c\000]\000*\000\000", "\000a\000b\000c\000\000", 0, 6);
+ x2("\000[\000^\000a\000b\000c\000]\000*\000\000", "\000a\000b\000c\000\000", 0, 0);
+ n("\000[\000^\000a\000b\000c\000]\000+\000\000", "\000a\000b\000c\000\000");
+ x2("\000a\000?\000?\000\000", "\000a\000a\000a\000\000", 0, 0);
+ x2("\000b\000a\000?\000?\000b\000\000", "\000b\000a\000b\000\000", 0, 6);
+ x2("\000a\000*\000?\000\000", "\000a\000a\000a\000\000", 0, 0);
+ x2("\000b\000a\000*\000?\000\000", "\000b\000a\000a\000\000", 0, 2);
+ x2("\000b\000a\000*\000?\000b\000\000", "\000b\000a\000a\000b\000\000", 0, 8);
+ x2("\000a\000+\000?\000\000", "\000a\000a\000a\000\000", 0, 2);
+ x2("\000b\000a\000+\000?\000\000", "\000b\000a\000a\000\000", 0, 4);
+ x2("\000b\000a\000+\000?\000b\000\000", "\000b\000a\000a\000b\000\000", 0, 8);
+ x2("\000(\000?\000:\000a\000?\000)\000?\000?\000\000", "\000a\000\000", 0, 0);
+ x2("\000(\000?\000:\000a\000?\000?\000)\000?\000\000", "\000a\000\000", 0, 0);
+ x2("\000(\000?\000:\000a\000?\000)\000+\000?\000\000", "\000a\000a\000a\000\000", 0, 2);
+ x2("\000(\000?\000:\000a\000+\000)\000?\000?\000\000", "\000a\000a\000a\000\000", 0, 0);
+ x2("\000(\000?\000:\000a\000+\000)\000?\000?\000b\000\000", "\000a\000a\000a\000b\000\000", 0, 8);
+ x2("\000(\000?\000:\000a\000b\000)\000?\000{\0002\000}\000\000", "\000\000", 0, 0);
+ x2("\000(\000?\000:\000a\000b\000)\000?\000{\0002\000}\000\000", "\000a\000b\000a\000b\000a\000\000", 0, 8);
+ x2("\000(\000?\000:\000a\000b\000)\000*\000{\0000\000}\000\000", "\000a\000b\000a\000b\000a\000\000", 0, 0);
+ x2("\000(\000?\000:\000a\000b\000)\000{\0003\000,\000}\000\000", "\000a\000b\000a\000b\000a\000b\000a\000b\000\000", 0, 16);
+ n("\000(\000?\000:\000a\000b\000)\000{\0003\000,\000}\000\000", "\000a\000b\000a\000b\000\000");
+ x2("\000(\000?\000:\000a\000b\000)\000{\0002\000,\0004\000}\000\000", "\000a\000b\000a\000b\000a\000b\000\000", 0, 12);
+ x2("\000(\000?\000:\000a\000b\000)\000{\0002\000,\0004\000}\000\000", "\000a\000b\000a\000b\000a\000b\000a\000b\000a\000b\000\000", 0, 16);
+ x2("\000(\000?\000:\000a\000b\000)\000{\0002\000,\0004\000}\000?\000\000", "\000a\000b\000a\000b\000a\000b\000a\000b\000a\000b\000\000", 0, 8);
+ x2("\000(\000?\000:\000a\000b\000)\000{\000,\000}\000\000", "\000a\000b\000{\000,\000}\000\000", 0, 10);
+ x2("\000(\000?\000:\000a\000b\000c\000)\000+\000?\000{\0002\000}\000\000", "\000a\000b\000c\000a\000b\000c\000a\000b\000c\000\000", 0, 12);
+ x2("\000(\000?\000:\000X\000*\000)\000(\000?\000i\000:\000x\000a\000)\000\000", "\000X\000X\000X\000a\000\000", 0, 8);
+ x2("\000(\000d\000+\000)\000(\000[\000^\000a\000b\000c\000]\000z\000)\000\000", "\000d\000d\000d\000z\000\000", 0, 8);
+ x2("\000(\000[\000^\000a\000b\000c\000]\000*\000)\000(\000[\000^\000a\000b\000c\000]\000z\000)\000\000", "\000d\000d\000d\000z\000\000", 0, 8);
+ x2("\000(\000\134\000w\000+\000)\000(\000\134\000w\000z\000)\000\000", "\000d\000d\000d\000z\000\000", 0, 8);
+ x3("\000(\000a\000)\000\000", "\000a\000\000", 0, 2, 1);
+ x3("\000(\000a\000b\000)\000\000", "\000a\000b\000\000", 0, 4, 1);
+ x2("\000(\000(\000a\000b\000)\000)\000\000", "\000a\000b\000\000", 0, 4);
+ x3("\000(\000(\000a\000b\000)\000)\000\000", "\000a\000b\000\000", 0, 4, 1);
+ x3("\000(\000(\000a\000b\000)\000)\000\000", "\000a\000b\000\000", 0, 4, 2);
+ x3("\000(\000(\000(\000(\000(\000(\000(\000(\000(\000(\000(\000(\000(\000(\000(\000(\000(\000(\000(\000(\000a\000b\000)\000)\000)\000)\000)\000)\000)\000)\000)\000)\000)\000)\000)\000)\000)\000)\000)\000)\000)\000)\000\000", "\000a\000b\000\000", 0, 4, 20);
+ x3("\000(\000a\000b\000)\000(\000c\000d\000)\000\000", "\000a\000b\000c\000d\000\000", 0, 4, 1);
+ x3("\000(\000a\000b\000)\000(\000c\000d\000)\000\000", "\000a\000b\000c\000d\000\000", 4, 8, 2);
+ x3("\000(\000)\000(\000a\000)\000b\000c\000(\000d\000e\000f\000)\000g\000h\000i\000j\000k\000\000", "\000a\000b\000c\000d\000e\000f\000g\000h\000i\000j\000k\000\000", 6, 12, 3);
+ x3("\000(\000(\000)\000(\000a\000)\000b\000c\000(\000d\000e\000f\000)\000g\000h\000i\000j\000k\000)\000\000", "\000a\000b\000c\000d\000e\000f\000g\000h\000i\000j\000k\000\000", 6, 12, 4);
+ x2("\000(\000^\000a\000)\000\000", "\000a\000\000", 0, 2);
+ x3("\000(\000a\000)\000|\000(\000a\000)\000\000", "\000b\000a\000\000", 2, 4, 1);
+ x3("\000(\000^\000a\000)\000|\000(\000a\000)\000\000", "\000b\000a\000\000", 2, 4, 2);
+ x3("\000(\000a\000?\000)\000\000", "\000a\000a\000a\000\000", 0, 2, 1);
+ x3("\000(\000a\000*\000)\000\000", "\000a\000a\000a\000\000", 0, 6, 1);
+ x3("\000(\000a\000*\000)\000\000", "\000\000", 0, 0, 1);
+ x3("\000(\000a\000+\000)\000\000", "\000a\000a\000a\000a\000a\000a\000a\000\000", 0, 14, 1);
+ x3("\000(\000a\000+\000|\000b\000*\000)\000\000", "\000b\000b\000b\000a\000a\000\000", 0, 6, 1);
+ x3("\000(\000a\000+\000|\000b\000?\000)\000\000", "\000b\000b\000b\000a\000a\000\000", 0, 2, 1);
+ x3("\000(\000a\000b\000c\000)\000?\000\000", "\000a\000b\000c\000\000", 0, 6, 1);
+ x3("\000(\000a\000b\000c\000)\000*\000\000", "\000a\000b\000c\000\000", 0, 6, 1);
+ x3("\000(\000a\000b\000c\000)\000+\000\000", "\000a\000b\000c\000\000", 0, 6, 1);
+ x3("\000(\000x\000y\000z\000|\000a\000b\000c\000)\000+\000\000", "\000a\000b\000c\000\000", 0, 6, 1);
+ x3("\000(\000[\000x\000y\000z\000]\000[\000a\000b\000c\000]\000|\000a\000b\000c\000)\000+\000\000", "\000a\000b\000c\000\000", 0, 6, 1);
+ x3("\000(\000(\000?\000i\000:\000a\000b\000c\000)\000)\000\000", "\000A\000b\000C\000\000", 0, 6, 1);
+ x2("\000(\000a\000b\000c\000)\000(\000?\000i\000:\000\134\0001\000)\000\000", "\000a\000b\000c\000A\000B\000C\000\000", 0, 12);
+ x3("\000(\000(\000?\000m\000:\000a\000.\000c\000)\000)\000\000", "\000a\000\012\000c\000\000", 0, 6, 1);
+ x3("\000(\000(\000?\000=\000a\000z\000)\000a\000)\000\000", "\000a\000z\000b\000\000", 0, 2, 1);
+ x3("\000a\000b\000c\000|\000(\000.\000a\000b\000d\000)\000\000", "\000z\000a\000b\000d\000\000", 0, 8, 1);
+ x2("\000(\000?\000:\000a\000b\000c\000)\000|\000(\000A\000B\000C\000)\000\000", "\000a\000b\000c\000\000", 0, 6);
+ x3("\000(\000?\000i\000:\000(\000a\000b\000c\000)\000)\000|\000(\000z\000z\000z\000)\000\000", "\000A\000B\000C\000\000", 0, 6, 1);
+ x3("\000a\000*\000(\000.\000)\000\000", "\000a\000a\000a\000a\000z\000\000", 8, 10, 1);
+ x3("\000a\000*\000?\000(\000.\000)\000\000", "\000a\000a\000a\000a\000z\000\000", 0, 2, 1);
+ x3("\000a\000*\000?\000(\000c\000)\000\000", "\000a\000a\000a\000a\000c\000\000", 8, 10, 1);
+ x3("\000[\000b\000c\000d\000]\000a\000*\000(\000.\000)\000\000", "\000c\000a\000a\000a\000a\000z\000\000", 10, 12, 1);
+ x3("\000(\000\134\000A\000b\000b\000)\000c\000c\000\000", "\000b\000b\000c\000c\000\000", 0, 4, 1);
+ n("\000(\000\134\000A\000b\000b\000)\000c\000c\000\000", "\000z\000b\000b\000c\000c\000\000");
+ x3("\000(\000^\000b\000b\000)\000c\000c\000\000", "\000b\000b\000c\000c\000\000", 0, 4, 1);
+ n("\000(\000^\000b\000b\000)\000c\000c\000\000", "\000z\000b\000b\000c\000c\000\000");
+ x3("\000c\000c\000(\000b\000b\000$\000)\000\000", "\000c\000c\000b\000b\000\000", 4, 8, 1);
+ n("\000c\000c\000(\000b\000b\000$\000)\000\000", "\000c\000c\000b\000b\000b\000\000");
+ n("\000(\000\134\0001\000)\000\000", "\000\000");
+ n("\000\134\0001\000(\000a\000)\000\000", "\000a\000a\000\000");
+ n("\000(\000a\000(\000b\000)\000\134\0001\000)\000\134\0002\000+\000\000", "\000a\000b\000a\000b\000b\000\000");
+ n("\000(\000?\000:\000(\000?\000:\000\134\0001\000|\000z\000)\000(\000a\000)\000)\000+\000$\000\000", "\000z\000a\000a\000\000");
+ x2("\000(\000?\000:\000(\000?\000:\000\134\0001\000|\000z\000)\000(\000a\000)\000)\000+\000$\000\000", "\000z\000a\000a\000a\000\000", 0, 8);
+ x2("\000(\000a\000)\000(\000?\000=\000\134\0001\000)\000\000", "\000a\000a\000\000", 0, 2);
+ n("\000(\000a\000)\000$\000|\000\134\0001\000\000", "\000a\000z\000\000");
+ x2("\000(\000a\000)\000\134\0001\000\000", "\000a\000a\000\000", 0, 4);
+ n("\000(\000a\000)\000\134\0001\000\000", "\000a\000b\000\000");
+ x2("\000(\000a\000?\000)\000\134\0001\000\000", "\000a\000a\000\000", 0, 4);
+ x2("\000(\000a\000?\000?\000)\000\134\0001\000\000", "\000a\000a\000\000", 0, 0);
+ x2("\000(\000a\000*\000)\000\134\0001\000\000", "\000a\000a\000a\000a\000a\000\000", 0, 8);
+ x3("\000(\000a\000*\000)\000\134\0001\000\000", "\000a\000a\000a\000a\000a\000\000", 0, 4, 1);
+ x2("\000a\000(\000b\000*\000)\000\134\0001\000\000", "\000a\000b\000b\000b\000b\000\000", 0, 10);
+ x2("\000a\000(\000b\000*\000)\000\134\0001\000\000", "\000a\000b\000\000", 0, 2);
+ x2("\000(\000a\000*\000)\000(\000b\000*\000)\000\134\0001\000\134\0002\000\000", "\000a\000a\000a\000b\000b\000a\000a\000a\000b\000b\000\000", 0, 20);
+ x2("\000(\000a\000*\000)\000(\000b\000*\000)\000\134\0002\000\000", "\000a\000a\000a\000b\000b\000b\000b\000\000", 0, 14);
+ x2("\000(\000(\000(\000(\000(\000(\000(\000a\000*\000)\000b\000)\000)\000)\000)\000)\000)\000c\000\134\0007\000\000", "\000a\000a\000a\000b\000c\000a\000a\000a\000\000", 0, 16);
+ x3("\000(\000(\000(\000(\000(\000(\000(\000a\000*\000)\000b\000)\000)\000)\000)\000)\000)\000c\000\134\0007\000\000", "\000a\000a\000a\000b\000c\000a\000a\000a\000\000", 0, 6, 7);
+ x2("\000(\000a\000)\000(\000b\000)\000(\000c\000)\000\134\0002\000\134\0001\000\134\0003\000\000", "\000a\000b\000c\000b\000a\000c\000\000", 0, 12);
+ x2("\000(\000[\000a\000-\000d\000]\000)\000\134\0001\000\000", "\000c\000c\000\000", 0, 4);
+ x2("\000(\000\134\000w\000\134\000d\000\134\000s\000)\000\134\0001\000\000", "\000f\0005\000 \000f\0005\000 \000\000", 0, 12);
+ n("\000(\000\134\000w\000\134\000d\000\134\000s\000)\000\134\0001\000\000", "\000f\0005\000 \000f\0005\000\000");
+ x2("\000(\000w\000h\000o\000|\000[\000a\000-\000c\000]\000{\0003\000}\000)\000\134\0001\000\000", "\000w\000h\000o\000w\000h\000o\000\000", 0, 12);
+ x2("\000.\000.\000.\000(\000w\000h\000o\000|\000[\000a\000-\000c\000]\000{\0003\000}\000)\000\134\0001\000\000", "\000a\000b\000c\000w\000h\000o\000w\000h\000o\000\000", 0, 18);
+ x2("\000(\000w\000h\000o\000|\000[\000a\000-\000c\000]\000{\0003\000}\000)\000\134\0001\000\000", "\000c\000b\000c\000c\000b\000c\000\000", 0, 12);
+ x2("\000(\000^\000a\000)\000\134\0001\000\000", "\000a\000a\000\000", 0, 4);
+ n("\000(\000^\000a\000)\000\134\0001\000\000", "\000b\000a\000a\000\000");
+ n("\000(\000a\000$\000)\000\134\0001\000\000", "\000a\000a\000\000");
+ n("\000(\000a\000b\000\134\000Z\000)\000\134\0001\000\000", "\000a\000b\000\000");
+ x2("\000(\000a\000*\000\134\000Z\000)\000\134\0001\000\000", "\000a\000\000", 2, 2);
+ x2("\000.\000(\000a\000*\000\134\000Z\000)\000\134\0001\000\000", "\000b\000a\000\000", 2, 4);
+ x3("\000(\000.\000(\000a\000b\000c\000)\000\134\0002\000)\000\000", "\000z\000a\000b\000c\000a\000b\000c\000\000", 0, 14, 1);
+ x3("\000(\000.\000(\000.\000.\000\134\000d\000.\000)\000\134\0002\000)\000\000", "\000z\0001\0002\0003\0004\0001\0002\0003\0004\000\000", 0, 18, 1);
+ x2("\000(\000(\000?\000i\000:\000a\000z\000)\000)\000\134\0001\000\000", "\000A\000z\000A\000z\000\000", 0, 8);
+ n("\000(\000(\000?\000i\000:\000a\000z\000)\000)\000\134\0001\000\000", "\000A\000z\000a\000z\000\000");
+ x2("\000(\000?\000<\000=\000a\000)\000b\000\000", "\000a\000b\000\000", 2, 4);
+ n("\000(\000?\000<\000=\000a\000)\000b\000\000", "\000b\000b\000\000");
+ x2("\000(\000?\000<\000=\000a\000|\000b\000)\000b\000\000", "\000b\000b\000\000", 2, 4);
+ x2("\000(\000?\000<\000=\000a\000|\000b\000c\000)\000b\000\000", "\000b\000c\000b\000\000", 4, 6);
+ x2("\000(\000?\000<\000=\000a\000|\000b\000c\000)\000b\000\000", "\000a\000b\000\000", 2, 4);
+ x2("\000(\000?\000<\000=\000a\000|\000b\000c\000|\000|\000d\000e\000f\000g\000h\000i\000j\000|\000k\000l\000m\000n\000o\000p\000q\000|\000r\000)\000z\000\000", "\000r\000z\000\000", 2, 4);
+ x2("\000(\000a\000)\000\134\000g\000<\0001\000>\000\000", "\000a\000a\000\000", 0, 4);
+ x2("\000(\000?\000<\000!\000a\000)\000b\000\000", "\000c\000b\000\000", 2, 4);
+ n("\000(\000?\000<\000!\000a\000)\000b\000\000", "\000a\000b\000\000");
+ x2("\000(\000?\000<\000!\000a\000|\000b\000c\000)\000b\000\000", "\000b\000b\000b\000\000", 0, 2);
+ n("\000(\000?\000<\000!\000a\000|\000b\000c\000)\000z\000\000", "\000b\000c\000z\000\000");
+ x2("\000(\000?\000<\000n\000a\000m\000e\0001\000>\000a\000)\000\000", "\000a\000\000", 0, 2);
+ x2("\000(\000?\000<\000n\000a\000m\000e\000_\0002\000>\000a\000b\000)\000\134\000g\000<\000n\000a\000m\000e\000_\0002\000>\000\000", "\000a\000b\000a\000b\000\000", 0, 8);
+ x2("\000(\000?\000<\000n\000a\000m\000e\000_\0003\000>\000.\000z\000v\000.\000)\000\134\000k\000<\000n\000a\000m\000e\000_\0003\000>\000\000", "\000a\000z\000v\000b\000a\000z\000v\000b\000\000", 0, 16);
+ x2("\000(\000?\000<\000=\000\134\000g\000<\000a\000b\000>\000)\000|\000-\000\134\000z\000E\000N\000D\000 \000(\000?\000<\000a\000b\000>\000X\000y\000Z\000)\000\000", "\000X\000y\000Z\000\000", 6, 6);
+ x2("\000(\000?\000<\000n\000>\000|\000a\000\134\000g\000<\000n\000>\000)\000+\000\000", "\000\000", 0, 0);
+ x2("\000(\000?\000<\000n\000>\000|\000\134\000(\000\134\000g\000<\000n\000>\000\134\000)\000)\000+\000$\000\000", "\000(\000)\000(\000(\000)\000)\000\000", 0, 12);
+ x3("\000\134\000g\000<\000n\000>\000(\000?\000<\000n\000>\000.\000)\000{\0000\000}\000\000", "\000X\000\000", 0, 2, 1);
+ x2("\000\134\000g\000<\000n\000>\000(\000a\000b\000c\000|\000d\000f\000(\000?\000<\000n\000>\000.\000Y\000Z\000)\000{\0002\000,\0008\000}\000)\000{\0000\000}\000\000", "\000X\000Y\000Z\000\000", 0, 6);
+ x2("\000\134\000A\000(\000?\000<\000n\000>\000(\000a\000\134\000g\000<\000n\000>\000)\000|\000)\000\134\000z\000\000", "\000a\000a\000a\000a\000\000", 0, 8);
+ x2("\000(\000?\000<\000n\000>\000|\000\134\000g\000<\000m\000>\000\134\000g\000<\000n\000>\000)\000\134\000z\000|\000\134\000z\000E\000N\000D\000 \000(\000?\000<\000m\000>\000a\000|\000(\000b\000)\000\134\000g\000<\000m\000>\000)\000\000", "\000b\000b\000b\000b\000a\000b\000b\000a\000\000", 0, 16);
+ x2("\000(\000?\000<\000n\000a\000m\000e\0001\0002\0004\0000\000>\000\134\000w\000+\000\134\000s\000x\000)\000a\000+\000\134\000k\000<\000n\000a\000m\000e\0001\0002\0004\0000\000>\000\000", "\000 \000 \000f\000g\000 \000x\000a\000a\000a\000a\000a\000a\000a\000a\000f\000g\000 \000x\000\000", 4, 36);
+ x3("\000(\000z\000)\000(\000)\000(\000)\000(\000?\000<\000_\0009\000>\000a\000)\000\134\000g\000<\000_\0009\000>\000\000", "\000z\000a\000a\000\000", 4, 6, 1);
+ x2("\000(\000.\000)\000(\000(\000(\000?\000<\000_\000>\000a\000)\000)\000)\000\134\000k\000<\000_\000>\000\000", "\000z\000a\000a\000\000", 0, 6);
+ x2("\000(\000(\000?\000<\000n\000a\000m\000e\0001\000>\000\134\000d\000)\000|\000(\000?\000<\000n\000a\000m\000e\0002\000>\000\134\000w\000)\000)\000(\000\134\000k\000<\000n\000a\000m\000e\0001\000>\000|\000\134\000k\000<\000n\000a\000m\000e\0002\000>\000)\000\000", "\000f\000f\000\000", 0, 4);
+ x2("\000(\000?\000:\000(\000?\000<\000x\000>\000)\000|\000(\000?\000<\000x\000>\000e\000f\000g\000)\000)\000\134\000k\000<\000x\000>\000\000", "\000\000", 0, 0);
+ x2("\000(\000?\000:\000(\000?\000<\000x\000>\000a\000b\000c\000)\000|\000(\000?\000<\000x\000>\000e\000f\000g\000)\000)\000\134\000k\000<\000x\000>\000\000", "\000a\000b\000c\000e\000f\000g\000e\000f\000g\000\000", 6, 18);
+ n("\000(\000?\000:\000(\000?\000<\000x\000>\000a\000b\000c\000)\000|\000(\000?\000<\000x\000>\000e\000f\000g\000)\000)\000\134\000k\000<\000x\000>\000\000", "\000a\000b\000c\000e\000f\000g\000\000");
+ x2("\000(\000?\000:\000(\000?\000<\000n\0001\000>\000.\000)\000|\000(\000?\000<\000n\0001\000>\000.\000.\000)\000|\000(\000?\000<\000n\0001\000>\000.\000.\000.\000)\000|\000(\000?\000<\000n\0001\000>\000.\000.\000.\000.\000)\000|\000(\000?\000<\000n\0001\000>\000.\000.\000.\000.\000.\000)\000|\000(\000?\000<\000n\0001\000>\000.\000.\000.\000.\000.\000.\000)\000|\000(\000?\000<\000n\0001\000>\000.\000.\000.\000.\000.\000.\000.\000)\000|\000(\000?\000<\000n\0001\000>\000.\000.\000.\000.\000.\000.\000.\000.\000)\000|\000(\000?\000<\000n\0001\000>\000.\000.\000.\000.\000.\000.\000.\000.\000.\000)\000|\000(\000?\000<\000n\0001\000>\000.\000.\000.\000.\000.\000.\000.\000.\000.\000.\000)\000|\000(\000?\000<\000n\0001\000>\000.\000.\000.\000.\000.\000.\000.\000.\000.\000.\000.\000)\000|\000(\000?\000<\000n\0001\000>\000.\000.\000.\000.\000.\000.\000.\000.\000.\000.\000.\000.\000)\000|\000(\000?\000<\000n\0001\000>\000.\000.\000.\000.\000.\000.\000.\000.\000.\000.\000.\000.\000.\000)\000|\000(\000?\000<\000n\0001\000>\000.\000.\000.\000.\000.\000.\000.\000.\000.\000.\000.\000.\000.\000.\000)\000)\000\134\000k\000<\000n\0001\000>\000$\000\000", "\000a\000-\000p\000y\000u\000m\000p\000y\000u\000m\000\000", 4, 20);
+ x3("\000(\000?\000:\000(\000?\000<\000n\0001\000>\000.\000)\000|\000(\000?\000<\000n\0001\000>\000.\000.\000)\000|\000(\000?\000<\000n\0001\000>\000.\000.\000.\000)\000|\000(\000?\000<\000n\0001\000>\000.\000.\000.\000.\000)\000|\000(\000?\000<\000n\0001\000>\000.\000.\000.\000.\000.\000)\000|\000(\000?\000<\000n\0001\000>\000.\000.\000.\000.\000.\000.\000)\000|\000(\000?\000<\000n\0001\000>\000.\000.\000.\000.\000.\000.\000.\000)\000|\000(\000?\000<\000n\0001\000>\000.\000.\000.\000.\000.\000.\000.\000.\000)\000|\000(\000?\000<\000n\0001\000>\000.\000.\000.\000.\000.\000.\000.\000.\000.\000)\000|\000(\000?\000<\000n\0001\000>\000.\000.\000.\000.\000.\000.\000.\000.\000.\000.\000)\000|\000(\000?\000<\000n\0001\000>\000.\000.\000.\000.\000.\000.\000.\000.\000.\000.\000.\000)\000|\000(\000?\000<\000n\0001\000>\000.\000.\000.\000.\000.\000.\000.\000.\000.\000.\000.\000.\000)\000|\000(\000?\000<\000n\0001\000>\000.\000.\000.\000.\000.\000.\000.\000.\000.\000.\000.\000.\000.\000)\000|\000(\000?\000<\000n\0001\000>\000.\000.\000.\000.\000.\000.\000.\000.\000.\000.\000.\000.\000.\000.\000)\000)\000\134\000k\000<\000n\0001\000>\000$\000\000", "\000x\000x\000x\000x\000a\000b\000c\000d\000e\000f\000g\000h\000i\000j\000k\000l\000m\000n\000a\000b\000c\000d\000e\000f\000g\000h\000i\000j\000k\000l\000m\000n\000\000", 8, 36, 14);
+ x3("\000(\000?\000<\000n\000a\000m\000e\0001\000>\000)\000(\000?\000<\000n\000a\000m\000e\0002\000>\000)\000(\000?\000<\000n\000a\000m\000e\0003\000>\000)\000(\000?\000<\000n\000a\000m\000e\0004\000>\000)\000(\000?\000<\000n\000a\000m\000e\0005\000>\000)\000(\000?\000<\000n\000a\000m\000e\0006\000>\000)\000(\000?\000<\000n\000a\000m\000e\0007\000>\000)\000(\000?\000<\000n\000a\000m\000e\0008\000>\000)\000(\000?\000<\000n\000a\000m\000e\0009\000>\000)\000(\000?\000<\000n\000a\000m\000e\0001\0000\000>\000)\000(\000?\000<\000n\000a\000m\000e\0001\0001\000>\000)\000(\000?\000<\000n\000a\000m\000e\0001\0002\000>\000)\000(\000?\000<\000n\000a\000m\000e\0001\0003\000>\000)\000(\000?\000<\000n\000a\000m\000e\0001\0004\000>\000)\000(\000?\000<\000n\000a\000m\000e\0001\0005\000>\000)\000(\000?\000<\000n\000a\000m\000e\0001\0006\000>\000a\000a\000a\000)\000(\000?\000<\000n\000a\000m\000e\0001\0007\000>\000)\000$\000\000", "\000a\000a\000a\000\000", 0, 6, 16);
+ x2("\000(\000?\000<\000f\000o\000o\000>\000a\000|\000\134\000(\000\134\000g\000<\000f\000o\000o\000>\000\134\000)\000)\000\000", "\000a\000\000", 0, 2);
+ x2("\000(\000?\000<\000f\000o\000o\000>\000a\000|\000\134\000(\000\134\000g\000<\000f\000o\000o\000>\000\134\000)\000)\000\000", "\000(\000(\000(\000(\000(\000(\000a\000)\000)\000)\000)\000)\000)\000\000", 0, 26);
+ x3("\000(\000?\000<\000f\000o\000o\000>\000a\000|\000\134\000(\000\134\000g\000<\000f\000o\000o\000>\000\134\000)\000)\000\000", "\000(\000(\000(\000(\000(\000(\000(\000(\000a\000)\000)\000)\000)\000)\000)\000)\000)\000\000", 0, 34, 1);
+ x2("\000\134\000g\000<\000b\000a\000r\000>\000|\000\134\000z\000E\000N\000D\000(\000?\000<\000b\000a\000r\000>\000.\000*\000a\000b\000c\000$\000)\000\000", "\000a\000b\000c\000x\000x\000x\000a\000b\000c\000\000", 0, 18);
+ x2("\000\134\000g\000<\0001\000>\000|\000\134\000z\000E\000N\000D\000(\000.\000a\000.\000)\000\000", "\000b\000a\000c\000\000", 0, 6);
+ x3("\000\134\000g\000<\000_\000A\000>\000\134\000g\000<\000_\000A\000>\000|\000\134\000z\000E\000N\000D\000(\000.\000a\000.\000)\000(\000?\000<\000_\000A\000>\000.\000b\000.\000)\000\000", "\000x\000b\000x\000y\000b\000y\000\000", 6, 12, 1);
+ x2("\000\134\000A\000(\000?\000:\000\134\000g\000<\000p\000o\000n\000>\000|\000\134\000g\000<\000p\000a\000n\000>\000|\000\134\000z\000E\000N\000D\000 \000 \000(\000?\000<\000p\000a\000n\000>\000a\000|\000c\000\134\000g\000<\000p\000o\000n\000>\000c\000)\000(\000?\000<\000p\000o\000n\000>\000b\000|\000d\000\134\000g\000<\000p\000a\000n\000>\000d\000)\000)\000$\000\000", "\000c\000d\000c\000b\000c\000d\000c\000\000", 0, 14);
+ x2("\000\134\000A\000(\000?\000<\000n\000>\000|\000a\000\134\000g\000<\000m\000>\000)\000\134\000z\000|\000\134\000z\000E\000N\000D\000 \000(\000?\000<\000m\000>\000\134\000g\000<\000n\000>\000)\000\000", "\000a\000a\000a\000a\000\000", 0, 8);
+ x2("\000(\000?\000<\000n\000>\000(\000a\000|\000b\000\134\000g\000<\000n\000>\000c\000)\000{\0003\000,\0005\000}\000)\000\000", "\000b\000a\000a\000a\000a\000c\000a\000\000", 2, 10);
+ x2("\000(\000?\000<\000n\000>\000(\000a\000|\000b\000\134\000g\000<\000n\000>\000c\000)\000{\0003\000,\0005\000}\000)\000\000", "\000b\000a\000a\000a\000a\000c\000a\000a\000a\000a\000a\000\000", 0, 20);
+ x2("\000(\000?\000<\000p\000a\000r\000e\000>\000\134\000(\000(\000[\000^\000\134\000(\000\134\000)\000]\000+\000+\000|\000\134\000g\000<\000p\000a\000r\000e\000>\000)\000*\000+\000\134\000)\000)\000\000", "\000(\000(\000a\000)\000)\000\000", 0, 10);
+ x2("\000(\000)\000*\000\134\0001\000\000", "\000\000", 0, 0);
+ x2("\000(\000?\000:\000(\000)\000|\000(\000)\000)\000*\000\134\0001\000\134\0002\000\000", "\000\000", 0, 0);
+ x3("\000(\000?\000:\000\134\0001\000a\000|\000(\000)\000)\000*\000\000", "\000a\000\000", 0, 0, 1);
+ x2("\000x\000(\000(\000.\000)\000*\000)\000*\000x\000\000", "\0000\000x\0001\000x\0002\000x\0003\000\000", 2, 12);
+ x2("\000x\000(\000(\000.\000)\000*\000)\000*\000x\000(\000?\000i\000:\000\134\0001\000)\000\134\000Z\000\000", "\0000\000x\0001\000x\0002\000x\0001\000X\0002\000\000", 2, 18);
+ x2("\000(\000?\000:\000(\000)\000|\000(\000)\000|\000(\000)\000|\000(\000)\000|\000(\000)\000|\000(\000)\000)\000*\000\134\0002\000\134\0005\000\000", "\000\000", 0, 0);
+ x2("\000(\000?\000:\000(\000)\000|\000(\000)\000|\000(\000)\000|\000(\000x\000)\000|\000(\000)\000|\000(\000)\000)\000*\000\134\0002\000b\000\134\0005\000\000", "\000b\000\000", 0, 2);
+ x2("\217\372\000\000", "\217\372\000\000", 0, 2);
+ x2("\000\000", "0B\000\000", 0, 0);
+ x2("0B\000\000", "0B\000\000", 0, 2);
+ n("0D\000\000", "0B\000\000");
+ x2("0F0F\000\000", "0F0F\000\000", 0, 4);
+ x2("0B0D0F\000\000", "0B0D0F\000\000", 0, 6);
+ x2("0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S\000\000", "0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S0S\000\000", 0, 70);
+ x2("0B\000\000", "0D0B\000\000", 2, 4);
+ x2("0D0F\000\000", "0B0D0F\000\000", 2, 6);
+ x2("e\207\000\000", "e\207\000\000", 0, 2);
+ x2("\000.\000\000", "0B\000\000", 0, 2);
+ x2("\000.\000.\000\000", "0K0M\000\000", 0, 4);
+ x2("\000\134\000w\000\000", "0J\000\000", 0, 2);
+ n("\000\134\000W\000\000", "0B\000\000");
+ x2("\000[\000\134\000W\000]\000\000", "0F\000$\000\000", 2, 4);
+ x2("\000\134\000S\000\000", "0]\000\000", 0, 2);
+ x2("\000\134\000S\000\000", "o\042\000\000", 0, 2);
+ x2("\000\134\000b\000\000", "l\027\000 \000\000", 0, 0);
+ x2("\000\134\000b\000\000", "\000 0{\000\000", 2, 2);
+ x2("\000\134\000B\000\000", "0[0]\000 \000\000", 2, 2);
+ x2("\000\134\000B\000\000", "0F\000 \000\000", 4, 4);
+ x2("\000\134\000B\000\000", "\000 0D\000\000", 0, 0);
+ x2("\000[0_0a\000]\000\000", "0a\000\000", 0, 2);
+ n("\000[0j0k\000]\000\000", "0l\000\000");
+ x2("\000[0F\000-0J\000]\000\000", "0H\000\000", 0, 2);
+ n("\000[\000^0Q\000]\000\000", "0Q\000\000");
+ x2("\000[\000\134\000w\000]\000\000", "0m\000\000", 0, 2);
+ n("\000[\000\134\000d\000]\000\000", "0u\000\000");
+ x2("\000[\000\134\000D\000]\000\000", "0o\000\000", 0, 2);
+ n("\000[\000\134\000s\000]\000\000", "0O\000\000");
+ x2("\000[\000\134\000S\000]\000\000", "0x\000\000", 0, 2);
+ x2("\000[\000\134\000w\000\134\000d\000]\000\000", "0\210\000\000", 0, 2);
+ x2("\000[\000\134\000w\000\134\000d\000]\000\000", "\000 \000 \000 0\210\000\000", 6, 8);
+ n("\000\134\000w\233<\216\312\000\000", "\000 \233<\216\312\000\000");
+ x2("\233<\000\134\000W\216\312\000\000", "\233<\000 \216\312\000\000", 0, 6);
+ x2("0B\000.0D\000.0F\000\000", "0B0B0D0D0F\000\000", 0, 10);
+ x2("\000.\000\134\000w0F\000\134\000W\000.\000.0^\000\000", "0H0F0F\000 0F0^0^\000\000", 0, 14);
+ x2("\000\134\000s\000\134\000w0S0S0S\000\000", "\000 0S0S0S0S\000\000", 0, 10);
+ x2("0B0B\000.0Q\000\000", "0B0B0Q0Q\000\000", 0, 8);
+ n("\000.0D\000\000", "0D0H\000\000");
+ x2("\000.0J\000\000", "0J0J\000\000", 0, 4);
+ x2("\000^0B\000\000", "0B\000\000", 0, 2);
+ x2("\000^0\200\000$\000\000", "0\200\000\000", 0, 2);
+ x2("\000^\000\134\000w\000$\000\000", "0k\000\000", 0, 2);
+ x2("\000^\000\134\000w0K0M0O0Q0S\000$\000\000", "\000z0K0M0O0Q0S\000\000", 0, 12);
+ x2("\000^\000\134\000w\000.\000.\000.0F0H0J\000$\000\000", "\000z0B0D0F0F0H0J\000\000", 0, 14);
+ x2("\000\134\000w\000\134\000w\000\134\000s\000\134\000W0J0J0J\000\134\000d\000\000", "\000a0J\000 \000 0J0J0J\0004\000\000", 0, 16);
+ x2("\000\134\000A0_0a0d\000\000", "0_0a0d\000\000", 0, 6);
+ x2("0\2000\2010\202\000\134\000Z\000\000", "0\2000\2010\202\000\000", 0, 6);
+ x2("0K0M0O\000\134\000z\000\000", "0K0M0O\000\000", 0, 6);
+ x2("0K0M0O\000\134\000Z\000\000", "0K0M0O\000\012\000\000", 0, 6);
+ x2("\000\134\000G0}0t\000\000", "0}0t\000\000", 0, 4);
+ n("\000\134\000G0H\000\000", "0F0H0J\000\000");
+ n("0h0f\000\134\000G\000\000", "0h0f\000\000");
+ n("0~0\177\000\134\000A\000\000", "0~0\177\000\000");
+ n("0~\000\134\000A0\177\000\000", "0~0\177\000\000");
+ x2("\000(\000?\000=0[\000)0[\000\000", "0[\000\000", 0, 2);
+ n("\000(\000?\000=0F\000)\000.\000\000", "0D\000\000");
+ x2("\000(\000?\000!0F\000)0K\000\000", "0K\000\000", 0, 2);
+ n("\000(\000?\000!0h\000)0B\000\000", "0h\000\000");
+ x2("\000(\000?\000i\000:0B\000)\000\000", "0B\000\000", 0, 2);
+ x2("\000(\000?\000i\000:0v0y\000)\000\000", "0v0y\000\000", 0, 4);
+ n("\000(\000?\000i\000:0D\000)\000\000", "0F\000\000");
+ x2("\000(\000?\000m\000:0\210\000.\000)\000\000", "0\210\000\012\000\000", 0, 4);
+ x2("\000(\000?\000m\000:\000.0\201\000)\000\000", "0~\000\0120\201\000\000", 2, 6);
+ x2("0B\000?\000\000", "\000\000", 0, 0);
+ x2("Y\011\000?\000\000", "S\026\000\000", 0, 0);
+ x2("Y\011\000?\000\000", "Y\011\000\000", 0, 2);
+ x2("\221\317\000*\000\000", "\000\000", 0, 0);
+ x2("\221\317\000*\000\000", "\221\317\000\000", 0, 2);
+ x2("[P\000*\000\000", "[P[P[P\000\000", 0, 6);
+ x2("\231\254\000*\000\000", "\236\177\231\254\231\254\231\254\231\254\000\000", 0, 0);
+ n("\134q\000+\000\000", "\000\000");
+ x2("l\263\000+\000\000", "l\263\000\000", 0, 2);
+ x2("fB\000+\000\000", "fBfBfBfB\000\000", 0, 8);
+ x2("0H\000+\000\000", "0H0H0F0F0F\000\000", 0, 4);
+ x2("0F\000+\000\000", "0J0F0F0F0F\000\000", 2, 10);
+ x2("\000.\000?\000\000", "0_\000\000", 0, 2);
+ x2("\000.\000*\000\000", "0q0t0w0z\000\000", 0, 8);
+ x2("\000.\000+\000\000", "0\215\000\000", 0, 2);
+ x2("\000.\000+\000\000", "0D0F0H0K\000\012\000\000", 0, 8);
+ x2("0B\000|0D\000\000", "0B\000\000", 0, 2);
+ x2("0B\000|0D\000\000", "0D\000\000", 0, 2);
+ x2("0B0D\000|0D0F\000\000", "0B0D\000\000", 0, 4);
+ x2("0B0D\000|0D0F\000\000", "0D0F\000\000", 0, 4);
+ x2("0\222\000(\000?\000:0K0M\000|0M0O\000)\000\000", "0\2220K0M\000\000", 0, 6);
+ x2("0\222\000(\000?\000:0K0M\000|0M0O\000)0Q\000\000", "0\2220M0O0Q\000\000", 0, 8);
+ x2("0B0D\000|\000(\000?\000:0B0F\000|0B0\222\000)\000\000", "0B0\222\000\000", 0, 4);
+ x2("0B\000|0D\000|0F\000\000", "0H0F\000\000", 2, 4);
+ x2("0B\000|0D\000|0F0H\000|0J0K0M\000|0O\000|0Q0S0U\000|0W0Y0[\000|0]\000|0_0a\000|0d0f0h0j0k\000|0l0m\000\000", "0W0Y0[\000\000", 0, 6);
+ n("0B\000|0D\000|0F0H\000|0J0K0M\000|0O\000|0Q0S0U\000|0W0Y0[\000|0]\000|0_0a\000|0d0f0h0j0k\000|0l0m\000\000", "0Y0[\000\000");
+ x2("0B\000|\000^0\217\000\000", "0v0B\000\000", 2, 4);
+ x2("0B\000|\000^0\222\000\000", "0\2220B\000\000", 0, 2);
+ x2("\233<\000|\000\134\000G\216\312\000\000", "0Q\216\312\233<\000\000", 4, 6);
+ x2("\233<\000|\000\134\000G\216\312\000\000", "\216\312\233<\000\000", 0, 2);
+ x2("\233<\000|\000\134\000A\216\312\000\000", "\000b\216\312\233<\000\000", 4, 6);
+ x2("\233<\000|\000\134\000A\216\312\000\000", "\216\312\000\000", 0, 2);
+ x2("\233<\000|\216\312\000\134\000Z\000\000", "\216\312\233<\000\000", 2, 4);
+ x2("\233<\000|\216\312\000\134\000Z\000\000", "\216\312\000\000", 0, 2);
+ x2("\233<\000|\216\312\000\134\000Z\000\000", "\216\312\000\012\000\000", 0, 2);
+ x2("\233<\000|\216\312\000\134\000z\000\000", "\216\312\233<\000\000", 2, 4);
+ x2("\233<\000|\216\312\000\134\000z\000\000", "\216\312\000\000", 0, 2);
+ x2("\000\134\000w\000|\000\134\000s\000\000", "0J\000\000", 0, 2);
+ x2("\000\134\000w\000|\000%\000\000", "\000%0J\000\000", 0, 2);
+ x2("\000\134\000w\000|\000[\000&\000$\000]\000\000", "0F\000&\000\000", 0, 2);
+ x2("\000[0D\000-0Q\000]\000\000", "0F\000\000", 0, 2);
+ x2("\000[0D\000-0Q\000]\000|\000[\000^0K\000-0S\000]\000\000", "0B\000\000", 0, 2);
+ x2("\000[0D\000-0Q\000]\000|\000[\000^0K\000-0S\000]\000\000", "0K\000\000", 0, 2);
+ x2("\000[\000^0B\000]\000\000", "\000\012\000\000", 0, 2);
+ x2("\000(\000?\000:0B\000|\000[0F\000-0M\000]\000)\000|0D0\222\000\000", "0F0\222\000\000", 0, 2);
+ x2("\000(\000?\000:0B\000|\000[0F\000-0M\000]\000)\000|0D0\222\000\000", "0D0\222\000\000", 0, 4);
+ x2("0B0D0F\000|\000(\000?\000=0Q0Q\000)\000.\000.0{\000\000", "0Q0Q0{\000\000", 0, 6);
+ x2("0B0D0F\000|\000(\000?\000!0Q0Q\000)\000.\000.0{\000\000", "0B0D0{\000\000", 0, 6);
+ x2("\000(\000?\000=0\2220B\000)\000.\000.0B\000|\000(\000?\000=0\2220\222\000)\000.\000.0B\000\000", "0\2220\2220B\000\000", 0, 6);
+ x2("\000(\000?\000<\000=0B\000|0D0F\000)0D\000\000", "0D0F0D\000\000", 4, 6);
+ n("\000(\000?\000>0B\000|0B0D0H\000)0F\000\000", "0B0D0H0F\000\000");
+ x2("\000(\000?\000>0B0D0H\000|0B\000)0F\000\000", "0B0D0H0F\000\000", 0, 8);
+ x2("0B\000?\000|0D\000\000", "0B\000\000", 0, 2);
+ x2("0B\000?\000|0D\000\000", "0D\000\000", 0, 0);
+ x2("0B\000?\000|0D\000\000", "\000\000", 0, 0);
+ x2("0B\000*\000|0D\000\000", "0B0B\000\000", 0, 4);
+ x2("0B\000*\000|0D\000*\000\000", "0D0B\000\000", 0, 0);
+ x2("0B\000*\000|0D\000*\000\000", "0B0D\000\000", 0, 2);
+ x2("\000[\000a0B\000]\000*\000|0D\000*\000\000", "\000a0B0D0D0D\000\000", 0, 4);
+ x2("0B\000+\000|0D\000*\000\000", "\000\000", 0, 0);
+ x2("0B\000+\000|0D\000*\000\000", "0D0D0D\000\000", 0, 6);
+ x2("0B\000+\000|0D\000*\000\000", "0B0D0D0D\000\000", 0, 2);
+ x2("0B\000+\000|0D\000*\000\000", "\000a0B0D0D0D\000\000", 0, 0);
+ n("0B\000+\000|0D\000+\000\000", "\000\000");
+ x2("\000(0B\000|0D\000)\000?\000\000", "0D\000\000", 0, 2);
+ x2("\000(0B\000|0D\000)\000*\000\000", "0D0B\000\000", 0, 4);
+ x2("\000(0B\000|0D\000)\000+\000\000", "0D0B0D\000\000", 0, 6);
+ x2("\000(0B0D\000|0F0B\000)\000+\000\000", "0F0B0B0D0F0H\000\000", 0, 8);
+ x2("\000(0B0D\000|0F0H\000)\000+\000\000", "0F0B0B0D0F0H\000\000", 4, 12);
+ x2("\000(0B0D\000|0F0B\000)\000+\000\000", "0B0B0D0F0B\000\000", 2, 10);
+ x2("\000(0B0D\000|0F0B\000)\000+\000\000", "0B0D0\2220F0B\000\000", 0, 4);
+ x2("\000(0B0D\000|0F0B\000)\000+\000\000", "\000$\000$\000z\000z\000z\000z0B0D0\2220F0B\000\000", 12, 16);
+ x2("\000(0B\000|0D0B0D\000)\000+\000\000", "0B0D0B0D0B\000\000", 0, 10);
+ x2("\000(0B\000|0D0B0D\000)\000+\000\000", "0D0B\000\000", 2, 4);
+ x2("\000(0B\000|0D0B0D\000)\000+\000\000", "0D0B0B0B0D0B\000\000", 2, 8);
+ x2("\000(\000?\000:0B\000|0D\000)\000(\000?\000:0B\000|0D\000)\000\000", "0B0D\000\000", 0, 4);
+ x2("\000(\000?\000:0B\000*\000|0D\000*\000)\000(\000?\000:0B\000*\000|0D\000*\000)\000\000", "0B0B0B0D0D0D\000\000", 0, 6);
+ x2("\000(\000?\000:0B\000*\000|0D\000*\000)\000(\000?\000:0B\000+\000|0D\000+\000)\000\000", "0B0B0B0D0D0D\000\000", 0, 12);
+ x2("\000(\000?\000:0B\000+\000|0D\000+\000)\000{\0002\000}\000\000", "0B0B0B0D0D0D\000\000", 0, 12);
+ x2("\000(\000?\000:0B\000+\000|0D\000+\000)\000{\0001\000,\0002\000}\000\000", "0B0B0B0D0D0D\000\000", 0, 12);
+ x2("\000(\000?\000:0B\000+\000|\000\134\000A0D\000*\000)0F0F\000\000", "0F0F\000\000", 0, 4);
+ n("\000(\000?\000:0B\000+\000|\000\134\000A0D\000*\000)0F0F\000\000", "0B0D0F0F\000\000");
+ x2("\000(\000?\000:\000^0B\000+\000|0D\000+\000)\000*0F\000\000", "0B0B0D0D0D0B0D0F\000\000", 12, 16);
+ x2("\000(\000?\000:\000^0B\000+\000|0D\000+\000)\000*0F\000\000", "0B0B0D0D0D0D0F\000\000", 0, 14);
+ x2("0F\000{\0000\000,\000}\000\000", "0F0F0F0F\000\000", 0, 8);
+ x2("0B\000|\000(\000?\000i\000)\000c\000\000", "\000C\000\000", 0, 2);
+ x2("\000(\000?\000i\000)\000c\000|0B\000\000", "\000C\000\000", 0, 2);
+ x2("\000(\000?\000i\000:0B\000)\000|\000a\000\000", "\000a\000\000", 0, 2);
+ n("\000(\000?\000i\000:0B\000)\000|\000a\000\000", "\000A\000\000");
+ x2("\000[0B0D0F\000]\000?\000\000", "0B0D0F\000\000", 0, 2);
+ x2("\000[0B0D0F\000]\000*\000\000", "0B0D0F\000\000", 0, 6);
+ x2("\000[\000^0B0D0F\000]\000*\000\000", "0B0D0F\000\000", 0, 0);
+ n("\000[\000^0B0D0F\000]\000+\000\000", "0B0D0F\000\000");
+ x2("0B\000?\000?\000\000", "0B0B0B\000\000", 0, 0);
+ x2("0D0B\000?\000?0D\000\000", "0D0B0D\000\000", 0, 6);
+ x2("0B\000*\000?\000\000", "0B0B0B\000\000", 0, 0);
+ x2("0D0B\000*\000?\000\000", "0D0B0B\000\000", 0, 2);
+ x2("0D0B\000*\000?0D\000\000", "0D0B0B0D\000\000", 0, 8);
+ x2("0B\000+\000?\000\000", "0B0B0B\000\000", 0, 2);
+ x2("0D0B\000+\000?\000\000", "0D0B0B\000\000", 0, 4);
+ x2("0D0B\000+\000?0D\000\000", "0D0B0B0D\000\000", 0, 8);
+ x2("\000(\000?\000:Y)\000?\000)\000?\000?\000\000", "Y)\000\000", 0, 0);
+ x2("\000(\000?\000:Y)\000?\000?\000)\000?\000\000", "Y)\000\000", 0, 0);
+ x2("\000(\000?\000:Y\042\000?\000)\000+\000?\000\000", "Y\042Y\042Y\042\000\000", 0, 2);
+ x2("\000(\000?\000:\230\250\000+\000)\000?\000?\000\000", "\230\250\230\250\230\250\000\000", 0, 0);
+ x2("\000(\000?\000:\226\352\000+\000)\000?\000?\227\034\000\000", "\226\352\226\352\226\352\227\034\000\000", 0, 8);
+ x2("\000(\000?\000:0B0D\000)\000?\000{\0002\000}\000\000", "\000\000", 0, 0);
+ x2("\000(\000?\000:\233<\216\312\000)\000?\000{\0002\000}\000\000", "\233<\216\312\233<\216\312\233<\000\000", 0, 8);
+ x2("\000(\000?\000:\233<\216\312\000)\000*\000{\0000\000}\000\000", "\233<\216\312\233<\216\312\233<\000\000", 0, 0);
+ x2("\000(\000?\000:\233<\216\312\000)\000{\0003\000,\000}\000\000", "\233<\216\312\233<\216\312\233<\216\312\233<\216\312\000\000", 0, 16);
+ n("\000(\000?\000:\233<\216\312\000)\000{\0003\000,\000}\000\000", "\233<\216\312\233<\216\312\000\000");
+ x2("\000(\000?\000:\233<\216\312\000)\000{\0002\000,\0004\000}\000\000", "\233<\216\312\233<\216\312\233<\216\312\000\000", 0, 12);
+ x2("\000(\000?\000:\233<\216\312\000)\000{\0002\000,\0004\000}\000\000", "\233<\216\312\233<\216\312\233<\216\312\233<\216\312\233<\216\312\000\000", 0, 16);
+ x2("\000(\000?\000:\233<\216\312\000)\000{\0002\000,\0004\000}\000?\000\000", "\233<\216\312\233<\216\312\233<\216\312\233<\216\312\233<\216\312\000\000", 0, 8);
+ x2("\000(\000?\000:\233<\216\312\000)\000{\000,\000}\000\000", "\233<\216\312\000{\000,\000}\000\000", 0, 10);
+ x2("\000(\000?\000:0K0M0O\000)\000+\000?\000{\0002\000}\000\000", "0K0M0O0K0M0O0K0M0O\000\000", 0, 12);
+ x3("\000(pk\000)\000\000", "pk\000\000", 0, 2, 1);
+ x3("\000(pkl4\000)\000\000", "pkl4\000\000", 0, 4, 1);
+ x2("\000(\000(fB\225\223\000)\000)\000\000", "fB\225\223\000\000", 0, 4);
+ x3("\000(\000(\230\250l4\000)\000)\000\000", "\230\250l4\000\000", 0, 4, 1);
+ x3("\000(\000(f(e\345\000)\000)\000\000", "f(e\345\000\000", 0, 4, 2);
+ x3("\000(\000(\000(\000(\000(\000(\000(\000(\000(\000(\000(\000(\000(\000(\000(\000(\000(\000(\000(\000(\221\317[P\000)\000)\000)\000)\000)\000)\000)\000)\000)\000)\000)\000)\000)\000)\000)\000)\000)\000)\000)\000)\000\000", "\221\317[P\000\000", 0, 4, 20);
+ x3("\000(0B0D\000)\000(0F0H\000)\000\000", "0B0D0F0H\000\000", 0, 4, 1);
+ x3("\000(0B0D\000)\000(0F0H\000)\000\000", "0B0D0F0H\000\000", 4, 8, 2);
+ x3("\000(\000)\000(0B\000)0D0F\000(0H0J0K\000)0M0O0Q0S\000\000", "0B0D0F0H0J0K0M0O0Q0S\000\000", 6, 12, 3);
+ x3("\000(\000(\000)\000(0B\000)0D0F\000(0H0J0K\000)0M0O0Q0S\000)\000\000", "0B0D0F0H0J0K0M0O0Q0S\000\000", 6, 12, 4);
+ x3("\000.\000*\000(0\3250\251\000)0\3630\3730\336\000(0\363\000(\000)0\2670\3450\277\000)0\2440\363\000\000", "0\3250\2510\3630\3730\3360\3630\2670\3450\2770\2440\363\000\000", 10, 18, 2);
+ x2("\000(\000^0B\000)\000\000", "0B\000\000", 0, 2);
+ x3("\000(0B\000)\000|\000(0B\000)\000\000", "0D0B\000\000", 2, 4, 1);
+ x3("\000(\000^0B\000)\000|\000(0B\000)\000\000", "0D0B\000\000", 2, 4, 2);
+ x3("\000(0B\000?\000)\000\000", "0B0B0B\000\000", 0, 2, 1);
+ x3("\000(0~\000*\000)\000\000", "0~0~0~\000\000", 0, 6, 1);
+ x3("\000(0h\000*\000)\000\000", "\000\000", 0, 0, 1);
+ x3("\000(0\213\000+\000)\000\000", "0\2130\2130\2130\2130\2130\2130\213\000\000", 0, 14, 1);
+ x3("\000(0u\000+\000|0x\000*\000)\000\000", "0u0u0u0x0x\000\000", 0, 6, 1);
+ x3("\000(0B\000+\000|0D\000?\000)\000\000", "0D0D0D0B0B\000\000", 0, 2, 1);
+ x3("\000(0B0D0F\000)\000?\000\000", "0B0D0F\000\000", 0, 6, 1);
+ x3("\000(0B0D0F\000)\000*\000\000", "0B0D0F\000\000", 0, 6, 1);
+ x3("\000(0B0D0F\000)\000+\000\000", "0B0D0F\000\000", 0, 6, 1);
+ x3("\000(0U0W0Y\000|0B0D0F\000)\000+\000\000", "0B0D0F\000\000", 0, 6, 1);
+ x3("\000(\000[0j0k0l\000]\000[0K0M0O\000]\000|0K0M0O\000)\000+\000\000", "0K0M0O\000\000", 0, 6, 1);
+ x3("\000(\000(\000?\000i\000:0B0D0F\000)\000)\000\000", "0B0D0F\000\000", 0, 6, 1);
+ x3("\000(\000(\000?\000m\000:0B\000.0F\000)\000)\000\000", "0B\000\0120F\000\000", 0, 6, 1);
+ x3("\000(\000(\000?\000=0B0\223\000)0B\000)\000\000", "0B0\2230D\000\000", 0, 2, 1);
+ x3("0B0D0F\000|\000(\000.0B0D0H\000)\000\000", "0\2230B0D0H\000\000", 0, 8, 1);
+ x3("0B\000*\000(\000.\000)\000\000", "0B0B0B0B0\223\000\000", 8, 10, 1);
+ x3("0B\000*\000?\000(\000.\000)\000\000", "0B0B0B0B0\223\000\000", 0, 2, 1);
+ x3("0B\000*\000?\000(0\223\000)\000\000", "0B0B0B0B0\223\000\000", 8, 10, 1);
+ x3("\000[0D0F0H\000]0B\000*\000(\000.\000)\000\000", "0H0B0B0B0B0\223\000\000", 10, 12, 1);
+ x3("\000(\000\134\000A0D0D\000)0F0F\000\000", "0D0D0F0F\000\000", 0, 4, 1);
+ n("\000(\000\134\000A0D0D\000)0F0F\000\000", "0\2230D0D0F0F\000\000");
+ x3("\000(\000^0D0D\000)0F0F\000\000", "0D0D0F0F\000\000", 0, 4, 1);
+ n("\000(\000^0D0D\000)0F0F\000\000", "0\2230D0D0F0F\000\000");
+ x3("0\2150\215\000(0\2130\213\000$\000)\000\000", "0\2150\2150\2130\213\000\000", 4, 8, 1);
+ n("0\2150\215\000(0\2130\213\000$\000)\000\000", "0\2150\2150\2130\2130\213\000\000");
+ x2("\000(q!\000)\000\134\0001\000\000", "q!q!\000\000", 0, 4);
+ n("\000(q!\000)\000\134\0001\000\000", "q!kf\000\000");
+ x2("\000(zz\000?\000)\000\134\0001\000\000", "zzzz\000\000", 0, 4);
+ x2("\000(zz\000?\000?\000)\000\134\0001\000\000", "zzzz\000\000", 0, 0);
+ x2("\000(zz\000*\000)\000\134\0001\000\000", "zzzzzzzzzz\000\000", 0, 8);
+ x3("\000(zz\000*\000)\000\134\0001\000\000", "zzzzzzzzzz\000\000", 0, 4, 1);
+ x2("0B\000(0D\000*\000)\000\134\0001\000\000", "0B0D0D0D0D\000\000", 0, 10);
+ x2("0B\000(0D\000*\000)\000\134\0001\000\000", "0B0D\000\000", 0, 2);
+ x2("\000(0B\000*\000)\000(0D\000*\000)\000\134\0001\000\134\0002\000\000", "0B0B0B0D0D0B0B0B0D0D\000\000", 0, 20);
+ x2("\000(0B\000*\000)\000(0D\000*\000)\000\134\0002\000\000", "0B0B0B0D0D0D0D\000\000", 0, 14);
+ x3("\000(0B\000*\000)\000(0D\000*\000)\000\134\0002\000\000", "0B0B0B0D0D0D0D\000\000", 6, 10, 2);
+ x2("\000(\000(\000(\000(\000(\000(\000(0}\000*\000)0z\000)\000)\000)\000)\000)\000)0t\000\134\0007\000\000", "0}0}0}0z0t0}0}0}\000\000", 0, 16);
+ x3("\000(\000(\000(\000(\000(\000(\000(0}\000*\000)0z\000)\000)\000)\000)\000)\000)0t\000\134\0007\000\000", "0}0}0}0z0t0}0}0}\000\000", 0, 6, 7);
+ x2("\000(0o\000)\000(0r\000)\000(0u\000)\000\134\0002\000\134\0001\000\134\0003\000\000", "0o0r0u0r0o0u\000\000", 0, 12);
+ x2("\000(\000[0M\000-0Q\000]\000)\000\134\0001\000\000", "0O0O\000\000", 0, 4);
+ x2("\000(\000\134\000w\000\134\000d\000\134\000s\000)\000\134\0001\000\000", "0B\0005\000 0B\0005\000 \000\000", 0, 12);
+ n("\000(\000\134\000w\000\134\000d\000\134\000s\000)\000\134\0001\000\000", "0B\0005\000 0B\0005\000\000");
+ x2("\000(\212\260\377\037\000|\000[0B\000-0F\000]\000{\0003\000}\000)\000\134\0001\000\000", "\212\260\377\037\212\260\377\037\000\000", 0, 8);
+ x2("\000.\000.\000.\000(\212\260\377\037\000|\000[0B\000-0F\000]\000{\0003\000}\000)\000\134\0001\000\000", "0B\000a0B\212\260\377\037\212\260\377\037\000\000", 0, 14);
+ x2("\000(\212\260\377\037\000|\000[0B\000-0F\000]\000{\0003\000}\000)\000\134\0001\000\000", "0F0D0F0F0D0F\000\000", 0, 12);
+ x2("\000(\000^0S\000)\000\134\0001\000\000", "0S0S\000\000", 0, 4);
+ n("\000(\000^0\200\000)\000\134\0001\000\000", "0\2010\2000\200\000\000");
+ n("\000(0B\000$\000)\000\134\0001\000\000", "0B0B\000\000");
+ n("\000(0B0D\000\134\000Z\000)\000\134\0001\000\000", "0B0D\000\000");
+ x2("\000(0B\000*\000\134\000Z\000)\000\134\0001\000\000", "0B\000\000", 2, 2);
+ x2("\000.\000(0B\000*\000\134\000Z\000)\000\134\0001\000\000", "0D0B\000\000", 2, 4);
+ x3("\000(\000.\000(0\2040D0\206\000)\000\134\0002\000)\000\000", "\000z0\2040D0\2060\2040D0\206\000\000", 0, 14, 1);
+ x3("\000(\000.\000(\000.\000.\000\134\000d\000.\000)\000\134\0002\000)\000\000", "0B\0001\0002\0003\0004\0001\0002\0003\0004\000\000", 0, 18, 1);
+ x2("\000(\000(\000?\000i\000:0B\000v0Z\000)\000)\000\134\0001\000\000", "0B\000v0Z0B\000v0Z\000\000", 0, 12);
+ x2("\000(\000?\000<a\0320K\000>Y\011\000|\000\134\000(\000\134\000g\000<a\0320K\000>\000\134\000)\000)\000\000", "\000(\000(\000(\000(\000(\000(Y\011\000)\000)\000)\000)\000)\000)\000\000", 0, 26);
+ x2("\000\134\000A\000(\000?\000:\000\134\000g\000<\226?\000_\0001\000>\000|\000\134\000g\000<N\221\000_\0002\000>\000|\000\134\000z}BN\206\000 \000 \000(\000?\000<\226?\000_\0001\000>\211\263\000|\201\352\000\134\000g\000<N\221\000_\0002\000>\201\352\000)\000(\000?\000<N\221\000_\0002\000>W(\000|\203\351\205\251\000\134\000g\000<\226?\000_\0001\000>\203\351\205\251\000)\000)\000$\000\000", "\203\351\205\251\201\352\203\351\205\251\201\352W(\201\352\203\351\205\251\201\352\203\351\205\251\000\000", 0, 26);
+ x2("\000[\000[0r0u\000]\000]\000\000", "0u\000\000", 0, 2);
+ x2("\000[\000[0D0J0F\000]0K\000]\000\000", "0K\000\000", 0, 2);
+ n("\000[\000[\000^0B\000]\000]\000\000", "0B\000\000");
+ n("\000[\000^\000[0B\000]\000]\000\000", "0B\000\000");
+ x2("\000[\000^\000[\000^0B\000]\000]\000\000", "0B\000\000", 0, 2);
+ x2("\000[\000[0K0M0O\000]\000&\000&0M0O\000]\000\000", "0O\000\000", 0, 2);
+ n("\000[\000[0K0M0O\000]\000&\000&0M0O\000]\000\000", "0K\000\000");
+ n("\000[\000[0K0M0O\000]\000&\000&0M0O\000]\000\000", "0Q\000\000");
+ x2("\000[0B\000-0\223\000&\000&0D\000-0\222\000&\000&0F\000-0\221\000]\000\000", "0\221\000\000", 0, 2);
+ n("\000[\000^0B\000-0\223\000&\000&0D\000-0\222\000&\000&0F\000-0\221\000]\000\000", "0\221\000\000");
+ x2("\000[\000[\000^0B\000&\000&0B\000]\000&\000&0B\000-0\223\000]\000\000", "0D\000\000", 0, 2);
+ n("\000[\000[\000^0B\000&\000&0B\000]\000&\000&0B\000-0\223\000]\000\000", "0B\000\000");
+ x2("\000[\000[\000^0B\000-0\223\000&\000&0D0F0H0J\000]\000&\000&\000[\000^0F\000-0K\000]\000]\000\000", "0M\000\000", 0, 2);
+ n("\000[\000[\000^0B\000-0\223\000&\000&0D0F0H0J\000]\000&\000&\000[\000^0F\000-0K\000]\000]\000\000", "0D\000\000");
+ x2("\000[\000^\000[\000^0B0D0F\000]\000&\000&\000[\000^0F0H0J\000]\000]\000\000", "0F\000\000", 0, 2);
+ x2("\000[\000^\000[\000^0B0D0F\000]\000&\000&\000[\000^0F0H0J\000]\000]\000\000", "0H\000\000", 0, 2);
+ n("\000[\000^\000[\000^0B0D0F\000]\000&\000&\000[\000^0F0H0J\000]\000]\000\000", "0K\000\000");
+ x2("\000[0B\000-\000&\000&\000-0B\000]\000\000", "\000-\000\000", 0, 2);
+ x2("\000[\000^\000[\000^\000a\000-\000z0B0D0F\000]\000&\000&\000[\000^\000b\000c\000d\000e\000f\000g0F0H0J\000]\000q\000-\000w\000]\000\000", "0H\000\000", 0, 2);
+ x2("\000[\000^\000[\000^\000a\000-\000z0B0D0F\000]\000&\000&\000[\000^\000b\000c\000d\000e\000f\000g0F0H0J\000]\000g\000-\000w\000]\000\000", "\000f\000\000", 0, 2);
+ x2("\000[\000^\000[\000^\000a\000-\000z0B0D0F\000]\000&\000&\000[\000^\000b\000c\000d\000e\000f\000g0F0H0J\000]\000g\000-\000w\000]\000\000", "\000g\000\000", 0, 2);
+ n("\000[\000^\000[\000^\000a\000-\000z0B0D0F\000]\000&\000&\000[\000^\000b\000c\000d\000e\000f\000g0F0H0J\000]\000g\000-\000w\000]\000\000", "\0002\000\000");
+ x2("\000a\000<\000b\000>0\3200\3740\2700\3470\3630n0\3000\2460\3630\3550\3740\311\000<\000\134\000/\000b\000>\000\000", "\000a\000<\000b\000>0\3200\3740\2700\3470\3630n0\3000\2460\3630\3550\3740\311\000<\000/\000b\000>\000\000", 0, 40);
+ x2("\000.\000<\000b\000>0\3200\3740\2700\3470\3630n0\3000\2460\3630\3550\3740\311\000<\000\134\000/\000b\000>\000\000", "\000a\000<\000b\000>0\3200\3740\2700\3470\3630n0\3000\2460\3630\3550\3740\311\000<\000/\000b\000>\000\000", 0, 40);
+ fprintf(stdout,
+ "\nRESULT SUCC: %d, FAIL: %d, ERROR: %d (by Oniguruma %s)\n",
+ nsucc, nfail, nerror, onig_version());
+
+#ifndef POSIX_TEST
+ onig_region_free(region, 1);
+ onig_end();
+#endif
+
+ return ((nfail == 0 && nerror == 0) ? 0 : -1);
+}
diff --git a/ext/mbstring/oniguruma/win32/Makefile b/ext/mbstring/oniguruma/win32/Makefile
new file mode 100644
index 0000000000..d08722baa9
--- /dev/null
+++ b/ext/mbstring/oniguruma/win32/Makefile
@@ -0,0 +1,200 @@
+# Oniguruma Makefile for Win32
+
+product_name = oniguruma
+
+CPPFLAGS =
+CFLAGS = -O2 -nologo /W3
+LDFLAGS =
+LOADLIBES =
+ARLIB = lib
+ARLIB_FLAGS = -nologo
+ARDLL = cl
+ARDLL_FLAGS = -nologo -LD $(LINKFLAGS) -dll
+LINKFLAGS = -link -incremental:no -pdb:none
+
+INSTALL = install -c
+CP = copy
+CC = cl
+DEFS = -DHAVE_CONFIG_H -DNOT_RUBY -DEXPORT
+RUBYDIR = ..
+
+subdirs =
+
+libbase = onig
+libname = $(libbase)_s.lib
+dllname = $(libbase).dll
+dlllib = $(libbase).lib
+
+onigheaders = oniguruma.h regint.h regparse.h regenc.h st.h
+posixheaders = onigposix.h
+headers = $(posixheaders) $(onigheaders)
+
+onigobjs = reggnu.obj regerror.obj regparse.obj regext.obj regcomp.obj \
+ regexec.obj regenc.obj regsyntax.obj regtrav.obj \
+ regversion.obj st.obj
+posixobjs = regposix.obj regposerr.obj
+libobjs = $(onigobjs) $(posixobjs)
+
+jp_objs = $(encdir)\euc_jp.obj $(encdir)\sjis.obj
+iso8859_objs = $(encdir)\iso8859_1.obj $(encdir)\iso8859_2.obj \
+ $(encdir)\iso8859_3.obj $(encdir)\iso8859_4.obj \
+ $(encdir)\iso8859_5.obj $(encdir)\iso8859_6.obj \
+ $(encdir)\iso8859_7.obj $(encdir)\iso8859_8.obj \
+ $(encdir)\iso8859_9.obj $(encdir)\iso8859_10.obj \
+ $(encdir)\iso8859_11.obj $(encdir)\iso8859_13.obj \
+ $(encdir)\iso8859_14.obj $(encdir)\iso8859_15.obj \
+ $(encdir)\iso8859_16.obj
+
+encobjs = $(encdir)\ascii.obj $(encdir)\utf8.obj \
+ $(encdir)\unicode.obj \
+ $(encdir)\utf16_be.obj $(encdir)\utf16_le.obj \
+ $(encdir)\utf32_be.obj $(encdir)\utf32_le.obj \
+ $(jp_objs) $(iso8859_objs) \
+ $(encdir)\euc_tw.obj $(encdir)\euc_kr.obj $(encdir)\big5.obj \
+ $(encdir)\gb18030.obj \
+ $(encdir)\koi8_r.obj \
+ $(encdir)\cp1251.obj # $(encdir)\koi8.obj
+
+onigsources = regerror.c regparse.c regext.c regcomp.c regexec.c regenc.c \
+ regsyntax.c regtrav.c regversion.c reggnu.c st.c
+posixsources = regposix.c regposerr.c
+libsources = $(posixsources) $(onigsources)
+rubysources = $(onigsources)
+
+encdir = enc
+patchfiles = re.c.168.patch re.c.181.patch
+distfiles = README COPYING HISTORY \
+ Makefile.in configure.in config.h.in configure \
+ $(headers) $(libsources) $(patchfiles) \
+ test.rb testconv.rb
+testc = testc
+testp = testp
+
+makeargs = $(MFLAGS) CPPFLAGS='$(CPPFLAGS)' CFLAGS='$(CFLAGS)' CC='$(CC)'
+
+.SUFFIXES:
+.SUFFIXES: .obj .c .h .ps .dvi .info .texinfo
+
+.c.obj:
+ $(CC) $(CFLAGS) $(CPPFLAGS) $(DEFS) /I. /I.. /Fo$@ /c $<
+
+# targets
+default: all
+
+setup:
+ $(CP) win32\config.h config.h
+ $(CP) win32\testc.c testc.c
+
+
+all: $(libname) $(dllname)
+
+$(libname): $(libobjs) $(encobjs)
+ $(ARLIB) $(ARLIB_FLAGS) -out:$@ $(libobjs) $(encobjs)
+
+$(dllname): $(libobjs) $(encobjs)
+ $(ARDLL) $(libobjs) $(encobjs) -Fe$@ $(ARDLL_FLAGS)
+
+regparse.obj: regparse.c $(onigheaders) config.h st.h
+regext.obj: regext.c $(onigheaders) config.h
+regtrav.obj: regtrav.c $(onigheaders) config.h
+regcomp.obj: regcomp.c $(onigheaders) config.h
+regexec.obj: regexec.c regint.h regenc.h oniguruma.h config.h
+reggnu.obj: reggnu.c regint.h regenc.h oniguruma.h config.h oniggnu.h
+regerror.obj: regerror.c regint.h regenc.h oniguruma.h config.h
+regenc.obj: regenc.c regenc.h oniguruma.h config.h
+regsyntax.obj: regsyntax.c regint.h regenc.h oniguruma.h config.h
+regversion.obj: regversion.c oniguruma.h config.h
+regposix.obj: regposix.c $(posixheaders) oniguruma.h config.h
+regposerr.obj: regposerr.c $(posixheaders) config.h
+st.obj: st.c regint.h oniguruma.h config.h st.h
+
+$(encdir)\ascii.obj: $(encdir)\ascii.c regenc.h config.h
+$(encdir)\unicode.obj: $(encdir)\unicode.c regenc.h config.h
+$(encdir)\utf8.obj: $(encdir)\utf8.c regenc.h config.h
+$(encdir)\utf16_be.obj: $(encdir)\utf16_be.c regenc.h config.h
+$(encdir)\utf16_le.obj: $(encdir)\utf16_le.c regenc.h config.h
+$(encdir)\utf32_be.obj: $(encdir)\utf32_be.c regenc.h config.h
+$(encdir)\utf32_le.obj: $(encdir)\utf32_le.c regenc.h config.h
+$(encdir)\euc_jp.obj: $(encdir)\euc_jp.c regenc.h config.h
+$(encdir)\euc_tw.obj: $(encdir)\euc_tw.c regenc.h config.h
+$(encdir)\euc_kr.obj: $(encdir)\euc_kr.c regenc.h config.h
+$(encdir)\sjis.obj: $(encdir)\sjis.c regenc.h config.h
+$(encdir)\iso8859_1.obj: $(encdir)\iso8859_1.c regenc.h config.h
+$(encdir)\iso8859_2.obj: $(encdir)\iso8859_2.c regenc.h config.h
+$(encdir)\iso8859_3.obj: $(encdir)\iso8859_3.c regenc.h config.h
+$(encdir)\iso8859_4.obj: $(encdir)\iso8859_4.c regenc.h config.h
+$(encdir)\iso8859_5.obj: $(encdir)\iso8859_5.c regenc.h config.h
+$(encdir)\iso8859_6.obj: $(encdir)\iso8859_6.c regenc.h config.h
+$(encdir)\iso8859_7.obj: $(encdir)\iso8859_7.c regenc.h config.h
+$(encdir)\iso8859_8.obj: $(encdir)\iso8859_8.c regenc.h config.h
+$(encdir)\iso8859_9.obj: $(encdir)\iso8859_9.c regenc.h config.h
+$(encdir)\iso8859_10.obj: $(encdir)\iso8859_10.c regenc.h config.h
+$(encdir)\iso8859_11.obj: $(encdir)\iso8859_11.c regenc.h config.h
+$(encdir)\iso8859_13.obj: $(encdir)\iso8859_13.c regenc.h config.h
+$(encdir)\iso8859_14.obj: $(encdir)\iso8859_14.c regenc.h config.h
+$(encdir)\iso8859_15.obj: $(encdir)\iso8859_15.c regenc.h config.h
+$(encdir)\iso8859_16.obj: $(encdir)\iso8859_16.c regenc.h config.h
+$(encdir)\koi8.obj: $(encdir)\koi8.c regenc.h config.h
+$(encdir)\koi8_r.obj: $(encdir)\koi8_r.c regenc.h config.h
+$(encdir)\cp1251.obj: $(encdir)\cp1251.c regenc.h config.h
+$(encdir)\big5.obj: $(encdir)\big5.c regenc.h config.h
+$(encdir)\gb18030.obj: $(encdir)\gb18030.c regenc.h config.h
+
+
+# Ruby test
+rtest:
+ $(RUBYDIR)\win32\ruby -w -Ke test.rb
+
+# C library test
+ctest: $(testc)
+ .\$(testc)
+
+# POSIX C library test
+ptest: $(testp)
+ .\$(testp)
+
+$(testc): $(testc).c $(libname)
+ $(CC) -nologo -o $(testc) -DONIG_EXTERN=extern $(testc).c $(libname)
+
+$(testp): $(testc).c $(dlllib)
+ $(CC) -nologo -DPOSIX_TEST -o $(testp) $(testc).c $(dlllib)
+
+#$(testc)u.c: test.rb testconvu.rb
+# ruby -Ke testconvu.rb test.rb > $@
+
+$(testc)u: $(testc)u.c $(libname)
+ $(CC) -nologo -o $(testc)u -DONIG_EXTERN=extern $(testc)u.c $(libname)
+
+clean:
+ del *.obj $(encdir)\*.obj *.lib *.exp *.dll $(testp).exe $(testc).exe $(testc).obj
+
+
+# backup file suffix
+SORIG = ruby_orig
+
+# ruby 1.9 source update
+19:
+ $(CP) regerror.c $(RUBYDIR)
+ $(CP) regparse.c $(RUBYDIR)
+ $(CP) regcomp.c $(RUBYDIR)
+ $(CP) regexec.c $(RUBYDIR)
+ $(CP) regenc.c $(RUBYDIR)
+ $(CP) regint.h $(RUBYDIR)
+ $(CP) regparse.h $(RUBYDIR)
+ $(CP) regenc.h $(RUBYDIR)
+ $(CP) oniguruma.h $(RUBYDIR)
+ $(CP) enc\ascii.c $(RUBYDIR)
+ $(CP) enc\utf8.c $(RUBYDIR)
+ $(CP) enc\euc_jp.c $(RUBYDIR)
+ $(CP) enc\sjis.c $(RUBYDIR)
+ $(CP) enc\unicode.c $(RUBYDIR)
+
+
+samples: all
+ $(CC) $(CFLAGS) -I. -o simple sample\simple.c $(dlllib)
+ $(CC) $(CFLAGS) -I. -o posix sample\posix.c $(dlllib)
+ $(CC) $(CFLAGS) -I. -o names sample\names.c $(dlllib)
+ $(CC) $(CFLAGS) -I. -o listcap sample\listcap.c $(dlllib)
+ $(CC) $(CFLAGS) -I. -o sql sample\sql.c $(dlllib)
+ $(CC) $(CFLAGS) -I. -o encode sample\encode.c $(dlllib)
+ $(CC) $(CFLAGS) -I. -o syntax sample\syntax.c $(dlllib)
diff --git a/ext/mbstring/oniguruma/win32/testc.c b/ext/mbstring/oniguruma/win32/testc.c
new file mode 100644
index 0000000000..acc13189d5
--- /dev/null
+++ b/ext/mbstring/oniguruma/win32/testc.c
@@ -0,0 +1,863 @@
+/*
+ * This program was generated by testconv.rb.
+ */
+#include "config.h"
+#ifdef ONIG_ESCAPE_UCHAR_COLLISION
+#undef ONIG_ESCAPE_UCHAR_COLLISION
+#endif
+#include <stdio.h>
+
+#ifdef POSIX_TEST
+#include "onigposix.h"
+#else
+#include "oniguruma.h"
+#endif
+
+#ifdef HAVE_STRING_H
+# include <string.h>
+#else
+# include <strings.h>
+#endif
+
+#define SLEN(s) strlen(s)
+
+static int nsucc = 0;
+static int nfail = 0;
+static int nerror = 0;
+
+static FILE* err_file;
+
+#ifndef POSIX_TEST
+static OnigRegion* region;
+#endif
+
+static void xx(char* pattern, char* str, int from, int to, int mem, int not)
+{
+ int r;
+
+#ifdef POSIX_TEST
+ regex_t reg;
+ char buf[200];
+ regmatch_t pmatch[25];
+
+ r = regcomp(&reg, pattern, REG_EXTENDED | REG_NEWLINE);
+ if (r) {
+ regerror(r, &reg, buf, sizeof(buf));
+ fprintf(err_file, "ERROR: %s\n", buf);
+ nerror++;
+ return ;
+ }
+
+ r = regexec(&reg, str, reg.re_nsub + 1, pmatch, 0);
+ if (r != 0 && r != REG_NOMATCH) {
+ regerror(r, &reg, buf, sizeof(buf));
+ fprintf(err_file, "ERROR: %s\n", buf);
+ nerror++;
+ return ;
+ }
+
+ if (r == REG_NOMATCH) {
+ if (not) {
+ fprintf(stdout, "OK(N): /%s/ '%s'\n", pattern, str);
+ nsucc++;
+ }
+ else {
+ fprintf(stdout, "FAIL: /%s/ '%s'\n", pattern, str);
+ nfail++;
+ }
+ }
+ else {
+ if (not) {
+ fprintf(stdout, "FAIL(N): /%s/ '%s'\n", pattern, str);
+ nfail++;
+ }
+ else {
+ if (pmatch[mem].rm_so == from && pmatch[mem].rm_eo == to) {
+ fprintf(stdout, "OK: /%s/ '%s'\n", pattern, str);
+ nsucc++;
+ }
+ else {
+ fprintf(stdout, "FAIL: /%s/ '%s' %d-%d : %d-%d\n", pattern, str,
+ from, to, pmatch[mem].rm_so, pmatch[mem].rm_eo);
+ nfail++;
+ }
+ }
+ }
+ regfree(&reg);
+
+#else
+ regex_t* reg;
+ OnigErrorInfo einfo;
+
+ r = onig_new(&reg, (UChar* )pattern, (UChar* )(pattern + SLEN(pattern)),
+ ONIG_OPTION_DEFAULT, ONIG_ENCODING_SJIS, ONIG_SYNTAX_DEFAULT, &einfo);
+ if (r) {
+ char s[ONIG_MAX_ERROR_MESSAGE_LEN];
+ onig_error_code_to_str((UChar* )s, r, &einfo);
+ fprintf(err_file, "ERROR: %s\n", s);
+ nerror++;
+ return ;
+ }
+
+ r = onig_search(reg, (UChar* )str, (UChar* )(str + SLEN(str)),
+ (UChar* )str, (UChar* )(str + SLEN(str)),
+ region, ONIG_OPTION_NONE);
+ if (r < ONIG_MISMATCH) {
+ char s[ONIG_MAX_ERROR_MESSAGE_LEN];
+ onig_error_code_to_str((UChar* )s, r);
+ fprintf(err_file, "ERROR: %s\n", s);
+ nerror++;
+ return ;
+ }
+
+ if (r == ONIG_MISMATCH) {
+ if (not) {
+ fprintf(stdout, "OK(N): /%s/ '%s'\n", pattern, str);
+ nsucc++;
+ }
+ else {
+ fprintf(stdout, "FAIL: /%s/ '%s'\n", pattern, str);
+ nfail++;
+ }
+ }
+ else {
+ if (not) {
+ fprintf(stdout, "FAIL(N): /%s/ '%s'\n", pattern, str);
+ nfail++;
+ }
+ else {
+ if (region->beg[mem] == from && region->end[mem] == to) {
+ fprintf(stdout, "OK: /%s/ '%s'\n", pattern, str);
+ nsucc++;
+ }
+ else {
+ fprintf(stdout, "FAIL: /%s/ '%s' %d-%d : %d-%d\n", pattern, str,
+ from, to, region->beg[mem], region->end[mem]);
+ nfail++;
+ }
+ }
+ }
+ onig_free(reg);
+#endif
+}
+
+static void x2(char* pattern, char* str, int from, int to)
+{
+ xx(pattern, str, from, to, 0, 0);
+}
+
+static void x3(char* pattern, char* str, int from, int to, int mem)
+{
+ xx(pattern, str, from, to, mem, 0);
+}
+
+static void n(char* pattern, char* str)
+{
+ xx(pattern, str, 0, 0, 0, 1);
+}
+
+extern int main(int argc, char* argv[])
+{
+ err_file = stdout;
+
+#ifdef POSIX_TEST
+ reg_set_encoding(REG_POSIX_ENCODING_SJIS);
+#else
+ region = onig_region_new();
+#endif
+
+ x2("", "", 0, 0);
+ x2("^", "", 0, 0);
+ x2("$", "", 0, 0);
+ x2("\\G", "", 0, 0);
+ x2("\\A", "", 0, 0);
+ x2("\\Z", "", 0, 0);
+ x2("\\z", "", 0, 0);
+ x2("^$", "", 0, 0);
+ x2("\\ca", "\001", 0, 1);
+ x2("\\C-b", "\002", 0, 1);
+ x2("\\c\\\\", "\034", 0, 1);
+ x2("q[\\c\\\\]", "q\034", 0, 2);
+ x2("", "a", 0, 0);
+ x2("a", "a", 0, 1);
+ x2("\\x61", "a", 0, 1);
+ x2("aa", "aa", 0, 2);
+ x2("aaa", "aaa", 0, 3);
+ x2("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 0, 35);
+ x2("ab", "ab", 0, 2);
+ x2("b", "ab", 1, 2);
+ x2("bc", "abc", 1, 3);
+ x2("(?i:#RET#)", "#INS##RET#", 5, 10);
+ x2("\\17", "\017", 0, 1);
+ x2("\\x1f", "\x1f", 0, 1);
+ x2("a(?#....\\\\JJJJ)b", "ab", 0, 2);
+ x2("(?x) G (o O(?-x)oO) g L", "GoOoOgLe", 0, 7);
+ x2(".", "a", 0, 1);
+ n(".", "");
+ x2("..", "ab", 0, 2);
+ x2("\\w", "e", 0, 1);
+ n("\\W", "e");
+ x2("\\s", " ", 0, 1);
+ x2("\\S", "b", 0, 1);
+ x2("\\d", "4", 0, 1);
+ n("\\D", "4");
+ x2("\\b", "z ", 0, 0);
+ x2("\\b", " z", 1, 1);
+ x2("\\B", "zz ", 1, 1);
+ x2("\\B", "z ", 2, 2);
+ x2("\\B", " z", 0, 0);
+ x2("[ab]", "b", 0, 1);
+ n("[ab]", "c");
+ x2("[a-z]", "t", 0, 1);
+ n("[^a]", "a");
+ x2("[^a]", "\n", 0, 1);
+ x2("[]]", "]", 0, 1);
+ n("[^]]", "]");
+ x2("[\\^]+", "0^^1", 1, 3);
+ x2("[b-]", "b", 0, 1);
+ x2("[b-]", "-", 0, 1);
+ x2("[\\w]", "z", 0, 1);
+ n("[\\w]", " ");
+ x2("[\\W]", "b$", 1, 2);
+ x2("[\\d]", "5", 0, 1);
+ n("[\\d]", "e");
+ x2("[\\D]", "t", 0, 1);
+ n("[\\D]", "3");
+ x2("[\\s]", " ", 0, 1);
+ n("[\\s]", "a");
+ x2("[\\S]", "b", 0, 1);
+ n("[\\S]", " ");
+ x2("[\\w\\d]", "2", 0, 1);
+ n("[\\w\\d]", " ");
+ x2("[[:upper:]]", "B", 0, 1);
+ x2("[*[:xdigit:]+]", "+", 0, 1);
+ x2("[*[:xdigit:]+]", "GHIKK-9+*", 6, 7);
+ x2("[*[:xdigit:]+]", "-@^+", 3, 4);
+ n("[[:upper]]", "A");
+ x2("[[:upper]]", ":", 0, 1);
+ x2("[\\044-\\047]", "\046", 0, 1);
+ x2("[\\x5a-\\x5c]", "\x5b", 0, 1);
+ x2("[\\x6A-\\x6D]", "\x6c", 0, 1);
+ n("[\\x6A-\\x6D]", "\x6E");
+ n("^[0-9A-F]+ 0+ UNDEF ", "75F 00000000 SECT14A notype () External | _rb_apply");
+ x2("[\\[]", "[", 0, 1);
+ x2("[\\]]", "]", 0, 1);
+ x2("[&]", "&", 0, 1);
+ x2("[[ab]]", "b", 0, 1);
+ x2("[[ab]c]", "c", 0, 1);
+ n("[[^a]]", "a");
+ n("[^[a]]", "a");
+ x2("[[ab]&&bc]", "b", 0, 1);
+ n("[[ab]&&bc]", "a");
+ n("[[ab]&&bc]", "c");
+ x2("[a-z&&b-y&&c-x]", "w", 0, 1);
+ n("[^a-z&&b-y&&c-x]", "w");
+ x2("[[^a&&a]&&a-z]", "b", 0, 1);
+ n("[[^a&&a]&&a-z]", "a");
+ x2("[[^a-z&&bcdef]&&[^c-g]]", "h", 0, 1);
+ n("[[^a-z&&bcdef]&&[^c-g]]", "c");
+ x2("[^[^abc]&&[^cde]]", "c", 0, 1);
+ x2("[^[^abc]&&[^cde]]", "e", 0, 1);
+ n("[^[^abc]&&[^cde]]", "f");
+ x2("[a-&&-a]", "-", 0, 1);
+ n("[a\\-&&\\-a]", "&");
+ n("\\wabc", " abc");
+ x2("a\\Wbc", "a bc", 0, 4);
+ x2("a.b.c", "aabbc", 0, 5);
+ x2(".\\wb\\W..c", "abb bcc", 0, 7);
+ x2("\\s\\wzzz", " zzzz", 0, 5);
+ x2("aa.b", "aabb", 0, 4);
+ n(".a", "ab");
+ x2(".a", "aa", 0, 2);
+ x2("^a", "a", 0, 1);
+ x2("^a$", "a", 0, 1);
+ x2("^\\w$", "a", 0, 1);
+ n("^\\w$", " ");
+ x2("^\\wab$", "zab", 0, 3);
+ x2("^\\wabcdef$", "zabcdef", 0, 7);
+ x2("^\\w...def$", "zabcdef", 0, 7);
+ x2("\\w\\w\\s\\Waaa\\d", "aa aaa4", 0, 8);
+ x2("\\A\\Z", "", 0, 0);
+ x2("\\Axyz", "xyz", 0, 3);
+ x2("xyz\\Z", "xyz", 0, 3);
+ x2("xyz\\z", "xyz", 0, 3);
+ x2("a\\Z", "a", 0, 1);
+ x2("\\Gaz", "az", 0, 2);
+ n("\\Gz", "bza");
+ n("az\\G", "az");
+ n("az\\A", "az");
+ n("a\\Az", "az");
+ x2("\\^\\$", "^$", 0, 2);
+ x2("^x?y", "xy", 0, 2);
+ x2("^(x?y)", "xy", 0, 2);
+ x2("\\w", "_", 0, 1);
+ n("\\W", "_");
+ x2("(?=z)z", "z", 0, 1);
+ n("(?=z).", "a");
+ x2("(?!z)a", "a", 0, 1);
+ n("(?!z)a", "z");
+ x2("(?i:a)", "a", 0, 1);
+ x2("(?i:a)", "A", 0, 1);
+ x2("(?i:A)", "a", 0, 1);
+ n("(?i:A)", "b");
+ x2("(?i:[A-Z])", "a", 0, 1);
+ x2("(?i:[f-m])", "H", 0, 1);
+ x2("(?i:[f-m])", "h", 0, 1);
+ n("(?i:[f-m])", "e");
+ x2("(?i:[A-c])", "D", 0, 1);
+ n("(?i:[^a-z])", "A");
+ n("(?i:[^a-z])", "a");
+ x2("(?i:[!-k])", "Z", 0, 1);
+ x2("(?i:[!-k])", "7", 0, 1);
+ x2("(?i:[T-}])", "b", 0, 1);
+ x2("(?i:[T-}])", "{", 0, 1);
+ x2("(?i:\\?a)", "?A", 0, 2);
+ x2("(?i:\\*A)", "*a", 0, 2);
+ n(".", "\n");
+ x2("(?m:.)", "\n", 0, 1);
+ x2("(?m:a.)", "a\n", 0, 2);
+ x2("(?m:.b)", "a\nb", 1, 3);
+ x2(".*abc", "dddabdd\nddabc", 8, 13);
+ x2("(?m:.*abc)", "dddabddabc", 0, 10);
+ n("(?i)(?-i)a", "A");
+ n("(?i)(?-i:a)", "A");
+ x2("a?", "", 0, 0);
+ x2("a?", "b", 0, 0);
+ x2("a?", "a", 0, 1);
+ x2("a*", "", 0, 0);
+ x2("a*", "a", 0, 1);
+ x2("a*", "aaa", 0, 3);
+ x2("a*", "baaaa", 0, 0);
+ n("a+", "");
+ x2("a+", "a", 0, 1);
+ x2("a+", "aaaa", 0, 4);
+ x2("a+", "aabbb", 0, 2);
+ x2("a+", "baaaa", 1, 5);
+ x2(".?", "", 0, 0);
+ x2(".?", "f", 0, 1);
+ x2(".?", "\n", 0, 0);
+ x2(".*", "", 0, 0);
+ x2(".*", "abcde", 0, 5);
+ x2(".+", "z", 0, 1);
+ x2(".+", "zdswer\n", 0, 6);
+ x2("(.*)a\\1f", "babfbac", 0, 4);
+ x2("(.*)a\\1f", "bacbabf", 3, 7);
+ x2("((.*)a\\2f)", "bacbabf", 3, 7);
+ x2("(.*)a\\1f", "baczzzzzz\nbazz\nzzzzbabf", 19, 23);
+ x2("a|b", "a", 0, 1);
+ x2("a|b", "b", 0, 1);
+ x2("|a", "a", 0, 0);
+ x2("(|a)", "a", 0, 0);
+ x2("ab|bc", "ab", 0, 2);
+ x2("ab|bc", "bc", 0, 2);
+ x2("z(?:ab|bc)", "zbc", 0, 3);
+ x2("a(?:ab|bc)c", "aabc", 0, 4);
+ x2("ab|(?:ac|az)", "az", 0, 2);
+ x2("a|b|c", "dc", 1, 2);
+ x2("a|b|cd|efg|h|ijk|lmn|o|pq|rstuvwx|yz", "pqr", 0, 2);
+ n("a|b|cd|efg|h|ijk|lmn|o|pq|rstuvwx|yz", "mn");
+ x2("a|^z", "ba", 1, 2);
+ x2("a|^z", "za", 0, 1);
+ x2("a|\\Gz", "bza", 2, 3);
+ x2("a|\\Gz", "za", 0, 1);
+ x2("a|\\Az", "bza", 2, 3);
+ x2("a|\\Az", "za", 0, 1);
+ x2("a|b\\Z", "ba", 1, 2);
+ x2("a|b\\Z", "b", 0, 1);
+ x2("a|b\\z", "ba", 1, 2);
+ x2("a|b\\z", "b", 0, 1);
+ x2("\\w|\\s", " ", 0, 1);
+ n("\\w|\\w", " ");
+ x2("\\w|%", "%", 0, 1);
+ x2("\\w|[&$]", "&", 0, 1);
+ x2("[b-d]|[^e-z]", "a", 0, 1);
+ x2("(?:a|[c-f])|bz", "dz", 0, 1);
+ x2("(?:a|[c-f])|bz", "bz", 0, 2);
+ x2("abc|(?=zz)..f", "zzf", 0, 3);
+ x2("abc|(?!zz)..f", "abf", 0, 3);
+ x2("(?=za)..a|(?=zz)..a", "zza", 0, 3);
+ n("(?>a|abd)c", "abdc");
+ x2("(?>abd|a)c", "abdc", 0, 4);
+ x2("a?|b", "a", 0, 1);
+ x2("a?|b", "b", 0, 0);
+ x2("a?|b", "", 0, 0);
+ x2("a*|b", "aa", 0, 2);
+ x2("a*|b*", "ba", 0, 0);
+ x2("a*|b*", "ab", 0, 1);
+ x2("a+|b*", "", 0, 0);
+ x2("a+|b*", "bbb", 0, 3);
+ x2("a+|b*", "abbb", 0, 1);
+ n("a+|b+", "");
+ x2("(a|b)?", "b", 0, 1);
+ x2("(a|b)*", "ba", 0, 2);
+ x2("(a|b)+", "bab", 0, 3);
+ x2("(ab|ca)+", "caabbc", 0, 4);
+ x2("(ab|ca)+", "aabca", 1, 5);
+ x2("(ab|ca)+", "abzca", 0, 2);
+ x2("(a|bab)+", "ababa", 0, 5);
+ x2("(a|bab)+", "ba", 1, 2);
+ x2("(a|bab)+", "baaaba", 1, 4);
+ x2("(?:a|b)(?:a|b)", "ab", 0, 2);
+ x2("(?:a*|b*)(?:a*|b*)", "aaabbb", 0, 3);
+ x2("(?:a*|b*)(?:a+|b+)", "aaabbb", 0, 6);
+ x2("(?:a+|b+){2}", "aaabbb", 0, 6);
+ x2("h{0,}", "hhhh", 0, 4);
+ x2("(?:a+|b+){1,2}", "aaabbb", 0, 6);
+ n("ax{2}*a", "0axxxa1");
+ n("a.{0,2}a", "0aXXXa0");
+ n("a.{0,2}?a", "0aXXXa0");
+ n("a.{0,2}?a", "0aXXXXa0");
+ x2("^a{2,}?a$", "aaa", 0, 3);
+ x2("^[a-z]{2,}?$", "aaa", 0, 3);
+ x2("(?:a+|\\Ab*)cc", "cc", 0, 2);
+ n("(?:a+|\\Ab*)cc", "abcc");
+ x2("(?:^a+|b+)*c", "aabbbabc", 6, 8);
+ x2("(?:^a+|b+)*c", "aabbbbc", 0, 7);
+ x2("a|(?i)c", "C", 0, 1);
+ x2("(?i)c|a", "C", 0, 1);
+ x2("(?i)c|a", "A", 0, 1);
+ x2("(?i:c)|a", "C", 0, 1);
+ n("(?i:c)|a", "A");
+ x2("[abc]?", "abc", 0, 1);
+ x2("[abc]*", "abc", 0, 3);
+ x2("[^abc]*", "abc", 0, 0);
+ n("[^abc]+", "abc");
+ x2("a?\?", "aaa", 0, 0);
+ x2("ba?\?b", "bab", 0, 3);
+ x2("a*?", "aaa", 0, 0);
+ x2("ba*?", "baa", 0, 1);
+ x2("ba*?b", "baab", 0, 4);
+ x2("a+?", "aaa", 0, 1);
+ x2("ba+?", "baa", 0, 2);
+ x2("ba+?b", "baab", 0, 4);
+ x2("(?:a?)?\?", "a", 0, 0);
+ x2("(?:a?\?)?", "a", 0, 0);
+ x2("(?:a?)+?", "aaa", 0, 1);
+ x2("(?:a+)?\?", "aaa", 0, 0);
+ x2("(?:a+)?\?b", "aaab", 0, 4);
+ x2("(?:ab)?{2}", "", 0, 0);
+ x2("(?:ab)?{2}", "ababa", 0, 4);
+ x2("(?:ab)*{0}", "ababa", 0, 0);
+ x2("(?:ab){3,}", "abababab", 0, 8);
+ n("(?:ab){3,}", "abab");
+ x2("(?:ab){2,4}", "ababab", 0, 6);
+ x2("(?:ab){2,4}", "ababababab", 0, 8);
+ x2("(?:ab){2,4}?", "ababababab", 0, 4);
+ x2("(?:ab){,}", "ab{,}", 0, 5);
+ x2("(?:abc)+?{2}", "abcabcabc", 0, 6);
+ x2("(?:X*)(?i:xa)", "XXXa", 0, 4);
+ x2("(d+)([^abc]z)", "dddz", 0, 4);
+ x2("([^abc]*)([^abc]z)", "dddz", 0, 4);
+ x2("(\\w+)(\\wz)", "dddz", 0, 4);
+ x3("(a)", "a", 0, 1, 1);
+ x3("(ab)", "ab", 0, 2, 1);
+ x2("((ab))", "ab", 0, 2);
+ x3("((ab))", "ab", 0, 2, 1);
+ x3("((ab))", "ab", 0, 2, 2);
+ x3("((((((((((((((((((((ab))))))))))))))))))))", "ab", 0, 2, 20);
+ x3("(ab)(cd)", "abcd", 0, 2, 1);
+ x3("(ab)(cd)", "abcd", 2, 4, 2);
+ x3("()(a)bc(def)ghijk", "abcdefghijk", 3, 6, 3);
+ x3("(()(a)bc(def)ghijk)", "abcdefghijk", 3, 6, 4);
+ x2("(^a)", "a", 0, 1);
+ x3("(a)|(a)", "ba", 1, 2, 1);
+ x3("(^a)|(a)", "ba", 1, 2, 2);
+ x3("(a?)", "aaa", 0, 1, 1);
+ x3("(a*)", "aaa", 0, 3, 1);
+ x3("(a*)", "", 0, 0, 1);
+ x3("(a+)", "aaaaaaa", 0, 7, 1);
+ x3("(a+|b*)", "bbbaa", 0, 3, 1);
+ x3("(a+|b?)", "bbbaa", 0, 1, 1);
+ x3("(abc)?", "abc", 0, 3, 1);
+ x3("(abc)*", "abc", 0, 3, 1);
+ x3("(abc)+", "abc", 0, 3, 1);
+ x3("(xyz|abc)+", "abc", 0, 3, 1);
+ x3("([xyz][abc]|abc)+", "abc", 0, 3, 1);
+ x3("((?i:abc))", "AbC", 0, 3, 1);
+ x2("(abc)(?i:\\1)", "abcABC", 0, 6);
+ x3("((?m:a.c))", "a\nc", 0, 3, 1);
+ x3("((?=az)a)", "azb", 0, 1, 1);
+ x3("abc|(.abd)", "zabd", 0, 4, 1);
+ x2("(?:abc)|(ABC)", "abc", 0, 3);
+ x3("(?i:(abc))|(zzz)", "ABC", 0, 3, 1);
+ x3("a*(.)", "aaaaz", 4, 5, 1);
+ x3("a*?(.)", "aaaaz", 0, 1, 1);
+ x3("a*?(c)", "aaaac", 4, 5, 1);
+ x3("[bcd]a*(.)", "caaaaz", 5, 6, 1);
+ x3("(\\Abb)cc", "bbcc", 0, 2, 1);
+ n("(\\Abb)cc", "zbbcc");
+ x3("(^bb)cc", "bbcc", 0, 2, 1);
+ n("(^bb)cc", "zbbcc");
+ x3("cc(bb$)", "ccbb", 2, 4, 1);
+ n("cc(bb$)", "ccbbb");
+ n("(\\1)", "");
+ n("\\1(a)", "aa");
+ n("(a(b)\\1)\\2+", "ababb");
+ n("(?:(?:\\1|z)(a))+$", "zaa");
+ x2("(?:(?:\\1|z)(a))+$", "zaaa", 0, 4);
+ x2("(a)(?=\\1)", "aa", 0, 1);
+ n("(a)$|\\1", "az");
+ x2("(a)\\1", "aa", 0, 2);
+ n("(a)\\1", "ab");
+ x2("(a?)\\1", "aa", 0, 2);
+ x2("(a?\?)\\1", "aa", 0, 0);
+ x2("(a*)\\1", "aaaaa", 0, 4);
+ x3("(a*)\\1", "aaaaa", 0, 2, 1);
+ x2("a(b*)\\1", "abbbb", 0, 5);
+ x2("a(b*)\\1", "ab", 0, 1);
+ x2("(a*)(b*)\\1\\2", "aaabbaaabb", 0, 10);
+ x2("(a*)(b*)\\2", "aaabbbb", 0, 7);
+ x2("(((((((a*)b))))))c\\7", "aaabcaaa", 0, 8);
+ x3("(((((((a*)b))))))c\\7", "aaabcaaa", 0, 3, 7);
+ x2("(a)(b)(c)\\2\\1\\3", "abcbac", 0, 6);
+ x2("([a-d])\\1", "cc", 0, 2);
+ x2("(\\w\\d\\s)\\1", "f5 f5 ", 0, 6);
+ n("(\\w\\d\\s)\\1", "f5 f5");
+ x2("(who|[a-c]{3})\\1", "whowho", 0, 6);
+ x2("...(who|[a-c]{3})\\1", "abcwhowho", 0, 9);
+ x2("(who|[a-c]{3})\\1", "cbccbc", 0, 6);
+ x2("(^a)\\1", "aa", 0, 2);
+ n("(^a)\\1", "baa");
+ n("(a$)\\1", "aa");
+ n("(ab\\Z)\\1", "ab");
+ x2("(a*\\Z)\\1", "a", 1, 1);
+ x2(".(a*\\Z)\\1", "ba", 1, 2);
+ x3("(.(abc)\\2)", "zabcabc", 0, 7, 1);
+ x3("(.(..\\d.)\\2)", "z12341234", 0, 9, 1);
+ x2("((?i:az))\\1", "AzAz", 0, 4);
+ n("((?i:az))\\1", "Azaz");
+ x2("(?<=a)b", "ab", 1, 2);
+ n("(?<=a)b", "bb");
+ x2("(?<=a|b)b", "bb", 1, 2);
+ x2("(?<=a|bc)b", "bcb", 2, 3);
+ x2("(?<=a|bc)b", "ab", 1, 2);
+ x2("(?<=a|bc||defghij|klmnopq|r)z", "rz", 1, 2);
+ x2("(a)\\g<1>", "aa", 0, 2);
+ x2("(?<!a)b", "cb", 1, 2);
+ n("(?<!a)b", "ab");
+ x2("(?<!a|bc)b", "bbb", 0, 1);
+ n("(?<!a|bc)z", "bcz");
+ x2("(?<name1>a)", "a", 0, 1);
+ x2("(?<name_2>ab)\\g<name_2>", "abab", 0, 4);
+ x2("(?<name_3>.zv.)\\k<name_3>", "azvbazvb", 0, 8);
+ x2("(?<=\\g<ab>)|-\\zEND (?<ab>XyZ)", "XyZ", 3, 3);
+ x2("(?<n>|a\\g<n>)+", "", 0, 0);
+ x2("(?<n>|\\(\\g<n>\\))+$", "()(())", 0, 6);
+ x3("\\g<n>(?<n>.){0}", "X", 0, 1, 1);
+ x2("\\g<n>(abc|df(?<n>.YZ){2,8}){0}", "XYZ", 0, 3);
+ x2("\\A(?<n>(a\\g<n>)|)\\z", "aaaa", 0, 4);
+ x2("(?<n>|\\g<m>\\g<n>)\\z|\\zEND (?<m>a|(b)\\g<m>)", "bbbbabba", 0, 8);
+ x2("(?<name1240>\\w+\\sx)a+\\k<name1240>", " fg xaaaaaaaafg x", 2, 18);
+ x3("(z)()()(?<_9>a)\\g<_9>", "zaa", 2, 3, 1);
+ x2("(.)(((?<_>a)))\\k<_>", "zaa", 0, 3);
+ x2("((?<name1>\\d)|(?<name2>\\w))(\\k<name1>|\\k<name2>)", "ff", 0, 2);
+ x2("(?:(?<x>)|(?<x>efg))\\k<x>", "", 0, 0);
+ x2("(?:(?<x>abc)|(?<x>efg))\\k<x>", "abcefgefg", 3, 9);
+ n("(?:(?<x>abc)|(?<x>efg))\\k<x>", "abcefg");
+ x2("(?:(?<n1>.)|(?<n1>..)|(?<n1>...)|(?<n1>....)|(?<n1>.....)|(?<n1>......)|(?<n1>.......)|(?<n1>........)|(?<n1>.........)|(?<n1>..........)|(?<n1>...........)|(?<n1>............)|(?<n1>.............)|(?<n1>..............))\\k<n1>$", "a-pyumpyum", 2, 10);
+ x3("(?:(?<n1>.)|(?<n1>..)|(?<n1>...)|(?<n1>....)|(?<n1>.....)|(?<n1>......)|(?<n1>.......)|(?<n1>........)|(?<n1>.........)|(?<n1>..........)|(?<n1>...........)|(?<n1>............)|(?<n1>.............)|(?<n1>..............))\\k<n1>$", "xxxxabcdefghijklmnabcdefghijklmn", 4, 18, 14);
+ x3("(?<name1>)(?<name2>)(?<name3>)(?<name4>)(?<name5>)(?<name6>)(?<name7>)(?<name8>)(?<name9>)(?<name10>)(?<name11>)(?<name12>)(?<name13>)(?<name14>)(?<name15>)(?<name16>aaa)(?<name17>)$", "aaa", 0, 3, 16);
+ x2("(?<foo>a|\\(\\g<foo>\\))", "a", 0, 1);
+ x2("(?<foo>a|\\(\\g<foo>\\))", "((((((a))))))", 0, 13);
+ x3("(?<foo>a|\\(\\g<foo>\\))", "((((((((a))))))))", 0, 17, 1);
+ x2("\\g<bar>|\\zEND(?<bar>.*abc$)", "abcxxxabc", 0, 9);
+ x2("\\g<1>|\\zEND(.a.)", "bac", 0, 3);
+ x3("\\g<_A>\\g<_A>|\\zEND(.a.)(?<_A>.b.)", "xbxyby", 3, 6, 1);
+ x2("\\A(?:\\g<pon>|\\g<pan>|\\zEND (?<pan>a|c\\g<pon>c)(?<pon>b|d\\g<pan>d))$", "cdcbcdc", 0, 7);
+ x2("\\A(?<n>|a\\g<m>)\\z|\\zEND (?<m>\\g<n>)", "aaaa", 0, 4);
+ x2("(?<n>(a|b\\g<n>c){3,5})", "baaaaca", 1, 5);
+ x2("(?<n>(a|b\\g<n>c){3,5})", "baaaacaaaaa", 0, 10);
+ x2("(?<pare>\\(([^\\(\\)]++|\\g<pare>)*+\\))", "((a))", 0, 5);
+ x2("()*\\1", "", 0, 0);
+ x2("(?:()|())*\\1\\2", "", 0, 0);
+ x3("(?:\\1a|())*", "a", 0, 0, 1);
+ x2("x((.)*)*x", "0x1x2x3", 1, 6);
+ x2("x((.)*)*x(?i:\\1)\\Z", "0x1x2x1X2", 1, 9);
+ x2("(?:()|()|()|()|()|())*\\2\\5", "", 0, 0);
+ x2("(?:()|()|()|(x)|()|())*\\2b\\5", "b", 0, 1);
+ x2("\\xED\\xF2", "\xed\xf2", 0, 2);
+ x2("", "", 0, 0);
+ x2("", "", 0, 2);
+ n("", "");
+ x2("", "", 0, 4);
+ x2("", "", 0, 6);
+ x2("", "", 0, 70);
+ x2("", "", 2, 4);
+ x2("", "", 2, 6);
+ x2("\\xca\\xb8", "\xca\xb8", 0, 2);
+ x2(".", "", 0, 2);
+ x2("..", "", 0, 4);
+ x2("\\w", "", 0, 2);
+ n("\\W", "");
+ x2("[\\W]", "$", 2, 3);
+ x2("\\S", "", 0, 2);
+ x2("\\S", "", 0, 2);
+ x2("\\b", "C ", 0, 0);
+ x2("\\b", " ", 1, 1);
+ x2("\\B", " ", 2, 2);
+ x2("\\B", " ", 3, 3);
+ x2("\\B", " ", 0, 0);
+ x2("[]", "", 0, 2);
+ n("[Ȃ]", "");
+ x2("[-]", "", 0, 2);
+ n("[^]", "");
+ x2("[\\w]", "", 0, 2);
+ n("[\\d]", "");
+ x2("[\\D]", "", 0, 2);
+ n("[\\s]", "");
+ x2("[\\S]", "", 0, 2);
+ x2("[\\w\\d]", "", 0, 2);
+ x2("[\\w\\d]", " ", 3, 5);
+ n("\\wS", " S");
+ x2("S\\W", "S ", 0, 5);
+ x2("..", "", 0, 10);
+ x2(".\\w\\W..", " ", 0, 13);
+ x2("\\s\\w", " ", 0, 9);
+ x2(".", "", 0, 8);
+ n(".", "");
+ x2(".", "", 0, 4);
+ x2("^", "", 0, 2);
+ x2("^$", "", 0, 2);
+ x2("^\\w$", "", 0, 2);
+ x2("^\\w$", "z", 0, 11);
+ x2("^\\w...$", "z", 0, 13);
+ x2("\\w\\w\\s\\W\\d", "a 4", 0, 12);
+ x2("\\A", "", 0, 6);
+ x2("ނ߂\\Z", "ނ߂", 0, 6);
+ x2("\\z", "", 0, 6);
+ x2("\\Z", "\n", 0, 6);
+ x2("\\Gۂ", "ۂ", 0, 4);
+ n("\\G", "");
+ n("Ƃ\\G", "Ƃ");
+ n("܂\\A", "܂");
+ n("\\A", "܂");
+ x2("(?=)", "", 0, 2);
+ n("(?=).", "");
+ x2("(?!)", "", 0, 2);
+ n("(?!)", "");
+ x2("(?i:)", "", 0, 2);
+ x2("(?i:Ԃ)", "Ԃ", 0, 4);
+ n("(?i:)", "");
+ x2("(?m:.)", "\n", 0, 3);
+ x2("(?m:.)", "\n", 2, 5);
+ x2("?", "", 0, 0);
+ x2("?", "", 0, 0);
+ x2("?", "", 0, 2);
+ x2("*", "", 0, 0);
+ x2("*", "", 0, 2);
+ x2("q*", "qqq", 0, 6);
+ x2("n*", "nnnn", 0, 0);
+ n("R+", "");
+ x2("+", "", 0, 2);
+ x2("+", "", 0, 8);
+ x2("+", "", 0, 4);
+ x2("+", "", 2, 10);
+ x2(".?", "", 0, 2);
+ x2(".*", "ς҂Ղ", 0, 8);
+ x2(".+", "", 0, 2);
+ x2(".+", "\n", 0, 8);
+ x2("|", "", 0, 2);
+ x2("|", "", 0, 2);
+ x2("|", "", 0, 4);
+ x2("|", "", 0, 4);
+ x2("(?:|)", "", 0, 6);
+ x2("(?:|)", "", 0, 8);
+ x2("|(?:|)", "", 0, 4);
+ x2("||", "", 2, 4);
+ x2("|||||||||‚ĂƂȂ|ʂ", "", 0, 6);
+ n("|||||||||‚ĂƂȂ|ʂ", "");
+ x2("|^", "Ԃ", 2, 4);
+ x2("|^", "", 0, 2);
+ x2("S|\\G", "ԋS", 4, 6);
+ x2("S|\\G", "ԋS", 0, 2);
+ x2("S|\\A", "bԋS", 3, 5);
+ x2("S|\\A", "", 0, 2);
+ x2("S|\\Z", "ԋS", 2, 4);
+ x2("S|\\Z", "", 0, 2);
+ x2("S|\\Z", "\n", 0, 2);
+ x2("S|\\z", "ԋS", 2, 4);
+ x2("S|\\z", "", 0, 2);
+ x2("\\w|\\s", "", 0, 2);
+ x2("\\w|%", "%", 0, 1);
+ x2("\\w|[&$]", "&", 0, 2);
+ x2("[-]", "", 0, 2);
+ x2("[-]|[^-]", "", 0, 2);
+ x2("[-]|[^-]", "", 0, 2);
+ x2("[^]", "\n", 0, 1);
+ x2("(?:|[-])|", "", 0, 2);
+ x2("(?:|[-])|", "", 0, 4);
+ x2("|(?=)..", "", 0, 6);
+ x2("|(?!)..", "", 0, 6);
+ x2("(?=)..|(?=)..", "", 0, 6);
+ x2("(?<=|)", "", 4, 6);
+ n("(?>|)", "");
+ x2("(?>|)", "", 0, 8);
+ x2("?|", "", 0, 2);
+ x2("?|", "", 0, 0);
+ x2("?|", "", 0, 0);
+ x2("*|", "", 0, 4);
+ x2("*|*", "", 0, 0);
+ x2("*|*", "", 0, 2);
+ x2("[a]*|*", "a", 0, 3);
+ x2("+|*", "", 0, 0);
+ x2("+|*", "", 0, 6);
+ x2("+|*", "", 0, 2);
+ x2("+|*", "a", 0, 0);
+ n("+|+", "");
+ x2("(|)?", "", 0, 2);
+ x2("(|)*", "", 0, 4);
+ x2("(|)+", "", 0, 6);
+ x2("(|)+", "", 0, 8);
+ x2("(|)+", "", 4, 12);
+ x2("(|)+", "", 2, 10);
+ x2("(|)+", "", 0, 4);
+ x2("(|)+", "$$zzzz", 6, 10);
+ x2("(|)+", "", 0, 10);
+ x2("(|)+", "", 2, 4);
+ x2("(|)+", "", 2, 8);
+ x2("(?:|)(?:|)", "", 0, 4);
+ x2("(?:*|*)(?:*|*)", "", 0, 6);
+ x2("(?:*|*)(?:+|+)", "", 0, 12);
+ x2("(?:+|+){2}", "", 0, 12);
+ x2("(?:+|+){1,2}", "", 0, 12);
+ x2("(?:+|\\A*)", "", 0, 4);
+ n("(?:+|\\A*)", "");
+ x2("(?:^+|+)*", "", 12, 16);
+ x2("(?:^+|+)*", "", 0, 14);
+ x2("{0,}", "", 0, 8);
+ x2("|(?i)c", "C", 0, 1);
+ x2("(?i)c|", "C", 0, 1);
+ x2("(?i:)|a", "a", 0, 1);
+ n("(?i:)|a", "A");
+ x2("[]?", "", 0, 2);
+ x2("[]*", "", 0, 6);
+ x2("[^]*", "", 0, 0);
+ n("[^]+", "");
+ x2("?\?", "", 0, 0);
+ x2("?\?", "", 0, 6);
+ x2("*?", "", 0, 0);
+ x2("*?", "", 0, 2);
+ x2("*?", "", 0, 8);
+ x2("+?", "", 0, 2);
+ x2("+?", "", 0, 4);
+ x2("+?", "", 0, 8);
+ x2("(?:V?)?\?", "V", 0, 0);
+ x2("(?:V?\?)?", "V", 0, 0);
+ x2("(?:?)+?", "", 0, 2);
+ x2("(?:+)?\?", "", 0, 0);
+ x2("(?:+)?\?", "ᑚ", 0, 8);
+ x2("(?:)?{2}", "", 0, 0);
+ x2("(?:S)?{2}", "SԋSԋS", 0, 8);
+ x2("(?:S)*{0}", "SԋSԋS", 0, 0);
+ x2("(?:S){3,}", "SԋSԋSԋS", 0, 16);
+ n("(?:S){3,}", "SԋS");
+ x2("(?:S){2,4}", "SԋSԋS", 0, 12);
+ x2("(?:S){2,4}", "SԋSԋSԋSԋS", 0, 16);
+ x2("(?:S){2,4}?", "SԋSԋSԋSԋS", 0, 8);
+ x2("(?:S){,}", "S{,}", 0, 7);
+ x2("(?:)+?{2}", "", 0, 12);
+ x3("()", "", 0, 2, 1);
+ x3("(ΐ)", "ΐ", 0, 4, 1);
+ x2("(())", "", 0, 4);
+ x3("(())", "", 0, 4, 1);
+ x3("(())", "", 0, 4, 2);
+ x3("((((((((((((((((((((ʎq))))))))))))))))))))", "ʎq", 0, 4, 20);
+ x3("()()", "", 0, 4, 1);
+ x3("()()", "", 4, 8, 2);
+ x3("()()()", "", 6, 12, 3);
+ x3("(()()())", "", 6, 12, 4);
+ x3(".*(tH)E}(()V^)C", "tHE}V^C", 10, 18, 2);
+ x2("(^)", "", 0, 2);
+ x3("()|()", "", 2, 4, 1);
+ x3("(^)|()", "", 2, 4, 2);
+ x3("(?)", "", 0, 2, 1);
+ x3("(*)", "܂܂", 0, 6, 1);
+ x3("(*)", "", 0, 0, 1);
+ x3("(+)", "", 0, 14, 1);
+ x3("(+|*)", "ӂӂӂւ", 0, 6, 1);
+ x3("(+|?)", "", 0, 2, 1);
+ x3("()?", "", 0, 6, 1);
+ x3("()*", "", 0, 6, 1);
+ x3("()+", "", 0, 6, 1);
+ x3("(|)+", "", 0, 6, 1);
+ x3("([Ȃɂ][]|)+", "", 0, 6, 1);
+ x3("((?i:))", "", 0, 6, 1);
+ x3("((?m:.))", "\n", 0, 5, 1);
+ x3("((?=))", "", 0, 2, 1);
+ x3("|(.)", "񂠂", 0, 8, 1);
+ x3("*(.)", "", 8, 10, 1);
+ x3("*?(.)", "", 0, 2, 1);
+ x3("*?()", "", 8, 10, 1);
+ x3("[]*(.)", "", 10, 12, 1);
+ x3("(\\A)", "", 0, 4, 1);
+ n("(\\A)", "񂢂");
+ x3("(^)", "", 0, 4, 1);
+ n("(^)", "񂢂");
+ x3("($)", "", 4, 8, 1);
+ n("($)", "");
+ x2("()\\1", "", 0, 4);
+ n("()\\1", "");
+ x2("(?)\\1", "", 0, 4);
+ x2("(?\?)\\1", "", 0, 0);
+ x2("(*)\\1", "", 0, 8);
+ x3("(*)\\1", "", 0, 4, 1);
+ x2("(*)\\1", "", 0, 10);
+ x2("(*)\\1", "", 0, 2);
+ x2("(*)(*)\\1\\2", "", 0, 20);
+ x2("(*)(*)\\2", "", 0, 14);
+ x3("(*)(*)\\2", "", 6, 10, 2);
+ x2("(((((((*)))))))\\7", "ۂۂۂ؂҂ۂۂ", 0, 16);
+ x3("(((((((*)))))))\\7", "ۂۂۂ؂҂ۂۂ", 0, 6, 7);
+ x2("()()()\\2\\1\\3", "͂ЂӂЂ͂", 0, 12);
+ x2("([-])\\1", "", 0, 4);
+ x2("(\\w\\d\\s)\\1", "5 5 ", 0, 8);
+ n("(\\w\\d\\s)\\1", "5 5");
+ x2("(NH|[-]{3})\\1", "NHNH", 0, 8);
+ x2("...(NH|[-]{3})\\1", "aNHNH", 0, 13);
+ x2("(NH|[-]{3})\\1", "", 0, 12);
+ x2("(^)\\1", "", 0, 4);
+ n("(^)\\1", "߂ނ");
+ n("($)\\1", "");
+ n("(\\Z)\\1", "");
+ x2("(*\\Z)\\1", "", 2, 2);
+ x2(".(*\\Z)\\1", "", 2, 4);
+ x3("(.(₢)\\2)", "z₢₢", 0, 13, 1);
+ x3("(.(..\\d.)\\2)", "12341234", 0, 10, 1);
+ x2("((?i:v))\\1", "vv", 0, 10);
+ x2("(?<>|\\(\\g<>\\))", "(((((())))))", 0, 14);
+ x2("\\A(?:\\g<_1>|\\g<]_2>|\\zI (?<_1>|\\g<]_2>)(?<]_2>|F\\g<_1>F))$", "FFݎFF", 0, 26);
+ x2("[[Ђ]]", "", 0, 2);
+ x2("[[]]", "", 0, 2);
+ n("[[^]]", "");
+ n("[^[]]", "");
+ x2("[^[^]]", "", 0, 2);
+ x2("[[]&&]", "", 0, 2);
+ n("[[]&&]", "");
+ n("[[]&&]", "");
+ x2("[-&&-&&-]", "", 0, 2);
+ n("[^-&&-&&-]", "");
+ x2("[[^&&]&&-]", "", 0, 2);
+ n("[[^&&]&&-]", "");
+ x2("[[^-&&]&&[^-]]", "", 0, 2);
+ n("[[^-&&]&&[^-]]", "");
+ x2("[^[^]&&[^]]", "", 0, 2);
+ x2("[^[^]&&[^]]", "", 0, 2);
+ n("[^[^]&&[^]]", "");
+ x2("[-&&-]", "-", 0, 1);
+ x2("[^[^a-z]&&[^bcdefg]q-w]", "", 0, 2);
+ x2("[^[^a-z]&&[^bcdefg]g-w]", "f", 0, 1);
+ x2("[^[^a-z]&&[^bcdefg]g-w]", "g", 0, 1);
+ n("[^[^a-z]&&[^bcdefg]g-w]", "2");
+ x2("a<b>o[W̃_E[h<\\/b>", "a<b>o[W̃_E[h</b>", 0, 32);
+ x2(".<b>o[W̃_E[h<\\/b>", "a<b>o[W̃_E[h</b>", 0, 32);
+ fprintf(stdout,
+ "\nRESULT SUCC: %d, FAIL: %d, ERROR: %d (by Oniguruma %s)\n",
+ nsucc, nfail, nerror, onig_version());
+
+#ifndef POSIX_TEST
+ onig_region_free(region, 1);
+ onig_end();
+#endif
+
+ return ((nfail == 0 && nerror == 0) ? 0 : -1);
+}
diff --git a/ext/mbstring/php_mbregex.h b/ext/mbstring/php_mbregex.h
index 3ec224366a..3d2e2b8e46 100644
--- a/ext/mbstring/php_mbregex.h
+++ b/ext/mbstring/php_mbregex.h
@@ -34,7 +34,7 @@
PHP_FE(mb_eregi, arginfo_mb_eregi) \
PHP_FE(mb_ereg_replace, arginfo_mb_ereg_replace) \
PHP_FE(mb_eregi_replace, arginfo_mb_eregi_replace) \
- PHP_FE(mb_ereg_replace_callback, arginfo_mb_ereg_replace_callback) \
+ PHP_FE(mb_ereg_replace_callback, arginfo_mb_ereg_replace_callback) \
PHP_FE(mb_split, arginfo_mb_split) \
PHP_FE(mb_ereg_match, arginfo_mb_ereg_match) \
PHP_FE(mb_ereg_search, arginfo_mb_ereg_search) \
diff --git a/ext/mcrypt/config.m4 b/ext/mcrypt/config.m4
index cc68d8627b..ab954e649e 100644
--- a/ext/mcrypt/config.m4
+++ b/ext/mcrypt/config.m4
@@ -21,7 +21,7 @@ AC_DEFUN([PHP_MCRYPT_CHECK_VERSION],[
PHP_ARG_WITH(mcrypt, for mcrypt support,
-[ --with-mcrypt[=DIR] Include mcrypt support])
+[ --with-mcrypt[=DIR] Include mcrypt support])
if test "$PHP_MCRYPT" != "no"; then
for i in $PHP_MCRYPT /usr/local /usr; do
diff --git a/ext/mcrypt/mcrypt.c b/ext/mcrypt/mcrypt.c
index 55302c77f8..89ad83f6bf 100644
--- a/ext/mcrypt/mcrypt.c
+++ b/ext/mcrypt/mcrypt.c
@@ -238,10 +238,10 @@ ZEND_END_ARG_INFO()
/* }}} */
const zend_function_entry mcrypt_functions[] = { /* {{{ */
- PHP_FE(mcrypt_ecb, arginfo_mcrypt_ecb)
- PHP_FE(mcrypt_cbc, arginfo_mcrypt_cbc)
- PHP_FE(mcrypt_cfb, arginfo_mcrypt_cfb)
- PHP_FE(mcrypt_ofb, arginfo_mcrypt_ofb)
+ PHP_DEP_FE(mcrypt_ecb, arginfo_mcrypt_ecb)
+ PHP_DEP_FE(mcrypt_cbc, arginfo_mcrypt_cbc)
+ PHP_DEP_FE(mcrypt_cfb, arginfo_mcrypt_cfb)
+ PHP_DEP_FE(mcrypt_ofb, arginfo_mcrypt_ofb)
PHP_FE(mcrypt_get_key_size, arginfo_mcrypt_get_key_size)
PHP_FE(mcrypt_get_block_size, arginfo_mcrypt_get_block_size)
PHP_FE(mcrypt_get_cipher_name, arginfo_mcrypt_get_cipher_name)
@@ -1387,7 +1387,7 @@ PHP_FUNCTION(mcrypt_create_iv)
}
iv = ecalloc(size + 1, 1);
-
+
if (source == RANDOM || source == URANDOM) {
#if PHP_WIN32
/* random/urandom equivalent on Windows */
diff --git a/ext/mcrypt/tests/mcrypt_cbc.phpt b/ext/mcrypt/tests/mcrypt_cbc.phpt
index f9160db011..27cc5b2224 100644
--- a/ext/mcrypt/tests/mcrypt_cbc.phpt
+++ b/ext/mcrypt/tests/mcrypt_cbc.phpt
@@ -18,6 +18,12 @@ echo trim(mcrypt_cbc($cipher, $key, $enc_data, MCRYPT_DECRYPT, $iv)) . "\n";
mcrypt_cbc($cipher, $key, $enc_data, MCRYPT_DECRYPT);
--EXPECTF--
+
+Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d
+
+Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d
PHP Testfest 2008
+Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d
+
Warning: mcrypt_cbc(): Attempt to use an empty IV, which is NOT recommend in %s on line %d
diff --git a/ext/mcrypt/tests/mcrypt_cbc_3des_decrypt.phpt b/ext/mcrypt/tests/mcrypt_cbc_3des_decrypt.phpt
index 6df3079935..67799a3fdd 100644
--- a/ext/mcrypt/tests/mcrypt_cbc_3des_decrypt.phpt
+++ b/ext/mcrypt/tests/mcrypt_cbc_3des_decrypt.phpt
@@ -72,16 +72,24 @@ function special_var_dump($str) {
--- testing different key lengths
key length=8
+
+Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d
string(32) "736563726574206d6573736167650000"
key length=20
+
+Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d
string(32) "736563726574206d6573736167650000"
key length=24
+
+Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d
string(32) "736563726574206d6573736167650000"
key length=26
+Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d
+
Warning: mcrypt_cbc(): Size of key is too large for this algorithm in %s on line %d
string(32) "736563726574206d6573736167650000"
@@ -89,14 +97,20 @@ string(32) "736563726574206d6573736167650000"
iv length=4
+Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d
+
Warning: mcrypt_cbc(): The IV parameter must be as long as the blocksize in %s on line %d
string(32) "736563726574206d6573736167650000"
iv length=8
+
+Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d
string(32) "736563726574206d6573736167650000"
iv length=9
+Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d
+
Warning: mcrypt_cbc(): The IV parameter must be as long as the blocksize in %s on line %d
string(32) "736563726574206d6573736167650000"
===DONE===
diff --git a/ext/mcrypt/tests/mcrypt_cbc_3des_encrypt.phpt b/ext/mcrypt/tests/mcrypt_cbc_3des_encrypt.phpt
index 35fabd9aca..1af094c27b 100644
--- a/ext/mcrypt/tests/mcrypt_cbc_3des_encrypt.phpt
+++ b/ext/mcrypt/tests/mcrypt_cbc_3des_encrypt.phpt
@@ -55,16 +55,24 @@ foreach ($ivs as $iv) {
--- testing different key lengths
key length=8
+
+Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d
string(112) "082b437d039d09418e20dc9de1dafa7ed6da5c6335b78950968441da1faf40c1f886e04da8ca177b80b376811e138c1bf51cb48dae2e7939"
key length=20
+
+Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d
string(112) "0627351e0f8a082bf7981ae2c700a43fd3d44b270ac67b00fded1c5796eea935be0fef2a23da0b3f5e243929e62ac957bf0bf463aa90fc4f"
key length=24
+
+Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d
string(112) "b85e21072239d60c63a80e7c9ae493cb741a1cd407e52f451c5f43a0d103f55a7b62617eb2e44213c2d44462d388bc0b8f119384b12c84ac"
key length=26
+Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d
+
Warning: mcrypt_cbc(): Size of key is too large for this algorithm in %s on line %d
string(112) "b85e21072239d60c63a80e7c9ae493cb741a1cd407e52f451c5f43a0d103f55a7b62617eb2e44213c2d44462d388bc0b8f119384b12c84ac"
@@ -72,14 +80,20 @@ string(112) "b85e21072239d60c63a80e7c9ae493cb741a1cd407e52f451c5f43a0d103f55a7b6
iv length=4
+Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d
+
Warning: mcrypt_cbc(): The IV parameter must be as long as the blocksize in %s on line %d
string(112) "440a6f54601969b127aad3c217ce7583c7f7b29989693130645569301db0020b29a34a3dcd104b2d0e3ba19d6cbd8a33d352b9c27cc34ef1"
iv length=8
+
+Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d
string(112) "bac347506bf092c5557c4363c301745d78f047028e2953e84fd66b30aeb6005812dadbe8baa871b83278341599b0c448ddaaa52b5a378ce5"
iv length=9
+Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d
+
Warning: mcrypt_cbc(): The IV parameter must be as long as the blocksize in %s on line %d
string(112) "440a6f54601969b127aad3c217ce7583c7f7b29989693130645569301db0020b29a34a3dcd104b2d0e3ba19d6cbd8a33d352b9c27cc34ef1"
===DONE===
diff --git a/ext/mcrypt/tests/mcrypt_cbc_error.phpt b/ext/mcrypt/tests/mcrypt_cbc_error.phpt
index ec3912b03f..3c22180214 100644
--- a/ext/mcrypt/tests/mcrypt_cbc_error.phpt
+++ b/ext/mcrypt/tests/mcrypt_cbc_error.phpt
@@ -41,11 +41,15 @@ var_dump( mcrypt_cbc($cipher, $key, $data) );
-- Testing mcrypt_cbc() function with more than expected no. of arguments --
+Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d
+
Warning: mcrypt_cbc() expects at most 5 parameters, 6 given in %s on line %d
NULL
-- Testing mcrypt_cbc() function with less than expected no. of arguments --
+Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d
+
Warning: mcrypt_cbc() expects at least 4 parameters, 3 given in %s on line %d
NULL
===DONE===
diff --git a/ext/mcrypt/tests/mcrypt_cbc_variation1.phpt b/ext/mcrypt/tests/mcrypt_cbc_variation1.phpt
index 5482de3e20..eb233e3f92 100644
--- a/ext/mcrypt/tests/mcrypt_cbc_variation1.phpt
+++ b/ext/mcrypt/tests/mcrypt_cbc_variation1.phpt
@@ -124,106 +124,132 @@ fclose($fp);
*** Testing mcrypt_cbc() : usage variation ***
--int 0--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): Module initialization failed, %s(%d)
bool(false)
--int 1--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): Module initialization failed, %s(%d)
bool(false)
--int 12345--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): Module initialization failed, %s(%d)
bool(false)
--int -12345--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): Module initialization failed, %s(%d)
bool(false)
--float 10.5--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): Module initialization failed, %s(%d)
bool(false)
--float -10.5--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): Module initialization failed, %s(%d)
bool(false)
--float 12.3456789000e10--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): Module initialization failed, %s(%d)
bool(false)
--float -12.3456789000e10--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): Module initialization failed, %s(%d)
bool(false)
--float .5--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): Module initialization failed, %s(%d)
bool(false)
--empty array--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc() expects parameter 1 to be string, array given, %s(%d)
NULL
--int indexed array--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc() expects parameter 1 to be string, array given, %s(%d)
NULL
--associative array--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc() expects parameter 1 to be string, array given, %s(%d)
NULL
--nested arrays--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc() expects parameter 1 to be string, array given, %s(%d)
NULL
--uppercase NULL--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): Module initialization failed, %s(%d)
bool(false)
--lowercase null--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): Module initialization failed, %s(%d)
bool(false)
--lowercase true--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): Module initialization failed, %s(%d)
bool(false)
--lowercase false--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): Module initialization failed, %s(%d)
bool(false)
--uppercase TRUE--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): Module initialization failed, %s(%d)
bool(false)
--uppercase FALSE--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): Module initialization failed, %s(%d)
bool(false)
--empty string DQ--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): Module initialization failed, %s(%d)
bool(false)
--empty string SQ--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): Module initialization failed, %s(%d)
bool(false)
--instance of classWithToString--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): Module initialization failed, %s(%d)
bool(false)
--instance of classWithoutToString--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc() expects parameter 1 to be string, object given, %s(%d)
NULL
--undefined var--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): Module initialization failed, %s(%d)
bool(false)
--unset var--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): Module initialization failed, %s(%d)
bool(false)
--resource--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc() expects parameter 1 to be string, resource given, %s(%d)
NULL
===DONE===
diff --git a/ext/mcrypt/tests/mcrypt_cbc_variation2.phpt b/ext/mcrypt/tests/mcrypt_cbc_variation2.phpt
index f49e80ee93..3d2a061472 100644
--- a/ext/mcrypt/tests/mcrypt_cbc_variation2.phpt
+++ b/ext/mcrypt/tests/mcrypt_cbc_variation2.phpt
@@ -124,87 +124,112 @@ fclose($fp);
*** Testing mcrypt_cbc() : usage variation ***
--int 0--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "bc27b3a4e33b531d5983fc7df693cd09"
--int 1--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "bc27b3a4e33b531d5983fc7df693cd09"
--int 12345--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "d109b7973383127002474ae731c4b3a8"
--int -12345--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "3e82a931cedb03a38b91a637ff8c9f9e"
--float 10.5--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "de71833586c1d7132a289960ebeeca7a"
--float -10.5--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "7d0489dd2e99ae910ecc015573f3dd16"
--float 12.3456789000e10--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "978055b42c0506a8947e3c3c8d994baf"
--float -12.3456789000e10--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "4aa84ba400c2b8ef467d4d98372b4f4e"
--float .5--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "e731dc5059b84e0c8774ac490f77d6e6"
--empty array--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc() expects parameter 2 to be string, array given, %s(%d)
string(0) ""
--int indexed array--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc() expects parameter 2 to be string, array given, %s(%d)
string(0) ""
--associative array--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc() expects parameter 2 to be string, array given, %s(%d)
string(0) ""
--nested arrays--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc() expects parameter 2 to be string, array given, %s(%d)
string(0) ""
--uppercase NULL--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "be722a5ffc361d721fbcab1eacc6acf5"
--lowercase null--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "be722a5ffc361d721fbcab1eacc6acf5"
--lowercase true--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "bc27b3a4e33b531d5983fc7df693cd09"
--lowercase false--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "be722a5ffc361d721fbcab1eacc6acf5"
--uppercase TRUE--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "bc27b3a4e33b531d5983fc7df693cd09"
--uppercase FALSE--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "be722a5ffc361d721fbcab1eacc6acf5"
--empty string DQ--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "be722a5ffc361d721fbcab1eacc6acf5"
--empty string SQ--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "be722a5ffc361d721fbcab1eacc6acf5"
--instance of classWithToString--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "19420fa26f561ee82ed84abbcd2d284b"
--instance of classWithoutToString--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc() expects parameter 2 to be string, object given, %s(%d)
string(0) ""
--undefined var--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "be722a5ffc361d721fbcab1eacc6acf5"
--unset var--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "be722a5ffc361d721fbcab1eacc6acf5"
--resource--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc() expects parameter 2 to be string, resource given, %s(%d)
string(0) ""
===DONE===
-
diff --git a/ext/mcrypt/tests/mcrypt_cbc_variation3.phpt b/ext/mcrypt/tests/mcrypt_cbc_variation3.phpt
index 5b2398ddbd..9a1464b112 100644
--- a/ext/mcrypt/tests/mcrypt_cbc_variation3.phpt
+++ b/ext/mcrypt/tests/mcrypt_cbc_variation3.phpt
@@ -124,87 +124,112 @@ fclose($fp);
*** Testing mcrypt_cbc() : usage variation ***
--int 0--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(16) "ce5fcfe737859795"
--int 1--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(16) "84df495f6cd82dd9"
--int 12345--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(16) "905ab1ae27ee9991"
--int -12345--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(16) "5835174e9c67c3e7"
--float 10.5--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(16) "28ff0601ad9e47fa"
--float -10.5--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(16) "ce9f2b6e2fc3d9f7"
--float 12.3456789000e10--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "24eb882ce9763e4018fba9b7f01b0c3e"
--float -12.3456789000e10--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "5eed30e428f32de1d7a7064d0ed4d3eb"
--float .5--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(16) "bebf2a13676e1e30"
--empty array--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc() expects parameter 3 to be string, array given, %s(%d)
string(0) ""
--int indexed array--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc() expects parameter 3 to be string, array given, %s(%d)
string(0) ""
--associative array--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc() expects parameter 3 to be string, array given, %s(%d)
string(0) ""
--nested arrays--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc() expects parameter 3 to be string, array given, %s(%d)
string(0) ""
--uppercase NULL--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(16) "206f6d3617a5ab32"
--lowercase null--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(16) "206f6d3617a5ab32"
--lowercase true--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(16) "84df495f6cd82dd9"
--lowercase false--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(16) "206f6d3617a5ab32"
--uppercase TRUE--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(16) "84df495f6cd82dd9"
--uppercase FALSE--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(16) "206f6d3617a5ab32"
--empty string DQ--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(16) "206f6d3617a5ab32"
--empty string SQ--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(16) "206f6d3617a5ab32"
--instance of classWithToString--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "7c91cdf8f8c51485034a9ee528eb016b"
--instance of classWithoutToString--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc() expects parameter 3 to be string, object given, %s(%d)
string(0) ""
--undefined var--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(16) "206f6d3617a5ab32"
--unset var--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(16) "206f6d3617a5ab32"
--resource--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc() expects parameter 3 to be string, resource given, %s(%d)
string(0) ""
===DONE===
-
diff --git a/ext/mcrypt/tests/mcrypt_cbc_variation4.phpt b/ext/mcrypt/tests/mcrypt_cbc_variation4.phpt
index f9a511f390..a3dd29ba41 100644
--- a/ext/mcrypt/tests/mcrypt_cbc_variation4.phpt
+++ b/ext/mcrypt/tests/mcrypt_cbc_variation4.phpt
@@ -124,82 +124,108 @@ fclose($fp);
*** Testing mcrypt_cbc() : usage variation ***
--float 10.5--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "983d5edc5f77fe42e2372a0339dc22b0"
--float -10.5--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "983d5edc5f77fe42e2372a0339dc22b0"
--float 12.3456789000e10--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "983d5edc5f77fe42e2372a0339dc22b0"
--float -12.3456789000e10--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "983d5edc5f77fe42e2372a0339dc22b0"
--float .5--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "5f781523f696d596e4b809d72197a0cc"
--empty array--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "5f781523f696d596e4b809d72197a0cc"
--int indexed array--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "983d5edc5f77fe42e2372a0339dc22b0"
--associative array--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "983d5edc5f77fe42e2372a0339dc22b0"
--nested arrays--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "983d5edc5f77fe42e2372a0339dc22b0"
--uppercase NULL--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "5f781523f696d596e4b809d72197a0cc"
--lowercase null--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "5f781523f696d596e4b809d72197a0cc"
--lowercase true--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "983d5edc5f77fe42e2372a0339dc22b0"
--lowercase false--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "5f781523f696d596e4b809d72197a0cc"
--uppercase TRUE--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "983d5edc5f77fe42e2372a0339dc22b0"
--uppercase FALSE--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "5f781523f696d596e4b809d72197a0cc"
--empty string DQ--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "5f781523f696d596e4b809d72197a0cc"
--empty string SQ--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "5f781523f696d596e4b809d72197a0cc"
--string DQ--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "5f781523f696d596e4b809d72197a0cc"
--string SQ--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "5f781523f696d596e4b809d72197a0cc"
--mixed case string--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "5f781523f696d596e4b809d72197a0cc"
--heredoc--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "5f781523f696d596e4b809d72197a0cc"
--instance of classWithToString--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 8 - Object of class classWithToString could not be converted to int, %s(%d)
string(32) "983d5edc5f77fe42e2372a0339dc22b0"
--instance of classWithoutToString--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 8 - Object of class classWithoutToString could not be converted to int, %s(%d)
string(32) "983d5edc5f77fe42e2372a0339dc22b0"
--undefined var--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "5f781523f696d596e4b809d72197a0cc"
--unset var--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
string(32) "5f781523f696d596e4b809d72197a0cc"
--resource--
-string(%d) %s
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
+string(32) "983d5edc5f77fe42e2372a0339dc22b0"
===DONE===
diff --git a/ext/mcrypt/tests/mcrypt_cbc_variation5.phpt b/ext/mcrypt/tests/mcrypt_cbc_variation5.phpt
index 7d49db853d..0c75c97934 100644
--- a/ext/mcrypt/tests/mcrypt_cbc_variation5.phpt
+++ b/ext/mcrypt/tests/mcrypt_cbc_variation5.phpt
@@ -124,106 +124,132 @@ fclose($fp);
*** Testing mcrypt_cbc() : usage variation ***
--int 0--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): The IV parameter must be as long as the blocksize, %s(%d)
string(32) "6438db90653c4d3080c3ceab43618c05"
--int 1--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): The IV parameter must be as long as the blocksize, %s(%d)
string(32) "6438db90653c4d3080c3ceab43618c05"
--int 12345--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): The IV parameter must be as long as the blocksize, %s(%d)
string(32) "6438db90653c4d3080c3ceab43618c05"
--int -12345--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): The IV parameter must be as long as the blocksize, %s(%d)
string(32) "6438db90653c4d3080c3ceab43618c05"
--float 10.5--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): The IV parameter must be as long as the blocksize, %s(%d)
string(32) "6438db90653c4d3080c3ceab43618c05"
--float -10.5--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): The IV parameter must be as long as the blocksize, %s(%d)
string(32) "6438db90653c4d3080c3ceab43618c05"
--float 12.3456789000e10--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): The IV parameter must be as long as the blocksize, %s(%d)
string(32) "6438db90653c4d3080c3ceab43618c05"
--float -12.3456789000e10--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): The IV parameter must be as long as the blocksize, %s(%d)
string(32) "6438db90653c4d3080c3ceab43618c05"
--float .5--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): The IV parameter must be as long as the blocksize, %s(%d)
string(32) "6438db90653c4d3080c3ceab43618c05"
--empty array--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc() expects parameter 5 to be string, array given, %s(%d)
string(0) ""
--int indexed array--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc() expects parameter 5 to be string, array given, %s(%d)
string(0) ""
--associative array--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc() expects parameter 5 to be string, array given, %s(%d)
string(0) ""
--nested arrays--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc() expects parameter 5 to be string, array given, %s(%d)
string(0) ""
--uppercase NULL--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): The IV parameter must be as long as the blocksize, %s(%d)
string(32) "6438db90653c4d3080c3ceab43618c05"
--lowercase null--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): The IV parameter must be as long as the blocksize, %s(%d)
string(32) "6438db90653c4d3080c3ceab43618c05"
--lowercase true--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): The IV parameter must be as long as the blocksize, %s(%d)
string(32) "6438db90653c4d3080c3ceab43618c05"
--lowercase false--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): The IV parameter must be as long as the blocksize, %s(%d)
string(32) "6438db90653c4d3080c3ceab43618c05"
--uppercase TRUE--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): The IV parameter must be as long as the blocksize, %s(%d)
string(32) "6438db90653c4d3080c3ceab43618c05"
--uppercase FALSE--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): The IV parameter must be as long as the blocksize, %s(%d)
string(32) "6438db90653c4d3080c3ceab43618c05"
--empty string DQ--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): The IV parameter must be as long as the blocksize, %s(%d)
string(32) "6438db90653c4d3080c3ceab43618c05"
--empty string SQ--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): The IV parameter must be as long as the blocksize, %s(%d)
string(32) "6438db90653c4d3080c3ceab43618c05"
--instance of classWithToString--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): The IV parameter must be as long as the blocksize, %s(%d)
string(32) "6438db90653c4d3080c3ceab43618c05"
--instance of classWithoutToString--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc() expects parameter 5 to be string, object given, %s(%d)
string(0) ""
--undefined var--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): The IV parameter must be as long as the blocksize, %s(%d)
string(32) "6438db90653c4d3080c3ceab43618c05"
--unset var--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc(): The IV parameter must be as long as the blocksize, %s(%d)
string(32) "6438db90653c4d3080c3ceab43618c05"
--resource--
+Error: 8192 - Function mcrypt_cbc() is deprecated, %s(%d)
Error: 2 - mcrypt_cbc() expects parameter 5 to be string, resource given, %s(%d)
string(0) ""
===DONE===
diff --git a/ext/mcrypt/tests/mcrypt_cfb.phpt b/ext/mcrypt/tests/mcrypt_cfb.phpt
index 54919c8589..11120633a5 100644
--- a/ext/mcrypt/tests/mcrypt_cfb.phpt
+++ b/ext/mcrypt/tests/mcrypt_cfb.phpt
@@ -18,6 +18,12 @@ echo trim(mcrypt_cfb($cipher, $key, $enc_data, MCRYPT_DECRYPT, $iv)) . "\n";
mcrypt_cfb($cipher, $key, $enc_data, MCRYPT_DECRYPT);
--EXPECTF--
+
+Deprecated: Function mcrypt_cfb() is deprecated in %s on line %d
+
+Deprecated: Function mcrypt_cfb() is deprecated in %s on line %d
PHP Testfest 2008
+Deprecated: Function mcrypt_cfb() is deprecated in %s on line %d
+
Warning: mcrypt_cfb(): Attempt to use an empty IV, which is NOT recommend in %s on line %d
diff --git a/ext/mcrypt/tests/mcrypt_ecb.phpt b/ext/mcrypt/tests/mcrypt_ecb.phpt
index e75d9fa6cd..b6d0a22786 100644
--- a/ext/mcrypt/tests/mcrypt_ecb.phpt
+++ b/ext/mcrypt/tests/mcrypt_ecb.phpt
@@ -18,4 +18,10 @@ echo trim(mcrypt_ecb($cipher, $key, $enc_data, MCRYPT_DECRYPT, $iv)) . "\n";
mcrypt_ecb($cipher, $key, $enc_data, MCRYPT_DECRYPT);
--EXPECTF--
+
+Deprecated: Function mcrypt_ecb() is deprecated in %s on line %d
+
+Deprecated: Function mcrypt_ecb() is deprecated in %s on line %d
PHP Testfest 2008
+
+Deprecated: Function mcrypt_ecb() is deprecated in %s on line %d
diff --git a/ext/mcrypt/tests/mcrypt_ecb_3des_decrypt.phpt b/ext/mcrypt/tests/mcrypt_ecb_3des_decrypt.phpt
index 7a5cc27f44..82f9608da8 100644
--- a/ext/mcrypt/tests/mcrypt_ecb_3des_decrypt.phpt
+++ b/ext/mcrypt/tests/mcrypt_ecb_3des_decrypt.phpt
@@ -8,6 +8,8 @@ if (!extension_loaded("mcrypt")) {
?>
--FILE--
<?php
+error_reporting(E_ALL & ~E_DEPRECATED);
+
/* Prototype : string mcrypt_ecb(int cipher, string key, string data, int mode, string iv)
* Description: ECB crypt/decrypt data using key key with cipher cipher starting with iv
* Source code: ext/mcrypt/mcrypt.c
@@ -94,4 +96,4 @@ string(32) "736563726574206d6573736167650000"
iv length=9
string(32) "736563726574206d6573736167650000"
-===DONE=== \ No newline at end of file
+===DONE===
diff --git a/ext/mcrypt/tests/mcrypt_ecb_3des_encrypt.phpt b/ext/mcrypt/tests/mcrypt_ecb_3des_encrypt.phpt
index da26b4ba83..50107b4b0f 100644
--- a/ext/mcrypt/tests/mcrypt_ecb_3des_encrypt.phpt
+++ b/ext/mcrypt/tests/mcrypt_ecb_3des_encrypt.phpt
@@ -8,6 +8,8 @@ if (!extension_loaded("mcrypt")) {
?>
--FILE--
<?php
+error_reporting(E_ALL & ~E_DEPRECATED);
+
/* Prototype : string mcrypt_ecb(int cipher, string key, string data, int mode, string iv)
* Description: ECB crypt/decrypt data using key key with cipher cipher starting with iv
* Source code: ext/mcrypt/mcrypt.c
diff --git a/ext/mcrypt/tests/mcrypt_ecb_error.phpt b/ext/mcrypt/tests/mcrypt_ecb_error.phpt
index b33034afcb..7e521f2225 100644
--- a/ext/mcrypt/tests/mcrypt_ecb_error.phpt
+++ b/ext/mcrypt/tests/mcrypt_ecb_error.phpt
@@ -8,6 +8,8 @@ if (!extension_loaded("mcrypt")) {
?>
--FILE--
<?php
+error_reporting(E_ALL & ~E_DEPRECATED);
+
/* Prototype : string mcrypt_ecb(int cipher, string key, string data, int mode, string iv)
* Description: ECB crypt/decrypt data using key key with cipher cipher starting with iv
* Source code: ext/mcrypt/mcrypt.c
diff --git a/ext/mcrypt/tests/mcrypt_ecb_variation1.phpt b/ext/mcrypt/tests/mcrypt_ecb_variation1.phpt
index 282a0cce1d..7271deec13 100644
--- a/ext/mcrypt/tests/mcrypt_ecb_variation1.phpt
+++ b/ext/mcrypt/tests/mcrypt_ecb_variation1.phpt
@@ -8,6 +8,8 @@ if (!extension_loaded("mcrypt")) {
?>
--FILE--
<?php
+error_reporting(E_ALL & ~E_DEPRECATED);
+
/* Prototype : string mcrypt_ecb(string cipher, string key, string data, int mode, string iv)
* Description: ECB crypt/decrypt data using key key with cipher cipher starting with iv
* Source code: ext/mcrypt/mcrypt.c
@@ -18,7 +20,7 @@ echo "*** Testing mcrypt_ecb() : usage variation ***\n";
// Define error handler
function test_error_handler($err_no, $err_msg, $filename, $linenum, $vars) {
- if (error_reporting() != 0) {
+ if ($err_no & error_reporting()) {
// report non-silenced errors
echo "Error: $err_no - $err_msg, $filename($linenum)\n";
}
diff --git a/ext/mcrypt/tests/mcrypt_ecb_variation2.phpt b/ext/mcrypt/tests/mcrypt_ecb_variation2.phpt
index 49e0a551f8..ed57400e0f 100644
--- a/ext/mcrypt/tests/mcrypt_ecb_variation2.phpt
+++ b/ext/mcrypt/tests/mcrypt_ecb_variation2.phpt
@@ -8,6 +8,8 @@ if (!extension_loaded("mcrypt")) {
?>
--FILE--
<?php
+error_reporting(E_ALL & ~E_DEPRECATED);
+
/* Prototype : string mcrypt_ecb(string cipher, string key, string data, int mode, string iv)
* Description: ECB crypt/decrypt data using key key with cipher cipher starting with iv
* Source code: ext/mcrypt/mcrypt.c
@@ -18,7 +20,7 @@ echo "*** Testing mcrypt_ecb() : usage variation ***\n";
// Define error handler
function test_error_handler($err_no, $err_msg, $filename, $linenum, $vars) {
- if (error_reporting() != 0) {
+ if ($err_no & error_reporting()) {
// report non-silenced errors
echo "Error: $err_no - $err_msg, $filename($linenum)\n";
}
diff --git a/ext/mcrypt/tests/mcrypt_ecb_variation3.phpt b/ext/mcrypt/tests/mcrypt_ecb_variation3.phpt
index cedda4930a..2999304563 100644
--- a/ext/mcrypt/tests/mcrypt_ecb_variation3.phpt
+++ b/ext/mcrypt/tests/mcrypt_ecb_variation3.phpt
@@ -8,6 +8,8 @@ if (!extension_loaded("mcrypt")) {
?>
--FILE--
<?php
+error_reporting(E_ALL & ~E_DEPRECATED);
+
/* Prototype : string mcrypt_ecb(string cipher, string key, string data, int mode, string iv)
* Description: ECB crypt/decrypt data using key key with cipher cipher starting with iv
* Source code: ext/mcrypt/mcrypt.c
@@ -18,7 +20,7 @@ echo "*** Testing mcrypt_ecb() : usage variation ***\n";
// Define error handler
function test_error_handler($err_no, $err_msg, $filename, $linenum, $vars) {
- if (error_reporting() != 0) {
+ if ($err_no & error_reporting()) {
// report non-silenced errors
echo "Error: $err_no - $err_msg, $filename($linenum)\n";
}
diff --git a/ext/mcrypt/tests/mcrypt_ecb_variation4.phpt b/ext/mcrypt/tests/mcrypt_ecb_variation4.phpt
index 599b4fbe70..e52040e295 100644
--- a/ext/mcrypt/tests/mcrypt_ecb_variation4.phpt
+++ b/ext/mcrypt/tests/mcrypt_ecb_variation4.phpt
@@ -8,6 +8,8 @@ if (!extension_loaded("mcrypt")) {
?>
--FILE--
<?php
+error_reporting(E_ALL & ~E_DEPRECATED);
+
/* Prototype : string mcrypt_ecb(string cipher, string key, string data, int mode, string iv)
* Description: ECB crypt/decrypt data using key key with cipher cipher starting with iv
* Source code: ext/mcrypt/mcrypt.c
@@ -18,7 +20,7 @@ echo "*** Testing mcrypt_ecb() : usage variation ***\n";
// Define error handler
function test_error_handler($err_no, $err_msg, $filename, $linenum, $vars) {
- if (error_reporting() != 0) {
+ if ($err_no & error_reporting()) {
// report non-silenced errors
echo "Error: $err_no - $err_msg, $filename($linenum)\n";
}
diff --git a/ext/mcrypt/tests/mcrypt_ecb_variation5.phpt b/ext/mcrypt/tests/mcrypt_ecb_variation5.phpt
index f64744fcdf..3f4f7f5ddb 100644
--- a/ext/mcrypt/tests/mcrypt_ecb_variation5.phpt
+++ b/ext/mcrypt/tests/mcrypt_ecb_variation5.phpt
@@ -8,6 +8,8 @@ if (!extension_loaded("mcrypt")) {
?>
--FILE--
<?php
+error_reporting(E_ALL & ~E_DEPRECATED);
+
/* Prototype : string mcrypt_ecb(string cipher, string key, string data, int mode, string iv)
* Description: ECB crypt/decrypt data using key key with cipher cipher starting with iv
* Source code: ext/mcrypt/mcrypt.c
@@ -18,7 +20,7 @@ echo "*** Testing mcrypt_ecb() : usage variation ***\n";
// Define error handler
function test_error_handler($err_no, $err_msg, $filename, $linenum, $vars) {
- if (error_reporting() != 0) {
+ if ($err_no & error_reporting()) {
// report non-silenced errors
echo "Error: $err_no - $err_msg, $filename($linenum)\n";
}
diff --git a/ext/mcrypt/tests/mcrypt_ofb.phpt b/ext/mcrypt/tests/mcrypt_ofb.phpt
index 1532c4cf29..9420353060 100644
--- a/ext/mcrypt/tests/mcrypt_ofb.phpt
+++ b/ext/mcrypt/tests/mcrypt_ofb.phpt
@@ -17,5 +17,11 @@ echo trim(mcrypt_ofb($cipher, $key, $enc_data, MCRYPT_DECRYPT, $iv)) . "\n";
// a warning must be issued if we don't use a IV on a AES cipher, that usually requires an IV
mcrypt_ofb($cipher, $key, $enc_data, MCRYPT_DECRYPT, $iv);
---EXPECT--
-PHP Testfest 2008 \ No newline at end of file
+--EXPECTF--
+
+Deprecated: Function mcrypt_ofb() is deprecated in %s on line %d
+
+Deprecated: Function mcrypt_ofb() is deprecated in %s on line %d
+PHP Testfest 2008
+
+Deprecated: Function mcrypt_ofb() is deprecated in %s on line %d
diff --git a/ext/mcrypt/tests/mcrypt_rijndael128_128BitKey.phpt b/ext/mcrypt/tests/mcrypt_rijndael128_128BitKey.phpt
index 100352a1c7..e450a69047 100644
--- a/ext/mcrypt/tests/mcrypt_rijndael128_128BitKey.phpt
+++ b/ext/mcrypt/tests/mcrypt_rijndael128_128BitKey.phpt
@@ -76,24 +76,34 @@ foreach ($ivs as $iv) {
key length=0
string(128) "4fbf24aaa789f5194260ade1acd9499402c1845cc517e8fe43cfb5b90a0df294db33ecd1a836c47d6bf6d8600512ba415e17008a1e1991f81056258d82099397"
+
+Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d
string(128) "546869732069732074686520736563726574206d657373616765207768696368206d75737420626520656e637279707465640000000000000000000000000000"
key length=0
string(128) "4fbf24aaa789f5194260ade1acd9499402c1845cc517e8fe43cfb5b90a0df294db33ecd1a836c47d6bf6d8600512ba415e17008a1e1991f81056258d82099397"
+
+Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d
string(128) "546869732069732074686520736563726574206d657373616765207768696368206d75737420626520656e637279707465640000000000000000000000000000"
key length=8
string(128) "d6a3042b278fa5816dc6f46152acbe5fd7d1813c3808c27cd969d8e10a64d0238724edfda0322f4512308f22d142df0e92bed861c2b732f7650e234df59183dc"
+
+Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d
string(128) "546869732069732074686520736563726574206d657373616765207768696368206d75737420626520656e637279707465640000000000000000000000000000"
key length=16
string(128) "dc8f957ec530acf10cd95ba7da7b6405380fe19a2941e9a8de54680512f18491bc374e5464885ae6c2ae2aa7a6cdd2fbe12a06bbc4bd59dbbfaa15f09044f101"
+
+Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d
string(128) "546869732069732074686520736563726574206d657373616765207768696368206d75737420626520656e637279707465640000000000000000000000000000"
--- testing different iv lengths
iv length=0
+Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d
+
Warning: mcrypt_cbc(): The IV parameter must be as long as the blocksize in %s on line %d
string(128) "c082b3fabaae4c8c410eb8dba64bae10e48d79b5241fb8f24462cad43bd0b35ad2746b00817e9dcbc636b44df0ec60b46a57e7a310a308a0947724e3817a13b4"
@@ -102,6 +112,8 @@ string(128) "546869732069732074686520736563726574206d657373616765207768696368206
iv length=0
+Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d
+
Warning: mcrypt_cbc(): The IV parameter must be as long as the blocksize in %s on line %d
string(128) "c082b3fabaae4c8c410eb8dba64bae10e48d79b5241fb8f24462cad43bd0b35ad2746b00817e9dcbc636b44df0ec60b46a57e7a310a308a0947724e3817a13b4"
@@ -110,6 +122,8 @@ string(128) "546869732069732074686520736563726574206d657373616765207768696368206
iv length=8
+Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d
+
Warning: mcrypt_cbc(): The IV parameter must be as long as the blocksize in %s on line %d
string(128) "c082b3fabaae4c8c410eb8dba64bae10e48d79b5241fb8f24462cad43bd0b35ad2746b00817e9dcbc636b44df0ec60b46a57e7a310a308a0947724e3817a13b4"
@@ -117,14 +131,18 @@ Warning: mcrypt_decrypt(): The IV parameter must be as long as the blocksize in
string(128) "546869732069732074686520736563726574206d657373616765207768696368206d75737420626520656e637279707465640000000000000000000000000000"
iv length=16
+
+Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d
string(128) "dc8f957ec530acf10cd95ba7da7b6405380fe19a2941e9a8de54680512f18491bc374e5464885ae6c2ae2aa7a6cdd2fbe12a06bbc4bd59dbbfaa15f09044f101"
string(128) "546869732069732074686520736563726574206d657373616765207768696368206d75737420626520656e637279707465640000000000000000000000000000"
iv length=17
+Deprecated: Function mcrypt_cbc() is deprecated in %s on line %d
+
Warning: mcrypt_cbc(): The IV parameter must be as long as the blocksize in %s on line %d
string(128) "c082b3fabaae4c8c410eb8dba64bae10e48d79b5241fb8f24462cad43bd0b35ad2746b00817e9dcbc636b44df0ec60b46a57e7a310a308a0947724e3817a13b4"
Warning: mcrypt_decrypt(): The IV parameter must be as long as the blocksize in %s on line %d
string(128) "546869732069732074686520736563726574206d657373616765207768696368206d75737420626520656e637279707465640000000000000000000000000000"
-===DONE=== \ No newline at end of file
+===DONE===
diff --git a/ext/mssql/config.m4 b/ext/mssql/config.m4
index 4231bb360a..2a298af734 100644
--- a/ext/mssql/config.m4
+++ b/ext/mssql/config.m4
@@ -3,7 +3,7 @@ dnl $Id$
dnl
PHP_ARG_WITH(mssql,for MSSQL support via FreeTDS,
-[ --with-mssql[=DIR] Include MSSQL-DB support. DIR is the FreeTDS home
+[ --with-mssql[=DIR] Include MSSQL-DB support. DIR is the FreeTDS home
directory [/usr/local/freetds]])
if test "$PHP_MSSQL" != "no"; then
diff --git a/ext/mssql/php_mssql.c b/ext/mssql/php_mssql.c
index 5b50216914..eef472aa3f 100644
--- a/ext/mssql/php_mssql.c
+++ b/ext/mssql/php_mssql.c
@@ -243,7 +243,12 @@ PHP_INI_BEGIN()
STD_PHP_INI_ENTRY_EX("mssql.max_links", "-1", PHP_INI_SYSTEM, OnUpdateLong, max_links, zend_mssql_globals, mssql_globals, display_link_numbers)
STD_PHP_INI_ENTRY_EX("mssql.min_error_severity", "10", PHP_INI_ALL, OnUpdateLong, cfg_min_error_severity, zend_mssql_globals, mssql_globals, display_link_numbers)
STD_PHP_INI_ENTRY_EX("mssql.min_message_severity", "10", PHP_INI_ALL, OnUpdateLong, cfg_min_message_severity, zend_mssql_globals, mssql_globals, display_link_numbers)
- STD_PHP_INI_BOOLEAN("mssql.compatability_mode", "0", PHP_INI_ALL, OnUpdateBool, compatability_mode, zend_mssql_globals, mssql_globals)
+ /*
+ mssql.compatAbility_mode (with typo) was used for relatively long time.
+ Unless it is fixed the old version is also kept for compatibility reasons.
+ */
+ STD_PHP_INI_BOOLEAN("mssql.compatability_mode", "0", PHP_INI_ALL, OnUpdateBool, compatibility_mode, zend_mssql_globals, mssql_globals)
+ STD_PHP_INI_BOOLEAN("mssql.compatibility_mode", "0", PHP_INI_ALL, OnUpdateBool, compatibility_mode, zend_mssql_globals, mssql_globals)
STD_PHP_INI_ENTRY_EX("mssql.connect_timeout", "5", PHP_INI_ALL, OnUpdateLong, connect_timeout, zend_mssql_globals, mssql_globals, display_link_numbers)
STD_PHP_INI_ENTRY_EX("mssql.timeout", "60", PHP_INI_ALL, OnUpdateLong, timeout, zend_mssql_globals, mssql_globals, display_link_numbers)
STD_PHP_INI_ENTRY_EX("mssql.textsize", "-1", PHP_INI_ALL, OnUpdateLong, textsize, zend_mssql_globals, mssql_globals, display_text_size)
@@ -415,12 +420,12 @@ static void _mssql_bind_hash_dtor(void *data)
*/
static PHP_GINIT_FUNCTION(mssql)
{
- long compatability_mode;
+ long compatibility_mode;
mssql_globals->num_persistent = 0;
mssql_globals->get_column_content = php_mssql_get_column_content_with_type;
- if (cfg_get_long("mssql.compatability_mode", &compatability_mode) == SUCCESS) {
- if (compatability_mode) {
+ if (cfg_get_long("mssql.compatibility_mode", &compatibility_mode) == SUCCESS) {
+ if (compatibility_mode) {
mssql_globals->get_column_content = php_mssql_get_column_content_without_type;
}
}
diff --git a/ext/mssql/php_mssql.h b/ext/mssql/php_mssql.h
index 463a030ab1..5b2456e9bd 100644
--- a/ext/mssql/php_mssql.h
+++ b/ext/mssql/php_mssql.h
@@ -166,7 +166,7 @@ ZEND_BEGIN_MODULE_GLOBALS(mssql)
long min_error_severity, min_message_severity;
long cfg_min_error_severity, cfg_min_message_severity;
long connect_timeout, timeout;
- zend_bool compatability_mode;
+ zend_bool compatibility_mode;
void (*get_column_content)(mssql_link *mssql_ptr,int offset,zval *result,int column_type TSRMLS_DC);
long textsize, textlimit, batchsize;
zend_bool datetimeconvert;
diff --git a/ext/mysql/CREDITS b/ext/mysql/CREDITS
index e5a6208bab..15b00a9a8e 100644
--- a/ext/mysql/CREDITS
+++ b/ext/mysql/CREDITS
@@ -1,2 +1,2 @@
MySQL
-Zeev Suraski, Zak Greant, Georg Richter
+Zeev Suraski, Zak Greant, Georg Richter, Andrey Hristov
diff --git a/ext/mysql/config.m4 b/ext/mysql/config.m4
index 998323d7c4..fd7f52ef3a 100644
--- a/ext/mysql/config.m4
+++ b/ext/mysql/config.m4
@@ -40,13 +40,14 @@ AC_DEFUN([PHP_MYSQL_SOCKET_SEARCH], [
PHP_ARG_WITH(mysql, for MySQL support,
-[ --with-mysql[=DIR] Include MySQL support. DIR is the MySQL base
+[ --with-mysql[=DIR] Include MySQL support. DIR is the MySQL base
directory, if no DIR is passed or the value is
mysqlnd the MySQL native driver will be used])
PHP_ARG_WITH(mysql-sock, for specified location of the MySQL UNIX socket,
-[ --with-mysql-sock[=SOCKPATH] MySQL/MySQLi/PDO_MYSQL: Location of the MySQL unix socket pointer.
- If unspecified, the default locations are searched], no, no)
+[ --with-mysql-sock[=SOCKPATH]
+ MySQL/MySQLi/PDO_MYSQL: Location of the MySQL unix socket pointer.
+ If unspecified, the default locations are searched], no, no)
if test -z "$PHP_ZLIB_DIR"; then
PHP_ARG_WITH(zlib-dir, for the location of libz,
diff --git a/ext/mysql/php_mysql.c b/ext/mysql/php_mysql.c
index 44561a1aa8..3d092b2d6a 100644
--- a/ext/mysql/php_mysql.c
+++ b/ext/mysql/php_mysql.c
@@ -297,27 +297,27 @@ static const zend_function_entry mysql_functions[] = {
PHP_FE(mysql_set_charset, arginfo_mysql_set_charset)
#endif
/* for downwards compatibility */
- PHP_FALIAS(mysql, mysql_db_query, arginfo_mysql_db_query)
- PHP_FALIAS(mysql_fieldname, mysql_field_name, arginfo_mysql_field_name)
- PHP_FALIAS(mysql_fieldtable, mysql_field_table, arginfo_mysql_field_seek)
- PHP_FALIAS(mysql_fieldlen, mysql_field_len, arginfo_mysql_field_seek)
- PHP_FALIAS(mysql_fieldtype, mysql_field_type, arginfo_mysql_field_seek)
- PHP_FALIAS(mysql_fieldflags, mysql_field_flags, arginfo_mysql_field_seek)
- PHP_FALIAS(mysql_selectdb, mysql_select_db, arginfo_mysql_select_db)
+ PHP_DEP_FALIAS(mysql, mysql_db_query, arginfo_mysql_db_query)
+ PHP_DEP_FALIAS(mysql_fieldname, mysql_field_name, arginfo_mysql_field_name)
+ PHP_DEP_FALIAS(mysql_fieldtable, mysql_field_table, arginfo_mysql_field_seek)
+ PHP_DEP_FALIAS(mysql_fieldlen, mysql_field_len, arginfo_mysql_field_seek)
+ PHP_DEP_FALIAS(mysql_fieldtype, mysql_field_type, arginfo_mysql_field_seek)
+ PHP_DEP_FALIAS(mysql_fieldflags, mysql_field_flags, arginfo_mysql_field_seek)
+ PHP_DEP_FALIAS(mysql_selectdb, mysql_select_db, arginfo_mysql_select_db)
#ifndef NETWARE /* The below two functions not supported on NetWare */
#if MYSQL_VERSION_ID < 40000
PHP_DEP_FALIAS(mysql_createdb, mysql_create_db, arginfo_mysql_select_db)
PHP_DEP_FALIAS(mysql_dropdb, mysql_drop_db, arginfo_mysql_select_db)
#endif
#endif /* NETWARE */
- PHP_FALIAS(mysql_freeresult, mysql_free_result, arginfo__result_mysql_arg)
- PHP_FALIAS(mysql_numfields, mysql_num_fields, arginfo__result_mysql_arg)
- PHP_FALIAS(mysql_numrows, mysql_num_rows, arginfo__result_mysql_arg)
- PHP_FALIAS(mysql_listdbs, mysql_list_dbs, arginfo__optional_mysql_link)
+ PHP_DEP_FALIAS(mysql_freeresult, mysql_free_result, arginfo__result_mysql_arg)
+ PHP_DEP_FALIAS(mysql_numfields, mysql_num_fields, arginfo__result_mysql_arg)
+ PHP_DEP_FALIAS(mysql_numrows, mysql_num_rows, arginfo__result_mysql_arg)
+ PHP_DEP_FALIAS(mysql_listdbs, mysql_list_dbs, arginfo__optional_mysql_link)
PHP_DEP_FALIAS(mysql_listtables,mysql_list_tables, arginfo_mysql_select_db)
- PHP_FALIAS(mysql_listfields, mysql_list_fields, arginfo_mysql_list_fields)
+ PHP_DEP_FALIAS(mysql_listfields, mysql_list_fields, arginfo_mysql_list_fields)
PHP_FALIAS(mysql_db_name, mysql_result, arginfo_mysql_result)
- PHP_FALIAS(mysql_dbname, mysql_result, arginfo_mysql_result)
+ PHP_DEP_FALIAS(mysql_dbname, mysql_result, arginfo_mysql_result)
PHP_FALIAS(mysql_tablename, mysql_result, arginfo_mysql_result)
PHP_FALIAS(mysql_table_name, mysql_result, arginfo_mysql_result)
PHP_FE_END
@@ -731,6 +731,10 @@ static void php_mysql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
zend_bool free_host=0, new_link=0;
long connect_timeout;
+ php_error_docref(NULL TSRMLS_CC,
+ E_DEPRECATED,
+ "The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead");
+
#if !defined(MYSQL_USE_MYSQLND)
if ((MYSQL_VERSION_ID / 100) != (mysql_get_client_version() / 100)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING,
@@ -1989,16 +1993,16 @@ Q: String or long first?
if (sql_row[field_offset]) {
Z_TYPE_P(return_value) = IS_STRING;
-#if PHP_API_VERSION < 20100412
+#if PHP_API_VERSION < 20100412
if (PG(magic_quotes_runtime)) {
Z_STRVAL_P(return_value) = php_addslashes(sql_row[field_offset], sql_row_lengths[field_offset],&Z_STRLEN_P(return_value), 0 TSRMLS_CC);
} else {
-#endif
+#endif
Z_STRLEN_P(return_value) = sql_row_lengths[field_offset];
Z_STRVAL_P(return_value) = (char *) safe_estrndup(sql_row[field_offset], Z_STRLEN_P(return_value));
#if PHP_API_VERSION < 20100412
}
-#endif
+#endif
} else {
Z_TYPE_P(return_value) = IS_NULL;
}
@@ -2116,16 +2120,16 @@ static void php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, long result_type,
MAKE_STD_ZVAL(data);
-#if PHP_API_VERSION < 20100412
+#if PHP_API_VERSION < 20100412
if (PG(magic_quotes_runtime)) {
Z_TYPE_P(data) = IS_STRING;
Z_STRVAL_P(data) = php_addslashes(mysql_row[i], mysql_row_lengths[i], &Z_STRLEN_P(data), 0 TSRMLS_CC);
} else {
-#endif
+#endif
ZVAL_STRINGL(data, mysql_row[i], mysql_row_lengths[i], 1);
-#if PHP_API_VERSION < 20100412
+#if PHP_API_VERSION < 20100412
}
-#endif
+#endif
if (result_type & MYSQL_NUM) {
add_index_zval(return_value, i, data);
diff --git a/ext/mysql/tests/001.phpt b/ext/mysql/tests/001.phpt
index 72b6614771..8782fd1252 100644
--- a/ext/mysql/tests/001.phpt
+++ b/ext/mysql/tests/001.phpt
@@ -29,5 +29,8 @@ var_dump($test);
print "done!";
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
%unicode|string%(2) "11"
done!
diff --git a/ext/mysql/tests/002.phpt b/ext/mysql/tests/002.phpt
index 8355c5f11e..8f53f4d724 100644
--- a/ext/mysql/tests/002.phpt
+++ b/ext/mysql/tests/002.phpt
@@ -37,6 +37,7 @@ print "done!";
require_once("clean_table.inc");
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
resource(%d) of type (mysql link)
bool(true)
bool(true)
diff --git a/ext/mysql/tests/003.phpt b/ext/mysql/tests/003.phpt
index 2d0b68b9f8..365abc20e9 100644
--- a/ext/mysql/tests/003.phpt
+++ b/ext/mysql/tests/003.phpt
@@ -57,6 +57,7 @@ print "done!";
require_once("clean_table.inc");
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
==stdClass==
object(stdClass)#%d (1) {
[%u|b%"a"]=>
diff --git a/ext/mysql/tests/bug47438.phpt b/ext/mysql/tests/bug47438.phpt
index 11f0ff33b8..fa7b3e6a2b 100644
--- a/ext/mysql/tests/bug47438.phpt
+++ b/ext/mysql/tests/bug47438.phpt
@@ -46,7 +46,8 @@ if (!mysql_select_db($db, $link) ||
mysql_close($link);
?>
---EXPECT--
+--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
0.a
1.b
2.c
diff --git a/ext/mysql/tests/bug48754.phpt b/ext/mysql/tests/bug48754.phpt
index fb322f4615..b461db3320 100644
--- a/ext/mysql/tests/bug48754.phpt
+++ b/ext/mysql/tests/bug48754.phpt
@@ -68,6 +68,8 @@ var_dump($link);
?>
--EXPECTF--
Explicit connection on close
+
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
Expect same thread id for $link and default conn: bool(true)
resource(%d) of type (mysql link)
resource(%d) of type (Unknown)
@@ -75,18 +77,24 @@ resource(%d) of type (Unknown)
Warning: mysql_close(): no MySQL-Link resource supplied in %s on line %d
Closing default link
+
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
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
+
+Deprecated: mysql_pconnect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
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
+
+Deprecated: mysql_pconnect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
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/bug51242.phpt b/ext/mysql/tests/bug51242.phpt
index 9b62cdb4cd..6801d3021f 100644
--- a/ext/mysql/tests/bug51242.phpt
+++ b/ext/mysql/tests/bug51242.phpt
@@ -35,4 +35,5 @@ if ($link = my_mysql_connect($host, $user, $passwd, $db, null, $socket)) {
}
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
resource(%d) of type (mysql link)
diff --git a/ext/mysql/tests/bug53649.phpt b/ext/mysql/tests/bug53649.phpt
index 70bf9bed36..7ccdf08e5f 100644
--- a/ext/mysql/tests/bug53649.phpt
+++ b/ext/mysql/tests/bug53649.phpt
@@ -67,5 +67,6 @@ mysql_close($link);
unlink('bug53649.data');
?>
---EXPECT--
-done \ No newline at end of file
+--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+done
diff --git a/ext/mysql/tests/bug55473.phpt b/ext/mysql/tests/bug55473.phpt
index befecef192..98fd0091dc 100644
--- a/ext/mysql/tests/bug55473.phpt
+++ b/ext/mysql/tests/bug55473.phpt
@@ -1,5 +1,5 @@
--TEST--
-Bug #55473 (mysql_pconnect leaks file descriptors on reconnect)
+Bug #5547 (mysql_pconnect leaks file descriptors on reconnect)
--SKIPIF--
<?php
require_once('skipif.inc');
@@ -8,7 +8,7 @@ if (defined('PHP_WINDOWS_VERSION_MAJOR')) {
die("skip Test doesn't work on Windows");
}
-if (!($output = @exec("lsof -nwp " . getmypid())))
+if (!($output = @exec("lsof -np " . getmypid())))
die("skip Test can't find command line tool lsof");
?>
--INI--
@@ -56,9 +56,9 @@ mysql.allow_persistent=1
if ($opened_files == -1) {
- $opened_files = trim(exec("lsof -nwp " . getmypid() . " | wc -l"));
+ $opened_files = trim(exec("lsof -np " . getmypid() . " | wc -l"));
printf("[005] Setting openened files...\n");
- } else if (($tmp = trim(exec("lsof -nwp " . getmypid() . " | wc -l"))) != $opened_files) {
+ } else if (($tmp = trim(exec("lsof -np " . getmypid() . " | wc -l"))) != $opened_files) {
printf("[006] [%d] different number of opened_files : expected %d, got %d", $i, $opened_files, $tmp);
} else {
printf("[007] Opened files as expected\n");
@@ -68,12 +68,29 @@ mysql.allow_persistent=1
print "done!";
?>
--EXPECTF--
+Deprecated: mysql_pconnect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
+Warning: mysql_ping(): MySQL server has gone away in %s on line %d
[003] reconnect 0
+
+Deprecated: mysql_pconnect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
[005] Setting openened files...
+
+Warning: mysql_ping(): MySQL server has gone away in %s on line %d
[003] reconnect 1
+
+Deprecated: mysql_pconnect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
[007] Opened files as expected
+
+Warning: mysql_ping(): MySQL server has gone away in %s on line %d
[003] reconnect 2
+
+Deprecated: mysql_pconnect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
[007] Opened files as expected
+
+Warning: mysql_ping(): MySQL server has gone away in %s on line %d
[003] reconnect 3
+
+Deprecated: mysql_pconnect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
[007] Opened files as expected
done!
diff --git a/ext/mysql/tests/mysql_affected_rows.phpt b/ext/mysql/tests/mysql_affected_rows.phpt
index 145e1f5c0b..2449ac416e 100644
--- a/ext/mysql/tests/mysql_affected_rows.phpt
+++ b/ext/mysql/tests/mysql_affected_rows.phpt
@@ -122,4 +122,5 @@ print "done!";
require_once("clean_table.inc");
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
done!
diff --git a/ext/mysql/tests/mysql_client_encoding.phpt b/ext/mysql/tests/mysql_client_encoding.phpt
index 8aa67a03ac..5b21765ddb 100644
--- a/ext/mysql/tests/mysql_client_encoding.phpt
+++ b/ext/mysql/tests/mysql_client_encoding.phpt
@@ -67,4 +67,5 @@ if (false !== ($tmp = @mysql_client_encoding($link)))
print "done!";
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
done!
diff --git a/ext/mysql/tests/mysql_close.phpt b/ext/mysql/tests/mysql_close.phpt
index 8f305ba780..e676511961 100644
--- a/ext/mysql/tests/mysql_close.phpt
+++ b/ext/mysql/tests/mysql_close.phpt
@@ -36,4 +36,5 @@ if (false !== ($tmp = @mysql_query("SELECT 1", $link)))
print "done!\n";
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
done!
diff --git a/ext/mysql/tests/mysql_connect.phpt b/ext/mysql/tests/mysql_connect.phpt
index 7158248040..2b73092375 100644
--- a/ext/mysql/tests/mysql_connect.phpt
+++ b/ext/mysql/tests/mysql_connect.phpt
@@ -104,5 +104,25 @@ if (!ini_get('sql.safe_mode')) {
print "done!";
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
Warning: mysql_connect(): Access denied for user '%s'@'%s' (using password: YES) in %s on line %d
+
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
done!
diff --git a/ext/mysql/tests/mysql_constants.phpt b/ext/mysql/tests/mysql_constants.phpt
index 1346100209..e68774503c 100644
--- a/ext/mysql/tests/mysql_constants.phpt
+++ b/ext/mysql/tests/mysql_constants.phpt
@@ -62,4 +62,5 @@ if (!empty($expected_constants)) {
print "done!";
?>
--EXPECTF--
-done! \ No newline at end of file
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+done!
diff --git a/ext/mysql/tests/mysql_create_db.phpt b/ext/mysql/tests/mysql_create_db.phpt
index bc91964f50..0b6d58a09e 100644
--- a/ext/mysql/tests/mysql_create_db.phpt
+++ b/ext/mysql/tests/mysql_create_db.phpt
@@ -53,4 +53,7 @@ if (!mysql_query("DROP DATABASE IF EXISTS mysqlcreatedb", $link))
mysql_close($link);
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
done!
diff --git a/ext/mysql/tests/mysql_data_seek.phpt b/ext/mysql/tests/mysql_data_seek.phpt
index 46a0f86bde..72d3e63274 100644
--- a/ext/mysql/tests/mysql_data_seek.phpt
+++ b/ext/mysql/tests/mysql_data_seek.phpt
@@ -67,6 +67,8 @@ print "done!\n";
require_once("clean_table.inc");
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
Warning: mysql_data_seek(): Offset 4 is invalid for MySQL result index %d (or the query data is unbuffered) in %s on line %d
Warning: mysql_data_seek(): Offset -1 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 b7f9042209..92878e994d 100644
--- a/ext/mysql/tests/mysql_db_name.phpt
+++ b/ext/mysql/tests/mysql_db_name.phpt
@@ -58,6 +58,8 @@ mysql_close($link);
print "done!\n";
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
Warning: mysql_db_name(): Unable to jump to row -1 on MySQL result index %d in %s on line %d
Warning: mysql_db_name(): Unable to jump to row %d on MySQL result index %d in %s on line %d
diff --git a/ext/mysql/tests/mysql_db_query.phpt b/ext/mysql/tests/mysql_db_query.phpt
index bb837dd6c0..291fbfaac6 100644
--- a/ext/mysql/tests/mysql_db_query.phpt
+++ b/ext/mysql/tests/mysql_db_query.phpt
@@ -62,4 +62,5 @@ print "done!\n";
require_once("clean_table.inc");
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
done!
diff --git a/ext/mysql/tests/mysql_deprecated_api.phpt b/ext/mysql/tests/mysql_deprecated_api.phpt
index d54307ca0e..ebf72375cf 100644
--- a/ext/mysql/tests/mysql_deprecated_api.phpt
+++ b/ext/mysql/tests/mysql_deprecated_api.phpt
@@ -75,4 +75,5 @@ print "done!";
require_once("clean_table.inc");
?>
--EXPECTF--
-done! \ No newline at end of file
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+done!
diff --git a/ext/mysql/tests/mysql_drop_db.phpt b/ext/mysql/tests/mysql_drop_db.phpt
index bd729e7ab8..3281b8a333 100644
--- a/ext/mysql/tests/mysql_drop_db.phpt
+++ b/ext/mysql/tests/mysql_drop_db.phpt
@@ -52,4 +52,5 @@ if (!mysql_query("DROP DATABASE IF EXISTS mysqldropdb", $link))
mysql_close($link);
?>
--EXPECTF--
-done! \ No newline at end of file
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+done!
diff --git a/ext/mysql/tests/mysql_errno.phpt b/ext/mysql/tests/mysql_errno.phpt
index 8cfa7bd33b..c9c2956290 100644
--- a/ext/mysql/tests/mysql_errno.phpt
+++ b/ext/mysql/tests/mysql_errno.phpt
@@ -55,6 +55,7 @@ print "done!";
require_once("clean_table.inc");
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
int(0)
int(%d)
diff --git a/ext/mysql/tests/mysql_error.phpt b/ext/mysql/tests/mysql_error.phpt
index aae4480174..a2cf7e0034 100644
--- a/ext/mysql/tests/mysql_error.phpt
+++ b/ext/mysql/tests/mysql_error.phpt
@@ -62,6 +62,8 @@ print "done!";
require_once("clean_table.inc");
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
Warning: mysql_error(): %d is not a valid MySQL-Link resource in %s on line %d
bool(false)
done!
diff --git a/ext/mysql/tests/mysql_fetch_array.phpt b/ext/mysql/tests/mysql_fetch_array.phpt
index 362cf99ddc..8ccefd0242 100644
--- a/ext/mysql/tests/mysql_fetch_array.phpt
+++ b/ext/mysql/tests/mysql_fetch_array.phpt
@@ -281,6 +281,7 @@ print "done!";
require_once("clean_table.inc");
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
[005]
array(4) {
[0]=>
diff --git a/ext/mysql/tests/mysql_fetch_assoc.phpt b/ext/mysql/tests/mysql_fetch_assoc.phpt
index 3c5ca79b2d..048613a6be 100644
--- a/ext/mysql/tests/mysql_fetch_assoc.phpt
+++ b/ext/mysql/tests/mysql_fetch_assoc.phpt
@@ -63,6 +63,7 @@ print "done!";
require_once("clean_table.inc");
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
[005]
array(2) {
[%u|b%"id"]=>
@@ -87,6 +88,8 @@ array(5) {
}
Warning: mysql_fetch_assoc(): %d is not a valid MySQL result resource in %s on line %d
+
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
[010]
array(5) {
[%u|b%"id"]=>
diff --git a/ext/mysql/tests/mysql_fetch_field.phpt b/ext/mysql/tests/mysql_fetch_field.phpt
index ef03279087..85c1fd6f7e 100644
--- a/ext/mysql/tests/mysql_fetch_field.phpt
+++ b/ext/mysql/tests/mysql_fetch_field.phpt
@@ -156,6 +156,7 @@ require_once('skipifconnectfailure.inc');
require_once("clean_table.inc");
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
object(stdClass)#%d (13) {
[%u|b%"name"]=>
%unicode|string%(2) "ID"
diff --git a/ext/mysql/tests/mysql_fetch_lengths.phpt b/ext/mysql/tests/mysql_fetch_lengths.phpt
index 4793e2649b..f0fbbb7bb8 100644
--- a/ext/mysql/tests/mysql_fetch_lengths.phpt
+++ b/ext/mysql/tests/mysql_fetch_lengths.phpt
@@ -39,6 +39,7 @@ print "done!";
require_once("clean_table.inc");
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
array(2) {
[0]=>
int(1)
diff --git a/ext/mysql/tests/mysql_fetch_object.phpt b/ext/mysql/tests/mysql_fetch_object.phpt
index c11631e04c..666d0ee821 100644
--- a/ext/mysql/tests/mysql_fetch_object.phpt
+++ b/ext/mysql/tests/mysql_fetch_object.phpt
@@ -82,6 +82,7 @@ print "done!";
require_once("clean_table.inc");
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
object(stdClass)#%d (2) {
[%u|b%"ID"]=>
%unicode|string%(1) "1"
diff --git a/ext/mysql/tests/mysql_fetch_row.phpt b/ext/mysql/tests/mysql_fetch_row.phpt
index 8d6b9585be..0ed932e2c0 100644
--- a/ext/mysql/tests/mysql_fetch_row.phpt
+++ b/ext/mysql/tests/mysql_fetch_row.phpt
@@ -41,6 +41,7 @@ print "done!";
require_once("clean_table.inc");
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
[004]
array(2) {
[0]=>
@@ -53,4 +54,4 @@ bool(false)
Warning: mysql_fetch_row(): %d is not a valid MySQL result resource in %s on line %d
bool(false)
-done! \ No newline at end of file
+done!
diff --git a/ext/mysql/tests/mysql_field_flags.phpt b/ext/mysql/tests/mysql_field_flags.phpt
index e07e041d2a..5f8eb0995f 100644
--- a/ext/mysql/tests/mysql_field_flags.phpt
+++ b/ext/mysql/tests/mysql_field_flags.phpt
@@ -45,12 +45,12 @@ mysql_free_result($res);
$version = mysql_get_server_info($link);
if (!preg_match('@(\d+)\.(\d+)\.(\d+)@ism', $version, $matches))
printf("[009] Cannot get server version\n");
-$version = ($matches[1] * 100) + ($matches[2] * 10) + $matches[3];
+$version = ($matches[1] * 1000) + ($matches[2] * 100) + $matches[3];
$tables = array(
'label INT, UNIQUE KEY (label)' => array(
array('label', '1'),
- 'label' => array(($version < 500) ? 'multiple_key' : 'unique_key')
+ 'label' => array(($version < 5000) ? 'multiple_key' : 'unique_key')
),
'labela INT, label2 CHAR(1), KEY keyname (labela, label2)' => array(
array('labela, label2', "1, 'a'"),
@@ -86,7 +86,7 @@ $tables = array(
),
);
-if ($version < 560) {
+if ($version < 5600) {
$tables['label1 TIMESTAMP']['label1'][] = 'zerofill';
$tables['label1 TIMESTAMP']['label1'][] = 'unsigned';
}
@@ -144,6 +144,8 @@ print "done!";
require_once("clean_table.inc");
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
Warning: mysql_field_flags() expects exactly 2 parameters, 1 given in %s on line %d
Warning: mysql_field_flags(): Field -1 is invalid for MySQL result index %d in %s on line %d
diff --git a/ext/mysql/tests/mysql_field_len.phpt b/ext/mysql/tests/mysql_field_len.phpt
index a740c62439..119d352164 100644
--- a/ext/mysql/tests/mysql_field_len.phpt
+++ b/ext/mysql/tests/mysql_field_len.phpt
@@ -47,6 +47,8 @@ print "done!";
require_once("clean_table.inc");
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
Warning: mysql_field_len() expects exactly 2 parameters, 1 given in %s on line %d
Warning: mysql_field_len(): Field -1 is invalid for MySQL result index %d in %s on line %d
diff --git a/ext/mysql/tests/mysql_field_name.phpt b/ext/mysql/tests/mysql_field_name.phpt
index c87ac188f7..85f6c42d93 100644
--- a/ext/mysql/tests/mysql_field_name.phpt
+++ b/ext/mysql/tests/mysql_field_name.phpt
@@ -46,6 +46,8 @@ print "done!";
require_once("clean_table.inc");
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
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
diff --git a/ext/mysql/tests/mysql_field_seek.phpt b/ext/mysql/tests/mysql_field_seek.phpt
index 7e8b313c87..8487493a88 100644
--- a/ext/mysql/tests/mysql_field_seek.phpt
+++ b/ext/mysql/tests/mysql_field_seek.phpt
@@ -44,6 +44,8 @@ print "done!";
require_once("clean_table.inc");
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
Warning: mysql_field_seek(): Field -1 is invalid for MySQL result index %d in %s on line %d
bool(false)
object(stdClass)#%d (13) {
diff --git a/ext/mysql/tests/mysql_field_table.phpt b/ext/mysql/tests/mysql_field_table.phpt
index 707d1df987..826651a855 100644
--- a/ext/mysql/tests/mysql_field_table.phpt
+++ b/ext/mysql/tests/mysql_field_table.phpt
@@ -46,6 +46,8 @@ print "done!";
require_once("clean_table.inc");
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
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
diff --git a/ext/mysql/tests/mysql_field_type.phpt b/ext/mysql/tests/mysql_field_type.phpt
index c737b4e3f2..c767cab6f1 100644
--- a/ext/mysql/tests/mysql_field_type.phpt
+++ b/ext/mysql/tests/mysql_field_type.phpt
@@ -46,6 +46,8 @@ print "done!";
require_once("clean_table.inc");
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
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
diff --git a/ext/mysql/tests/mysql_free_result.phpt b/ext/mysql/tests/mysql_free_result.phpt
index fe132d8c2d..90498bd59a 100644
--- a/ext/mysql/tests/mysql_free_result.phpt
+++ b/ext/mysql/tests/mysql_free_result.phpt
@@ -44,6 +44,7 @@ print "done!";
require_once("clean_table.inc");
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
bool(true)
Warning: mysql_free_result(): %d is not a valid MySQL result resource in %s on line %d
diff --git a/ext/mysql/tests/mysql_get_host_info.phpt b/ext/mysql/tests/mysql_get_host_info.phpt
index 443910c319..4b21ddbb41 100644
--- a/ext/mysql/tests/mysql_get_host_info.phpt
+++ b/ext/mysql/tests/mysql_get_host_info.phpt
@@ -41,4 +41,5 @@ print "done!";
require_once("clean_table.inc");
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
done!
diff --git a/ext/mysql/tests/mysql_get_proto_info.phpt b/ext/mysql/tests/mysql_get_proto_info.phpt
index 043fb62043..3e1481121e 100644
--- a/ext/mysql/tests/mysql_get_proto_info.phpt
+++ b/ext/mysql/tests/mysql_get_proto_info.phpt
@@ -31,4 +31,5 @@ print "done!";
require_once("clean_table.inc");
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
done!
diff --git a/ext/mysql/tests/mysql_get_server_info.phpt b/ext/mysql/tests/mysql_get_server_info.phpt
index e806335e29..ad192e4722 100644
--- a/ext/mysql/tests/mysql_get_server_info.phpt
+++ b/ext/mysql/tests/mysql_get_server_info.phpt
@@ -36,4 +36,5 @@ if (NULL !== ($tmp = @mysql_get_server_info('too many', 'just too many')))
print "done!";
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
done!
diff --git a/ext/mysql/tests/mysql_info.phpt b/ext/mysql/tests/mysql_info.phpt
index 464578c8a5..c478679042 100644
--- a/ext/mysql/tests/mysql_info.phpt
+++ b/ext/mysql/tests/mysql_info.phpt
@@ -70,4 +70,5 @@ print "done!";
require_once("clean_table.inc");
?>
--EXPECTF--
-done! \ No newline at end of file
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+done!
diff --git a/ext/mysql/tests/mysql_insert_id.phpt b/ext/mysql/tests/mysql_insert_id.phpt
index 460d9f3f4d..b69a96ae9b 100644
--- a/ext/mysql/tests/mysql_insert_id.phpt
+++ b/ext/mysql/tests/mysql_insert_id.phpt
@@ -66,6 +66,8 @@ print "done!";
require_once("clean_table.inc");
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
Warning: mysql_insert_id(): %d is not a valid MySQL-Link resource in %s on line %d
bool(false)
done!
diff --git a/ext/mysql/tests/mysql_list_dbs.phpt b/ext/mysql/tests/mysql_list_dbs.phpt
index 054e02ef98..402161aa63 100644
--- a/ext/mysql/tests/mysql_list_dbs.phpt
+++ b/ext/mysql/tests/mysql_list_dbs.phpt
@@ -51,4 +51,5 @@ print "done!\n";
require_once("clean_table.inc");
?>
--EXPECTF--
-done! \ No newline at end of file
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+done!
diff --git a/ext/mysql/tests/mysql_list_fields.phpt b/ext/mysql/tests/mysql_list_fields.phpt
index e0b3fd5e39..6b6ae9b319 100644
--- a/ext/mysql/tests/mysql_list_fields.phpt
+++ b/ext/mysql/tests/mysql_list_fields.phpt
@@ -64,6 +64,7 @@ if (!mysql_query("DROP TABLE IF EXISTS test2", $link))
mysql_close($link);
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
[006] [%d] %s
bool(false)
Field Offset 0
@@ -73,7 +74,7 @@ mysql_field_name(): id
mysql_field_type(): int
Field Offset 1
mysql_field_flags()%s
-mysql_field_len(): 1
+mysql_field_len(): %s
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 b0c71ad1b4..7838a6f98a 100644
--- a/ext/mysql/tests/mysql_list_processes.phpt
+++ b/ext/mysql/tests/mysql_list_processes.phpt
@@ -49,4 +49,5 @@ mysql_close($link);
print "done!\n";
?>
--EXPECTF--
-done! \ No newline at end of file
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+done!
diff --git a/ext/mysql/tests/mysql_list_tables.phpt b/ext/mysql/tests/mysql_list_tables.phpt
index cf0b1a636d..3b753ae37a 100644
--- a/ext/mysql/tests/mysql_list_tables.phpt
+++ b/ext/mysql/tests/mysql_list_tables.phpt
@@ -82,4 +82,5 @@ print "done!\n";
require_once("clean_table.inc");
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
done!
diff --git a/ext/mysql/tests/mysql_max_links.phpt b/ext/mysql/tests/mysql_max_links.phpt
index 52ecd0ac08..32096c426e 100644
--- a/ext/mysql/tests/mysql_max_links.phpt
+++ b/ext/mysql/tests/mysql_max_links.phpt
@@ -54,9 +54,19 @@ mysql_close($links[1]);
print "done!\n";
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
Warning: mysql_connect(): Too many open links (2) in %s on line %s
[030] Cannot connect using host '%s', user '%s', password '****', [0] 0
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
Warning: mysql_connect(): Too many open links (2) in %s on line %s
[060] Cannot connect using host '%s', user '%s', password '****', [0] 0
array(3) {
@@ -67,4 +77,4 @@ array(3) {
[2]=>
bool(false)
}
-done! \ No newline at end of file
+done!
diff --git a/ext/mysql/tests/mysql_max_persistent.phpt b/ext/mysql/tests/mysql_max_persistent.phpt
index ac35cd178b..36f2266665 100644
--- a/ext/mysql/tests/mysql_max_persistent.phpt
+++ b/ext/mysql/tests/mysql_max_persistent.phpt
@@ -90,10 +90,16 @@ if (!$link = my_mysql_connect($host, $user, $passwd, $db, $port, $socket)) {
mysql_close($link);
?>
--EXPECTF--
+Deprecated: mysql_pconnect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
+Deprecated: mysql_pconnect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
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
+
+Deprecated: mysql_pconnect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
array(1) {
[0]=>
resource(%d) of type (mysql link persistent)
}
-done! \ No newline at end of file
+done!
diff --git a/ext/mysql/tests/mysql_mysqlnd_read_timeout_long.phpt b/ext/mysql/tests/mysql_mysqlnd_read_timeout_long.phpt
index d54cb50708..2c67e64878 100644
--- a/ext/mysql/tests/mysql_mysqlnd_read_timeout_long.phpt
+++ b/ext/mysql/tests/mysql_mysqlnd_read_timeout_long.phpt
@@ -30,8 +30,9 @@ max_execution_time=12
print "done!";
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
array(1) {
[%u|b%"SLEEP(6)"]=>
%unicode|string%(1) "0"
}
-done! \ No newline at end of file
+done!
diff --git a/ext/mysql/tests/mysql_num_fields.phpt b/ext/mysql/tests/mysql_num_fields.phpt
index 0dad5f771d..4621dc91f8 100644
--- a/ext/mysql/tests/mysql_num_fields.phpt
+++ b/ext/mysql/tests/mysql_num_fields.phpt
@@ -52,5 +52,7 @@ print "done!";
require_once("clean_table.inc");
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
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 0f538c4a2b..5a803d41f9 100644
--- a/ext/mysql/tests/mysql_num_rows.phpt
+++ b/ext/mysql/tests/mysql_num_rows.phpt
@@ -79,6 +79,8 @@ print "done!";
require_once("clean_table.inc");
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
Warning: mysql_num_rows() expects parameter 1 to be resource, boolean given in %s on line %d
Warning: mysql_free_result() 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 532e2e5788..6997e5970f 100644
--- a/ext/mysql/tests/mysql_pconn_disable.phpt
+++ b/ext/mysql/tests/mysql_pconn_disable.phpt
@@ -49,6 +49,13 @@ mysql.max_links=2
require_once("clean_table.inc");
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
+Deprecated: mysql_pconnect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
[001] Can connect to the server.
[002] Can fetch data using persistent connection! Data = '1'
-done! \ No newline at end of file
+
+Deprecated: mysql_pconnect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+done!
diff --git a/ext/mysql/tests/mysql_pconn_kill.phpt b/ext/mysql/tests/mysql_pconn_kill.phpt
index efef421604..eb1feb7b85 100644
--- a/ext/mysql/tests/mysql_pconn_kill.phpt
+++ b/ext/mysql/tests/mysql_pconn_kill.phpt
@@ -106,5 +106,12 @@ mysql.max_persistent=2
require_once("clean_table.inc");
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
+Deprecated: mysql_pconnect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
bool(true)
+
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
done!
diff --git a/ext/mysql/tests/mysql_pconn_max_links.phpt b/ext/mysql/tests/mysql_pconn_max_links.phpt
index 3eca0e534a..ced94b3dbf 100644
--- a/ext/mysql/tests/mysql_pconn_max_links.phpt
+++ b/ext/mysql/tests/mysql_pconn_max_links.phpt
@@ -191,12 +191,17 @@ $host = substr($row['_user'], strrpos($row['_user'], "@") + 1, strlen($row['_use
mysql_close($link);
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
+Deprecated: mysql_pconnect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
array(2) {
[%u|b%"id"]=>
%unicode|string%(1) "1"
[%u|b%"label"]=>
%unicode|string%(1) "a"
}
+
+Deprecated: mysql_pconnect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
array(2) {
[%u|b%"id"]=>
%unicode|string%(1) "1"
diff --git a/ext/mysql/tests/mysql_pconn_reuse.phpt b/ext/mysql/tests/mysql_pconn_reuse.phpt
index ffa5f75f1b..26b4ca5f49 100644
--- a/ext/mysql/tests/mysql_pconn_reuse.phpt
+++ b/ext/mysql/tests/mysql_pconn_reuse.phpt
@@ -59,8 +59,17 @@ mysql.max_links=2
print "done!";
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
+Deprecated: mysql_pconnect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
[001] Can connect to the server.
[002] Can fetch data using persistent connection! Data = '1'
+Deprecated: mysql_pconnect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
Warning: mysql_connect(): Too many open links (2) in %s on line %d
-done! \ No newline at end of file
+done!
diff --git a/ext/mysql/tests/mysql_pconnect.phpt b/ext/mysql/tests/mysql_pconnect.phpt
index 5a7db93ab3..ec28d2ea8a 100644
--- a/ext/mysql/tests/mysql_pconnect.phpt
+++ b/ext/mysql/tests/mysql_pconnect.phpt
@@ -81,5 +81,17 @@ mysql.allow_persistent=1
print "done!";
?>
--EXPECTF--
+Deprecated: mysql_pconnect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
+Deprecated: mysql_pconnect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
Warning: mysql_pconnect(): Access denied for user '%s'@'%s' (using password: YES) in %s on line %d
+
+Deprecated: mysql_pconnect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
+Deprecated: mysql_pconnect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
+Deprecated: mysql_pconnect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
+Deprecated: mysql_pconnect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
done!
diff --git a/ext/mysql/tests/mysql_ping.phpt b/ext/mysql/tests/mysql_ping.phpt
index edf18c4391..0308df3396 100644
--- a/ext/mysql/tests/mysql_ping.phpt
+++ b/ext/mysql/tests/mysql_ping.phpt
@@ -42,6 +42,7 @@ print "done!";
require_once("clean_table.inc");
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
bool(true)
bool(true)
bool(true)
diff --git a/ext/mysql/tests/mysql_query.phpt b/ext/mysql/tests/mysql_query.phpt
index a5978a6c11..01b14ee284 100644
--- a/ext/mysql/tests/mysql_query.phpt
+++ b/ext/mysql/tests/mysql_query.phpt
@@ -113,6 +113,7 @@ if (!mysql_query('DROP TABLE IF EXISTS test', $link)) {
mysql_close($link);
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
array(1) {
[%u|b%"valid"]=>
%unicode|string%(30) "this is sql but with semicolon"
diff --git a/ext/mysql/tests/mysql_query_load_data_openbasedir.phpt b/ext/mysql/tests/mysql_query_load_data_openbasedir.phpt
index aa15f5ca12..c2cb41e026 100644
--- a/ext/mysql/tests/mysql_query_load_data_openbasedir.phpt
+++ b/ext/mysql/tests/mysql_query_load_data_openbasedir.phpt
@@ -111,6 +111,9 @@ unlink("./simple.csv");
print "done!";
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
[006] [1148] %s
[007] [0] ''
[008] LOAD DATA not run?
diff --git a/ext/mysql/tests/mysql_real_escape_string.phpt b/ext/mysql/tests/mysql_real_escape_string.phpt
index 2789ad276c..4fdedf7b37 100644
--- a/ext/mysql/tests/mysql_real_escape_string.phpt
+++ b/ext/mysql/tests/mysql_real_escape_string.phpt
@@ -33,6 +33,7 @@ assert($tmp === mysql_real_escape_string("foo" . chr(0) . "bar"));
print "done!";
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
%unicode|string%(31) "Am I a unicode string in PHP 6?"
%unicode|string%(2) "\\"
%unicode|string%(2) "\""
diff --git a/ext/mysql/tests/mysql_reflection_extension.phpt b/ext/mysql/tests/mysql_reflection_extension.phpt
new file mode 100644
index 0000000000..169036cd54
--- /dev/null
+++ b/ext/mysql/tests/mysql_reflection_extension.phpt
@@ -0,0 +1,105 @@
+--TEST--
+ReflectionExtension basics to check API
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+?>
+--FILE--
+<?php
+ $r = new ReflectionExtension("mysql");
+
+ printf("Name: %s\n", $r->name);
+ printf("Version: %s\n", $r->getVersion());
+ $classes = $r->getClasses();
+ if (!empty($classes)) {
+ printf("[002] Expecting no class\n");
+ asort($classes);
+ var_dump($classes);
+ }
+
+ $ignore = array();
+
+ $functions = $r->getFunctions();
+ asort($functions);
+ printf("Functions:\n");
+ foreach ($functions as $func) {
+ if (isset($ignore[$func->name])) {
+ unset($ignore[$func->name]);
+ } else {
+ printf(" %s\n", $func->name);
+ }
+ }
+ if (!empty($ignore)) {
+ printf("Dumping version dependent and missing functions\n");
+ var_dump($ignore);
+ }
+
+
+ print "done!";
+?>
+--EXPECTF--
+Name: mysql
+Version: 1.0
+Functions:
+ mysql
+ mysql_affected_rows
+ mysql_client_encoding
+ mysql_close
+ mysql_connect
+ mysql_data_seek
+ mysql_db_name
+ mysql_db_query
+ mysql_dbname
+ mysql_errno
+ mysql_error
+ mysql_escape_string
+ mysql_fetch_array
+ mysql_fetch_assoc
+ mysql_fetch_field
+ mysql_fetch_lengths
+ mysql_fetch_object
+ mysql_fetch_row
+ mysql_field_flags
+ mysql_field_len
+ mysql_field_name
+ mysql_field_seek
+ mysql_field_table
+ mysql_field_type
+ mysql_fieldflags
+ mysql_fieldlen
+ mysql_fieldname
+ mysql_fieldtable
+ mysql_fieldtype
+ mysql_free_result
+ mysql_freeresult
+ mysql_get_client_info
+ mysql_get_host_info
+ mysql_get_proto_info
+ mysql_get_server_info
+ mysql_info
+ mysql_insert_id
+ mysql_list_dbs
+ mysql_list_fields
+ mysql_list_processes
+ mysql_list_tables
+ mysql_listdbs
+ mysql_listfields
+ mysql_listtables
+ mysql_num_fields
+ mysql_num_rows
+ mysql_numfields
+ mysql_numrows
+ mysql_pconnect
+ mysql_ping
+ mysql_query
+ mysql_real_escape_string
+ mysql_result
+ mysql_select_db
+ mysql_selectdb
+ mysql_set_charset
+ mysql_stat
+ mysql_table_name
+ mysql_tablename
+ mysql_thread_id
+ mysql_unbuffered_query
+done! \ No newline at end of file
diff --git a/ext/mysql/tests/mysql_reflection_functions.phpt b/ext/mysql/tests/mysql_reflection_functions.phpt
new file mode 100644
index 0000000000..4f2710d806
--- /dev/null
+++ b/ext/mysql/tests/mysql_reflection_functions.phpt
@@ -0,0 +1,387 @@
+--TEST--
+ReflectionFunction to check API
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+?>
+--FILE--
+<?php
+ $r = new ReflectionExtension("mysql");
+
+ $ignore = array();
+
+ $functions = $r->getFunctions();
+ asort($functions);
+ printf("Functions:\n");
+ foreach ($functions as $func) {
+ if (isset($ignore[$func->name]))
+ continue;
+
+ printf(" %s\n", $func->name);
+ $rf = new ReflectionFunction($func->name);
+ printf(" Deprecated: %s\n", $rf->isDeprecated() ? "yes" : "no");
+ printf(" Accepted parameters: %d\n", $rf->getNumberOfParameters());
+ printf(" Required parameters: %d\n", $rf->getNumberOfRequiredParameters());
+ foreach( $rf->getParameters() as $param ) {
+ printf(" %s\n", $param);
+ }
+ }
+
+ print "done!";
+?>
+--EXPECTF--
+Functions:
+ mysql
+ Deprecated: yes
+ Accepted parameters: 3
+ Required parameters: 2
+ Parameter #0 [ <required> $database_name ]
+ Parameter #1 [ <required> $query ]
+ Parameter #2 [ <optional> $link_identifier ]
+ mysql_affected_rows
+ Deprecated: no
+ Accepted parameters: 1
+ Required parameters: 0
+ Parameter #0 [ <optional> $link_identifier ]
+ mysql_client_encoding
+ Deprecated: no
+ Accepted parameters: 1
+ Required parameters: 0
+ Parameter #0 [ <optional> $link_identifier ]
+ mysql_close
+ Deprecated: no
+ Accepted parameters: 1
+ Required parameters: 0
+ Parameter #0 [ <optional> $link_identifier ]
+ mysql_connect
+ Deprecated: no
+ Accepted parameters: 5
+ Required parameters: 0
+ Parameter #0 [ <optional> $hostname ]
+ Parameter #1 [ <optional> $username ]
+ Parameter #2 [ <optional> $password ]
+ Parameter #3 [ <optional> $new ]
+ Parameter #4 [ <optional> $flags ]
+ mysql_data_seek
+ Deprecated: no
+ Accepted parameters: 2
+ Required parameters: 2
+ Parameter #0 [ <required> $result ]
+ Parameter #1 [ <required> $row_number ]
+ mysql_db_name
+ Deprecated: no
+ Accepted parameters: 3
+ Required parameters: 2
+ Parameter #0 [ <required> $result ]
+ Parameter #1 [ <required> $row ]
+ Parameter #2 [ <optional> $field ]
+ mysql_db_query
+ Deprecated: yes
+ Accepted parameters: 3
+ Required parameters: 2
+ Parameter #0 [ <required> $database_name ]
+ Parameter #1 [ <required> $query ]
+ Parameter #2 [ <optional> $link_identifier ]
+ mysql_dbname
+ Deprecated: yes
+ Accepted parameters: 3
+ Required parameters: 2
+ Parameter #0 [ <required> $result ]
+ Parameter #1 [ <required> $row ]
+ Parameter #2 [ <optional> $field ]
+ mysql_errno
+ Deprecated: no
+ Accepted parameters: 1
+ Required parameters: 0
+ Parameter #0 [ <optional> $link_identifier ]
+ mysql_error
+ Deprecated: no
+ Accepted parameters: 1
+ Required parameters: 0
+ Parameter #0 [ <optional> $link_identifier ]
+ mysql_escape_string
+ Deprecated: no
+ Accepted parameters: 1
+ Required parameters: 1
+ Parameter #0 [ <required> $string ]
+ mysql_fetch_array
+ Deprecated: no
+ Accepted parameters: 2
+ Required parameters: 1
+ Parameter #0 [ <required> $result ]
+ Parameter #1 [ <optional> $result_type ]
+ mysql_fetch_assoc
+ Deprecated: no
+ Accepted parameters: 1
+ Required parameters: 1
+ Parameter #0 [ <required> $result ]
+ mysql_fetch_field
+ Deprecated: no
+ Accepted parameters: 2
+ Required parameters: 1
+ Parameter #0 [ <required> $result ]
+ Parameter #1 [ <optional> $field_offset ]
+ mysql_fetch_lengths
+ Deprecated: no
+ Accepted parameters: 1
+ Required parameters: 1
+ Parameter #0 [ <required> $result ]
+ mysql_fetch_object
+ Deprecated: no
+ Accepted parameters: 3
+ Required parameters: 1
+ Parameter #0 [ <required> $result ]
+ Parameter #1 [ <optional> $class_name ]
+ Parameter #2 [ <optional> $ctor_params ]
+ mysql_fetch_row
+ Deprecated: no
+ Accepted parameters: 1
+ Required parameters: 1
+ Parameter #0 [ <required> $result ]
+ mysql_field_flags
+ Deprecated: no
+ Accepted parameters: 2
+ Required parameters: 2
+ Parameter #0 [ <required> $result ]
+ Parameter #1 [ <required> $field_offset ]
+ mysql_field_len
+ Deprecated: no
+ Accepted parameters: 2
+ Required parameters: 2
+ Parameter #0 [ <required> $result ]
+ Parameter #1 [ <required> $field_offset ]
+ mysql_field_name
+ Deprecated: no
+ Accepted parameters: 2
+ Required parameters: 2
+ Parameter #0 [ <required> $result ]
+ Parameter #1 [ <required> $field_index ]
+ mysql_field_seek
+ Deprecated: no
+ Accepted parameters: 2
+ Required parameters: 2
+ Parameter #0 [ <required> $result ]
+ Parameter #1 [ <required> $field_offset ]
+ mysql_field_table
+ Deprecated: no
+ Accepted parameters: 2
+ Required parameters: 2
+ Parameter #0 [ <required> $result ]
+ Parameter #1 [ <required> $field_offset ]
+ mysql_field_type
+ Deprecated: no
+ Accepted parameters: 2
+ Required parameters: 2
+ Parameter #0 [ <required> $result ]
+ Parameter #1 [ <required> $field_offset ]
+ mysql_fieldflags
+ Deprecated: yes
+ Accepted parameters: 2
+ Required parameters: 2
+ Parameter #0 [ <required> $result ]
+ Parameter #1 [ <required> $field_offset ]
+ mysql_fieldlen
+ Deprecated: yes
+ Accepted parameters: 2
+ Required parameters: 2
+ Parameter #0 [ <required> $result ]
+ Parameter #1 [ <required> $field_offset ]
+ mysql_fieldname
+ Deprecated: yes
+ Accepted parameters: 2
+ Required parameters: 2
+ Parameter #0 [ <required> $result ]
+ Parameter #1 [ <required> $field_index ]
+ mysql_fieldtable
+ Deprecated: yes
+ Accepted parameters: 2
+ Required parameters: 2
+ Parameter #0 [ <required> $result ]
+ Parameter #1 [ <required> $field_offset ]
+ mysql_fieldtype
+ Deprecated: yes
+ Accepted parameters: 2
+ Required parameters: 2
+ Parameter #0 [ <required> $result ]
+ Parameter #1 [ <required> $field_offset ]
+ mysql_free_result
+ Deprecated: no
+ Accepted parameters: 1
+ Required parameters: 1
+ Parameter #0 [ <required> $result ]
+ mysql_freeresult
+ Deprecated: yes
+ Accepted parameters: 1
+ Required parameters: 1
+ Parameter #0 [ <required> $result ]
+ mysql_get_client_info
+ Deprecated: no
+ Accepted parameters: 0
+ Required parameters: 0
+ mysql_get_host_info
+ Deprecated: no
+ Accepted parameters: 1
+ Required parameters: 0
+ Parameter #0 [ <optional> $link_identifier ]
+ mysql_get_proto_info
+ Deprecated: no
+ Accepted parameters: 1
+ Required parameters: 0
+ Parameter #0 [ <optional> $link_identifier ]
+ mysql_get_server_info
+ Deprecated: no
+ Accepted parameters: 1
+ Required parameters: 0
+ Parameter #0 [ <optional> $link_identifier ]
+ mysql_info
+ Deprecated: no
+ Accepted parameters: 1
+ Required parameters: 0
+ Parameter #0 [ <optional> $link_identifier ]
+ mysql_insert_id
+ Deprecated: no
+ Accepted parameters: 1
+ Required parameters: 0
+ Parameter #0 [ <optional> $link_identifier ]
+ mysql_list_dbs
+ Deprecated: yes
+ Accepted parameters: 1
+ Required parameters: 0
+ Parameter #0 [ <optional> $link_identifier ]
+ mysql_list_fields
+ Deprecated: no
+ Accepted parameters: 3
+ Required parameters: 2
+ Parameter #0 [ <required> $database_name ]
+ Parameter #1 [ <required> $table_name ]
+ Parameter #2 [ <optional> $link_identifier ]
+ mysql_list_processes
+ Deprecated: no
+ Accepted parameters: 1
+ Required parameters: 0
+ Parameter #0 [ <optional> $link_identifier ]
+ mysql_list_tables
+ Deprecated: yes
+ Accepted parameters: 2
+ Required parameters: 1
+ Parameter #0 [ <required> $database_name ]
+ Parameter #1 [ <optional> $link_identifier ]
+ mysql_listdbs
+ Deprecated: yes
+ Accepted parameters: 1
+ Required parameters: 0
+ Parameter #0 [ <optional> $link_identifier ]
+ mysql_listfields
+ Deprecated: yes
+ Accepted parameters: 3
+ Required parameters: 2
+ Parameter #0 [ <required> $database_name ]
+ Parameter #1 [ <required> $table_name ]
+ Parameter #2 [ <optional> $link_identifier ]
+ mysql_listtables
+ Deprecated: yes
+ Accepted parameters: 2
+ Required parameters: 1
+ Parameter #0 [ <required> $database_name ]
+ Parameter #1 [ <optional> $link_identifier ]
+ mysql_num_fields
+ Deprecated: no
+ Accepted parameters: 1
+ Required parameters: 1
+ Parameter #0 [ <required> $result ]
+ mysql_num_rows
+ Deprecated: no
+ Accepted parameters: 1
+ Required parameters: 1
+ Parameter #0 [ <required> $result ]
+ mysql_numfields
+ Deprecated: yes
+ Accepted parameters: 1
+ Required parameters: 1
+ Parameter #0 [ <required> $result ]
+ mysql_numrows
+ Deprecated: yes
+ Accepted parameters: 1
+ Required parameters: 1
+ Parameter #0 [ <required> $result ]
+ mysql_pconnect
+ Deprecated: no
+ Accepted parameters: 4
+ Required parameters: 0
+ Parameter #0 [ <optional> $hostname ]
+ Parameter #1 [ <optional> $username ]
+ Parameter #2 [ <optional> $password ]
+ Parameter #3 [ <optional> $flags ]
+ mysql_ping
+ Deprecated: no
+ Accepted parameters: 1
+ Required parameters: 0
+ Parameter #0 [ <optional> $link_identifier ]
+ mysql_query
+ Deprecated: no
+ Accepted parameters: 2
+ Required parameters: 1
+ Parameter #0 [ <required> $query ]
+ Parameter #1 [ <optional> $link_identifier ]
+ mysql_real_escape_string
+ Deprecated: no
+ Accepted parameters: 2
+ Required parameters: 1
+ Parameter #0 [ <required> $string ]
+ Parameter #1 [ <optional> $link_identifier ]
+ mysql_result
+ Deprecated: no
+ Accepted parameters: 3
+ Required parameters: 2
+ Parameter #0 [ <required> $result ]
+ Parameter #1 [ <required> $row ]
+ Parameter #2 [ <optional> $field ]
+ mysql_select_db
+ Deprecated: no
+ Accepted parameters: 2
+ Required parameters: 1
+ Parameter #0 [ <required> $database_name ]
+ Parameter #1 [ <optional> $link_identifier ]
+ mysql_selectdb
+ Deprecated: yes
+ Accepted parameters: 2
+ Required parameters: 1
+ Parameter #0 [ <required> $database_name ]
+ Parameter #1 [ <optional> $link_identifier ]
+ mysql_set_charset
+ Deprecated: no
+ Accepted parameters: 2
+ Required parameters: 1
+ Parameter #0 [ <required> $charset_name ]
+ Parameter #1 [ <optional> $link_identifier ]
+ mysql_stat
+ Deprecated: no
+ Accepted parameters: 1
+ Required parameters: 0
+ Parameter #0 [ <optional> $link_identifier ]
+ mysql_table_name
+ Deprecated: no
+ Accepted parameters: 3
+ Required parameters: 2
+ Parameter #0 [ <required> $result ]
+ Parameter #1 [ <required> $row ]
+ Parameter #2 [ <optional> $field ]
+ mysql_tablename
+ Deprecated: no
+ Accepted parameters: 3
+ Required parameters: 2
+ Parameter #0 [ <required> $result ]
+ Parameter #1 [ <required> $row ]
+ Parameter #2 [ <optional> $field ]
+ mysql_thread_id
+ Deprecated: no
+ Accepted parameters: 1
+ Required parameters: 0
+ Parameter #0 [ <optional> $link_identifier ]
+ mysql_unbuffered_query
+ Deprecated: no
+ Accepted parameters: 2
+ Required parameters: 1
+ Parameter #0 [ <required> $query ]
+ Parameter #1 [ <optional> $link_identifier ]
+done! \ No newline at end of file
diff --git a/ext/mysql/tests/mysql_result.phpt b/ext/mysql/tests/mysql_result.phpt
index 2c7c618547..0a58b9b883 100644
--- a/ext/mysql/tests/mysql_result.phpt
+++ b/ext/mysql/tests/mysql_result.phpt
@@ -65,6 +65,8 @@ print "done!";
require_once("clean_table.inc");
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
Warning: mysql_result(): Unable to jump to row -1 on MySQL result index %d in %s on line %d
bool(false)
diff --git a/ext/mysql/tests/mysql_select_db.phpt b/ext/mysql/tests/mysql_select_db.phpt
index 211e34222e..e9bc99aa73 100644
--- a/ext/mysql/tests/mysql_select_db.phpt
+++ b/ext/mysql/tests/mysql_select_db.phpt
@@ -66,6 +66,7 @@ if (false !== ($tmp = mysql_select_db($db, $link)))
print "done!\n";
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
%unicode|string%(%d) "%s"
bool(false)
diff --git a/ext/mysql/tests/mysql_set_charset.phpt b/ext/mysql/tests/mysql_set_charset.phpt
index 953323b49c..a0bccd8c31 100644
--- a/ext/mysql/tests/mysql_set_charset.phpt
+++ b/ext/mysql/tests/mysql_set_charset.phpt
@@ -58,4 +58,5 @@ mysql_close($link);
print "done!";
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
done!
diff --git a/ext/mysql/tests/mysql_stat.phpt b/ext/mysql/tests/mysql_stat.phpt
index 30a840a2a1..d6a34df581 100644
--- a/ext/mysql/tests/mysql_stat.phpt
+++ b/ext/mysql/tests/mysql_stat.phpt
@@ -44,5 +44,7 @@ if (false !== ($tmp = mysql_stat($link)))
print "done!";
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
Warning: mysql_stat(): %d is not a valid MySQL-Link resource in %s on line %d
done!
diff --git a/ext/mysql/tests/mysql_tablename.phpt b/ext/mysql/tests/mysql_tablename.phpt
index 2415e4fda0..4bbe54d443 100644
--- a/ext/mysql/tests/mysql_tablename.phpt
+++ b/ext/mysql/tests/mysql_tablename.phpt
@@ -42,6 +42,8 @@ mysql_close($link);
print "done!";
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
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
diff --git a/ext/mysql/tests/mysql_thread_id.phpt b/ext/mysql/tests/mysql_thread_id.phpt
index b05bb3ed1c..aa95d31944 100644
--- a/ext/mysql/tests/mysql_thread_id.phpt
+++ b/ext/mysql/tests/mysql_thread_id.phpt
@@ -35,5 +35,7 @@ if (false !== ($tmp = mysql_thread_id($link)))
print "done!";
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
+
Warning: mysql_thread_id(): %d is not a valid MySQL-Link resource in %s on line %d
-done! \ No newline at end of file
+done!
diff --git a/ext/mysql/tests/mysql_trace_mode.phpt b/ext/mysql/tests/mysql_trace_mode.phpt
index 2b6c61d27b..7655975d70 100644
--- a/ext/mysql/tests/mysql_trace_mode.phpt
+++ b/ext/mysql/tests/mysql_trace_mode.phpt
@@ -29,6 +29,7 @@ print "done!\n";
require_once("clean_table.inc");
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
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 ad9b4fbc52..8754b58b59 100644
--- a/ext/mysql/tests/mysql_unbuffered_query.phpt
+++ b/ext/mysql/tests/mysql_unbuffered_query.phpt
@@ -107,6 +107,7 @@ if (!mysql_query('DROP TABLE IF EXISTS test', $link)) {
mysql_close($link);
?>
--EXPECTF--
+Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in %s on line %d
array(1) {
[%u|b%"valid"]=>
%unicode|string%(30) "this is sql but with semicolon"
diff --git a/ext/mysqli/config.m4 b/ext/mysqli/config.m4
index 687b422898..f6c86e762b 100644
--- a/ext/mysqli/config.m4
+++ b/ext/mysqli/config.m4
@@ -3,13 +3,14 @@ dnl $Id$
dnl config.m4 for extension mysqli
PHP_ARG_WITH(mysqli, for MySQLi support,
-[ --with-mysqli[=FILE] Include MySQLi support. FILE is the path
+[ --with-mysqli[=FILE] Include MySQLi support. FILE is the path
to mysql_config. If no value or mysqlnd is passed
as FILE, the MySQL native driver will be used])
PHP_ARG_ENABLE(embedded_mysqli, whether to enable embedded MySQLi support,
-[ --enable-embedded-mysqli MYSQLi: Enable embedded support
- Note: Does not work with MySQL native driver!], no, no)
+[ --enable-embedded-mysqli
+ MYSQLi: Enable embedded support
+ Note: Does not work with MySQL native driver!], no, no)
if test "$PHP_MYSQLI" = "yes" || test "$PHP_MYSQLI" = "mysqlnd"; then
dnl This needs to be set in any extension which wishes to use mysqlnd
diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c
index 4e4ed5b2ab..929f776a43 100644
--- a/ext/mysqli/mysqli.c
+++ b/ext/mysqli/mysqli.c
@@ -699,6 +699,10 @@ PHP_MINIT_FUNCTION(mysqli)
REGISTER_LONG_CONSTANT("MYSQLI_OPT_SSL_VERIFY_SERVER_CERT", MYSQL_OPT_SSL_VERIFY_SERVER_CERT, CONST_CS | CONST_PERSISTENT);
#endif
+#if MYSQL_VERSION_ID > 50605 || defined(MYSQLI_USE_MYSQLND)
+ REGISTER_LONG_CONSTANT("MYSQLI_SERVER_PUBLIC_KEY", MYSQL_SERVER_PUBLIC_KEY, CONST_CS | CONST_PERSISTENT);
+#endif
+
/* mysqli_real_connect flags */
REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_SSL", CLIENT_SSL, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("MYSQLI_CLIENT_COMPRESS",CLIENT_COMPRESS, CONST_CS | CONST_PERSISTENT);
@@ -838,10 +842,20 @@ PHP_MINIT_FUNCTION(mysqli)
REGISTER_LONG_CONSTANT("MYSQLI_REFRESH_BACKUP_LOG", REFRESH_BACKUP_LOG, CONST_CS | CONST_PERSISTENT);
#endif
-#if MYSQL_VERSION_ID >= 50611 || defined(MYSQLI_USE_MYSQLND)
+#if (MYSQL_VERSION_ID >= 50611 && defined(CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS)) || defined(MYSQLI_USE_MYSQLND)
REGISTER_LONG_CONSTANT("MYSQLI_OPT_CAN_HANDLE_EXPIRED_PASSWORDS", MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS, CONST_CS | CONST_PERSISTENT);
#endif
+ REGISTER_LONG_CONSTANT("MYSQLI_TRANS_START_WITH_CONSISTENT_SNAPSHOT", TRANS_START_WITH_CONSISTENT_SNAPSHOT, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("MYSQLI_TRANS_START_READ_WRITE", TRANS_START_READ_WRITE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("MYSQLI_TRANS_START_READ_ONLY", TRANS_START_READ_ONLY, CONST_CS | CONST_PERSISTENT);
+
+ REGISTER_LONG_CONSTANT("MYSQLI_TRANS_COR_AND_CHAIN", TRANS_COR_AND_CHAIN, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("MYSQLI_TRANS_COR_AND_NO_CHAIN", TRANS_COR_AND_NO_CHAIN, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("MYSQLI_TRANS_COR_RELEASE", TRANS_COR_RELEASE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("MYSQLI_TRANS_COR_NO_RELEASE", TRANS_COR_NO_RELEASE, CONST_CS | CONST_PERSISTENT);
+
+
#ifdef MYSQLI_USE_MYSQLND
mysqlnd_reverse_api_register_api(&mysqli_reverse_api TSRMLS_CC);
#endif
@@ -1324,218 +1338,6 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags
}
/* }}} */
-
-#if !defined(MYSQLI_USE_MYSQLND)
-
-#define ALLOC_CALLBACK_ARGS(a, b, c)\
-if (c) {\
- a = (zval ***)safe_emalloc(c, sizeof(zval **), 0);\
- for (i = b; i < c; i++) {\
- a[i] = emalloc(sizeof(zval *));\
- MAKE_STD_ZVAL(*a[i]);\
- }\
-}
-
-#define FREE_CALLBACK_ARGS(a, b, c)\
-if (a) {\
- for (i=b; i < c; i++) {\
- zval_ptr_dtor(a[i]);\
- efree(a[i]);\
- }\
- efree(a);\
-}
-
-#define LOCAL_INFILE_ERROR_MSG(source,dest)\
- memset(source, 0, LOCAL_INFILE_ERROR_LEN);\
- memcpy(source, dest, MIN(strlen(dest), LOCAL_INFILE_ERROR_LEN-1));\
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", dest);
-
-
-/* {{{ php_local_infile_init
- */
-static int php_local_infile_init(void **ptr, const char *filename, void *userdata)
-{
- mysqli_local_infile *data;
- MY_MYSQL *mysql;
- php_stream_context *context = NULL;
-
- TSRMLS_FETCH();
-
- /* save pointer to MY_MYSQL structure (userdata) */
- if (!(*ptr= data= ((mysqli_local_infile *)calloc(1, sizeof(mysqli_local_infile))))) {
- return 1;
- }
-
- if (!(mysql = (MY_MYSQL *)userdata)) {
- LOCAL_INFILE_ERROR_MSG(data->error_msg, ER(CR_UNKNOWN_ERROR));
- return 1;
- }
-
- /* check open_basedir */
- if (PG(open_basedir)) {
- if (php_check_open_basedir_ex(filename, 0 TSRMLS_CC) == -1) {
- LOCAL_INFILE_ERROR_MSG(data->error_msg, "open_basedir restriction in effect. Unable to open file");
- return 1;
- }
- }
-
- mysql->li_stream = php_stream_open_wrapper_ex((char *)filename, "r", 0, NULL, context);
-
- if (mysql->li_stream == NULL) {
- snprintf((char *)data->error_msg, sizeof(data->error_msg), "Can't find file '%-.64s'.", filename);
- return 1;
- }
-
- data->userdata = mysql;
-
- return 0;
-}
-/* }}} */
-
-/* {{{ int php_local_infile_read */
-static int php_local_infile_read(void *ptr, char *buf, uint buf_len)
-{
- mysqli_local_infile *data;
- MY_MYSQL *mysql;
- zval ***callback_args;
- zval *retval;
- zval *fp;
- int argc = 4;
- int i;
- long rc;
-
- TSRMLS_FETCH();
-
- data= (mysqli_local_infile *)ptr;
- mysql = data->userdata;
-
- /* default processing */
- if (!mysql->li_read) {
- int count = (int)php_stream_read(mysql->li_stream, buf, buf_len);
-
- if (count < 0) {
- LOCAL_INFILE_ERROR_MSG(data->error_msg, ER(2));
- }
-
- return count;
- }
-
- ALLOC_CALLBACK_ARGS(callback_args, 1, argc);
-
- /* set parameters: filepointer, buffer, buffer_len, errormsg */
-
- MAKE_STD_ZVAL(fp);
- php_stream_to_zval(mysql->li_stream, fp);
- callback_args[0] = &fp;
- ZVAL_STRING(*callback_args[1], "", 1);
- ZVAL_LONG(*callback_args[2], buf_len);
- ZVAL_STRING(*callback_args[3], "", 1);
-
- if (call_user_function_ex(EG(function_table),
- NULL,
- mysql->li_read,
- &retval,
- argc,
- callback_args,
- 0,
- NULL TSRMLS_CC) == SUCCESS) {
-
- rc = Z_LVAL_P(retval);
- zval_ptr_dtor(&retval);
-
- if (rc > 0) {
- if (rc >= 0 && rc != Z_STRLEN_P(*callback_args[1])) {
- LOCAL_INFILE_ERROR_MSG(data->error_msg,
- "Mismatch between the return value of the callback and the content "
- "length of the buffer.");
- rc = -1;
- } else if (rc > buf_len) {
- /* check buffer overflow */
- LOCAL_INFILE_ERROR_MSG(data->error_msg, "Too much data returned");
- rc = -1;
- } else {
- memcpy(buf, Z_STRVAL_P(*callback_args[1]), MIN(rc, Z_STRLEN_P(*callback_args[1])));
- }
- } else if (rc < 0) {
- LOCAL_INFILE_ERROR_MSG(data->error_msg, Z_STRVAL_P(*callback_args[3]));
- }
- } else {
- LOCAL_INFILE_ERROR_MSG(data->error_msg, "Can't execute load data local init callback function");
- rc = -1;
- }
- /*
- If the (ab)user has closed the file handle we should
- not try to use it anymore or even close it
- */
- if (!zend_rsrc_list_get_rsrc_type(Z_LVAL_P(fp) TSRMLS_CC)) {
- LOCAL_INFILE_ERROR_MSG(data->error_msg, "File handle closed");
- rc = -1;
- /* Thus the end handler won't try to free already freed memory */
- mysql->li_stream = NULL;
- }
-
- FREE_CALLBACK_ARGS(callback_args, 1, argc);
- efree(fp);
- return rc;
-}
-/* }}} */
-
-/* {{{ php_local_infile_error
- */
-static int php_local_infile_error(void *ptr, char *error_msg, uint error_msg_len)
-{
- mysqli_local_infile *data = (mysqli_local_infile *) ptr;
-
- if (data) {
- strlcpy(error_msg, data->error_msg, error_msg_len);
- return 2000;
- }
- strlcpy(error_msg, ER(CR_OUT_OF_MEMORY), error_msg_len);
- return CR_OUT_OF_MEMORY;
-}
-/* }}} */
-
-/* {{{ php_local_infile_end
- */
-static void php_local_infile_end(void *ptr)
-{
- mysqli_local_infile *data;
- MY_MYSQL *mysql;
-
- TSRMLS_FETCH();
-
- data= (mysqli_local_infile *)ptr;
-
- if (!data || !(mysql = data->userdata)) {
- if (data) {
- free(data);
- }
- return;
- }
-
- if (mysql->li_stream) {
- php_stream_close(mysql->li_stream);
- }
- free(data);
- return;
-}
-/* }}} */
-
-
-/* {{{ void php_set_local_infile_handler_default
-*/
-void php_set_local_infile_handler_default(MY_MYSQL *mysql) {
- /* register internal callback functions */
- mysql_set_local_infile_handler(mysql->mysql, &php_local_infile_init, &php_local_infile_read,
- &php_local_infile_end, &php_local_infile_error, (void *)mysql);
- if (mysql->li_read) {
- zval_ptr_dtor(&mysql->li_read);
- mysql->li_read = NULL;
- }
-}
-/* }}} */
-#endif
-
/*
* Local variables:
* tab-width: 4
diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c
index 1dbff8712b..9028401595 100644
--- a/ext/mysqli/mysqli_api.c
+++ b/ext/mysqli/mysqli_api.c
@@ -30,6 +30,7 @@
#include "php_ini.h"
#include "php_globals.h"
#include "ext/standard/info.h"
+#include "ext/standard/php_smart_str.h"
#include "php_mysqli_structs.h"
#include "mysqli_priv.h"
@@ -566,14 +567,17 @@ PHP_FUNCTION(mysqli_character_set_name)
{
MY_MYSQL *mysql;
zval *mysql_link;
+ const char *cs_name;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
return;
}
MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
-
- RETURN_STRING((char *)mysql_character_set_name(mysql->mysql), 1);
+ cs_name = mysql_character_set_name(mysql->mysql);
+ if (cs_name) {
+ RETURN_STRING(cs_name, 1);
+ }
}
/* }}} */
@@ -632,18 +636,86 @@ PHP_FUNCTION(mysqli_close)
}
/* }}} */
+
+#if !defined(MYSQLI_USE_MYSQLND)
+/* {{{ mysqli_tx_cor_options_to_string */
+static void mysqli_tx_cor_options_to_string(const MYSQL * const conn, smart_str * str, const unsigned int mode)
+{
+ if (mode & TRANS_COR_AND_CHAIN && !(mode & TRANS_COR_AND_NO_CHAIN)) {
+ if (str->len) {
+ smart_str_appendl(str, ", ", sizeof(", ") - 1);
+ }
+ smart_str_appendl(str, "AND CHAIN", sizeof("AND CHAIN") - 1);
+ } else if (mode & TRANS_COR_AND_NO_CHAIN && !(mode & TRANS_COR_AND_CHAIN)) {
+ if (str->len) {
+ smart_str_appendl(str, ", ", sizeof(", ") - 1);
+ }
+ smart_str_appendl(str, "AND NO CHAIN", sizeof("AND NO CHAIN") - 1);
+ }
+
+ if (mode & TRANS_COR_RELEASE && !(mode & TRANS_COR_NO_RELEASE)) {
+ if (str->len) {
+ smart_str_appendl(str, ", ", sizeof(", ") - 1);
+ }
+ smart_str_appendl(str, "RELEASE", sizeof("RELEASE") - 1);
+ } else if (mode & TRANS_COR_NO_RELEASE && !(mode & TRANS_COR_RELEASE)) {
+ if (str->len) {
+ smart_str_appendl(str, ", ", sizeof(", ") - 1);
+ }
+ smart_str_appendl(str, "NO RELEASE", sizeof("NO RELEASE") - 1);
+ }
+ smart_str_0(str);
+}
+/* }}} */
+
+
+/* {{{ proto bool mysqli_commit_or_rollback_libmysql */
+static int mysqli_commit_or_rollback_libmysql(MYSQL * conn, zend_bool commit, const unsigned int mode, const char * const name)
+{
+ int ret;
+ smart_str tmp_str = {0, 0, 0};
+ mysqli_tx_cor_options_to_string(conn, &tmp_str, mode);
+ smart_str_0(&tmp_str);
+
+ {
+ char * commented_name = NULL;
+ unsigned int commented_name_len = name? spprintf(&commented_name, 0, " /*%s*/", name):0;
+ char * query;
+ unsigned int query_len = spprintf(&query, 0, (commit? "COMMIT%s %s":"ROLLBACK%s %s"),
+ commented_name? commented_name:"", tmp_str.c? tmp_str.c:"");
+ smart_str_free(&tmp_str);
+
+ ret = mysql_real_query(conn, query, query_len);
+ efree(query);
+ if (commented_name) {
+ efree(commented_name);
+ }
+ }
+}
+/* }}} */
+#endif
+
+
/* {{{ proto bool mysqli_commit(object link)
Commit outstanding actions and close transaction */
PHP_FUNCTION(mysqli_commit)
{
MY_MYSQL *mysql;
zval *mysql_link;
+ long flags = TRANS_COR_NO_OPT;
+ char * name = NULL;
+ int name_len = 0;
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|ls", &mysql_link, mysqli_link_class_entry, &flags, &name, &name_len) == FAILURE) {
return;
}
MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
- if (mysql_commit(mysql->mysql)) {
+
+#if !defined(MYSQLI_USE_MYSQLND)
+ if (mysqli_commit_or_rollback_libmysql(mysql->mysql, TRUE, flags, name)) {
+#else
+ if (FAIL == mysqlnd_commit(mysql->mysql, flags, name)) {
+#endif
RETURN_FALSE;
}
RETURN_TRUE;
@@ -732,12 +804,16 @@ PHP_FUNCTION(mysqli_error)
{
MY_MYSQL *mysql;
zval *mysql_link;
+ const char *err;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
return;
}
MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
- RETURN_STRING((char *)mysql_error(mysql->mysql),1);
+ err = mysql_error(mysql->mysql);
+ if (err) {
+ RETURN_STRING(err, 1);
+ }
}
/* }}} */
@@ -1268,7 +1344,10 @@ PHP_FUNCTION(mysqli_free_result)
Get MySQL client info */
PHP_FUNCTION(mysqli_get_client_info)
{
- RETURN_STRING((char *)mysql_get_client_info(), 1);
+ const char * info = mysql_get_client_info();
+ if (info) {
+ RETURN_STRING(info, 1);
+ }
}
/* }}} */
@@ -1320,15 +1399,18 @@ PHP_FUNCTION(mysqli_get_server_info)
{
MY_MYSQL *mysql;
zval *mysql_link = NULL;
+ const char *info;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
return;
}
MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
- RETURN_STRING((char *)mysql_get_server_info(mysql->mysql), 1);
+ info = mysql_get_server_info(mysql->mysql);
+ if (info) {
+ RETURN_STRING(info, 1);
+ }
}
-
/* }}} */
/* {{{ proto int mysqli_get_server_version(object link)
@@ -1361,7 +1443,9 @@ PHP_FUNCTION(mysqli_info)
MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
info = mysql_info(mysql->mysql);
- RETURN_STRING((info) ? (char *)info : "", 1);
+ if (info) {
+ RETURN_STRING(info, 1);
+ }
}
/* }}} */
@@ -1456,64 +1540,6 @@ PHP_FUNCTION(mysqli_kill)
}
/* }}} */
-/* {{{ proto void mysqli_set_local_infile_default(object link)
- unsets user defined handler for load local infile command */
-#if !defined(MYSQLI_USE_MYSQLND)
-PHP_FUNCTION(mysqli_set_local_infile_default)
-{
- MY_MYSQL *mysql;
- zval *mysql_link;
-
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
- return;
- }
-
- MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
-
- if (mysql->li_read) {
- zval_ptr_dtor(&(mysql->li_read));
- mysql->li_read = NULL;
- }
-}
-/* }}} */
-
-/* {{{ proto bool mysqli_set_local_infile_handler(object link, callback read_func)
- Set callback functions for LOAD DATA LOCAL INFILE */
-PHP_FUNCTION(mysqli_set_local_infile_handler)
-{
- MY_MYSQL *mysql;
- zval *mysql_link;
- char *callback_name;
- zval *callback_func;
-
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oz", &mysql_link, mysqli_link_class_entry,
- &callback_func) == FAILURE) {
- return;
- }
-
- MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
-
- /* check callback function */
- if (!zend_is_callable(callback_func, 0, &callback_name TSRMLS_CC)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not a valid callback function %s", callback_name);
- efree(callback_name);
- RETURN_FALSE;
- }
- efree(callback_name);
-
- /* save callback function */
- if (!mysql->li_read) {
- MAKE_STD_ZVAL(mysql->li_read);
- } else {
- zval_dtor(mysql->li_read);
- }
- ZVAL_ZVAL(mysql->li_read, callback_func, 1, 0);
-
- RETURN_TRUE;
-}
-#endif
-/* }}} */
-
/* {{{ proto bool mysqli_more_results(object link)
check if there any more query results from a multi query */
PHP_FUNCTION(mysqli_more_results)
@@ -1645,10 +1671,10 @@ static int mysqli_options_get_option_zval_type(int option)
#endif /* MYSQLI_USE_MYSQLND */
case MYSQL_OPT_CONNECT_TIMEOUT:
#ifdef MYSQL_REPORT_DATA_TRUNCATION
- case MYSQL_REPORT_DATA_TRUNCATION:
+ case MYSQL_REPORT_DATA_TRUNCATION:
#endif
- case MYSQL_OPT_LOCAL_INFILE:
- case MYSQL_OPT_NAMED_PIPE:
+ case MYSQL_OPT_LOCAL_INFILE:
+ case MYSQL_OPT_NAMED_PIPE:
#ifdef MYSQL_OPT_PROTOCOL
case MYSQL_OPT_PROTOCOL:
#endif /* MySQL 4.1.0 */
@@ -1664,7 +1690,7 @@ static int mysqli_options_get_option_zval_type(int option)
case MYSQL_OPT_RECONNECT:
#endif /* MySQL 5.0.13 */
#ifdef MYSQL_OPT_SSL_VERIFY_SERVER_CERT
- case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
+ case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
#endif /* MySQL 5.0.23 */
#ifdef MYSQL_OPT_COMPRESS
case MYSQL_OPT_COMPRESS:
@@ -1672,7 +1698,7 @@ static int mysqli_options_get_option_zval_type(int option)
#ifdef MYSQL_OPT_SSL_VERIFY_SERVER_CERT
REGISTER_LONG_CONSTANT("MYSQLI_OPT_SSL_VERIFY_SERVER_CERT", MYSQL_OPT_SSL_VERIFY_SERVER_CERT, CONST_CS | CONST_PERSISTENT);
#endif /* MySQL 5.1.1., mysqlnd @ PHP 5.3.3 */
-#if MYSQL_VERSION_ID >= 50611 || defined(MYSQLI_USE_MYSQLND)
+#if (MYSQL_VERSION_ID >= 50611 && defined(CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS)) || defined(MYSQLI_USE_MYSQLND)
case MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS:
#endif
return IS_LONG;
@@ -1688,6 +1714,9 @@ static int mysqli_options_get_option_zval_type(int option)
case MYSQL_INIT_COMMAND:
case MYSQL_SET_CHARSET_NAME:
case MYSQL_SET_CHARSET_DIR:
+#if MYSQL_VERSION_ID > 50605 || defined(MYSQLI_USE_MYSQLND)
+ case MYSQL_SERVER_PUBLIC_KEY:
+#endif
return IS_STRING;
default:
@@ -1912,19 +1941,27 @@ PHP_FUNCTION(mysqli_real_escape_string) {
}
/* }}} */
+
/* {{{ proto bool mysqli_rollback(object link)
Undo actions from current transaction */
PHP_FUNCTION(mysqli_rollback)
{
MY_MYSQL *mysql;
zval *mysql_link;
+ long flags = TRANS_COR_NO_OPT;
+ char * name = NULL;
+ int name_len = 0;
- if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|ls", &mysql_link, mysqli_link_class_entry, &flags, &name, &name_len) == FAILURE) {
return;
}
MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
- if (mysql_rollback(mysql->mysql)) {
+#if !defined(MYSQLI_USE_MYSQLND)
+ if (mysqli_commit_or_rollback_libmysql(mysql->mysql, FALSE, flags, name)) {
+#else
+ if (FAIL == mysqlnd_rollback(mysql->mysql, flags, name)) {
+#endif
RETURN_FALSE;
}
RETURN_TRUE;
@@ -2154,12 +2191,16 @@ PHP_FUNCTION(mysqli_sqlstate)
{
MY_MYSQL *mysql;
zval *mysql_link;
+ const char *state;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
return;
}
MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
- RETURN_STRING((char *)mysql_sqlstate(mysql->mysql),1);
+ state = mysql_sqlstate(mysql->mysql);
+ if (state) {
+ RETURN_STRING(state, 1);
+ }
}
/* }}} */
@@ -2337,13 +2378,17 @@ PHP_FUNCTION(mysqli_stmt_error)
{
MY_STMT *stmt;
zval *mysql_stmt;
+ const char * err;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
return;
}
MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_INITIALIZED);
- RETURN_STRING((char *)mysql_stmt_error(stmt->stmt),1);
+ err = mysql_stmt_error(stmt->stmt);
+ if (err) {
+ RETURN_STRING(err, 1);
+ }
}
/* }}} */
@@ -2482,13 +2527,17 @@ PHP_FUNCTION(mysqli_stmt_sqlstate)
{
MY_STMT *stmt;
zval *mysql_stmt;
+ const char * state;
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_stmt, mysqli_stmt_class_entry) == FAILURE) {
return;
}
MYSQLI_FETCH_RESOURCE_STMT(stmt, &mysql_stmt, MYSQLI_STATUS_VALID);
- RETURN_STRING((char *)mysql_stmt_sqlstate(stmt->stmt),1);
+ state = mysql_stmt_sqlstate(stmt->stmt);
+ if (state) {
+ RETURN_STRING(state, 1);
+ }
}
/* }}} */
diff --git a/ext/mysqli/mysqli_fe.c b/ext/mysqli/mysqli_fe.c
index 1f6cc32d00..78fe02ab76 100644
--- a/ext/mysqli/mysqli_fe.c
+++ b/ext/mysqli/mysqli_fe.c
@@ -86,6 +86,56 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_autocommit, 0, 0, 1)
ZEND_ARG_INFO(0, mode)
ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_begin_transaction, 0, 0, 1)
+ MYSQLI_ZEND_ARG_OBJ_INFO_LINK()
+ ZEND_ARG_INFO(0, flags)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_begin_transaction, 0, 0, 0)
+ ZEND_ARG_INFO(0, flags)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_savepoint, 0, 0, 2)
+ MYSQLI_ZEND_ARG_OBJ_INFO_LINK()
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_savepoint, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_release_savepoint, 0, 0, 2)
+ MYSQLI_ZEND_ARG_OBJ_INFO_LINK()
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_release_savepoint, 0, 0, 1)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_commit, 0, 0, 1)
+ MYSQLI_ZEND_ARG_OBJ_INFO_LINK()
+ ZEND_ARG_INFO(0, flags)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_commit, 0, 0, 0)
+ ZEND_ARG_INFO(0, flags)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_rollback, 0, 0, 1)
+ MYSQLI_ZEND_ARG_OBJ_INFO_LINK()
+ ZEND_ARG_INFO(0, flags)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_rollback, 0, 0, 0)
+ ZEND_ARG_INFO(0, flags)
+ ZEND_ARG_INFO(0, name)
+ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_change_user, 0, 0, 4)
MYSQLI_ZEND_ARG_OBJ_INFO_LINK()
@@ -200,16 +250,6 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_kill, 0, 0, 1)
ZEND_ARG_INFO(0, connection_id)
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_set_local_infile_handler, 0, 0, 2)
- MYSQLI_ZEND_ARG_OBJ_INFO_LINK()
- ZEND_ARG_INFO(0, read_callback)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_set_local_infile_handler, 0, 0, 1)
- MYSQLI_ZEND_ARG_OBJ_INFO_LINK()
- ZEND_ARG_INFO(0, read_callback)
-ZEND_END_ARG_INFO()
-
ZEND_BEGIN_ARG_INFO_EX(arginfo_mysqli_query, 0, 0, 2)
MYSQLI_ZEND_ARG_OBJ_INFO_LINK()
ZEND_ARG_INFO(0, query)
@@ -336,10 +376,11 @@ ZEND_END_ARG_INFO()
const zend_function_entry mysqli_functions[] = {
PHP_FE(mysqli_affected_rows, arginfo_mysqli_only_link)
PHP_FE(mysqli_autocommit, arginfo_mysqli_autocommit)
+ PHP_FE(mysqli_begin_transaction, arginfo_mysqli_begin_transaction)
PHP_FE(mysqli_change_user, arginfo_mysqli_change_user)
PHP_FE(mysqli_character_set_name, arginfo_mysqli_only_link)
PHP_FE(mysqli_close, arginfo_mysqli_only_link)
- PHP_FE(mysqli_commit, arginfo_mysqli_only_link)
+ PHP_FE(mysqli_commit, arginfo_mysqli_commit)
PHP_FE(mysqli_connect, arginfo_mysqli_connect)
PHP_FE(mysqli_connect_errno, arginfo_mysqli_no_params)
PHP_FE(mysqli_connect_error, arginfo_mysqli_no_params)
@@ -388,10 +429,6 @@ const zend_function_entry mysqli_functions[] = {
PHP_FE(mysqli_info, arginfo_mysqli_only_link)
PHP_FE(mysqli_insert_id, arginfo_mysqli_only_link)
PHP_FE(mysqli_kill, arginfo_mysqli_kill)
-#if !defined(MYSQLI_USE_MYSQLND)
- PHP_FE(mysqli_set_local_infile_default, arginfo_mysqli_only_link)
- PHP_FE(mysqli_set_local_infile_handler, arginfo_mysqli_set_local_infile_handler)
-#endif
PHP_FE(mysqli_more_results, arginfo_mysqli_only_link)
PHP_FE(mysqli_multi_query, arginfo_mysqli_query)
PHP_FE(mysqli_next_result, arginfo_mysqli_only_link)
@@ -411,7 +448,9 @@ const zend_function_entry mysqli_functions[] = {
#if defined(MYSQLI_USE_MYSQLND)
PHP_FE(mysqli_reap_async_query, arginfo_mysqli_only_link)
#endif
- PHP_FE(mysqli_rollback, arginfo_mysqli_only_link)
+ PHP_FE(mysqli_release_savepoint, arginfo_mysqli_release_savepoint)
+ PHP_FE(mysqli_rollback, arginfo_mysqli_rollback)
+ PHP_FE(mysqli_savepoint, arginfo_mysqli_savepoint)
PHP_FE(mysqli_select_db, arginfo_mysqli_select_db)
#ifdef HAVE_MYSQLI_SET_CHARSET
PHP_FE(mysqli_set_charset, arginfo_mysqli_set_charset)
@@ -472,10 +511,11 @@ const zend_function_entry mysqli_functions[] = {
*/
const zend_function_entry mysqli_link_methods[] = {
PHP_FALIAS(autocommit, mysqli_autocommit, arginfo_class_mysqli_autocommit)
+ PHP_FALIAS(begin_transaction, mysqli_begin_transaction, arginfo_class_mysqli_begin_transaction)
PHP_FALIAS(change_user,mysqli_change_user, arginfo_class_mysqli_change_user)
PHP_FALIAS(character_set_name, mysqli_character_set_name, arginfo_mysqli_no_params)
PHP_FALIAS(close, mysqli_close, arginfo_mysqli_no_params)
- PHP_FALIAS(commit, mysqli_commit, arginfo_mysqli_no_params)
+ PHP_FALIAS(commit, mysqli_commit, arginfo_class_mysqli_commit)
PHP_FALIAS(connect, mysqli_connect, arginfo_mysqli_connect)
PHP_FALIAS(dump_debug_info, mysqli_dump_debug_info, arginfo_mysqli_no_params)
PHP_FALIAS(debug, mysqli_debug, arginfo_mysqli_debug)
@@ -490,10 +530,6 @@ const zend_function_entry mysqli_link_methods[] = {
PHP_FALIAS(get_warnings, mysqli_get_warnings, arginfo_mysqli_no_params)
PHP_FALIAS(init,mysqli_init, arginfo_mysqli_no_params)
PHP_FALIAS(kill,mysqli_kill, arginfo_class_mysqli_kill)
-#if !defined(MYSQLI_USE_MYSQLND)
- PHP_FALIAS(set_local_infile_default, mysqli_set_local_infile_default, arginfo_mysqli_no_params)
- PHP_FALIAS(set_local_infile_handler, mysqli_set_local_infile_handler, arginfo_class_mysqli_set_local_infile_handler)
-#endif
PHP_FALIAS(multi_query, mysqli_multi_query, arginfo_class_mysqli_query)
PHP_FALIAS(mysqli, mysqli_link_construct, arginfo_mysqli_connect)
PHP_FALIAS(more_results, mysqli_more_results, arginfo_mysqli_no_params)
@@ -512,7 +548,9 @@ const zend_function_entry mysqli_link_methods[] = {
#endif
PHP_FALIAS(escape_string, mysqli_real_escape_string, arginfo_class_mysqli_real_escape_string)
PHP_FALIAS(real_query, mysqli_real_query, arginfo_class_mysqli_query)
- PHP_FALIAS(rollback,mysqli_rollback, arginfo_mysqli_no_params)
+ PHP_FALIAS(release_savepoint, mysqli_release_savepoint, arginfo_class_mysqli_release_savepoint)
+ PHP_FALIAS(rollback, mysqli_rollback, arginfo_class_mysqli_rollback)
+ PHP_FALIAS(savepoint, mysqli_savepoint, arginfo_class_mysqli_savepoint)
PHP_FALIAS(select_db,mysqli_select_db, arginfo_class_mysqli_select_db)
#ifdef HAVE_MYSQLI_SET_CHARSET
PHP_FALIAS(set_charset, mysqli_set_charset, arginfo_class_mysqli_set_charset)
diff --git a/ext/mysqli/mysqli_fe.h b/ext/mysqli/mysqli_fe.h
index d9247644a8..d5ae8a6ff9 100644
--- a/ext/mysqli/mysqli_fe.h
+++ b/ext/mysqli/mysqli_fe.h
@@ -25,6 +25,7 @@
PHP_FUNCTION(mysqli);
PHP_FUNCTION(mysqli_affected_rows);
PHP_FUNCTION(mysqli_autocommit);
+PHP_FUNCTION(mysqli_begin_transaction);
PHP_FUNCTION(mysqli_change_user);
PHP_FUNCTION(mysqli_character_set_name);
PHP_FUNCTION(mysqli_set_charset);
@@ -107,6 +108,8 @@ PHP_FUNCTION(mysqli_sqlstate);
PHP_FUNCTION(mysqli_ssl_set);
PHP_FUNCTION(mysqli_stat);
PHP_FUNCTION(mysqli_refresh);
+PHP_FUNCTION(mysqli_savepoint);
+PHP_FUNCTION(mysqli_release_savepoint);
PHP_FUNCTION(mysqli_stmt_affected_rows);
PHP_FUNCTION(mysqli_stmt_close);
PHP_FUNCTION(mysqli_stmt_data_seek);
@@ -136,4 +139,3 @@ PHP_METHOD(mysqli_warning,__construct);
#endif /* MYSQLI_FE_H */
-
diff --git a/ext/mysqli/mysqli_libmysql.h b/ext/mysqli/mysqli_libmysql.h
index 87c53ce30e..5e7f730aec 100644
--- a/ext/mysqli/mysqli_libmysql.h
+++ b/ext/mysqli/mysqli_libmysql.h
@@ -42,6 +42,18 @@
#define mysqli_change_user_silent(c, u, p, d, p_len) mysql_change_user((c), (u), (p), (d))
+#define TRANS_START_NO_OPT 0
+#define TRANS_START_WITH_CONSISTENT_SNAPSHOT 1
+#define TRANS_START_READ_WRITE 2
+#define TRANS_START_READ_ONLY 4
+
+#define TRANS_COR_NO_OPT 0
+#define TRANS_COR_AND_CHAIN 1
+#define TRANS_COR_AND_NO_CHAIN 2
+#define TRANS_COR_RELEASE 4
+#define TRANS_COR_NO_RELEASE 8
+
+
/*
These functions also reside in ext/mysqlnd/mysqlnd_portability.h but since it is only made
available if one wants to build mysqli against mysqlnd and they are useful for libmysql as
diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c
index 60d185dcca..db0352baeb 100644
--- a/ext/mysqli/mysqli_nonapi.c
+++ b/ext/mysqli/mysqli_nonapi.c
@@ -29,6 +29,7 @@
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
+#include "ext/standard/php_smart_str.h"
#include "php_mysqli_structs.h"
#include "mysqli_priv.h"
@@ -259,9 +260,6 @@ void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_real_conne
#if !defined(MYSQLI_USE_MYSQLND)
mysql->mysql->reconnect = MyG(reconnect);
-
- /* set our own local_infile handler */
- php_set_local_infile_handler_default(mysql);
#endif
mysql_options(mysql->mysql, MYSQL_OPT_LOCAL_INFILE, (char *)&MyG(allow_local_infile));
@@ -737,7 +735,7 @@ static int mysqlnd_dont_poll_zval_array_from_mysqlnd_array(MYSQLND **in_array, z
int ret = 0;
ALLOC_HASHTABLE(new_hash);
- zend_hash_init(new_hash, zend_hash_num_elements(Z_ARRVAL_P(in_zval_array)), NULL, ZVAL_PTR_DTOR, 0);
+ zend_hash_init(new_hash, in_zval_array? zend_hash_num_elements(Z_ARRVAL_P(in_zval_array)):0, NULL, ZVAL_PTR_DTOR, 0);
if (in_array) {
for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(in_zval_array));
zend_hash_get_current_data(Z_ARRVAL_P(in_zval_array), (void **) &elem) == SUCCESS;
@@ -1048,6 +1046,167 @@ PHP_FUNCTION(mysqli_get_charset)
/* }}} */
#endif
+
+#if !defined(MYSQLI_USE_MYSQLND)
+/* {{{ proto bool mysqli_begin_transaction_libmysql */
+static int mysqli_begin_transaction_libmysql(MYSQL * conn, const unsigned int mode, const char * const name)
+{
+ int ret;
+ smart_str tmp_str = {0, 0, 0};
+ if (mode & TRANS_START_WITH_CONSISTENT_SNAPSHOT) {
+ if (tmp_str.len) {
+ smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
+ }
+ smart_str_appendl(&tmp_str, "WITH CONSISTENT SNAPSHOT", sizeof("WITH CONSISTENT SNAPSHOT") - 1);
+ }
+ if (mode & TRANS_START_READ_WRITE) {
+ if (tmp_str.len) {
+ smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
+ }
+ smart_str_appendl(&tmp_str, "READ WRITE", sizeof("READ WRITE") - 1);
+ }
+ if (mode & TRANS_START_READ_ONLY) {
+ if (tmp_str.len) {
+ smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
+ }
+ smart_str_appendl(&tmp_str, "READ ONLY", sizeof("READ ONLY") - 1);
+ }
+ smart_str_0(&tmp_str);
+
+ {
+ char * commented_name = NULL;
+ unsigned int commented_name_len = name? spprintf(&commented_name, 0, " /*%s*/", name):0;
+ char * query;
+ unsigned int query_len = spprintf(&query, 0, "START TRANSACTION%s %s",
+ commented_name? commented_name:"", tmp_str.c? tmp_str.c:"");
+ smart_str_free(&tmp_str);
+
+ ret = mysql_real_query(conn, query, query_len);
+ efree(query);
+ if (commented_name) {
+ efree(commented_name);
+ }
+ }
+ return ret;
+}
+/* }}} */
+#endif
+
+/* {{{ proto bool mysqli_begin_transaction(object link, [int flags [, string name]])
+ Starts a transaction */
+PHP_FUNCTION(mysqli_begin_transaction)
+{
+ MY_MYSQL *mysql;
+ zval *mysql_link;
+ long flags = TRANS_START_NO_OPT;
+ char * name = NULL;
+ int name_len = -1;
+ zend_bool err = FALSE;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|ls", &mysql_link, mysqli_link_class_entry, &flags, &name, &name_len) == FAILURE) {
+ return;
+ }
+ MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
+ if (flags < 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid value for parameter flags (%ld)", flags);
+ err = TRUE;
+ }
+ if (!name_len) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Savepoint name cannot be empty");
+ err = TRUE;
+ }
+ if (TRUE == err) {
+ RETURN_FALSE;
+ }
+
+#if !defined(MYSQLI_USE_MYSQLND)
+ if (mysqli_begin_transaction_libmysql(mysql->mysql, flags, name)) {
+ RETURN_FALSE;
+ }
+#else
+ if (FAIL == mysqlnd_begin_transaction(mysql->mysql, flags, name)) {
+ RETURN_FALSE;
+ }
+#endif
+ RETURN_TRUE;
+}
+/* }}} */
+
+
+#if !defined(MYSQLI_USE_MYSQLND)
+/* {{{ proto bool mysqli_savepoint_libmysql */
+static int mysqli_savepoint_libmysql(MYSQL * conn, const char * const name, zend_bool release)
+{
+ int ret;
+ char * query;
+ unsigned int query_len = spprintf(&query, 0, release? "RELEASE SAVEPOINT `%s`":"SAVEPOINT `%s`", name);
+ ret = mysql_real_query(conn, query, query_len);
+ efree(query);
+ return ret;
+}
+/* }}} */
+#endif
+
+
+/* {{{ proto bool mysqli_savepoint(object link, string name)
+ Starts a transaction */
+PHP_FUNCTION(mysqli_savepoint)
+{
+ MY_MYSQL *mysql;
+ zval *mysql_link;
+ char * name = NULL;
+ int name_len = -1;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &name, &name_len) == FAILURE) {
+ return;
+ }
+ MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
+ if (!name || !name_len) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Savepoint name cannot be empty");
+ RETURN_FALSE;
+ }
+
+#if !defined(MYSQLI_USE_MYSQLND)
+ if (mysqli_savepoint_libmysql(mysql->mysql, name, FALSE)) {
+#else
+ if (FAIL == mysqlnd_savepoint(mysql->mysql, name)) {
+#endif
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+
+/* {{{ proto bool mysqli_release_savepoint(object link, string name)
+ Starts a transaction */
+PHP_FUNCTION(mysqli_release_savepoint)
+{
+ MY_MYSQL *mysql;
+ zval *mysql_link;
+ char * name = NULL;
+ int name_len = -1;
+
+ if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &name, &name_len) == FAILURE) {
+ return;
+ }
+ MYSQLI_FETCH_RESOURCE_CONN(mysql, &mysql_link, MYSQLI_STATUS_VALID);
+ if (!name || !name_len) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Savepoint name cannot be empty");
+ RETURN_FALSE;
+ }
+#if !defined(MYSQLI_USE_MYSQLND)
+ if (mysqli_savepoint_libmysql(mysql->mysql, name, TRUE)) {
+#else
+ if (FAIL == mysqlnd_savepoint(mysql->mysql, name)) {
+#endif
+ RETURN_FALSE;
+ }
+ RETURN_TRUE;
+}
+/* }}} */
+
+
/*
* Local variables:
* tab-width: 4
diff --git a/ext/mysqli/mysqli_priv.h b/ext/mysqli/mysqli_priv.h
index a583f4f0e2..190572b689 100644
--- a/ext/mysqli/mysqli_priv.h
+++ b/ext/mysqli/mysqli_priv.h
@@ -76,7 +76,6 @@ extern void php_clear_warnings(MYSQLI_WARNING *w);
extern void php_free_stmt_bind_buffer(BIND_BUFFER bbuf, int type);
extern void php_mysqli_report_error(const char *sqlstate, int errorno, const char *error TSRMLS_DC);
extern void php_mysqli_report_index(const char *query, unsigned int status TSRMLS_DC);
-extern void php_set_local_infile_handler_default(MY_MYSQL *);
extern void php_mysqli_throw_sql_exception(char *sqlstate, int errorno TSRMLS_DC, char *format, ...);
#ifdef HAVE_SPL
diff --git a/ext/mysqli/mysqli_prop.c b/ext/mysqli/mysqli_prop.c
index 1a4fb1e3ce..7060367394 100644
--- a/ext/mysqli/mysqli_prop.c
+++ b/ext/mysqli/mysqli_prop.c
@@ -253,8 +253,8 @@ MYSQLI_MAP_PROPERTY_FUNC_LONG(link_thread_id_read, mysql_thread_id, MYSQLI_GET_M
MYSQLI_MAP_PROPERTY_FUNC_LONG(link_warning_count_read, mysql_warning_count, MYSQLI_GET_MYSQL(MYSQLI_STATUS_VALID), ulong, "%lu")
/* {{{ property link_stat_read */
-static int link_stat_read(mysqli_object *obj, zval **retval TSRMLS_DC)\
-{\
+static int link_stat_read(mysqli_object *obj, zval **retval TSRMLS_DC)
+{
MY_MYSQL *mysql;
MAKE_STD_ZVAL(*retval);
diff --git a/ext/mysqli/mysqli_report.h b/ext/mysqli/mysqli_report.h
deleted file mode 100644
index 637586b3c4..0000000000
--- a/ext/mysqli/mysqli_report.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- +----------------------------------------------------------------------+
- | PHP Version 5 |
- +----------------------------------------------------------------------+
- | Copyright (c) 1997-2014 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: Georg Richter <georg@php.net> |
- +----------------------------------------------------------------------+
-
- $Id$
-*/
-
-#ifndef __HAVE_MYSQLI_PROFILER_H__
-#define __HAVE_MYSQLI_PROFILER_H__
-
-#ifdef PHP_WIN32
-#include <process.h>
-#include <direct.h>
-#include "win32/time.h"
-#else
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <sys/time.h>
-#endif
-
-typedef struct {
- struct timeval starttime,
- endtime; /* execution time */
-} PR_TIME_INFO;
-
-
-#define MYSQLI_PR_REPORT_STDERR 1
-#define MYSQLI_PR_REPORT_PORT 2
-
-
-
-/*** PROFILER MACROS ***/
-#define MYSQLI_PROFILER_STARTTIME(ptr) if (MyG(profiler.mode)) gettimeofday(&ptr.starttime, NULL)
-#define MYSQLI_PROFILER_ENDTIME(ptr) if (MyG(profiler.mode)) gettimeofday(&ptr.endtime, NULL)
-#define MYSQLI_PROFILER_REPORT(_type, _time, ptr) if (MyG(profiler.mode)) php_mysqli_profiler_report(_type, _time, (void *)ptr)
-
-
-
-#endif
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * indent-tabs-mode: t
- * End:
- * vim600: noet sw=4 ts=4 fdm=marker
- * vim<600: noet sw=4 ts=4
- */
diff --git a/ext/mysqli/mysqli_result_iterator.c b/ext/mysqli/mysqli_result_iterator.c
index 98d854838c..a84060316b 100644
--- a/ext/mysqli/mysqli_result_iterator.c
+++ b/ext/mysqli/mysqli_result_iterator.c
@@ -150,12 +150,11 @@ static void php_mysqli_result_iterator_rewind(zend_object_iterator *iter TSRMLS_
/* {{{ php_mysqli_result_iterator_current_key */
-static int php_mysqli_result_iterator_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
+static void php_mysqli_result_iterator_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC)
{
php_mysqli_result_iterator *iterator = (php_mysqli_result_iterator*) iter;
- *int_key = (ulong) iterator->row_num;
- return HASH_KEY_IS_LONG;
+ ZVAL_LONG(key, iterator->row_num);
}
/* }}} */
diff --git a/ext/mysqli/package.xml b/ext/mysqli/package.xml
index 6de81d7a93..c27316a055 100644
--- a/ext/mysqli/package.xml
+++ b/ext/mysqli/package.xml
@@ -43,7 +43,6 @@ package.xml added to support installation using pear installer
<file role="src" name="mysqli_prop.c"/>
<file role="src" name="mysqli_repl.c"/>
<file role="src" name="mysqli_report.c"/>
- <file role="src" name="mysqli_report.h"/>
<file role="src" name="php_mysqli.h"/>
<file role="doc" name="CREDITS"/>
<file role="test" name="tests/001.phpt"/>
diff --git a/ext/mysqli/php_mysqli_structs.h b/ext/mysqli/php_mysqli_structs.h
index d652592707..e7c02f9c9b 100644
--- a/ext/mysqli/php_mysqli_structs.h
+++ b/ext/mysqli/php_mysqli_structs.h
@@ -131,12 +131,6 @@ typedef struct {
} MY_MYSQL;
typedef struct {
- int mode;
- int socket;
- FILE *fp;
-} PROFILER;
-
-typedef struct {
void *ptr; /* resource: (mysql, result, stmt) */
void *info; /* additional buffer */
enum mysqli_status status; /* object status */
@@ -164,12 +158,6 @@ typedef struct _mysqli_property_entry {
int (*w_func)(mysqli_object *obj, zval *value TSRMLS_DC);
} mysqli_property_entry;
-#if !defined(MYSQLI_USE_MYSQLND)
-typedef struct {
- char error_msg[LOCAL_INFILE_ERROR_LEN];
- void *userdata;
-} mysqli_local_infile;
-#endif
typedef struct {
zend_ptr_stack free_links;
diff --git a/ext/mysqli/tests/057.phpt b/ext/mysqli/tests/057.phpt
index 2cb887506a..7c7e2b7568 100644
--- a/ext/mysqli/tests/057.phpt
+++ b/ext/mysqli/tests/057.phpt
@@ -35,8 +35,8 @@ require_once('skipifconnectfailure.inc');
var_dump(mysqli_stmt_reset($stmt));
var_dump($stmt = mysqli_prepare($link, "SELECT * FROM test_store_result"));
- if ($IS_MYSQLND && $stmt->affected_rows !== -1)
- printf("[001] Expecting -1, got %d\n", $stmt->affected_rows);
+ if ($stmt->affected_rows !== 0)
+ printf("[001] Expecting 0, got %d\n", $stmt->affected_rows);
var_dump(mysqli_stmt_execute($stmt));
var_dump($stmt = @mysqli_prepare($link, "SELECT * FROM test_store_result"), mysqli_error($link));
diff --git a/ext/mysqli/tests/connect.inc b/ext/mysqli/tests/connect.inc
index 3a9d8ec258..4acc20cb91 100644
--- a/ext/mysqli/tests/connect.inc
+++ b/ext/mysqli/tests/connect.inc
@@ -129,99 +129,6 @@
}
}
- function my_get_charsets($link) {
-
- /* Those tree are set by SET NAMES */
- $charsets = array(
- 'client' => NULL,
- 'results' => NULL,
- 'connection' => NULL,
- );
-
- if (!($res = mysqli_query($link, "SHOW VARIABLES LIKE '%character%'"))) {
- printf("[%d] %s\n", mysqli_errno($link), mysqli_error($link));
- return $charsets;
- }
-
- $names = array();
- while ($row = mysqli_fetch_assoc($res)) {
- $names[$row['Variable_name']] = $row['Value'];
- }
- mysqli_free_result($res);
-
- if (!($res = mysqli_query($link, sprintf("SHOW CHARACTER SET LIKE '%s'", $names['character_set_client']))) ||
- !($details = mysqli_fetch_assoc($res))) {
- printf("[%d] %s\n", mysqli_errno($link), mysqli_error($link));
- return $charsets;
- }
- mysqli_free_result($res);
-
- $charsets['client'] = array(
- 'charset' => $details['Charset'],
- 'desc' => $details['Description'],
- 'collation' => $details['Default collation'],
- 'maxlen' => $details['Maxlen'],
- 'nr' => NULL,
- );
-
- if (!($res = mysqli_query($link, sprintf("SHOW COLLATION LIKE '%s'", $details['Default collation']))) ||
- !($collation = mysqli_fetch_assoc($res))) {
- printf("[%d] %s\n", mysqli_errno($link), mysqli_error($link));
- return $charsets;
- }
- mysqli_free_result($res);
- $charsets['client']['nr'] = $collation['Id'];
-
- if (!($res = mysqli_query($link, sprintf("SHOW CHARACTER SET LIKE '%s'", $names['character_set_results']))) ||
- !($details = mysqli_fetch_assoc($res))) {
- printf("[%d] %s\n", mysqli_errno($link), mysqli_error($link));
- return $charsets;
- }
- mysqli_free_result($res);
-
- $charsets['results'] = array(
- 'charset' => $details['Charset'],
- 'desc' => $details['Description'],
- 'collation' => $details['Default collation'],
- 'maxlen' => $details['Maxlen'],
- 'nr' => NULL,
- );
-
- if (!($res = mysqli_query($link, sprintf("SHOW COLLATION LIKE '%s'", $details['Default collation']))) ||
- !($collation = mysqli_fetch_assoc($res))) {
- printf("[%d] %s\n", mysqli_errno($link), mysqli_error($link));
- return $charsets;
- }
- mysqli_free_result($res);
- $charsets['results']['nr'] = $collation['Id'];
-
-
- if (!($res = mysqli_query($link, sprintf("SHOW CHARACTER SET LIKE '%s'", $names['character_set_connection']))) ||
- !($details = mysqli_fetch_assoc($res))) {
- printf("[%d] %s\n", mysqli_errno($link), mysqli_error($link));
- return $charsets;
- }
- mysqli_free_result($res);
-
- $charsets['connection'] = array(
- 'charset' => $details['Charset'],
- 'desc' => $details['Description'],
- 'collation' => $details['Default collation'],
- 'maxlen' => $details['Maxlen'],
- 'nr' => NULL,
- );
-
- if (!($res = mysqli_query($link, sprintf("SHOW COLLATION LIKE '%s'", $details['Default collation']))) ||
- !($collation = mysqli_fetch_assoc($res))) {
- printf("[%d] %s\n", mysqli_errno($link), mysqli_error($link));
- return $charsets;
- }
- mysqli_free_result($res);
- $charsets['connection']['nr'] = $collation['Id'];
-
- return $charsets;
- }
-
function have_innodb($link) {
if (($res = $link->query("SHOW VARIABLES LIKE 'have_innodb'")) &&
($row = $res->fetch_row()) &&
diff --git a/ext/mysqli/tests/mysqli_class_mysqli_interface.phpt b/ext/mysqli/tests/mysqli_class_mysqli_interface.phpt
index df7d1c6580..ea86c198e7 100644
--- a/ext/mysqli/tests/mysqli_class_mysqli_interface.phpt
+++ b/ext/mysqli/tests/mysqli_class_mysqli_interface.phpt
@@ -20,38 +20,41 @@ require_once('skipifconnectfailure.inc');
$methods = get_class_methods($mysqli);
$expected_methods = array(
'autocommit' => true,
+ 'begin_transaction' => true,
'change_user' => true,
- 'character_set_name' => true,
- 'close' => true,
- 'commit' => true,
- 'connect' => true,
+ 'character_set_name' => true,
+ 'close' => true,
+ 'commit' => true,
+ 'connect' => true,
'dump_debug_info' => true,
'escape_string' => true,
'get_charset' => true,
'get_client_info' => true,
'get_server_info' => true,
'get_warnings' => true,
- 'init' => true,
- 'kill' => true,
+ 'init' => true,
+ 'kill' => true,
'more_results' => true,
'multi_query' => true,
- 'mysqli' => true,
+ 'mysqli' => true,
'next_result' => true,
- 'options' => true,
- 'ping' => true,
- 'prepare' => true,
- 'query' => true,
+ 'options' => true,
+ 'ping' => true,
+ 'prepare' => true,
+ 'query' => true,
'real_connect' => true,
- 'real_escape_string' => true,
+ 'real_escape_string' => true,
'real_query' => true,
- 'refresh' => true,
- 'rollback' => true,
- 'select_db' => true,
+ 'refresh' => true,
+ 'rollback' => true,
+ 'release_savepoint' => true,
+ 'savepoint' => true,
+ 'select_db' => true,
'set_charset' => true,
- 'set_opt' => true,
- 'ssl_set' => true,
- 'stat' => true,
- 'stmt_init' => true,
+ 'set_opt' => true,
+ 'ssl_set' => true,
+ 'stat' => true,
+ 'stmt_init' => true,
'store_result' => true,
'thread_safe' => true,
'use_result' => true,
@@ -67,12 +70,6 @@ require_once('skipifconnectfailure.inc');
$expected_methods['get_connection_stats'] = true;
$expected_methods['reap_async_query'] = true;
$expected_methods['poll'] = true;
- } else {
- // libmysql only
- if (function_exists('mysqli_ssl_set'))
- $expected_methods['ssl_set'] = true;
- $expected_methods['set_local_infile_default'] = true;
- $expected_methods['set_local_infile_handler'] = true;
}
/* we should add ruled when to expect them */
@@ -301,7 +298,7 @@ mysqli->insert_id = '0'/integer ('0'/integer)
mysqli->sqlstate = '00000'/%unicode|string% ('00000'/%unicode|string%)
mysqli->stat = 'Uptime: %d Threads: %d Questions: %d Slow queries: %d Opens: %d Flush tables: %d Open tables: %d Queries per second avg: %d.%d'/string ('Uptime: %d Threads: %d Questions: %d Slow queries: %d Opens: %d Flush tables: %d Open tables: %d Queries per second avg: %d.%d'/string)
mysqli->host_info = '%s'/%unicode|string% ('%s'/%unicode|string%)
-mysqli->info = ''/NULL (''/%unicode|string%)
+mysqli->info = ''/NULL (''/NULL)
mysqli->thread_id = '%d'/integer ('%d'/integer)
mysqli->protocol_version = '%d'/integer ('%d'/integer)
mysqli->server_info = '%s'/%unicode|string% ('%s'/%unicode|string%)
diff --git a/ext/mysqli/tests/mysqli_class_mysqli_reflection.phpt b/ext/mysqli/tests/mysqli_class_mysqli_reflection.phpt
index 5fd4b6f45c..259fcd9ae6 100644
--- a/ext/mysqli/tests/mysqli_class_mysqli_reflection.phpt
+++ b/ext/mysqli/tests/mysqli_class_mysqli_reflection.phpt
@@ -6,8 +6,6 @@ require_once('skipif.inc');
require_once('skipifemb.inc');
require_once('connect.inc');
-if (($tmp = substr(PHP_VERSION, 0, strpos(PHP_VERSION, '.'))) && ($tmp < 5))
- die("skip Reflection not available before PHP 5 (found PHP $tmp)");
/*
Let's not deal with cross-version issues in the EXPECTF/UEXPECTF.
Most of the things which we test are covered by mysqli_class_*_interface.phpt.
@@ -120,6 +118,36 @@ isPassedByReference: no
isOptional: no
isDefaultValueAvailable: no
+Inspecting method 'begin_transaction'
+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: 2
+Number of Required Parameters: 0
+
+Inspecting parameter 'flags' of method 'begin_transaction'
+isArray: no
+allowsNull: no
+isPassedByReference: no
+isOptional: yes
+isDefaultValueAvailable: no
+
+Inspecting parameter 'name' of method 'begin_transaction'
+isArray: no
+allowsNull: no
+isPassedByReference: no
+isOptional: yes
+isDefaultValueAvailable: no
+
Inspecting method 'change_user'
isFinal: no
isAbstract: no
@@ -202,9 +230,23 @@ isInternal: yes
isUserDefined: no
returnsReference: no
Modifiers: 256
-Number of Parameters: 0
+Number of Parameters: 2
Number of Required Parameters: 0
+Inspecting parameter 'flags' of method 'commit'
+isArray: no
+allowsNull: no
+isPassedByReference: no
+isOptional: yes
+isDefaultValueAvailable: no
+
+Inspecting parameter 'name' of method 'commit'
+isArray: no
+allowsNull: no
+isPassedByReference: no
+isOptional: yes
+isDefaultValueAvailable: no
+
Inspecting method 'connect'
isFinal: no
isAbstract: no
@@ -850,6 +892,29 @@ isPassedByReference: no
isOptional: no
isDefaultValueAvailable: no
+Inspecting method 'release_savepoint'
+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: 1
+Number of Required Parameters: 1
+
+Inspecting parameter 'name' of method 'release_savepoint'
+isArray: no
+allowsNull: no
+isPassedByReference: no
+isOptional: no
+isDefaultValueAvailable: no
+
Inspecting method 'rollback'
isFinal: no
isAbstract: no
@@ -863,9 +928,46 @@ isInternal: yes
isUserDefined: no
returnsReference: no
Modifiers: 256
-Number of Parameters: 0
+Number of Parameters: 2
Number of Required Parameters: 0
+Inspecting parameter 'flags' of method 'rollback'
+isArray: no
+allowsNull: no
+isPassedByReference: no
+isOptional: yes
+isDefaultValueAvailable: no
+
+Inspecting parameter 'name' of method 'rollback'
+isArray: no
+allowsNull: no
+isPassedByReference: no
+isOptional: yes
+isDefaultValueAvailable: no
+
+Inspecting method 'savepoint'
+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: 1
+Number of Required Parameters: 1
+
+Inspecting parameter 'name' of method 'savepoint'
+isArray: no
+allowsNull: no
+isPassedByReference: no
+isOptional: no
+isDefaultValueAvailable: no
+
Inspecting method 'select_db'
isFinal: no
isAbstract: no
diff --git a/ext/mysqli/tests/mysqli_commit_oo.phpt b/ext/mysqli/tests/mysqli_commit_oo.phpt
index 34ec4bfcdc..e19f698e81 100644
--- a/ext/mysqli/tests/mysqli_commit_oo.phpt
+++ b/ext/mysqli/tests/mysqli_commit_oo.phpt
@@ -28,12 +28,8 @@ if (!have_innodb($link))
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 (!is_null($tmp = @$mysqli->commit($link)))
- printf("[002] Expecting NULL/NULL, got %s/%s, [%d] %s\n",
- gettype($tmp), $tmp, $mysqli->errno, $mysqli->error);
-
if (true !== ($tmp = $mysqli->commit()))
- printf("[014] Expecting boolean/true got %s/%s\n", gettype($tmp), $tmp);
+ printf("[002] Expecting boolean/true got %s/%s\n", gettype($tmp), $tmp);
if (true !== ($tmp = $mysqli->autocommit(false)))
printf("[003] Cannot turn off autocommit, expecting true, got %s/%s\n", gettype($tmp), $tmp);
diff --git a/ext/mysqli/tests/mysqli_constants.phpt b/ext/mysqli/tests/mysqli_constants.phpt
index 8bdc849f78..7c6dacd393 100644
--- a/ext/mysqli/tests/mysqli_constants.phpt
+++ b/ext/mysqli/tests/mysqli_constants.phpt
@@ -32,7 +32,7 @@ require_once('skipifconnectfailure.inc');
"MYSQLI_ASSOC" => true,
"MYSQLI_NUM" => true,
"MYSQLI_BOTH" => true,
- "MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH" => true,
+ "MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH"=> true,
"MYSQLI_NOT_NULL_FLAG" => true,
"MYSQLI_PRI_KEY_FLAG" => true,
"MYSQLI_UNIQUE_KEY_FLAG" => true,
@@ -86,14 +86,21 @@ require_once('skipifconnectfailure.inc');
"MYSQLI_SET_CHARSET_NAME" => true,
"MYSQLI_SET_CHARSET_DIR" => true,
"MYSQLI_REFRESH_GRANT" => true,
- "MYSQLI_REFRESH_LOG" => true,
+ "MYSQLI_REFRESH_LOG" => true,
"MYSQLI_REFRESH_TABLES" => true,
"MYSQLI_REFRESH_HOSTS" => true,
"MYSQLI_REFRESH_STATUS" => true,
"MYSQLI_REFRESH_THREADS" => true,
"MYSQLI_REFRESH_SLAVE" => true,
"MYSQLI_REFRESH_MASTER" => true,
- "MYSQLI_DEBUG_TRACE_ENABLED" => true,
+ "MYSQLI_DEBUG_TRACE_ENABLED" => true,
+ "MYSQLI_TRANS_START_WITH_CONSISTENT_SNAPSHOT" => true,
+ "MYSQLI_TRANS_START_READ_WRITE" => true,
+ "MYSQLI_TRANS_START_READ_ONLY" => true,
+ "MYSQLI_TRANS_COR_AND_CHAIN" => true,
+ "MYSQLI_TRANS_COR_AND_NO_CHAIN" => true,
+ "MYSQLI_TRANS_COR_RELEASE" => true,
+ "MYSQLI_TRANS_COR_NO_RELEASE" => true,
);
/* depends on the build - experimental */
@@ -125,6 +132,12 @@ require_once('skipifconnectfailure.inc');
$expected_constants['MYSQLI_SERVER_QUERY_WAS_SLOW'] = true;
}
+
+ /* First introduced in MySQL 6.0, backported to MySQL 5.5 */
+ if ($version >= 50606 || $IS_MYSQLND) {
+ $expected_constants['MYSQLI_SERVER_PUBLIC_KEY'] = true;
+ }
+
if ($version > 50002) {
$expected_constants = array_merge($expected_constants, array(
"MYSQLI_TYPE_NEWDECIMAL" => true,
diff --git a/ext/mysqli/tests/mysqli_expire_password.phpt b/ext/mysqli/tests/mysqli_expire_password.phpt
index ce89a21670..4fdf902c79 100644
--- a/ext/mysqli/tests/mysqli_expire_password.phpt
+++ b/ext/mysqli/tests/mysqli_expire_password.phpt
@@ -127,11 +127,11 @@ if (!mysqli_query($link, sprintf("GRANT SELECT ON TABLE %s.test TO expiretest@'%
?>
--EXPECTF--
-Warning: mysqli_real_connect(): (HY000/1820): %s in %s on line %d
-[001] Cannot connect [1820] %s
+Warning: mysqli_real_connect(): (HY000/1862): %s in %s on line %d
+[001] Cannot connect [1862] %s
-Warning: mysqli_real_connect(): (HY000/1820): %s in %s on line %d
-[003] Cannot connect [1820] %s
+Warning: mysqli_real_connect(): (HY000/1862): %s in %s on line %d
+[003] Cannot connect [1862] %s
[006] Connect allowed, query fail, [1820] %s
[008] Connect allowed, pw set, [0%A
array(1) {
diff --git a/ext/mysqli/tests/mysqli_fetch_field.phpt b/ext/mysqli/tests/mysqli_fetch_field.phpt
index d1d358b342..2b9108072b 100644
--- a/ext/mysqli/tests/mysqli_fetch_field.phpt
+++ b/ext/mysqli/tests/mysqli_fetch_field.phpt
@@ -22,7 +22,13 @@ require_once('skipifconnectfailure.inc');
require('table.inc');
- $charsets = my_get_charsets($link);
+ // Make sure that client, connection and result charsets are all the
+ // same. Not sure whether this is strictly necessary.
+ if (!mysqli_set_charset($link, 'utf8'))
+ printf("[%d] %s\n", mysqli_errno($link), mysqli_errno($link));
+
+ $charsetInfo = mysqli_get_charset($link);
+
if (!$res = mysqli_query($link, "SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 1")) {
printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
}
@@ -34,19 +40,17 @@ require_once('skipifconnectfailure.inc');
/* label column, result set charset */
$tmp = mysqli_fetch_field($res);
var_dump($tmp);
- if ($tmp->charsetnr != $charsets['results']['nr']) {
+ if ($tmp->charsetnr != $charsetInfo->number) {
printf("[004] Expecting charset %s/%d got %d\n",
- $charsets['results']['charset'],
- $charsets['results']['nr'], $tmp->charsetnr);
+ $charsetInfo->charset, $charsetInfo->number, $tmp->charsetnr);
}
- if ($tmp->length != (1 * $charsets['results']['maxlen'])) {
+ if ($tmp->length != $charsetInfo->max_length) {
printf("[005] Expecting length %d got %d\n",
- $charsets['results']['maxlen'],
- $tmp->max_length);
+ $charsetInfo->max_length, $tmp->max_length);
}
if ($tmp->db != $db) {
printf("011] Expecting database '%s' got '%s'\n",
- $db, $tmp->db);
+ $db, $tmp->db);
}
var_dump(mysqli_fetch_field($res));
@@ -174,4 +178,4 @@ object(stdClass)#%d (13) {
[%u|b%"decimals"]=>
int(0)
}
-done! \ No newline at end of file
+done!
diff --git a/ext/mysqli/tests/mysqli_fetch_field_oo.phpt b/ext/mysqli/tests/mysqli_fetch_field_oo.phpt
index 2d5ad261b1..8c5609b163 100644
--- a/ext/mysqli/tests/mysqli_fetch_field_oo.phpt
+++ b/ext/mysqli/tests/mysqli_fetch_field_oo.phpt
@@ -27,7 +27,12 @@ require_once('skipifconnectfailure.inc');
if (!is_null($tmp = @$res->fetch_field($link)))
printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
- $charsets = my_get_charsets($link);
+ // Make sure that client, connection and result charsets are all the
+ // same. Not sure whether this is strictly necessary.
+ if (!$mysqli->set_charset('utf8'))
+ printf("[%d] %s\n", $mysqli->errno, $mysqli->errno);
+
+ $charsetInfo = $mysqli->get_charset();
if (!$res = $mysqli->query("SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 1")) {
printf("[004] [%d] %s\n", $mysqli->errno, $mysqli->error);
@@ -37,18 +42,16 @@ require_once('skipifconnectfailure.inc');
$tmp = $res->fetch_field();
var_dump($tmp);
- if ($tmp->charsetnr != $charsets['results']['nr']) {
+ if ($tmp->charsetnr != $charsetInfo->number) {
printf("[005] Expecting charset %s/%d got %d\n",
- $charsets['results']['charset'],
- $charsets['results']['nr'], $tmp->charsetnr);
+ $charsetInfo->charset, $charsetInfo->number, $tmp->charsetnr);
}
- if ($tmp->length != (1 * $charsets['results']['maxlen'])) {
+ if ($tmp->length != $charsetInfo->max_length) {
printf("[006] Expecting length %d got %d\n",
- $charsets['results']['maxlen'],
- $tmp->max_length);
+ $charsetInfo->max_length, $tmp->max_length);
}
if ($tmp->db != $db) {
- printf("008] Expecting database '%s' got '%s'\n",
+ printf("[007] Expecting database '%s' got '%s'\n",
$db, $tmp->db);
}
@@ -126,4 +129,4 @@ object(stdClass)#%d (13) {
bool(false)
Warning: mysqli_result::fetch_field(): Couldn't fetch mysqli_result in %s on line %d
-done! \ No newline at end of file
+done!
diff --git a/ext/mysqli/tests/mysqli_fetch_fields.phpt b/ext/mysqli/tests/mysqli_fetch_fields.phpt
index 479c71cbbc..6b66d6f231 100644
--- a/ext/mysqli/tests/mysqli_fetch_fields.phpt
+++ b/ext/mysqli/tests/mysqli_fetch_fields.phpt
@@ -21,7 +21,13 @@ require_once('skipifconnectfailure.inc');
printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
require('table.inc');
- $charsets = my_get_charsets($link);
+
+ // Make sure that client, connection and result charsets are all the
+ // same. Not sure whether this is strictly necessary.
+ if (!mysqli_set_charset($link, 'utf8'))
+ printf("[%d] %s\n", mysqli_errno($link), mysqli_errno($link));
+
+ $charsetInfo = mysqli_get_charset($link);
if (!$res = mysqli_query($link, "SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 1")) {
printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
@@ -33,14 +39,14 @@ require_once('skipifconnectfailure.inc');
switch ($k) {
case 1:
/* label column, result set charset */
- if ($field->charsetnr != $charsets['results']['nr']) {
+ if ($field->charsetnr != $charsetInfo->number) {
printf("[004] Expecting charset %s/%d got %d\n",
- $charsets['results']['charset'],
- $charsets['results']['nr'], $field->charsetnr);
+ $charsetInfo->charset,
+ $charsetInfo->number, $field->charsetnr);
}
- if ($field->length != (1 * $charsets['results']['maxlen'])) {
+ if ($field->length != $charsetInfo->max_length) {
printf("[005] Expecting length %d got %d\n",
- $charsets['results']['maxlen'],
+ $charsetInfo->max_length,
$field->max_length);
}
break;
@@ -118,4 +124,4 @@ object(stdClass)#%d (13) {
}
Warning: mysqli_fetch_fields(): Couldn't fetch mysqli_result in %s on line %d
-done! \ No newline at end of file
+done!
diff --git a/ext/mysqli/tests/mysqli_field_seek.phpt b/ext/mysqli/tests/mysqli_field_seek.phpt
index a747bdfa01..449d2f90d4 100644
--- a/ext/mysqli/tests/mysqli_field_seek.phpt
+++ b/ext/mysqli/tests/mysqli_field_seek.phpt
@@ -66,7 +66,13 @@ require_once('skipifconnectfailure.inc');
printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp);
require('table.inc');
- $charsets = my_get_charsets($link);
+
+ // Make sure that client, connection and result charsets are all the
+ // same. Not sure whether this is strictly necessary.
+ if (!mysqli_set_charset($link, 'utf8'))
+ printf("[%d] %s\n", mysqli_errno($link), mysqli_errno($link));
+
+ $charsetInfo = mysqli_get_charset($link);
if (!$res = mysqli_query($link, "SELECT id, label FROM test ORDER BY id LIMIT 1", MYSQLI_USE_RESULT)) {
printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
@@ -81,15 +87,13 @@ require_once('skipifconnectfailure.inc');
$field = mysqli_fetch_field($res);
var_dump($field);
/* label column, result set charset */
- if ($field->charsetnr != $charsets['results']['nr']) {
+ if ($field->charsetnr != $charsetInfo->number) {
printf("[004] Expecting charset %s/%d got %d\n",
- $charsets['results']['charset'],
- $charsets['results']['nr'], $field->charsetnr);
+ $charsetInfo->charset, $charsetInfo->number, $field->charsetnr);
}
- if ($field->length != (1 * $charsets['results']['maxlen'])) {
+ if ($field->length != $charsetInfo->max_length) {
printf("[005] Expecting length %d got %d\n",
- $charsets['results']['maxlen'],
- $field->max_length);
+ $charsetInfo->max_length, $field->max_length);
}
var_dump(mysqli_field_tell($res));
@@ -217,7 +221,7 @@ bool(false)
Warning: mysqli_field_seek(): Invalid field offset in %s on line %d
bool(false)
bool(true)
-object(stdClass)#3 (13) {
+object(stdClass)#%d (13) {
[%u|b%"name"]=>
%unicode|string%(5) "_null"
[%u|b%"orgname"]=>
@@ -248,4 +252,4 @@ object(stdClass)#3 (13) {
Warning: mysqli_field_seek(): Couldn't fetch mysqli_result in %s on line %d
NULL
-done! \ No newline at end of file
+done!
diff --git a/ext/mysqli/tests/mysqli_info.phpt b/ext/mysqli/tests/mysqli_info.phpt
index 2d5004fe6e..6bb5d215e0 100644
--- a/ext/mysqli/tests/mysqli_info.phpt
+++ b/ext/mysqli/tests/mysqli_info.phpt
@@ -21,8 +21,8 @@ require_once('skipifconnectfailure.inc');
printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
// NOTE: empty string, no multiple insert syntax
- if (!is_string($tmp = mysqli_info($link)) || ('' != $tmp))
- printf("[004] Expecting string/empty, got %s/%s\n", gettype($tmp), $tmp);
+ if (!is_null($tmp = mysqli_info($link)) || ('' != $tmp))
+ printf("[004] Expecting null, got %s/%s\n", gettype($tmp), $tmp);
if (!$res = mysqli_query($link, "INSERT INTO test(id, label) VALUES (101, 'a'), (102, 'b')"))
printf("[005] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
@@ -54,8 +54,8 @@ require_once('skipifconnectfailure.inc');
if (!$res = mysqli_query($link, "SELECT 1"))
printf("[013] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
- if (!is_string($tmp = mysqli_info($link)) || ('' != $tmp))
- printf("[014] Expecting string/empty, got %s/%s\n", gettype($tmp), $tmp);
+ if (!is_null($tmp = mysqli_info($link)) || ('' != $tmp))
+ printf("[014] Expecting null, got %s/%s\n", gettype($tmp), $tmp);
mysqli_free_result($res);
// NOTE: no LOAD DATA INFILE test
diff --git a/ext/mysqli/tests/mysqli_pam_sha256.phpt b/ext/mysqli/tests/mysqli_pam_sha256.phpt
new file mode 100644
index 0000000000..3016e200d7
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_pam_sha256.phpt
@@ -0,0 +1,113 @@
+--TEST--
+PAM: SHA-256
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+
+ob_start();
+phpinfo(INFO_MODULES);
+$tmp = ob_get_contents();
+ob_end_clean();
+if (!stristr($tmp, "auth_plugin_sha256_password"))
+ die("skip SHA256 auth plugin not built-in to mysqlnd");
+
+require_once('connect.inc');
+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) < 50606)
+ die("skip: SHA-256 requires MySQL 5.6.6+");
+
+if (!($res = $link->query("SHOW PLUGINS"))) {
+ die(sprintf("skip [%d] %s\n", $link->errno, $link->error));
+}
+
+$found = false;
+while ($row = $res->fetch_assoc()) {
+ if (($row['Name'] == 'sha256_password') && ($row['Status'] == 'ACTIVE')) {
+ $found = true;
+ break;
+ }
+}
+if (!$found)
+ die("skip SHA-256 server plugin unavailable");
+
+if (!($res = $link->query("SHOW STATUS LIKE 'Rsa_public_key'"))) {
+ die(sprintf("skip [%d] %s\n", $link->errno, $link->error));
+}
+
+if (!($row = $res->fetch_assoc())) {
+ die(sprintf("skip Failed to check RSA pub key, [%d] %s\n", $link->errno, $link->error));
+}
+
+if (strlen($row['Value']) < 100) {
+ die(sprintf("skip Server misconfiguration? RSA pub key is suspicious, [%d] %s\n", $link->errno, $link->error));
+}
+
+if (!$link->query("SET @@session.old_passwords=2")) {
+ die(sprintf("skip Cannot set @@session.old_passwords=2 [%d] %s", $link->errno, $link->error));
+}
+
+$link->query('DROP USER shatest');
+$link->query("DROP USER shatest@localhost");
+
+
+if (!$link->query('CREATE USER shatest@"%" IDENTIFIED WITH sha256_password') ||
+ !$link->query('CREATE USER shatest@"localhost" IDENTIFIED WITH sha256_password')) {
+ die(sprintf("skip CREATE USER failed [%d] %s", $link->errno, $link->error));
+}
+
+if (!$link->query('SET PASSWORD FOR shatest@"%" = PASSWORD("shatest")') ||
+ !$link->query('SET PASSWORD FOR shatest@"localhost" = PASSWORD("shatest")')) {
+ die(sprintf("skip SET PASSWORD failed [%d] %s", $link->errno, $link->error));
+}
+
+if (!$link->query("DROP TABLE IF EXISTS test") ||
+ !$link->query("CREATE TABLE test (id INT)") ||
+ !$link->query("INSERT INTO test(id) VALUES (1), (2), (3)"))
+ die(sprintf("SKIP [%d] %s\n", $link->errno, $link->error));
+
+
+if (!$link->query(sprintf("GRANT SELECT ON TABLE %s.test TO shatest@'%%'", $db)) ||
+ !$link->query(sprintf("GRANT SELECT ON TABLE %s.test TO shatest@'localhost'", $db))) {
+ die(sprintf("skip Cannot grant SELECT to user [%d] %s", mysqli_errno($link), mysqli_error($link)));
+}
+
+$link->close();
+?>
+--FILE--
+<?php
+ require_once("connect.inc");
+
+ if (!$link = my_mysqli_connect($host, 'shatest', 'shatest', $db, $port, $socket)) {
+ printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n",
+ $host, "shatest", $db, $port, $socket);
+ } else {
+
+ if (!$res = $link->query("SELECT id FROM test WHERE id = 1"))
+ printf("[002] [%d] %s\n", $link->errno, $link->error);
+
+ if (!$row = mysqli_fetch_assoc($res)) {
+ printf("[003] [%d] %s\n", $link->errno, $link->error);
+ }
+
+ if ($row['id'] != 1) {
+ printf("[004] Expecting 1 got %s/'%s'", gettype($row['id']), $row['id']);
+ }
+
+ $res->close();
+ $link->close();
+ }
+
+ print "done!";
+?>
+--CLEAN--
+<?php
+ require_once("clean_table.inc");
+ $link->query('DROP USER shatest');
+ $link->query('DROP USER shatest@localhost');
+?>
+--EXPECTF--
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_pam_sha256_public_key_ini.phpt b/ext/mysqli/tests/mysqli_pam_sha256_public_key_ini.phpt
new file mode 100644
index 0000000000..27bbed138c
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_pam_sha256_public_key_ini.phpt
@@ -0,0 +1,129 @@
+--TEST--
+PAM: SHA-256, mysqlnd.sha256_server_public_key
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+
+ob_start();
+phpinfo(INFO_MODULES);
+$tmp = ob_get_contents();
+ob_end_clean();
+if (!stristr($tmp, "auth_plugin_sha256_password"))
+ die("skip SHA256 auth plugin not built-in to mysqlnd");
+
+require_once('connect.inc');
+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) < 50606)
+ die("skip: SHA-256 requires MySQL 5.6.6+");
+
+if (!($res = $link->query("SHOW PLUGINS"))) {
+ die(sprintf("skip [%d] %s\n", $link->errno, $link->error));
+}
+
+$found = false;
+while ($row = $res->fetch_assoc()) {
+ if (($row['Name'] == 'sha256_password') && ($row['Status'] == 'ACTIVE')) {
+ $found = true;
+ break;
+ }
+}
+if (!$found)
+ die("skip SHA-256 server plugin unavailable");
+
+if (!($res = $link->query("SHOW STATUS LIKE 'Rsa_public_key'"))) {
+ die(sprintf("skip [%d] %s\n", $link->errno, $link->error));
+}
+
+if (!($row = $res->fetch_assoc())) {
+ die(sprintf("skip Failed to check RSA pub key, [%d] %s\n", $link->errno, $link->error));
+}
+
+$key = $row['Value'];
+if (strlen($key) < 100) {
+ die(sprintf("skip Server misconfiguration? RSA pub key is suspicious, [%d] %s\n", $link->errno, $link->error));
+}
+
+/* date changes may give false positive */
+$file = "test_sha256_ini";
+if ((file_exists($file) && !unlink($file)) || !($fp = @fopen($file, "w"))) {
+ die(sprintf("skip Cannot create RSA pub key file '%s'", $file));
+}
+$key = str_replace("A", "a", $key);
+$key = str_replace("M", "m", $key);
+if (strlen($key) != fwrite($fp, $key)) {
+ die(sprintf("skip Failed to create pub key file"));
+}
+
+
+if (!$link->query("SET @@session.old_passwords=2")) {
+ die(sprintf("skip Cannot set @@session.old_passwords=2 [%d] %s", $link->errno, $link->error));
+}
+
+$link->query('DROP USER shatest');
+$link->query("DROP USER shatest@localhost");
+
+
+if (!$link->query('CREATE USER shatest@"%" IDENTIFIED WITH sha256_password') ||
+ !$link->query('CREATE USER shatest@"localhost" IDENTIFIED WITH sha256_password')) {
+ die(sprintf("skip CREATE USER failed [%d] %s", $link->errno, $link->error));
+}
+
+if (!$link->query('SET PASSWORD FOR shatest@"%" = PASSWORD("shatest")') ||
+ !$link->query('SET PASSWORD FOR shatest@"localhost" = PASSWORD("shatest")')) {
+ die(sprintf("skip SET PASSWORD failed [%d] %s", $link->errno, $link->error));
+}
+
+if (!$link->query("DROP TABLE IF EXISTS test") ||
+ !$link->query("CREATE TABLE test (id INT)") ||
+ !$link->query("INSERT INTO test(id) VALUES (1), (2), (3)"))
+ die(sprintf("SKIP [%d] %s\n", $link->errno, $link->error));
+
+
+if (!$link->query(sprintf("GRANT SELECT ON TABLE %s.test TO shatest@'%%'", $db)) ||
+ !$link->query(sprintf("GRANT SELECT ON TABLE %s.test TO shatest@'localhost'", $db))) {
+ die(sprintf("skip Cannot grant SELECT to user [%d] %s", mysqli_errno($link), mysqli_error($link)));
+}
+
+$link->close();
+?>
+--INI--
+mysqlnd.sha256_server_public_key="test_sha256_ini"
+--FILE--
+<?php
+ require_once("connect.inc");
+
+
+ $link = new mysqli($host, 'shatest', 'shatest', $db, $port, $socket);
+ if ($link->connect_errno) {
+ printf("[001] [%d] %s\n", $link->connect_errno, $link->connect_error);
+ } else {
+ if (!$res = $link->query("SELECT id FROM test WHERE id = 1"))
+ printf("[002] [%d] %s\n", $link->errno, $link->error);
+
+ if (!$row = mysqli_fetch_assoc($res)) {
+ printf("[003] [%d] %s\n", $link->errno, $link->error);
+ }
+
+ if ($row['id'] != 1) {
+ printf("[004] Expecting 1 got %s/'%s'", gettype($row['id']), $row['id']);
+ }
+ }
+ print "done!";
+?>
+--CLEAN--
+<?php
+ require_once("clean_table.inc");
+ $link->query('DROP USER shatest');
+ $link->query('DROP USER shatest@localhost');
+ $file = "test_sha256_ini";
+ @unlink($file);
+?>
+--EXPECTF--
+
+Warning: mysqli::mysqli(): (HY000/1045): %s in %s on line %d
+[001] [1045] %s
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_pam_sha256_public_key_option.phpt b/ext/mysqli/tests/mysqli_pam_sha256_public_key_option.phpt
new file mode 100644
index 0000000000..afed773b01
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_pam_sha256_public_key_option.phpt
@@ -0,0 +1,132 @@
+--TEST--
+PAM: SHA-256, option: MYSQLI_SERVER_PUBLIC_KEY
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+
+ob_start();
+phpinfo(INFO_MODULES);
+$tmp = ob_get_contents();
+ob_end_clean();
+if (!stristr($tmp, "auth_plugin_sha256_password"))
+ die("skip SHA256 auth plugin not built-in to mysqlnd");
+
+require_once('connect.inc');
+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) < 50606)
+ die("skip: SHA-256 requires MySQL 5.6.6+");
+
+if (!($res = $link->query("SHOW PLUGINS"))) {
+ die(sprintf("skip [%d] %s\n", $link->errno, $link->error));
+}
+
+$found = false;
+while ($row = $res->fetch_assoc()) {
+ if (($row['Name'] == 'sha256_password') && ($row['Status'] == 'ACTIVE')) {
+ $found = true;
+ break;
+ }
+}
+if (!$found)
+ die("skip SHA-256 server plugin unavailable");
+
+if (!($res = $link->query("SHOW STATUS LIKE 'Rsa_public_key'"))) {
+ die(sprintf("skip [%d] %s\n", $link->errno, $link->error));
+}
+
+if (!($row = $res->fetch_assoc())) {
+ die(sprintf("skip Failed to check RSA pub key, [%d] %s\n", $link->errno, $link->error));
+}
+
+if (strlen($row['Value']) < 100) {
+ die(sprintf("skip Server misconfiguration? RSA pub key is suspicious, [%d] %s\n", $link->errno, $link->error));
+}
+
+/* date changes may give false positive */
+$file = sprintf("%s%s%s_%s", sys_get_temp_dir(), DIRECTORY_SEPARATOR, "test_sha256_" , @date("Ymd"));
+if ((file_exists($file) && !unlink($file)) || !($fp = @fopen($file, "w"))) {
+ die(sprintf("skip Cannot create RSA pub key file '%s'", $file));
+}
+if (strlen($row['Value']) != fwrite($fp, $row['Value'])) {
+ die(sprintf("skip Failed to create pub key file"));
+}
+
+
+if (!$link->query("SET @@session.old_passwords=2")) {
+ die(sprintf("skip Cannot set @@session.old_passwords=2 [%d] %s", $link->errno, $link->error));
+}
+
+$link->query('DROP USER shatest');
+$link->query("DROP USER shatest@localhost");
+
+
+if (!$link->query('CREATE USER shatest@"%" IDENTIFIED WITH sha256_password') ||
+ !$link->query('CREATE USER shatest@"localhost" IDENTIFIED WITH sha256_password')) {
+ die(sprintf("skip CREATE USER failed [%d] %s", $link->errno, $link->error));
+}
+
+if (!$link->query('SET PASSWORD FOR shatest@"%" = PASSWORD("shatest")') ||
+ !$link->query('SET PASSWORD FOR shatest@"localhost" = PASSWORD("shatest")')) {
+ die(sprintf("skip SET PASSWORD failed [%d] %s", $link->errno, $link->error));
+}
+
+if (!$link->query("DROP TABLE IF EXISTS test") ||
+ !$link->query("CREATE TABLE test (id INT)") ||
+ !$link->query("INSERT INTO test(id) VALUES (1), (2), (3)"))
+ die(sprintf("SKIP [%d] %s\n", $link->errno, $link->error));
+
+
+if (!$link->query(sprintf("GRANT SELECT ON TABLE %s.test TO shatest@'%%'", $db)) ||
+ !$link->query(sprintf("GRANT SELECT ON TABLE %s.test TO shatest@'localhost'", $db))) {
+ die(sprintf("skip Cannot grant SELECT to user [%d] %s", mysqli_errno($link), mysqli_error($link)));
+}
+
+$link->close();
+?>
+--FILE--
+<?php
+ require_once("connect.inc");
+
+ $file = sprintf("%s%s%s_%s", sys_get_temp_dir(), DIRECTORY_SEPARATOR, "test_sha256_" , @date("Ymd"));
+ if (file_exists($file) && is_readable($file)) {
+
+ $link = mysqli_init();
+ if (!($link->options(MYSQLI_SERVER_PUBLIC_KEY, $file))) {
+ printf("[001] mysqli_options failed, [%d] %s\n", $link->errno, $link->error);
+ }
+
+ if (!$link->real_connect($host, 'shatest', 'shatest', $db, $port, $socket)) {
+ printf("[002] [%d] %s\n", $link->connect_errno, $link->connect_error);
+ }
+
+ if (!$res = $link->query("SELECT id FROM test WHERE id = 1"))
+ printf("[003] [%d] %s\n", $link->errno, $link->error);
+
+ if (!$row = mysqli_fetch_assoc($res)) {
+ printf("[004] [%d] %s\n", $link->errno, $link->error);
+ }
+
+ if ($row['id'] != 1) {
+ printf("[005] Expecting 1 got %s/'%s'", gettype($row['id']), $row['id']);
+ }
+
+ $res->close();
+ $link->close();
+ }
+
+ print "done!";
+?>
+--CLEAN--
+<?php
+ require_once("clean_table.inc");
+ $link->query('DROP USER shatest');
+ $link->query('DROP USER shatest@localhost');
+ $file = sprintf("%s%s%s_%s", sys_get_temp_dir(), DIRECTORY_SEPARATOR, "test_sha256_" , @date("Ymd"));
+ @unlink($file);
+?>
+--EXPECTF--
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_pam_sha256_public_key_option_invalid.phpt b/ext/mysqli/tests/mysqli_pam_sha256_public_key_option_invalid.phpt
new file mode 100644
index 0000000000..e2626240d8
--- /dev/null
+++ b/ext/mysqli/tests/mysqli_pam_sha256_public_key_option_invalid.phpt
@@ -0,0 +1,188 @@
+--TEST--
+PAM: SHA-256, option: MYSQLI_SERVER_PUBLIC_KEY (invalid)
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+require_once('skipifemb.inc');
+require_once('skipifconnectfailure.inc');
+
+ob_start();
+phpinfo(INFO_MODULES);
+$tmp = ob_get_contents();
+ob_end_clean();
+if (!stristr($tmp, "auth_plugin_sha256_password"))
+ die("skip SHA256 auth plugin not built-in to mysqlnd");
+
+require_once('connect.inc');
+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) < 50606)
+ die("skip: SHA-256 requires MySQL 5.6.6+");
+
+if (!($res = $link->query("SHOW PLUGINS"))) {
+ die(sprintf("skip [%d] %s\n", $link->errno, $link->error));
+}
+
+$found = false;
+while ($row = $res->fetch_assoc()) {
+ if (($row['Name'] == 'sha256_password') && ($row['Status'] == 'ACTIVE')) {
+ $found = true;
+ break;
+ }
+}
+if (!$found)
+ die("skip SHA-256 server plugin unavailable");
+
+if (!($res = $link->query("SHOW STATUS LIKE 'Rsa_public_key'"))) {
+ die(sprintf("skip [%d] %s\n", $link->errno, $link->error));
+}
+
+if (!($row = $res->fetch_assoc())) {
+ die(sprintf("skip Failed to check RSA pub key, [%d] %s\n", $link->errno, $link->error));
+}
+
+if (strlen($row['Value']) < 100) {
+ die(sprintf("skip Server misconfiguration? RSA pub key is suspicious, [%d] %s\n", $link->errno, $link->error));
+}
+
+/* date changes may give false positive */
+$file = sprintf("%s%s%s_%s", sys_get_temp_dir(), DIRECTORY_SEPARATOR, "test_sha256_" , @date("Ymd"));
+if ((file_exists($file) && !unlink($file)) || !($fp = @fopen($file, "w"))) {
+ die(sprintf("skip Cannot create RSA pub key file '%s'", $file));
+}
+if (strlen($row['Value']) != fwrite($fp, $row['Value'])) {
+ die(sprintf("skip Failed to create pub key file"));
+}
+
+
+if (!$link->query("SET @@session.old_passwords=2")) {
+ die(sprintf("skip Cannot set @@session.old_passwords=2 [%d] %s", $link->errno, $link->error));
+}
+
+$link->query('DROP USER shatest');
+$link->query("DROP USER shatest@localhost");
+
+
+if (!$link->query('CREATE USER shatest@"%" IDENTIFIED WITH sha256_password') ||
+ !$link->query('CREATE USER shatest@"localhost" IDENTIFIED WITH sha256_password')) {
+ die(sprintf("skip CREATE USER failed [%d] %s", $link->errno, $link->error));
+}
+
+if (!$link->query('SET PASSWORD FOR shatest@"%" = PASSWORD("shatest")') ||
+ !$link->query('SET PASSWORD FOR shatest@"localhost" = PASSWORD("shatest")')) {
+ die(sprintf("skip SET PASSWORD failed [%d] %s", $link->errno, $link->error));
+}
+
+if (!$link->query("DROP TABLE IF EXISTS test") ||
+ !$link->query("CREATE TABLE test (id INT)") ||
+ !$link->query("INSERT INTO test(id) VALUES (1), (2), (3)"))
+ die(sprintf("SKIP [%d] %s\n", $link->errno, $link->error));
+
+
+if (!$link->query(sprintf("GRANT SELECT ON TABLE %s.test TO shatest@'%%'", $db)) ||
+ !$link->query(sprintf("GRANT SELECT ON TABLE %s.test TO shatest@'localhost'", $db))) {
+ die(sprintf("skip Cannot grant SELECT to user [%d] %s", mysqli_errno($link), mysqli_error($link)));
+}
+
+$link->close();
+?>
+--FILE--
+<?php
+ require_once("connect.inc");
+
+ function sha_connect($offset, $host, $db, $port, $socket, $file) {
+
+ $link = mysqli_init();
+ if (!($link->options(MYSQLI_SERVER_PUBLIC_KEY, $file))) {
+ printf("[%03d + 001] mysqli_options failed, [%d] %s\n", $offset, $link->errno, $link->error);
+ return false;
+ }
+
+ if (!$link->real_connect($host, 'shatest', 'shatest', $db, $port, $socket)) {
+ printf("[%03d + 002] [%d] %s\n", $offset, $link->connect_errno, $link->connect_error);
+ return false;
+ }
+
+ if (!$res = $link->query("SELECT id FROM test WHERE id = 1"))
+ printf("[%03d + 003] [%d] %s\n", $offset, $link->errno, $link->error);
+ return false;
+
+ if (!$row = mysqli_fetch_assoc($res)) {
+ printf("[%03d + 004] [%d] %s\n", $offset, $link->errno, $link->error);
+ return false;
+ }
+
+ if ($row['id'] != 1) {
+ printf("[%03d + 005] Expecting 1 got %s/'%s'", $offset, gettype($row['id']), $row['id']);
+ return false;
+ }
+
+ $res->close();
+ $link->close();
+ return true;
+ }
+
+ $file = sprintf("%s%s%s_%s", sys_get_temp_dir(), DIRECTORY_SEPARATOR, "test_sha256_" , @date("Ymd"));
+ if (file_exists($file) && is_readable($file)) {
+
+ /* valid key */
+ sha_connect(100, $host, $db, $port, $socket, $file);
+
+ /* invalid key */
+ $file_wrong = sprintf("%s%s%s_%s", sys_get_temp_dir(), DIRECTORY_SEPARATOR, "test_sha256_wrong" , @date("Ymd"));
+
+ $key = file_get_contents($file);
+ $key = str_replace("A", "a", $key);
+ $key = str_replace("M", "m", $key);
+ @unlink($file_wrong);
+ if (!($fp = fopen($file_wrong, "w"))) {
+ printf("[002] Can't write public key file.");
+ } else {
+ fwrite($fp, $key);
+ fclose($fp);
+ sha_connect(200, $host, $db, $port, $socket, $file_wrong);
+ }
+
+ /* empty file */
+ @unlink($file_wrong);
+ if (!($fp = fopen($file_wrong, "w"))) {
+ printf("[003] Can't write public key file.");
+ } else {
+ fwrite($fp, "");
+ fclose($fp);
+ sha_connect(300, $host, $db, $port, $socket, $file_wrong);
+ }
+
+ /* file does not exist */
+ @unlink($file_wrong);
+ sha_connect(400, $host, $db, $port, $socket, $file_wrong);
+
+ } else {
+ printf("[001] Cannot read public key file.");
+ }
+
+ print "done!";
+?>
+--CLEAN--
+<?php
+ require_once("clean_table.inc");
+ $link->query('DROP USER shatest');
+ $link->query('DROP USER shatest@localhost');
+ $file = sprintf("%s%s%s_%s", sys_get_temp_dir(), DIRECTORY_SEPARATOR, "test_sha256_" , @date("Ymd"));
+ @unlink($file);
+ $file_wrong = sprintf("%s%s%s_%s", sys_get_temp_dir(), DIRECTORY_SEPARATOR, "test_sha256_wrong" , @date("Ymd"));
+ @unlink($file_wrong);
+?>
+--EXPECTF--
+Warning: mysqli::real_connect(): (HY000/1045): %s in %s on line %d
+[200 + 002] [1045] %s
+
+Warning: mysqli::real_connect(): (HY000/1045): %s in %s on line %d
+[300 + 002] [1045] %s
+
+Warning: mysqli::real_connect(%sest_sha256_wrong_%d): failed to open stream: No such file or directory in %s on line %d
+
+Warning: mysqli::real_connect(): (HY000/1045): %s in %s on line %d
+[400 + 002] [1045] %s
+done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_query_local_infile_large.phpt b/ext/mysqli/tests/mysqli_query_local_infile_large.phpt
deleted file mode 100644
index 76bc415d8b..0000000000
--- a/ext/mysqli/tests/mysqli_query_local_infile_large.phpt
+++ /dev/null
@@ -1,103 +0,0 @@
---TEST--
-mysql_query(LOAD DATA LOCAL INFILE) with large data set (10MB)
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifconnectfailure.inc');
-
-$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket);
-if (!$link)
- die(sprintf("skip Can't connect [%d] %s", mysqli_connect_errno(), mysqli_connect_error()));
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-mysqli.allow_local_infile=1
---FILE--
-<?php
- // Create a large CVS file
- $file = tempnam(sys_get_temp_dir(), 'mysqli_test.cvs');
- if (!$fp = fopen($file, 'w'))
- printf("[001] Cannot create CVS file '%s'\n", $file);
-
- $data = str_repeat("a", 127) . ";" . str_repeat("b", 127) . "\n";
-
- $runtime = 5;
- $max_bytes = 1024 * 1024 * 10;
-
- $start = microtime(true);
- $bytes = 0;
- $rowno = 0;
- while (($bytes < $max_bytes) && ((microtime(true) - $start) < $runtime)) {
- if ((version_compare(PHP_VERSION, '5.9.9', '>') == 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);
-
- require_once("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--
-<?php
-$file = tempnam(sys_get_temp_dir(), 'mysqli_test.cvs');
-if (file_exists($file))
- unlink($file);
-
-require_once("connect.inc");
-if (!($link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)))
- printf("[c001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error());
-
-if (!mysqli_query($link, "DROP TABLE IF EXISTS test"))
- printf("[c002] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
-?>
---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_set_local_infile_default.phpt b/ext/mysqli/tests/mysqli_set_local_infile_default.phpt
deleted file mode 100644
index 0348b01f6a..0000000000
--- a/ext/mysqli/tests/mysqli_set_local_infile_default.phpt
+++ /dev/null
@@ -1,132 +0,0 @@
---TEST--
-mysqli_set_local_infile_default()
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifemb.inc');
-require_once('skipifconnectfailure.inc');
-
-if (!function_exists('mysqli_set_local_infile_handler'))
- die("skip - function not available.");
-
-$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket);
-if (!$link)
- die(sprintf("skip Can't connect [%d] %s", mysqli_connect_errno(), mysqli_connect_error()));
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-mysqli.allow_local_infile=1
---FILE--
-<?php
- require_once('connect.inc');
- require_once('local_infile_tools.inc');
-
- $link = $tmp = null;
- if (!is_null($tmp = @mysqli_set_local_infile_default()))
- printf("[001] Expecting NULL got %s/%s\n", gettype($tmp), $tmp);
-
- if (!is_null($tmp = @mysqli_set_local_infile_default($link)))
- printf("[002] Expecting NULL got %s/%s\n", gettype($tmp), $tmp);
-
- $link = new mysqli();
- if (!is_null($tmp = @mysqli_set_local_infile_default($link)))
- printf("[002a] Expecting NULL got %s/%s\n", gettype($tmp), $tmp);
-
- include("table.inc");
-
- if (!is_null($tmp = @mysqli_set_local_infile_default($link, 'foo')))
- printf("[003] Expecting NULL got %s/%s\n", gettype($tmp), $tmp);
-
-
- function callback_simple($fp, &$buffer, $buflen, &$error) {
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation);
-
- $invocation++;
- if (!is_resource($fp))
- printf("[012] First argument passed to callback is not a resource but %s/%s\n",
- $fp, gettype($fp));
-
- if (!$buffer = fread($fp, $buflen)) {
- if ($invocation == 1) {
- printf("[013] Cannot read from stream\n");
- $error = 'Cannot read from stream';
- } else {
- return strlen($buffer);
- }
- }
-
- $lines = explode("\n", $buffer);
- if (count($lines) != 4 && strlen($buffer) > 0) {
- printf("[014] Test is too simple to handle a buffer of size %d that cannot hold all lines\n", $buflen);
- $error = 'Parser too simple';
- }
-
- $buffer = '';
- foreach ($lines as $k => $line) {
- if ('' === trim($line))
- continue;
-
- $columns = explode(';', $line);
- if (empty($columns)) {
- printf("[015] Cannot parse columns\n");
- $error = 'Cannot parse columns';
- }
-
- // increase id column value
- $columns[0] += 1;
- $buffer .= implode(';', $columns);
- $buffer .= "\n";
- }
-
- return strlen($buffer);
- }
-
- $file = create_standard_csv(4);
- $expected = array(
- array('id' => 98, 'label' => 'x'),
- array('id' => 99, 'label' => 'y'),
- array('id' => 100, 'label' => 'z'),
- );
- try_handler(10, $link, $file, 'callback_simple', $expected);
-
- $expected = array(
- array('id' => 97, 'label' => 'x'),
- array('id' => 98, 'label' => 'y'),
- array('id' => 99, 'label' => 'z'),
- );
- try_handler(20, $link, $file, 'default', $expected);
-
- $expected = array(
- array('id' => 98, 'label' => 'x'),
- array('id' => 99, 'label' => 'y'),
- array('id' => 100, 'label' => 'z'),
- );
- try_handler(30, $link, $file, 'callback_simple', $expected);
-
- mysqli_close($link);
-
- if (!is_null($tmp = @mysqli_set_local_infile_default($link)))
- printf("[300] Expecting NULL/NULL got %s/%s\n", $tmp, gettype($tmp));
-
- print "done!";
-?>
---CLEAN--
-<?php
- require_once("clean_table.inc");
-?>
---EXPECTF--
-Callback set to 'callback_simple'
-Callback: 0
-Callback: 1
-Callback set to 'default'
-Callback set to 'callback_simple'
-Callback: 2
-Callback: 3
-done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler.phpt
deleted file mode 100644
index 58f4c70351..0000000000
--- a/ext/mysqli/tests/mysqli_set_local_infile_handler.phpt
+++ /dev/null
@@ -1,196 +0,0 @@
---TEST--
-mysqli_set_local_infile_handler()
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifemb.inc');
-require_once('skipifconnectfailure.inc');
-
-if (!function_exists('mysqli_set_local_infile_handler'))
- die("skip - function not available.");
-
-require_once('connect.inc');
-if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
- die("skip Cannot connect to MySQL");
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-mysqli.allow_local_infile=1
---FILE--
-<?php
- require_once('connect.inc');
- require_once('local_infile_tools.inc');
- require_once('table.inc');
-
- function callback_simple($fp, &$buffer, $buflen, &$error) {
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation);
-
- $invocation++;
- if (!is_resource($fp))
- printf("[012] First argument passed to callback is not a resource but %s/%s\n",
- $fp, gettype($fp));
-
- if (!$buffer = fread($fp, $buflen)) {
- if ($invocation == 1) {
- printf("[013] Cannot read from stream\n");
- $error = 'Cannot read from stream';
- } else {
- return strlen($buffer);
- }
- }
-
- $lines = explode("\n", $buffer);
- if (count($lines) != 4 && strlen($buffer) > 0) {
- printf("[014] Test is too simple to handle a buffer of size %d that cannot hold all lines\n", $buflen);
- $error = 'Parser too simple';
- }
-
- $buffer = '';
- foreach ($lines as $k => $line) {
- if ('' === trim($line))
- continue;
-
- $columns = explode(';', $line);
- if (empty($columns)) {
- printf("[015] Cannot parse columns\n");
- $error = 'Cannot parse columns';
- }
-
- // increase id column value
- $columns[0] += 1;
- $buffer .= implode(';', $columns);
- $buffer .= "\n";
- }
-
- return strlen($buffer);
- }
-
- function callback_fclose($fp, &$buffer, $buflen, &$error) {
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation++);
-
- fclose($fp);
- return strlen($buffer);
- }
-
- function callback_closefile($fp, &$buffer, $buflen, &$error) {
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation++);
- flush();
- if (is_resource($fp))
- fclose($fp);
- $buffer = "1;'a';\n";
- if ($invocation > 10)
- return 0;
-
- return strlen($buffer);
- }
-
- function callback_invalid_args($fp, &$buffer, $buflen) {
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation++);
- $buffer = fread($fp, $buflen);
-
- return strlen($buffer);
- }
-
- function callback_error($fp, &$buffer, $buflen, &$error) {
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation++);
- $buffer = fread($fp, $buflen);
- $error = 'How to access this error?';
-
- return -1;
- }
-
- if (!is_null($tmp = @mysqli_set_local_infile_handler()))
- printf("[001] Expecting NULL/NULL got %s/%s\n", $tmp, gettype($tmp));
-
- $handle = null;
- if (!is_null($tmp = @mysqli_set_local_infile_handler($handle)))
- printf("[002] Expecting NULL/NULL got %s/%s\n", $tmp, gettype($tmp));
-
- $handle = @new mysqli();
- if (!is_null($tmp = @mysqli_set_local_infile_handler($handle, 'callback_simple')))
- printf("[003] Expecting NULL/NULL got %s/%s\n", $tmp, gettype($tmp));
-
- if (false !== ($tmp = @mysqli_set_local_infile_handler($link, 'unknown')))
- printf("[004] Expecting false/boolean got %s/%s\n", $tmp, gettype($tmp));
-
- $file = create_standard_csv(5);
-
- $expected = array(
- array('id' => 98, 'label' => 'x'),
- array('id' => 99, 'label' => 'y'),
- array('id' => 100, 'label' => 'z'),
- );
- try_handler(10, $link, $file, 'callback_simple', $expected);
-
- $expected = array();
- try_handler(20, $link, $file, 'callback_fclose', $expected);
-
- // FIXME - TODO - KLUDGE -
- // IMHO this is wrong. ext/mysqli should bail as the function signature
- // is not complete. That's a BC break, OK, but it makes perfectly sense.
- $expected = array();
- try_handler(30, $link, $file, 'callback_invalid_args', $expected);
-
- $expected = array();
- try_handler(40, $link, $file, 'callback_error', $expected);
-
-
- mysqli_close($link);
-
- if (!is_null($tmp = @mysqli_set_local_infile_handler($link, 'callback_simple')))
- printf("[300] Expecting NULL/NULL got %s/%s\n", $tmp, gettype($tmp));
-
- print "done!";
-?>
---CLEAN--
-<?php
- require_once("clean_table.inc");
-?>
---EXPECTF--
-Callback set to 'callback_simple'
-Callback: 0
-Callback: 1
-Callback set to 'callback_fclose'
-Callback: 0
-[022] LOAD DATA failed, [2000] File handle close%s
-Callback set to 'callback_invalid_args'
-Callback: 0
-Callback: 1
-[037] More results than expected!
-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"
-}
-Callback set to 'callback_error'
-Callback: 0
-[042] LOAD DATA failed, [2000] How to access this error?
-done! \ No newline at end of file
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
deleted file mode 100644
index b8f51c214f..0000000000
--- a/ext/mysqli/tests/mysqli_set_local_infile_handler_bad_character.phpt
+++ /dev/null
@@ -1,82 +0,0 @@
---TEST--
-mysqli_set_local_infile_handler() - random ASCII character including \0
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifemb.inc');
-require_once('skipifconnectfailure.inc');
-require_once('connect.inc');
-
-if (!function_exists('mysqli_set_local_infile_handler'))
- die("skip - function not available.");
-
-if (!$TEST_EXPERIMENTAL)
- die("skip - experimental (= unsupported) feature");
-
-if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
- die("skip Cannot connect to MySQL");
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-mysqli.allow_local_infile=1
---FILE--
-<?php
- require_once('connect.inc');
- require_once('local_infile_tools.inc');
- require_once('table.inc');
-
- function callback_bad_character($fp, &$buffer, $buflen, &$error) {
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation++);
-
- $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;
-
- $buffer = '';
- for ($i = 0; $i < $part1; $i++)
- $buffer .= chr(mt_rand(0, 255));
-
- $buffer .= ';"';
-
- for ($i = 0; $i < $part2; $i++)
- $buffer .= chr(mt_rand(0, 255));
-
- $buffer .= '";';
- if ($invocation > 10)
- return 0;
-
- return strlen($buffer);
- }
-
- $file = create_standard_csv(5);
- /* we feed the handler with random data, therefore we cannot specify and expected rows */
- try_handler(20, $link, $file, 'callback_bad_character');
-
- mysqli_close($link);
- print "done!";
-?>
---CLEAN--
-<?php
- require_once("clean_table.inc");
-?>
---EXPECTF--
-Callback set to 'callback_bad_character'
-Callback: 0
-Callback: 1
-Callback: 2
-Callback: 3
-Callback: 4
-Callback: 5
-Callback: 6
-Callback: 7
-Callback: 8
-Callback: 9
-Callback: 10
-done! \ No newline at end of file
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
deleted file mode 100644
index a3c8801023..0000000000
--- a/ext/mysqli/tests/mysqli_set_local_infile_handler_buffer_overflow.phpt
+++ /dev/null
@@ -1,60 +0,0 @@
---TEST--
-mysqli_set_local_infile_handler() - buffer overflow
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifemb.inc');
-require_once('skipifconnectfailure.inc');
-
-if (!function_exists('mysqli_set_local_infile_handler'))
- die("skip - function not available.");
-
-require_once('connect.inc');
-if (!$TEST_EXPERIMENTAL)
- die("skip - experimental (= unsupported) feature");
-
-if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
- die("skip Cannot connect to MySQL");
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-mysqli.allow_local_infile=1
---FILE--
-<?php
- require_once('connect.inc');
- require_once('local_infile_tools.inc');
- require_once('table.inc');
-
- function callback_buffer_overflow($fp, &$buffer, $buflen, &$error) {
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation);
- $buffer = fread($fp, $buflen);
-
- $buffer = str_repeat(';', $buflen * 2);
- return strlen($buffer);
- }
-
- $file = create_standard_csv(5);
- $expected = array();
- try_handler(20, $link, $file, 'callback_buffer_overflow', $expected);
-
- mysqli_close($link);
- print "done!";
-?>
---CLEAN--
-<?php
- require_once("clean_table.inc");
-?>
---EXPECTF--
-Callback set to 'callback_buffer_overflow'
-Callback: 0
-
-Warning: mysqli_query(): Too much data returned in %s on line %d
-[022] LOAD DATA failed, [%d] Too much data returned
-done! \ No newline at end of file
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
deleted file mode 100644
index 408bb29ec4..0000000000
--- a/ext/mysqli/tests/mysqli_set_local_infile_handler_close_link.phpt
+++ /dev/null
@@ -1,61 +0,0 @@
---TEST--
-mysqli_set_local_infile_handler() - close database link
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifemb.inc');
-require_once('skipifconnectfailure.inc');
-
-if (!function_exists('mysqli_set_local_infile_handler'))
- die("skip - function not available.");
-
-require_once('connect.inc');
-if (!$TEST_EXPERIMENTAL)
- die("skip - experimental (= unsupported) feature");
-
-if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
- die("skip Cannot connect to MySQL");
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-mysqli.allow_local_infile=1
---FILE--
-<?php
- require("table.inc");
- require_once('local_infile_tools.inc');
-
- function callback_close_link($fp, &$buffer, $buflen, &$error) {
- global $link;
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation++);
- flush();
- if (is_object($link))
- mysqli_close($link);
-
- $buffer = "1;'a';\n";
- if ($invocation > 10)
- return 0;
-
- return strlen($buffer);
- }
-
- $file = create_standard_csv(1);
- $expected = array(array('id' => 1, 'label' => 'a'));
- try_handler(20, $link, $file, 'callback_close_link', $expected);
- mysqli_close($link);
- print "done!";
-?>
---CLEAN--
-<?php
- require_once("clean_table.inc");
-?>
---EXPECTF--
-Callback set to 'callback_close_link'
-Callback: 0
-done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_closefile.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_closefile.phpt
deleted file mode 100644
index 168cbc1358..0000000000
--- a/ext/mysqli/tests/mysqli_set_local_infile_handler_closefile.phpt
+++ /dev/null
@@ -1,70 +0,0 @@
---TEST--
-mysqli_set_local_infile_handler() - do not use the file pointer
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifemb.inc');
-require_once('skipifconnectfailure.inc');
-
-if (!function_exists('mysqli_set_local_infile_handler'))
- die("skip - function not available.");
-
-require_once('connect.inc');
-if (!$TEST_EXPERIMENTAL)
- die("skip - experimental (= unsupported) feature");
-
-if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
- die("skip Cannot connect to MySQL");
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-mysqli.allow_local_infile=1
---FILE--
-<?php
- require_once("table.inc");
- require_once('local_infile_tools.inc');
-
- function callback_closefile($fp, &$buffer, $buflen, &$error) {
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation++);
- flush();
- if (is_resource($fp))
- fclose($fp);
- $buffer = "1;'a';\n";
- if ($invocation > 10)
- return 0;
-
- return strlen($buffer);
- }
-
- $file = create_standard_csv(1);
- $expected = array(array('id' => 1, 'label' => 'a'));
- try_handler(20, $link, $file, 'callback_closefile', $expected);
-
- mysqli_close($link);
- print "done!";
-?>
---CLEAN--
-<?php
- require_once("clean_table.inc");
-?>
---EXPECTF--
-Callback set to 'callback_closefile'
-Callback: 0
-Callback: 1
-Callback: 2
-Callback: 3
-Callback: 4
-Callback: 5
-Callback: 6
-Callback: 7
-Callback: 8
-Callback: 9
-Callback: 10
-done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_closures.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_closures.phpt
deleted file mode 100644
index ad7ab32c1c..0000000000
--- a/ext/mysqli/tests/mysqli_set_local_infile_handler_closures.phpt
+++ /dev/null
@@ -1,62 +0,0 @@
---TEST--
-mysqli_set_local_infile_handler() - use closures as handler
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifemb.inc');
-require_once('skipifconnectfailure.inc');
-
-if (!function_exists('mysqli_set_local_infile_handler'))
- die("skip - function not available.");
-
-require_once('connect.inc');
-if (!$TEST_EXPERIMENTAL)
- die("skip - experimental (= unsupported) feature");
-
-if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
- die("skip Cannot connect to MySQL");
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-mysqli.allow_local_infile=1
---FILE--
-<?php
- require_once('connect.inc');
- require_once('local_infile_tools.inc');
- require_once('table.inc');
-
- $callback_replace_buffer = function ($fp, &$buffer, $buflen, &$error) {
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation++);
- flush();
-
- $buffer = fread($fp, $buflen);
-
- if ($invocation > 10)
- return 0;
-
- return strlen($buffer);
- };
-
- $file = create_standard_csv(1);
- if (!try_handler(20, $link, $file, $callback_replace_buffer, null))
- printf("[008] Failure\n");
-
- mysqli_close($link);
- print "done!";
-?>
---CLEAN--
-<?php
- require_once("clean_table.inc");
-?>
---EXPECTF--
-Callback set to 'Closure object'
-Callback: 0
-Callback: 1
-done! \ No newline at end of file
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
deleted file mode 100644
index b2b42a22e5..0000000000
--- a/ext/mysqli/tests/mysqli_set_local_infile_handler_kill_link.phpt
+++ /dev/null
@@ -1,61 +0,0 @@
---TEST--
-mysqli_set_local_infile_handler() - kill database link
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifemb.inc');
-require_once('skipifconnectfailure.inc');
-
-if (!function_exists('mysqli_set_local_infile_handler'))
- die("skip - function not available.");
-
-require_once('connect.inc');
-if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
- die("skip Cannot connect to MySQL");
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-mysqli.allow_local_infile=1
---FILE--
-<?php
- require("table.inc");
- require_once('local_infile_tools.inc');
-
- function callback_kill_link($fp, &$buffer, $buflen, &$error) {
- global $link;
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation++);
- flush();
- if (is_object($link))
- mysqli_kill($link, mysqli_thread_id($link));
-
- $buffer = "1;'a';\n";
- if ($invocation > 10)
- return 0;
-
- mysqli_set_local_infile_default($link);
- return strlen($buffer);
- }
-
- $file = create_standard_csv(1);
- $expected = array(array('id' => 1, 'label' => 'a'));
- try_handler(20, $link, $file, 'callback_kill_link', $expected);
-
- mysqli_close($link);
- print "done!";
-?>
---CLEAN--
-<?php
- require_once("clean_table.inc");
-?>
---EXPECTF--
-Callback set to 'callback_kill_link'
-Callback: 0
-[022] LOAD DATA failed, [2000] Can't execute load data local init callback function
-done! \ No newline at end of file
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
deleted file mode 100644
index 16e38c5fa2..0000000000
--- a/ext/mysqli/tests/mysqli_set_local_infile_handler_negative_len.phpt
+++ /dev/null
@@ -1,58 +0,0 @@
---TEST--
-mysqli_set_local_infile_handler() - negative return value/buflen to indicate an error
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifemb.inc');
-require_once('skipifconnectfailure.inc');
-
-if (!function_exists('mysqli_set_local_infile_handler'))
- die("skip - function not available.");
-
-require_once('connect.inc');
-if (!$TEST_EXPERIMENTAL)
- die("skip - experimental (= unsupported) feature");
-
-if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
- die("skip Cannot connect to MySQL");
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-mysqli.allow_local_infile=1
---FILE--
-<?php
- require_once('connect.inc');
- require_once('local_infile_tools.inc');
- require_once('table.inc');
-
- function callback_negative_len($fp, &$buffer, $buflen, &$error) {
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation);
- $buffer = fread($fp, $buflen);
-
- $error = "negative length means error";
- return -1;
- }
-
- $file = create_standard_csv(1);
- $expected = array();
- try_handler(20, $link, $file, 'callback_negative_len', $expected);
-
- mysqli_close($link);
- print "done!";
-?>
---CLEAN--
-<?php
- require_once("clean_table.inc");
-?>
---EXPECTF--
-Callback set to 'callback_negative_len'
-Callback: 0
-[022] LOAD DATA failed, [2000] negative length means error
-done! \ No newline at end of file
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
deleted file mode 100644
index 4663fe236e..0000000000
--- a/ext/mysqli/tests/mysqli_set_local_infile_handler_nested_call.phpt
+++ /dev/null
@@ -1,107 +0,0 @@
---TEST--
-mysqli_set_local_infile_handler() - nested calls
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifemb.inc');
-require_once('skipifconnectfailure.inc');
-
-if (!function_exists('mysqli_set_local_infile_handler'))
- die("skip - function not available.");
-
-require_once('connect.inc');
-if (!$TEST_EXPERIMENTAL)
- die("skip - experimental (= unsupported) feature");
-
-if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
- die("skip Cannot connect to MySQL");
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-mysqli.allow_local_infile=1
---FILE--
-<?php
- require_once('connect.inc');
- require_once('local_infile_tools.inc');
- require_once('table.inc');
-
- function callback_simple($fp, &$buffer, $buflen, &$error) {
- static $invocation = 0;
-
- printf("Callback - callback_simple(): %d\n", $invocation);
-
- $invocation++;
- if (!is_resource($fp))
- printf("[012] First argument passed to callback is not a resource but %s/%s\n",
- $fp, gettype($fp));
-
- if (!$buffer = fread($fp, $buflen)) {
- if ($invocation == 1) {
- printf("[013] Cannot read from stream\n");
- $error = 'Cannot read from stream';
- } else {
- return strlen($buffer);
- }
- }
-
- $lines = explode("\n", $buffer);
- if (count($lines) != 4 && strlen($buffer) > 0) {
- printf("[014] Test is too simple to handle a buffer of size %d that cannot hold all lines\n", $buflen);
- $error = 'Parser too simple';
- }
-
- $buffer = '';
- foreach ($lines as $k => $line) {
- if ('' === trim($line))
- continue;
-
- $columns = explode(';', $line);
- if (empty($columns)) {
- printf("[015] Cannot parse columns\n");
- $error = 'Cannot parse columns';
- }
-
- // increase id column value
- $columns[0] += 1;
- $buffer .= implode(';', $columns);
- $buffer .= "\n";
- }
-
- /* report the wrong length */
- return strlen($buffer);
- }
-
- function callback_report_short_len($fp, &$buffer, $buflen, &$error) {
- static $invocation = 0;
-
- printf("Callback - report_short_len(): %d\n", $invocation++);
- return callback_simple($fp, $buffer, $buflen, $error);
- }
-
- $file = create_standard_csv(1);
- $expected = array(
- array('id' => 98, 'label' => 'x'),
- array('id' => 99, 'label' => 'y'),
- array('id' => 100, 'label' => 'z'),
- );
- try_handler(20, $link, $file, 'callback_report_short_len', $expected);
-
- mysqli_close($link);
- print "done!";
-?>
---CLEAN--
-<?php
- require_once("clean_table.inc");
-?>
---EXPECTF--
-Callback set to 'callback_report_short_len'
-Callback - report_short_len(): 0
-Callback - callback_simple(): 0
-Callback - report_short_len(): 1
-Callback - callback_simple(): 1
-done! \ No newline at end of file
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
deleted file mode 100644
index ca06435c5e..0000000000
--- a/ext/mysqli/tests/mysqli_set_local_infile_handler_new_query.phpt
+++ /dev/null
@@ -1,71 +0,0 @@
---TEST--
-mysqli_set_local_infile_handler() - run new query on db link
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifemb.inc');
-require_once('skipifconnectfailure.inc');
-
-if (!function_exists('mysqli_set_local_infile_handler'))
- die("skip - function not available.");
-
-require_once('connect.inc');
-if (!$TEST_EXPERIMENTAL)
- die("skip - experimental (= unsupported) feature");
-
-if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
- die("skip Cannot connect to MySQL");
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-mysqli.allow_local_infile=1
---FILE--
-<?php
- require_once('connect.inc');
- require_once('local_infile_tools.inc');
- require_once('table.inc');
-
- function callback_new_query($fp, &$buffer, $buflen, &$error) {
- global $link;
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation++);
- flush();
- if (is_object($link)) {
- if (!$res = mysqli_query($link, "SELECT id, label FROM test")) {
- printf("[Callback 001 - %03d] Cannot run query, [%d] %s\n",
- $invocation, mysqli_errno($link), mysqli_error($link));
- }
- if ($res)
- mysqli_free_result($res);
- }
- $buffer = "1;'a';\n";
- if ($invocation > 10)
- return 0;
-
- mysqli_set_local_infile_default($link);
- return strlen($buffer);
- }
-
- $file = create_standard_csv(1);
- $expected = array(array('id' => 1, 'label' => 'a'));
- try_handler(20, $link, $file, 'callback_new_query', $expected);
-
- mysqli_close($link);
- print "done!";
-?>
---CLEAN--
-<?php
- require_once("clean_table.inc");
-?>
---EXPECTF--
-Callback set to 'callback_new_query'
-Callback: 0
-[Callback 001 - 001] Cannot run query, [2014] Commands out of sync; you can't run this command now
-[022] LOAD DATA failed, [2000] Can't execute load data local init callback function
-done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_nofileop.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_nofileop.phpt
deleted file mode 100644
index 601a09e12c..0000000000
--- a/ext/mysqli/tests/mysqli_set_local_infile_handler_nofileop.phpt
+++ /dev/null
@@ -1,70 +0,0 @@
---TEST--
-mysqli_set_local_infile_handler() - do not use the file pointer
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifemb.inc');
-require_once('skipifconnectfailure.inc');
-
-if (!function_exists('mysqli_set_local_infile_handler'))
- die("skip - function not available.");
-
-require_once('connect.inc');
-if (!$TEST_EXPERIMENTAL)
- die("skip - experimental (= unsupported) feature");
-
-if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
- die("skip Cannot connect to MySQL");
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-mysqli.allow_local_infile=1
---FILE--
-<?php
- require_once('connect.inc');
- require_once('local_infile_tools.inc');
- require_once('table.inc');
-
- function callback_nofileop($fp, &$buffer, $buflen, &$error) {
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation++);
- flush();
-
- $buffer = "1;'a';\n";
- if ($invocation > 10)
- return 0;
-
- return strlen($buffer);
- }
-
- $file = create_standard_csv(1);
- $expected = array(array('id' => 1, 'label' => 'a'));
- try_handler(20, $link, $file, 'callback_nofileop', $expected);
-
- mysqli_close($link);
- print "done!";
-?>
---CLEAN--
-<?php
- require_once("clean_table.inc");
-?>
---EXPECTF--
-Callback set to 'callback_nofileop'
-Callback: 0
-Callback: 1
-Callback: 2
-Callback: 3
-Callback: 4
-Callback: 5
-Callback: 6
-Callback: 7
-Callback: 8
-Callback: 9
-Callback: 10
-done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_openbasedir.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_openbasedir.phpt
deleted file mode 100644
index 7163aca10d..0000000000
--- a/ext/mysqli/tests/mysqli_set_local_infile_handler_openbasedir.phpt
+++ /dev/null
@@ -1,115 +0,0 @@
---TEST--
-mysqli_set_local_infile_handler() - open basedir restrictions
---SKIPIF--
-<?php
-if (!$fp = @fopen('skipif.inc', 'r'))
- die("skip open_basedir restrictions forbid opening include files");
-
-include_once('skipif.inc');
-include_once('skipifemb.inc');
-include_once('skipifconnectfailure.inc');
-
-if (!function_exists('mysqli_set_local_infile_handler'))
- die("skip - function not available.");
-
-include_once('connect.inc');
-if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
- die("skip Cannot connect to MySQL");
-
-if (!$res = mysqli_query($link, 'SHOW VARIABLES LIKE "local_infile"')) {
- mysqli_close($link);
- die("skip Cannot check if Server variable 'local_infile' is set to 'ON'");
-}
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-open_basedir="."
---FILE--
-<?php
- @include('connect.inc');
- if (!isset($db)) {
- // stupid run-tests.php - any idea how to set system ini setting dynamically???
- print "Warning: tempnam(): open_basedir restriction in effect. File(grrr) is not within the allowed path(s): (grrr) in grrr on line 0
-[005 + 1] Cannot create CVS file ''
-Callback set to 'callback_simple'
-[012] LOAD DATA failed, [0] grrr
-[014/0] [0] ''
-done!";
- die();
- }
-
- require_once('connect.inc');
- require_once('local_infile_tools.inc');
- require_once('table.inc');
-
- function callback_simple($fp, &$buffer, $buflen, &$error) {
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation);
-
- $invocation++;
- if (!is_resource($fp))
- printf("[012] First argument passed to callback is not a resource but %s/%s\n",
- $fp, gettype($fp));
-
- if (!$buffer = fread($fp, $buflen)) {
- if ($invocation == 1) {
- printf("[013] Cannot read from stream\n");
- $error = 'Cannot read from stream';
- } else {
- return strlen($buffer);
- }
- }
-
- $lines = explode("\n", $buffer);
- if (count($lines) != 4 && strlen($buffer) > 0) {
- printf("[014] Test is too simple to handle a buffer of size %d that cannot hold all lines\n", $buflen);
- $error = 'Parser too simple';
- }
-
- $buffer = '';
- foreach ($lines as $k => $line) {
- if ('' === trim($line))
- continue;
-
- $columns = explode(';', $line);
- if (empty($columns)) {
- printf("[015] Cannot parse columns\n");
- $error = 'Cannot parse columns';
- }
-
- // increase id column value
- $columns[0] += 1;
- $buffer .= implode(';', $columns);
- $buffer .= "\n";
- }
-
- return strlen($buffer);
- }
-
- $file = create_standard_csv(5);
- $expected = array(
- array('id' => 98, 'label' => 'x'),
- array('id' => 99, 'label' => 'y'),
- array('id' => 100, 'label' => 'z'),
- );
- try_handler(10, $link, $file, 'callback_simple', $expected);
- mysqli_close($link);
- print "done!";
-?>
---CLEAN--
-<?php
- require_once("clean_table.inc");
-?>
---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 ''
-Callback set to 'callback_simple'
-[012] LOAD DATA failed, [%d] %s
-[014/0] [0] ''
-done! \ No newline at end of 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
deleted file mode 100644
index 0d4024e528..0000000000
--- a/ext/mysqli/tests/mysqli_set_local_infile_handler_replace_buffer.phpt
+++ /dev/null
@@ -1,78 +0,0 @@
---TEST--
-mysqli_set_local_infile_handler() - replace buffer pointer
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifemb.inc');
-require_once('skipifconnectfailure.inc');
-
-if (!function_exists('mysqli_set_local_infile_handler'))
- die("skip - function not available.");
-
-require_once('connect.inc');
-if (!$TEST_EXPERIMENTAL)
- die("skip - experimental (= unsupported) feature");
-
-if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
- die("skip Cannot connect to MySQL");
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-mysqli.allow_local_infile=1
---FILE--
-<?php
- require_once('connect.inc');
- require_once('local_infile_tools.inc');
- require_once('table.inc');
-
- function callback_replace_buffer($fp, &$buffer, $buflen, &$error) {
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation++);
- flush();
-
- $buffer = fread($fp, $buflen);
-
- $ret = "1;'a';\n";
- $buffer = $ret;
-
- $num_chars = ((version_compare(PHP_VERSION, '5.9.9', '>') == 1)) ? floor($buflen / 2) : $buflen;
- assert(strlen($buffer) < $num_chars);
-
- if ($invocation > 10)
- return 0;
-
- return strlen($buffer);
- }
-
- $file = create_standard_csv(1);
- $expected = array(array('id' => 1, 'label' => 'a'));
- if (!try_handler(20, $link, $file, 'callback_replace_buffer', $expected))
- printf("[008] Failure\n");
-
- mysqli_close($link);
- print "done!";
-?>
---CLEAN--
-<?php
- require_once("clean_table.inc");
-?>
---EXPECTF--
-Callback set to 'callback_replace_buffer'
-Callback: 0
-Callback: 1
-Callback: 2
-Callback: 3
-Callback: 4
-Callback: 5
-Callback: 6
-Callback: 7
-Callback: 8
-Callback: 9
-Callback: 10
-done! \ No newline at end of file
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
deleted file mode 100644
index b3144e430e..0000000000
--- a/ext/mysqli/tests/mysqli_set_local_infile_handler_short_len.phpt
+++ /dev/null
@@ -1,101 +0,0 @@
---TEST--
-mysqli_set_local_infile_handler() - report shorter buffer
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifemb.inc');
-require_once('skipifconnectfailure.inc');
-
-if (!function_exists('mysqli_set_local_infile_handler'))
- die("skip - function not available.");
-
-require_once('connect.inc');
-if (!$TEST_EXPERIMENTAL)
- die("skip - experimental (= unsupported) feature");
-
-if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
- die("skip Cannot connect to MySQL");
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-mysqli.allow_local_infile=1
---FILE--
-<?php
- require_once('connect.inc');
- require_once('local_infile_tools.inc');
- require_once('table.inc');
-
- function callback_short_len($fp, &$buffer, $buflen, &$error) {
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation);
-
- $invocation++;
- if (!is_resource($fp))
- printf("[012] First argument passed to callback is not a resource but %s/%s\n",
- $fp, gettype($fp));
-
- if (!$buffer = fread($fp, $buflen)) {
- if ($invocation == 1) {
- printf("[013] Cannot read from stream\n");
- $error = 'Cannot read from stream';
- } else {
- return strlen($buffer);
- }
- }
-
- $lines = explode("\n", $buffer);
- if (count($lines) != 4 && strlen($buffer) > 0) {
- printf("[014] Test is too simple to handle a buffer of size %d that cannot hold all lines\n", $buflen);
- $error = 'Parser too simple';
- }
-
- $buffer = '';
- foreach ($lines as $k => $line) {
- if ('' === trim($line))
- continue;
-
- $columns = explode(';', $line);
- if (empty($columns)) {
- printf("[015] Cannot parse columns\n");
- $error = 'Cannot parse columns';
- }
-
- // increase id column value
- $columns[0] += 1;
- $buffer .= implode(';', $columns);
- $buffer .= "\n";
- }
-
- /* report the wrong length */
- return strlen($buffer) - 1;
- }
-
- $file = create_standard_csv(1);
- $expected = array(
- array('id' => 98, 'label' => 'x'),
- array('id' => 99, 'label' => 'y'),
- array('id' => 100, 'label' => 'z'),
- );
- try_handler(20, $link, $file, 'callback_short_len', $expected);
-
- mysqli_close($link);
- print "done!";
-?>
---CLEAN--
-<?php
- require_once("clean_table.inc");
-?>
---EXPECTF--
-Callback set to 'callback_short_len'
-Callback: 0
-
-Warning: mysqli_query(): Mismatch between the return value of the callback and the content length of the buffer. in %s on line %d
-[022] LOAD DATA failed, [2000] Mismatch between the return value of the callback and the content length of the buffer.
-[024/0] [0] ''
-done! \ No newline at end of file
diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_unregister.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_unregister.phpt
deleted file mode 100644
index f287f4d874..0000000000
--- a/ext/mysqli/tests/mysqli_set_local_infile_handler_unregister.phpt
+++ /dev/null
@@ -1,64 +0,0 @@
---TEST--
-mysqli_set_local_infile_handler() - do not use the file pointer
---SKIPIF--
-<?php
-require_once('skipif.inc');
-require_once('skipifemb.inc');
-require_once('skipifconnectfailure.inc');
-
-if (!function_exists('mysqli_set_local_infile_handler'))
- die("skip - function not available.");
-
-require_once('connect.inc');
-if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))
- die("skip Cannot connect to MySQL");
-
-include_once("local_infile_tools.inc");
-if ($msg = check_local_infile_support($link, $engine))
- die(sprintf("skip %s, [%d] %s", $msg, $link->errno, $link->error));
-
-mysqli_close($link);
-?>
---INI--
-mysqli.allow_local_infile=1
---FILE--
-<?php
- require_once('connect.inc');
- require_once('local_infile_tools.inc');
- require_once('table.inc');
-
- function callback_unregister($fp, &$buffer, $buflen, &$error) {
- global $link;
- static $invocation = 0;
-
- printf("Callback: %d\n", $invocation++);
- flush();
- if (is_resource($fp))
- fclose($fp);
- $buffer = "1;'a';\n";
- if ($invocation > 10)
- return 0;
-
- mysqli_set_local_infile_default($link);
- return strlen($buffer);
- }
-
- $file = create_standard_csv(1);
- $expected = array(array('id' => 1, 'label' => 'a'));
- try_handler(20, $link, $file, 'callback_unregister', $expected);
-
- mysqli_close($link);
- print "done!";
-?>
---CLEAN--
-<?php
- require_once("clean_table.inc");
-?>
---EXPECTF--
-Callback set to 'callback_unregister'
-Callback: 0
-
-Warning: mysqli_query(): File handle closed in %s on line %d
-[022] LOAD DATA failed, [2000] File handle closed
-[024/0] [0] ''
-done!
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 afaccaf3c7..739bf56ea1 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
@@ -12,7 +12,13 @@ if (!function_exists('mysqli_stmt_get_result'))
--FILE--
<?php
require('table.inc');
- $charsets = my_get_charsets($link);
+
+ // Make sure that client, connection and result charsets are all the
+ // same. Not sure whether this is strictly necessary.
+ if (!mysqli_set_charset($link, 'utf8'))
+ printf("[%d] %s\n", mysqli_errno($link), mysqli_errno($link));
+
+ $charsetInfo = mysqli_get_charset($link);
if (!($stmt = mysqli_stmt_init($link)) ||
!mysqli_stmt_prepare($stmt, "SELECT id, label, id + 1 as _id, concat(label, '_') ___label FROM test ORDER BY id ASC LIMIT 3") ||
@@ -39,15 +45,14 @@ if (!function_exists('mysqli_stmt_get_result'))
Label column, result set charset.
All of the following columns are "too hot" - too server dependent
*/
- if ($field->charsetnr != $charsets['results']['nr']) {
+ if ($field->charsetnr != $charsetInfo->number) {
printf("[004] Expecting charset %s/%d got %d\n",
- $charsets['results']['charset'],
- $charsets['results']['nr'], $field->charsetnr);
+ $charsetInfo->charset,
+ $charsetInfo->number, $field->charsetnr);
}
- if ($field->length != (1 * $charsets['results']['maxlen'])) {
+ if ($field->length != $charsetInfo->max_length) {
printf("[005] Expecting length %d got %d\n",
- $charsets['results']['maxlen'],
- $field->max_length);
+ $charsetInfo->max_length, $field->max_length);
}
}
}
@@ -173,4 +178,4 @@ object(stdClass)#%d (13) {
[%u|b%"decimals"]=>
int(31)
}
-done! \ No newline at end of file
+done!
diff --git a/ext/mysqlnd/CREDITS b/ext/mysqlnd/CREDITS
index 5aed316e89..08ebb21aa7 100644
--- a/ext/mysqlnd/CREDITS
+++ b/ext/mysqlnd/CREDITS
@@ -1,2 +1,2 @@
MySQLnd
-Andrey Hristov, Ulf Wendel, Georg Richter
+Andrey Hristov, Ulf Wendel, Georg Richter, Johannes Schlüter
diff --git a/ext/mysqlnd/config9.m4 b/ext/mysqlnd/config9.m4
index 2c15c34e8d..09aca5af8a 100644
--- a/ext/mysqlnd/config9.m4
+++ b/ext/mysqlnd/config9.m4
@@ -8,11 +8,11 @@ PHP_ARG_ENABLE(mysqlnd, whether to enable mysqlnd,
PHP_ARG_ENABLE(mysqlnd_compression_support, whether to disable compressed protocol support in mysqlnd,
[ --disable-mysqlnd-compression-support
- Disable support for the MySQL compressed protocol in mysqlnd], yes, no)
+ Disable support for the MySQL compressed protocol in mysqlnd], yes, no)
if test -z "$PHP_ZLIB_DIR"; then
PHP_ARG_WITH(zlib-dir, for the location of libz,
- [ --with-zlib-dir[=DIR] mysqlnd: Set the path to libz install prefix], no, no)
+ [ --with-zlib-dir[=DIR] mysqlnd: Set the path to libz install prefix], no, no)
fi
dnl If some extension uses mysqlnd it will get compiled in PHP core
@@ -28,7 +28,17 @@ if test "$PHP_MYSQLND" != "no" || test "$PHP_MYSQLND_ENABLED" = "yes"; then
if test "$PHP_MYSQLND_COMPRESSION_SUPPORT" != "no"; then
AC_DEFINE([MYSQLND_COMPRESSION_WANTED], 1, [Enable compressed protocol support])
fi
- AC_DEFINE([MYSQLND_SSL_SUPPORTED], 1, [Enable SSL support])
+
+ AC_DEFINE([MYSQLND_SSL_SUPPORTED], 1, [Enable core mysqlnd SSL code])
+
+ test -z "$PHP_OPENSSL" && PHP_OPENSSL=no
+
+ if test "$PHP_OPENSSL" != "no" || test "$PHP_OPENSSL_DIR" != "no"; then
+ AC_CHECK_LIB(ssl, DSA_get_default_method, AC_DEFINE(HAVE_DSA_DEFAULT_METHOD, 1, [OpenSSL 0.9.7 or later]))
+ AC_CHECK_LIB(crypto, X509_free, AC_DEFINE(HAVE_DSA_DEFAULT_METHOD, 1, [OpenSSL 0.9.7 or later]))
+
+ PHP_SETUP_OPENSSL(MYSQLND_SHARED_LIBADD, [AC_DEFINE(MYSQLND_HAVE_SSL,1,[Enable mysqlnd code that uses OpenSSL directly])])
+ fi
mysqlnd_sources="$mysqlnd_base_sources $mysqlnd_ps_sources"
PHP_NEW_EXTENSION(mysqlnd, $mysqlnd_sources, $ext_shared)
diff --git a/ext/mysqlnd/mysqlnd.c b/ext/mysqlnd/mysqlnd.c
index d265dfd392..39813145ba 100644
--- a/ext/mysqlnd/mysqlnd.c
+++ b/ext/mysqlnd/mysqlnd.c
@@ -27,6 +27,7 @@
#include "mysqlnd_statistics.h"
#include "mysqlnd_charset.h"
#include "mysqlnd_debug.h"
+#include "ext/standard/php_smart_str.h"
/*
TODO :
@@ -95,6 +96,11 @@ MYSQLND_METHOD(mysqlnd_conn_data, free_options)(MYSQLND_CONN_DATA * conn TSRMLS_
mnd_pefree(conn->options->cfg_section, pers);
conn->options->cfg_section = NULL;
}
+ if (conn->options->connect_attr) {
+ zend_hash_destroy(conn->options->connect_attr);
+ mnd_pefree(conn->options->connect_attr, pers);
+ conn->options->connect_attr = NULL;
+ }
}
/* }}} */
@@ -114,7 +120,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, free_contents)(MYSQLND_CONN_DATA * conn TSRMLS
}
if (conn->net) {
- conn->net->m.free_contents(conn->net TSRMLS_CC);
+ conn->net->data->m.free_contents(conn->net TSRMLS_CC);
}
DBG_INF("Freeing memory of members");
@@ -304,17 +310,16 @@ MYSQLND_METHOD(mysqlnd_conn_data, simple_command_handle_response)(MYSQLND_CONN_D
/* }}} */
-/* {{{ mysqlnd_conn_data::simple_command */
+/* {{{ mysqlnd_conn_data::simple_command_send_request */
static enum_func_status
-MYSQLND_METHOD(mysqlnd_conn_data, simple_command)(MYSQLND_CONN_DATA * conn, enum php_mysqlnd_server_command command,
- const zend_uchar * const arg, size_t arg_len, enum mysqlnd_packet_type ok_packet, zend_bool silent,
- zend_bool ignore_upsert_status TSRMLS_DC)
+MYSQLND_METHOD(mysqlnd_conn_data, simple_command_send_request)(MYSQLND_CONN_DATA * conn, enum php_mysqlnd_server_command command,
+ const zend_uchar * const arg, size_t arg_len, zend_bool silent, zend_bool ignore_upsert_status TSRMLS_DC)
{
enum_func_status ret = PASS;
MYSQLND_PACKET_COMMAND * cmd_packet;
- DBG_ENTER("mysqlnd_conn_data::simple_command");
- DBG_INF_FMT("command=%s ok_packet=%u silent=%u", mysqlnd_command_to_text[command], ok_packet, silent);
+ DBG_ENTER("mysqlnd_conn_data::simple_command_send_request");
+ DBG_INF_FMT("command=%s silent=%u", mysqlnd_command_to_text[command], silent);
DBG_INF_FMT("conn->server_status=%u", conn->upsert_status->server_status);
switch (CONN_GET_STATE(conn)) {
@@ -353,13 +358,30 @@ MYSQLND_METHOD(mysqlnd_conn_data, simple_command)(MYSQLND_CONN_DATA * conn, enum
php_error(E_WARNING, "Error while sending %s packet. PID=%d", mysqlnd_command_to_text[command], getpid());
}
CONN_SET_STATE(conn, CONN_QUIT_SENT);
+ conn->m->send_close(conn TSRMLS_CC);
DBG_ERR("Server is gone");
ret = FAIL;
- } else if (ok_packet != PROT_LAST) {
+ }
+ PACKET_FREE(cmd_packet);
+ DBG_RETURN(ret);
+}
+/* }}} */
+
+
+/* {{{ mysqlnd_conn_data::simple_command */
+static enum_func_status
+MYSQLND_METHOD(mysqlnd_conn_data, simple_command)(MYSQLND_CONN_DATA * conn, enum php_mysqlnd_server_command command,
+ const zend_uchar * const arg, size_t arg_len, enum mysqlnd_packet_type ok_packet, zend_bool silent,
+ zend_bool ignore_upsert_status TSRMLS_DC)
+{
+ enum_func_status ret;
+ DBG_ENTER("mysqlnd_conn_data::simple_command");
+
+ ret = conn->m->simple_command_send_request(conn, command, arg, arg_len, silent, ignore_upsert_status TSRMLS_CC);
+ if (PASS == ret && ok_packet != PROT_LAST) {
ret = conn->m->simple_command_handle_response(conn, ok_packet, silent, command, ignore_upsert_status TSRMLS_CC);
}
- PACKET_FREE(cmd_packet);
DBG_INF(ret == PASS ? "PASS":"FAIL");
DBG_RETURN(ret);
}
@@ -438,11 +460,7 @@ mysqlnd_switch_to_ssl_if_needed(
if (options->charset_name && (charset = mysqlnd_find_charset_name(options->charset_name))) {
auth_packet->charset_no = charset->nr;
} else {
-#if MYSQLND_UNICODE
- auth_packet->charset_no = 200;/* utf8 - swedish collation, check mysqlnd_charset.c */
-#else
auth_packet->charset_no = greet_packet->charset_no;
-#endif
}
#ifdef MYSQLND_SSL_SUPPORTED
@@ -451,13 +469,14 @@ mysqlnd_switch_to_ssl_if_needed(
DBG_INF("Switching to SSL");
if (!PACKET_WRITE(auth_packet, conn)) {
CONN_SET_STATE(conn, CONN_QUIT_SENT);
+ conn->m->send_close(conn TSRMLS_CC);
SET_CLIENT_ERROR(*conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
goto end;
}
- conn->net->m.set_client_option(conn->net, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, (const char *) &verify TSRMLS_CC);
+ conn->net->data->m.set_client_option(conn->net, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, (const char *) &verify TSRMLS_CC);
- if (FAIL == conn->net->m.enable_ssl(conn->net TSRMLS_CC)) {
+ if (FAIL == conn->net->data->m.enable_ssl(conn->net TSRMLS_CC)) {
goto end;
}
}
@@ -470,6 +489,159 @@ end:
/* }}} */
+/* {{{ mysqlnd_conn_data::fetch_auth_plugin_by_name */
+static struct st_mysqlnd_authentication_plugin *
+MYSQLND_METHOD(mysqlnd_conn_data, fetch_auth_plugin_by_name)(const char * const requested_protocol TSRMLS_DC)
+{
+ struct st_mysqlnd_authentication_plugin * auth_plugin;
+ char * plugin_name = NULL;
+ DBG_ENTER("mysqlnd_conn_data::fetch_auth_plugin_by_name");
+
+ mnd_sprintf(&plugin_name, 0, "auth_plugin_%s", requested_protocol);
+ DBG_INF_FMT("looking for %s auth plugin", plugin_name);
+ auth_plugin = mysqlnd_plugin_find(plugin_name);
+ mnd_sprintf_free(plugin_name);
+
+ DBG_RETURN(auth_plugin);
+}
+/* }}} */
+
+
+/* {{{ mysqlnd_run_authentication */
+static enum_func_status
+mysqlnd_run_authentication(
+ MYSQLND_CONN_DATA * conn,
+ const char * const user,
+ const char * const passwd,
+ const size_t passwd_len,
+ const char * const db,
+ const size_t db_len,
+ const zend_uchar * const auth_plugin_data,
+ const size_t auth_plugin_data_len,
+ const char * const auth_protocol,
+ unsigned int charset_no,
+ const MYSQLND_OPTIONS * const options,
+ unsigned long mysql_flags,
+ zend_bool silent,
+ zend_bool is_change_user
+ TSRMLS_DC)
+{
+ enum_func_status ret = FAIL;
+ zend_bool first_call = TRUE;
+
+ char * switch_to_auth_protocol = NULL;
+ size_t switch_to_auth_protocol_len = 0;
+ char * requested_protocol = NULL;
+ zend_uchar * plugin_data;
+ size_t plugin_data_len;
+
+ DBG_ENTER("mysqlnd_run_authentication");
+
+ plugin_data_len = auth_plugin_data_len;
+ plugin_data = mnd_emalloc(plugin_data_len + 1);
+ if (!plugin_data) {
+ goto end;
+ }
+ memcpy(plugin_data, auth_plugin_data, plugin_data_len);
+ plugin_data[plugin_data_len] = '\0';
+
+ requested_protocol = mnd_pestrdup(auth_protocol? auth_protocol : MYSQLND_DEFAULT_AUTH_PROTOCOL, FALSE);
+ if (!requested_protocol) {
+ goto end;
+ }
+
+ do {
+ struct st_mysqlnd_authentication_plugin * auth_plugin = conn->m->fetch_auth_plugin_by_name(requested_protocol TSRMLS_CC);
+
+ if (!auth_plugin) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "The server requested authentication method unknown to the client [%s]", requested_protocol);
+ SET_CLIENT_ERROR(*conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, "The server requested authentication method unknown to the client");
+ goto end;
+ }
+ DBG_INF("plugin found");
+
+ {
+ zend_uchar * switch_to_auth_protocol_data = NULL;
+ size_t switch_to_auth_protocol_data_len = 0;
+ zend_uchar * scrambled_data = NULL;
+ size_t scrambled_data_len = 0;
+
+ switch_to_auth_protocol = NULL;
+ switch_to_auth_protocol_len = 0;
+
+ if (conn->auth_plugin_data) {
+ mnd_pefree(conn->auth_plugin_data, conn->persistent);
+ conn->auth_plugin_data = NULL;
+ }
+ conn->auth_plugin_data_len = plugin_data_len;
+ conn->auth_plugin_data = mnd_pemalloc(conn->auth_plugin_data_len, conn->persistent);
+ if (!conn->auth_plugin_data) {
+ SET_OOM_ERROR(*conn->error_info);
+ goto end;
+ }
+ memcpy(conn->auth_plugin_data, plugin_data, plugin_data_len);
+
+ DBG_INF_FMT("salt(%d)=[%.*s]", plugin_data_len, plugin_data_len, plugin_data);
+ /* The data should be allocated with malloc() */
+ scrambled_data =
+ auth_plugin->methods.get_auth_data(NULL, &scrambled_data_len, conn, user, passwd, passwd_len,
+ plugin_data, plugin_data_len, options, &conn->net->data->options, mysql_flags TSRMLS_CC);
+ if (conn->error_info->error_no) {
+ goto end;
+ }
+ if (FALSE == is_change_user) {
+ ret = mysqlnd_auth_handshake(conn, user, passwd, passwd_len, db, db_len, options, mysql_flags,
+ charset_no,
+ first_call,
+ requested_protocol,
+ scrambled_data, scrambled_data_len,
+ &switch_to_auth_protocol, &switch_to_auth_protocol_len,
+ &switch_to_auth_protocol_data, &switch_to_auth_protocol_data_len
+ TSRMLS_CC);
+ } else {
+ ret = mysqlnd_auth_change_user(conn, user, strlen(user), passwd, passwd_len, db, db_len, silent,
+ first_call,
+ requested_protocol,
+ scrambled_data, scrambled_data_len,
+ &switch_to_auth_protocol, &switch_to_auth_protocol_len,
+ &switch_to_auth_protocol_data, &switch_to_auth_protocol_data_len
+ TSRMLS_CC);
+ }
+ first_call = FALSE;
+ free(scrambled_data);
+
+ DBG_INF_FMT("switch_to_auth_protocol=%s", switch_to_auth_protocol? switch_to_auth_protocol:"n/a");
+ if (requested_protocol && switch_to_auth_protocol) {
+ mnd_efree(requested_protocol);
+ requested_protocol = switch_to_auth_protocol;
+ }
+
+ if (plugin_data) {
+ mnd_efree(plugin_data);
+ }
+ plugin_data_len = switch_to_auth_protocol_data_len;
+ plugin_data = switch_to_auth_protocol_data;
+ }
+ DBG_INF_FMT("conn->error_info->error_no = %d", conn->error_info->error_no);
+ } while (ret == FAIL && conn->error_info->error_no == 0 && switch_to_auth_protocol != NULL);
+
+ if (ret == PASS) {
+ DBG_INF_FMT("saving requested_protocol=%s", requested_protocol);
+ conn->m->set_client_option(conn, MYSQLND_OPT_AUTH_PROTOCOL, requested_protocol TSRMLS_CC);
+ }
+end:
+ if (plugin_data) {
+ mnd_efree(plugin_data);
+ }
+ if (requested_protocol) {
+ mnd_efree(requested_protocol);
+ }
+
+ DBG_RETURN(ret);
+}
+/* }}} */
+
+
/* {{{ mysqlnd_connect_run_authentication */
static enum_func_status
mysqlnd_connect_run_authentication(
@@ -489,116 +661,166 @@ mysqlnd_connect_run_authentication(
ret = mysqlnd_switch_to_ssl_if_needed(conn, greet_packet, options, mysql_flags TSRMLS_CC);
if (PASS == ret) {
- zend_bool first_call = TRUE;
+ ret = mysqlnd_run_authentication(conn, user, passwd, passwd_len, db, db_len,
+ greet_packet->auth_plugin_data, greet_packet->auth_plugin_data_len, greet_packet->auth_protocol,
+ greet_packet->charset_no, options, mysql_flags, FALSE /*silent*/, FALSE/*is_change*/ TSRMLS_CC);
+ }
+ DBG_RETURN(ret);
+}
+/* }}} */
- char * switch_to_auth_protocol = NULL;
- size_t switch_to_auth_protocol_len = 0;
- char * requested_protocol = NULL;
- zend_uchar * plugin_data;
- size_t plugin_data_len;
- plugin_data_len = greet_packet->auth_plugin_data_len;
- plugin_data = mnd_emalloc(plugin_data_len + 1);
- if (!plugin_data) {
- ret = FAIL;
- goto end;
- }
- memcpy(plugin_data, greet_packet->auth_plugin_data, plugin_data_len);
- plugin_data[plugin_data_len] = '\0';
+/* {{{ mysqlnd_conn_data::execute_init_commands */
+static enum_func_status
+MYSQLND_METHOD(mysqlnd_conn_data, execute_init_commands)(MYSQLND_CONN_DATA * conn TSRMLS_DC)
+{
+ enum_func_status ret = PASS;
- requested_protocol = mnd_pestrdup(greet_packet->auth_protocol? greet_packet->auth_protocol: "mysql_native_password", FALSE);
- if (!requested_protocol) {
- ret = FAIL;
- goto end;
+ DBG_ENTER("mysqlnd_conn_data::execute_init_commands");
+ if (conn->options->init_commands) {
+ unsigned int current_command = 0;
+ for (; current_command < conn->options->num_commands; ++current_command) {
+ const char * const command = conn->options->init_commands[current_command];
+ if (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);
+ ret = FAIL;
+ break;
+ }
+ if (conn->last_query_type == QUERY_SELECT) {
+ MYSQLND_RES * result = conn->m->use_result(conn TSRMLS_CC);
+ if (result) {
+ result->m.free_result(result, TRUE TSRMLS_CC);
+ }
+ }
+ }
}
+ }
+ DBG_RETURN(ret);
+}
+/* }}} */
- do {
- struct st_mysqlnd_authentication_plugin * auth_plugin;
- {
- char * plugin_name = NULL;
- mnd_sprintf(&plugin_name, 0, "auth_plugin_%s", requested_protocol);
+/* {{{ mysqlnd_conn_data::get_updated_connect_flags */
+static unsigned int
+MYSQLND_METHOD(mysqlnd_conn_data, get_updated_connect_flags)(MYSQLND_CONN_DATA * conn, unsigned int mysql_flags TSRMLS_DC)
+{
+ MYSQLND_NET * net = conn->net;
- DBG_INF_FMT("looking for %s auth plugin", plugin_name);
- auth_plugin = mysqlnd_plugin_find(plugin_name);
- mnd_sprintf_free(plugin_name);
+ DBG_ENTER("mysqlnd_conn_data::get_updated_connect_flags");
+ /* we allow load data local infile by default */
+ mysql_flags |= MYSQLND_CAPABILITIES;
- if (!auth_plugin) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "The server requested authentication method unknown to the client [%s]", requested_protocol);
- SET_CLIENT_ERROR(*conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, "The server requested authentication method unknown to the client");
- break;
- }
- }
- DBG_INF("plugin found");
+ mysql_flags |= conn->options->flags; /* use the flags from set_client_option() */
- {
- zend_uchar * switch_to_auth_protocol_data = NULL;
- size_t switch_to_auth_protocol_data_len = 0;
- zend_uchar * scrambled_data = NULL;
- size_t scrambled_data_len = 0;
+ if (PG(open_basedir) && strlen(PG(open_basedir))) {
+ mysql_flags ^= CLIENT_LOCAL_FILES;
+ }
+
+#ifndef MYSQLND_COMPRESSION_ENABLED
+ if (mysql_flags & CLIENT_COMPRESS) {
+ mysql_flags &= ~CLIENT_COMPRESS;
+ }
+#else
+ if (net && net->data->options.flags & MYSQLND_NET_FLAG_USE_COMPRESSION) {
+ mysql_flags |= CLIENT_COMPRESS;
+ }
+#endif
+#ifndef MYSQLND_SSL_SUPPORTED
+ if (mysql_flags & CLIENT_SSL) {
+ mysql_flags &= ~CLIENT_SSL;
+ }
+#else
+ if (net && (net->data->options.ssl_key || net->data->options.ssl_cert ||
+ net->data->options.ssl_ca || net->data->options.ssl_capath || net->data->options.ssl_cipher))
+ {
+ mysql_flags |= CLIENT_SSL;
+ }
+#endif
- switch_to_auth_protocol = NULL;
- switch_to_auth_protocol_len = 0;
+ DBG_RETURN(mysql_flags);
+}
+/* }}} */
- if (conn->auth_plugin_data) {
- mnd_pefree(conn->auth_plugin_data, conn->persistent);
- conn->auth_plugin_data = NULL;
- }
- conn->auth_plugin_data_len = plugin_data_len;
- conn->auth_plugin_data = mnd_pemalloc(conn->auth_plugin_data_len, conn->persistent);
- if (!conn->auth_plugin_data) {
- SET_OOM_ERROR(*conn->error_info);
- goto end;
- }
- memcpy(conn->auth_plugin_data, plugin_data, plugin_data_len);
- DBG_INF_FMT("salt=[%*s]", plugin_data_len - 1, plugin_data);
- /* The data should be allocated with malloc() */
- scrambled_data =
- auth_plugin->methods.get_auth_data(NULL, &scrambled_data_len, conn, user, passwd, passwd_len,
- plugin_data, plugin_data_len, options, mysql_flags TSRMLS_CC);
+/* {{{ mysqlnd_conn_data::connect_handshake */
+static enum_func_status
+MYSQLND_METHOD(mysqlnd_conn_data, connect_handshake)(MYSQLND_CONN_DATA * conn,
+ const char * const host, const char * const user,
+ const char * const passwd, const unsigned int passwd_len,
+ const char * const db, const unsigned int db_len,
+ const unsigned int mysql_flags TSRMLS_DC)
+{
+ MYSQLND_PACKET_GREET * greet_packet;
+ MYSQLND_NET * net = conn->net;
+ DBG_ENTER("mysqlnd_conn_data::connect_handshake");
- ret = mysqlnd_auth_handshake(conn, user, passwd, passwd_len, db, db_len, options, mysql_flags,
- greet_packet->charset_no,
- first_call,
- requested_protocol,
- scrambled_data, scrambled_data_len,
- &switch_to_auth_protocol, &switch_to_auth_protocol_len,
- &switch_to_auth_protocol_data, &switch_to_auth_protocol_data_len
- TSRMLS_CC);
- first_call = FALSE;
- free(scrambled_data);
+ greet_packet = conn->protocol->m.get_greet_packet(conn->protocol, FALSE TSRMLS_CC);
+ if (!greet_packet) {
+ SET_OOM_ERROR(*conn->error_info);
+ DBG_RETURN(FAIL); /* OOM */
+ }
- DBG_INF_FMT("switch_to_auth_protocol=%s", switch_to_auth_protocol? switch_to_auth_protocol:"n/a");
- if (requested_protocol && switch_to_auth_protocol) {
- mnd_efree(requested_protocol);
- requested_protocol = switch_to_auth_protocol;
- }
+ if (FAIL == net->data->m.connect_ex(conn->net, conn->scheme, conn->scheme_len, conn->persistent,
+ conn->stats, conn->error_info TSRMLS_CC))
+ {
+ goto err;
+ }
- if (plugin_data) {
- mnd_efree(plugin_data);
- }
- plugin_data_len = switch_to_auth_protocol_data_len;
- plugin_data = switch_to_auth_protocol_data;
- }
- DBG_INF_FMT("conn->error_info->error_no = %d", conn->error_info->error_no);
- } while (ret == FAIL && conn->error_info->error_no == 0 && switch_to_auth_protocol != NULL);
- if (plugin_data) {
- mnd_efree(plugin_data);
- }
-
- if (ret == PASS) {
- DBG_INF_FMT("saving requested_protocol=%s", requested_protocol);
- conn->m->set_client_option(conn, MYSQLND_OPT_AUTH_PROTOCOL, requested_protocol TSRMLS_CC);
- }
+ DBG_INF_FMT("stream=%p", net->data->m.get_stream(net TSRMLS_CC));
- if (requested_protocol) {
- mnd_efree(requested_protocol);
- }
+ if (FAIL == PACKET_READ(greet_packet, conn)) {
+ DBG_ERR("Error while reading greeting packet");
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error while reading greeting packet. PID=%d", getpid());
+ goto err;
+ } else if (greet_packet->error_no) {
+ DBG_ERR_FMT("errorno=%u error=%s", greet_packet->error_no, greet_packet->error);
+ SET_CLIENT_ERROR(*conn->error_info, greet_packet->error_no, greet_packet->sqlstate, greet_packet->error);
+ goto err;
+ } else if (greet_packet->pre41) {
+ DBG_ERR_FMT("Connecting to 3.22, 3.23 & 4.0 is not supported. Server is %-.32s", greet_packet->server_version);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Connecting to 3.22, 3.23 & 4.0 "
+ " is not supported. Server is %-.32s", greet_packet->server_version);
+ SET_CLIENT_ERROR(*conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE,
+ "Connecting to 3.22, 3.23 & 4.0 servers is not supported");
+ goto err;
}
-end:
- DBG_RETURN(ret);
+
+ conn->thread_id = greet_packet->thread_id;
+ conn->protocol_version = greet_packet->protocol_version;
+ conn->server_version = mnd_pestrdup(greet_packet->server_version, conn->persistent);
+
+ conn->greet_charset = mysqlnd_find_charset_nr(greet_packet->charset_no);
+ if (!conn->greet_charset) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "Server sent charset (%d) unknown to the client. Please, report to the developers", greet_packet->charset_no);
+ SET_CLIENT_ERROR(*conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE,
+ "Server sent charset unknown to the client. Please, report to the developers");
+ goto err;
+ }
+
+ conn->client_flag = mysql_flags;
+ conn->server_capabilities = greet_packet->server_capabilities;
+
+ if (FAIL == mysqlnd_connect_run_authentication(conn, user, passwd, db, db_len, (size_t) passwd_len,
+ greet_packet, conn->options, mysql_flags TSRMLS_CC))
+ {
+ goto err;
+ }
+ memset(conn->upsert_status, 0, sizeof(*conn->upsert_status));
+ conn->upsert_status->warning_count = 0;
+ conn->upsert_status->server_status = greet_packet->server_status;
+ conn->upsert_status->affected_rows = 0;
+
+ PACKET_FREE(greet_packet);
+ DBG_RETURN(PASS);
+err:
+ conn->client_flag = 0;
+ conn->server_capabilities = 0;
+ PACKET_FREE(greet_packet);
+ DBG_RETURN(FAIL);
}
/* }}} */
@@ -621,10 +843,10 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect)(MYSQLND_CONN_DATA * conn,
zend_bool reconnect = FALSE;
zend_bool saved_compression = FALSE;
zend_bool local_tx_started = FALSE;
-
- MYSQLND_PACKET_GREET * greet_packet = NULL;
+ MYSQLND_NET * net = conn->net;
DBG_ENTER("mysqlnd_conn_data::connect");
+ DBG_INF_FMT("conn=%p", conn);
if (PASS != conn->m->local_tx_start(conn, this_func TSRMLS_CC)) {
goto err;
@@ -653,14 +875,17 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect)(MYSQLND_CONN_DATA * conn,
MYSQLND_DEC_CONN_STATISTIC(conn->stats, STAT_OPENED_PERSISTENT_CONNECTIONS);
}
/* Now reconnect using the same handle */
- if (conn->net->compressed) {
+ if (net->data->compressed) {
/*
we need to save the state. As we will re-connect, net->compressed should be off, or
we will look for a compression header as part of the greet message, but there will
be none.
*/
saved_compression = TRUE;
- conn->net->compressed = FALSE;
+ net->data->compressed = FALSE;
+ }
+ if (net->data->ssl) {
+ net->data->ssl = FALSE;
}
} else {
unsigned int max_allowed_size = MYSQLND_ASSEMBLED_PACKET_MAX_SIZE;
@@ -683,6 +908,8 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect)(MYSQLND_CONN_DATA * conn,
DBG_INF_FMT("no db given, using empty string");
db = "";
db_len = 0;
+ } else {
+ mysql_flags |= CLIENT_CONNECT_WITH_DB;
}
host_len = strlen(host);
@@ -726,86 +953,9 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect)(MYSQLND_CONN_DATA * conn,
}
}
- greet_packet = conn->protocol->m.get_greet_packet(conn->protocol, FALSE TSRMLS_CC);
- if (!greet_packet) {
- SET_OOM_ERROR(*conn->error_info);
- goto err; /* OOM */
- }
+ mysql_flags = conn->m->get_updated_connect_flags(conn, mysql_flags TSRMLS_CC);
- if (FAIL == conn->net->m.connect_ex(conn->net, conn->scheme, conn->scheme_len, conn->persistent,
- conn->stats, conn->error_info TSRMLS_CC))
- {
- goto err;
- }
-
- DBG_INF_FMT("stream=%p", conn->net->stream);
-
- if (FAIL == PACKET_READ(greet_packet, conn)) {
- DBG_ERR("Error while reading greeting packet");
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error while reading greeting packet. PID=%d", getpid());
- goto err;
- } else if (greet_packet->error_no) {
- DBG_ERR_FMT("errorno=%u error=%s", greet_packet->error_no, greet_packet->error);
- SET_CLIENT_ERROR(*conn->error_info, greet_packet->error_no, greet_packet->sqlstate, greet_packet->error);
- goto err;
- } else if (greet_packet->pre41) {
- DBG_ERR_FMT("Connecting to 3.22, 3.23 & 4.0 is not supported. Server is %-.32s", greet_packet->server_version);
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Connecting to 3.22, 3.23 & 4.0 "
- " is not supported. Server is %-.32s", greet_packet->server_version);
- SET_CLIENT_ERROR(*conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE,
- "Connecting to 3.22, 3.23 & 4.0 servers is not supported");
- goto err;
- }
-
- conn->thread_id = greet_packet->thread_id;
- conn->protocol_version = greet_packet->protocol_version;
- conn->server_version = mnd_pestrdup(greet_packet->server_version, conn->persistent);
-
- conn->greet_charset = mysqlnd_find_charset_nr(greet_packet->charset_no);
- if (!conn->greet_charset) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
- "Server sent charset (%d) unknown to the client. Please, report to the developers", greet_packet->charset_no);
- SET_CLIENT_ERROR(*conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE,
- "Server sent charset unknown to the client. Please, report to the developers");
- goto err;
- }
- /* we allow load data local infile by default */
- mysql_flags |= MYSQLND_CAPABILITIES;
-
- mysql_flags |= conn->options->flags; /* use the flags from set_client_option() */
-
- if (db) {
- mysql_flags |= CLIENT_CONNECT_WITH_DB;
- }
-
- if (PG(open_basedir) && strlen(PG(open_basedir))) {
- mysql_flags ^= CLIENT_LOCAL_FILES;
- }
-
-#ifndef MYSQLND_COMPRESSION_ENABLED
- if (mysql_flags & CLIENT_COMPRESS) {
- mysql_flags &= ~CLIENT_COMPRESS;
- }
-#else
- if (conn->net->options.flags & MYSQLND_NET_FLAG_USE_COMPRESSION) {
- mysql_flags |= CLIENT_COMPRESS;
- }
-#endif
-#ifndef MYSQLND_SSL_SUPPORTED
- if (mysql_flags & CLIENT_SSL) {
- mysql_flags &= ~CLIENT_SSL;
- }
-#else
- if (conn->net->options.ssl_key || conn->net->options.ssl_cert ||
- conn->net->options.ssl_ca || conn->net->options.ssl_capath || conn->net->options.ssl_cipher)
- {
- mysql_flags |= CLIENT_SSL;
- }
-#endif
-
- if (FAIL == mysqlnd_connect_run_authentication(conn, user, passwd, db, db_len, (size_t) passwd_len,
- greet_packet, conn->options, mysql_flags TSRMLS_CC))
- {
+ if (FAIL == conn->m->connect_handshake(conn, host, user, passwd, passwd_len, db, db_len, mysql_flags TSRMLS_CC)) {
goto err;
}
@@ -813,14 +963,14 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect)(MYSQLND_CONN_DATA * conn,
CONN_SET_STATE(conn, CONN_READY);
if (saved_compression) {
- conn->net->compressed = TRUE;
+ net->data->compressed = TRUE;
}
/*
If a connect on a existing handle is performed and mysql_flags is
passed which doesn't CLIENT_COMPRESS, then we need to overwrite the value
which we set based on saved_compression.
*/
- conn->net->compressed = mysql_flags & CLIENT_COMPRESS? TRUE:FALSE;
+ net->data->compressed = mysql_flags & CLIENT_COMPRESS? TRUE:FALSE;
conn->user = mnd_pestrdup(user, conn->persistent);
conn->user_len = strlen(conn->user);
@@ -882,47 +1032,17 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect)(MYSQLND_CONN_DATA * conn,
}
conn->unix_socket_len = strlen(conn->unix_socket);
}
- conn->client_flag = mysql_flags;
conn->max_packet_size = MYSQLND_ASSEMBLED_PACKET_MAX_SIZE;
/* todo: check if charset is available */
- conn->server_capabilities = greet_packet->server_capabilities;
- memset(conn->upsert_status, 0, sizeof(*conn->upsert_status));
- conn->upsert_status->warning_count = 0;
- conn->upsert_status->server_status = greet_packet->server_status;
- conn->upsert_status->affected_rows = 0;
SET_EMPTY_ERROR(*conn->error_info);
mysqlnd_local_infile_default(conn);
-#if MYSQLND_UNICODE
- {
- unsigned int as_unicode = 1;
- conn->m->set_client_option(conn, MYSQLND_OPT_NUMERIC_AND_DATETIME_AS_UNICODE, (char *)&as_unicode TSRMLS_CC);
- DBG_INF("unicode set");
- }
-#endif
- if (conn->options->init_commands) {
- unsigned int current_command = 0;
- for (; current_command < conn->options->num_commands; ++current_command) {
- const char * const command = conn->options->init_commands[current_command];
- if (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);
- if (result) {
- result->m.free_result(result, TRUE TSRMLS_CC);
- }
- }
- }
- }
+ if (FAIL == conn->m->execute_init_commands(conn TSRMLS_CC)) {
+ goto err;
}
-
MYSQLND_INC_CONN_STATISTIC_W_VALUE2(conn->stats, STAT_CONNECT_SUCCESS, 1, STAT_OPENED_CONNECTIONS, 1);
if (reconnect) {
MYSQLND_INC_GLOBAL_STATISTIC(STAT_RECONNECT);
@@ -933,13 +1053,10 @@ MYSQLND_METHOD(mysqlnd_conn_data, connect)(MYSQLND_CONN_DATA * conn,
DBG_INF_FMT("connection_id=%llu", conn->thread_id);
- PACKET_FREE(greet_packet);
-
conn->m->local_tx_end(conn, this_func, PASS TSRMLS_CC);
DBG_RETURN(PASS);
}
err:
- PACKET_FREE(greet_packet);
DBG_ERR_FMT("[%u] %.128s (trying to connect via %s)", conn->error_info->error_no, conn->error_info->error, conn->scheme);
if (!conn->error_info->error_no) {
@@ -977,6 +1094,7 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND * conn_handle,
DBG_ENTER("mysqlnd_conn::connect");
if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) {
+ mysqlnd_options4(conn_handle, MYSQL_OPT_CONNECT_ATTR_ADD, "_client_name", "mysqlnd");
ret = conn->m->connect(conn, host, user, passwd, passwd_len, db, db_len, port, socket_or_pipe, mysql_flags TSRMLS_CC);
conn->m->local_tx_end(conn, this_func, FAIL TSRMLS_CC);
@@ -985,6 +1103,7 @@ MYSQLND_METHOD(mysqlnd_conn, connect)(MYSQLND * conn_handle,
}
/* }}} */
+
/* {{{ mysqlnd_connect */
PHPAPI MYSQLND * mysqlnd_connect(MYSQLND * conn_handle,
const char * host, const char * user,
@@ -1037,7 +1156,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, query)(MYSQLND_CONN_DATA * conn, const char *
size_t this_func = STRUCT_OFFSET(struct st_mysqlnd_conn_data_methods, query);
enum_func_status ret = FAIL;
DBG_ENTER("mysqlnd_conn_data::query");
- DBG_INF_FMT("conn=%llu query=%s", conn->thread_id, query);
+ DBG_INF_FMT("conn=%p conn=%llu query=%s", conn, conn->thread_id, query);
if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) {
if (PASS == conn->m->send_query(conn, query, query_len TSRMLS_CC) &&
@@ -1109,6 +1228,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, reap_query)(MYSQLND_CONN_DATA * conn TSRMLS_DC
#include "php_network.h"
+/* {{{ mysqlnd_stream_array_to_fd_set */
MYSQLND ** mysqlnd_stream_array_check_for_readiness(MYSQLND ** conn_array TSRMLS_DC)
{
int cnt = 0;
@@ -1139,15 +1259,17 @@ MYSQLND ** mysqlnd_stream_array_check_for_readiness(MYSQLND ** conn_array TSRMLS
}
return ret;
}
+/* }}} */
-/* {{{ stream_select mysqlnd_stream_array_to_fd_set functions */
+/* {{{ mysqlnd_stream_array_to_fd_set */
static int mysqlnd_stream_array_to_fd_set(MYSQLND ** conn_array, fd_set * fds, php_socket_t * max_fd TSRMLS_DC)
{
php_socket_t this_fd;
php_stream *stream = NULL;
- int cnt = 0;
+ unsigned int cnt = 0;
MYSQLND **p = conn_array;
+ DBG_ENTER("mysqlnd_stream_array_to_fd_set");
while (*p) {
/* get the fd.
@@ -1155,7 +1277,8 @@ static int mysqlnd_stream_array_to_fd_set(MYSQLND ** conn_array, fd_set * fds, p
* when casting. It is only used here so that the buffered data warning
* is not displayed.
* */
- stream = (*p)->data->net->stream;
+ stream = (*p)->data->net->data->m.get_stream((*p)->data->net TSRMLS_CC);
+ DBG_INF_FMT("conn=%llu stream=%p", (*p)->data->thread_id, stream);
if (stream != NULL && SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL,
(void*)&this_fd, 1) && this_fd >= 0) {
@@ -1168,21 +1291,24 @@ static int mysqlnd_stream_array_to_fd_set(MYSQLND ** conn_array, fd_set * fds, p
}
p++;
}
- return cnt ? 1 : 0;
+ DBG_RETURN(cnt ? 1 : 0);
}
+/* }}} */
+
+/* {{{ mysqlnd_stream_array_from_fd_set */
static int mysqlnd_stream_array_from_fd_set(MYSQLND ** conn_array, fd_set * fds TSRMLS_DC)
{
php_socket_t this_fd;
php_stream *stream = NULL;
int ret = 0;
zend_bool disproportion = FALSE;
-
-
MYSQLND **fwd = conn_array, **bckwd = conn_array;
+ DBG_ENTER("mysqlnd_stream_array_from_fd_set");
while (*fwd) {
- stream = (*fwd)->data->net->stream;
+ stream = (*fwd)->data->net->data->m.get_stream((*fwd)->data->net TSRMLS_CC);
+ DBG_INF_FMT("conn=%llu stream=%p", (*fwd)->data->thread_id, stream);
if (stream != NULL && SUCCESS == php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL,
(void*)&this_fd, 1) && this_fd >= 0) {
if (PHP_SAFE_FD_ISSET(this_fd, fds)) {
@@ -1200,7 +1326,7 @@ static int mysqlnd_stream_array_from_fd_set(MYSQLND ** conn_array, fd_set * fds
}
*bckwd = NULL;/* NULL-terminate the list */
- return ret;
+ DBG_RETURN(ret);
}
/* }}} */
@@ -1229,13 +1355,12 @@ _mysqlnd_poll(MYSQLND **r_array, MYSQLND **e_array, MYSQLND ***dont_poll, long s
DBG_RETURN(FAIL);
}
- *dont_poll = mysqlnd_stream_array_check_for_readiness(r_array TSRMLS_CC);
-
FD_ZERO(&rfds);
FD_ZERO(&wfds);
FD_ZERO(&efds);
if (r_array != NULL) {
+ *dont_poll = mysqlnd_stream_array_check_for_readiness(r_array TSRMLS_CC);
set_count = mysqlnd_stream_array_to_fd_set(r_array, &rfds, &max_fd TSRMLS_CC);
if (set_count > max_set_count) {
max_set_count = set_count;
@@ -1454,14 +1579,15 @@ MYSQLND_METHOD(mysqlnd_conn_data, ssl_set)(MYSQLND_CONN_DATA * const conn, const
{
size_t this_func = STRUCT_OFFSET(struct st_mysqlnd_conn_data_methods, ssl_set);
enum_func_status ret = FAIL;
+ MYSQLND_NET * net = conn->net;
DBG_ENTER("mysqlnd_conn_data::ssl_set");
if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) {
- ret = (PASS == conn->net->m.set_client_option(conn->net, MYSQLND_OPT_SSL_KEY, key TSRMLS_CC) &&
- PASS == conn->net->m.set_client_option(conn->net, MYSQLND_OPT_SSL_CERT, cert TSRMLS_CC) &&
- PASS == conn->net->m.set_client_option(conn->net, MYSQLND_OPT_SSL_CA, ca TSRMLS_CC) &&
- PASS == conn->net->m.set_client_option(conn->net, MYSQLND_OPT_SSL_CAPATH, capath TSRMLS_CC) &&
- PASS == conn->net->m.set_client_option(conn->net, MYSQLND_OPT_SSL_CIPHER, cipher TSRMLS_CC)) ? PASS : FAIL;
+ ret = (PASS == net->data->m.set_client_option(net, MYSQLND_OPT_SSL_KEY, key TSRMLS_CC) &&
+ PASS == net->data->m.set_client_option(net, MYSQLND_OPT_SSL_CERT, cert TSRMLS_CC) &&
+ PASS == net->data->m.set_client_option(net, MYSQLND_OPT_SSL_CA, ca TSRMLS_CC) &&
+ PASS == net->data->m.set_client_option(net, MYSQLND_OPT_SSL_CAPATH, capath TSRMLS_CC) &&
+ PASS == net->data->m.set_client_option(net, MYSQLND_OPT_SSL_CIPHER, cipher TSRMLS_CC)) ? PASS : FAIL;
conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
}
@@ -1637,6 +1763,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, kill)(MYSQLND_CONN_DATA * conn, unsigned int p
SET_ERROR_AFF_ROWS(conn);
} else if (PASS == (ret = conn->m->simple_command(conn, COM_PROCESS_KILL, buff, 4, PROT_LAST, FALSE, TRUE TSRMLS_CC))) {
CONN_SET_STATE(conn, CONN_QUIT_SENT);
+ conn->m->send_close(conn TSRMLS_CC);
}
conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
@@ -1734,10 +1861,11 @@ static enum_func_status
MYSQLND_METHOD(mysqlnd_conn_data, send_close)(MYSQLND_CONN_DATA * const conn TSRMLS_DC)
{
enum_func_status ret = PASS;
+ MYSQLND_NET * net = conn->net;
+ php_stream * net_stream = net->data->m.get_stream(net TSRMLS_CC);
DBG_ENTER("mysqlnd_send_close");
- DBG_INF_FMT("conn=%llu conn->net->stream->abstract=%p",
- conn->thread_id, conn->net->stream? conn->net->stream->abstract:NULL);
+ DBG_INF_FMT("conn=%llu net->data->stream->abstract=%p", conn->thread_id, net_stream? net_stream->abstract:NULL);
if (CONN_GET_STATE(conn) >= CONN_READY) {
MYSQLND_DEC_CONN_STATISTIC(conn->stats, STAT_OPENED_CONNECTIONS);
@@ -1748,10 +1876,11 @@ MYSQLND_METHOD(mysqlnd_conn_data, send_close)(MYSQLND_CONN_DATA * const conn TSR
switch (CONN_GET_STATE(conn)) {
case CONN_READY:
DBG_INF("Connection clean, sending COM_QUIT");
- if (conn->net->stream) {
+ if (net_stream) {
ret = conn->m->simple_command(conn, COM_QUIT, NULL, 0, PROT_LAST, TRUE, TRUE TSRMLS_CC);
+ net->data->m.close_stream(net, conn->stats, conn->error_info TSRMLS_CC);
}
- /* Do nothing */
+ CONN_SET_STATE(conn, CONN_QUIT_SENT);
break;
case CONN_SENDING_LOAD_DATA:
/*
@@ -1767,6 +1896,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, send_close)(MYSQLND_CONN_DATA * const conn TSR
Do nothing, the connection will be brutally closed
and the server will catch it and free close from its side.
*/
+ /* Fall-through */
case CONN_ALLOCED:
/*
Allocated but not connected or there was failure when trying
@@ -1774,15 +1904,13 @@ MYSQLND_METHOD(mysqlnd_conn_data, send_close)(MYSQLND_CONN_DATA * const conn TSR
Fall-through
*/
+ CONN_SET_STATE(conn, CONN_QUIT_SENT);
+ /* Fall-through */
case CONN_QUIT_SENT:
/* The user has killed its own connection */
+ net->data->m.close_stream(net, conn->stats, conn->error_info TSRMLS_CC);
break;
}
- /*
- We hold one reference, and every other object which needs the
- connection does increase it by 1.
- */
- CONN_SET_STATE(conn, CONN_QUIT_SENT);
DBG_RETURN(ret);
}
@@ -1824,7 +1952,7 @@ MYSQLND_METHOD_PRIVATE(mysqlnd_conn_data, free_reference)(MYSQLND_CONN_DATA * co
/* {{{ mysqlnd_conn_data::get_state */
static enum mysqlnd_connection_state
-MYSQLND_METHOD_PRIVATE(mysqlnd_conn_data, get_state)(MYSQLND_CONN_DATA * const conn TSRMLS_DC)
+MYSQLND_METHOD_PRIVATE(mysqlnd_conn_data, get_state)(const MYSQLND_CONN_DATA * const conn TSRMLS_DC)
{
DBG_ENTER("mysqlnd_conn_data::get_state");
DBG_RETURN(conn->state);
@@ -2022,6 +2150,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, next_result)(MYSQLND_CONN_DATA * const conn TS
DBG_ERR_FMT("Serious error. %s::%u", __FILE__, __LINE__);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Serious error. PID=%d", getpid());
CONN_SET_STATE(conn, CONN_QUIT_SENT);
+ conn->m->send_close(conn TSRMLS_CC);
} else {
DBG_INF_FMT("Error from the server : (%u) %s", conn->error_info->error_no, conn->error_info->error);
}
@@ -2101,13 +2230,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, change_user)(MYSQLND_CONN_DATA * const conn,
TSRMLS_DC)
{
size_t this_func = STRUCT_OFFSET(struct st_mysqlnd_conn_data_methods, change_user);
- /*
- User could be max 16 * 3 (utf8), pass is 20 usually, db is up to 64*3
- Stack space is not that expensive, so use a bit more to be protected against
- buffer overflows.
- */
enum_func_status ret = FAIL;
- zend_bool local_tx_started = FALSE;
DBG_ENTER("mysqlnd_conn_data::change_user");
DBG_INF_FMT("conn=%llu user=%s passwd=%s db=%s silent=%u",
@@ -2116,7 +2239,6 @@ MYSQLND_METHOD(mysqlnd_conn_data, change_user)(MYSQLND_CONN_DATA * const conn,
if (PASS != conn->m->local_tx_start(conn, this_func TSRMLS_CC)) {
goto end;
}
- local_tx_started = TRUE;
SET_EMPTY_ERROR(*conn->error_info);
SET_ERROR_AFF_ROWS(conn);
@@ -2131,120 +2253,17 @@ MYSQLND_METHOD(mysqlnd_conn_data, change_user)(MYSQLND_CONN_DATA * const conn,
db = "";
}
- {
- zend_bool first_call = TRUE;
- char * switch_to_auth_protocol = NULL;
- size_t switch_to_auth_protocol_len = 0;
- char * requested_protocol = NULL;
- zend_uchar * plugin_data;
- size_t plugin_data_len;
-
- plugin_data_len = conn->auth_plugin_data_len;
- plugin_data = mnd_emalloc(plugin_data_len);
- if (!plugin_data) {
- ret = FAIL;
- goto end;
- }
- memcpy(plugin_data, conn->auth_plugin_data, plugin_data_len);
-
- requested_protocol = mnd_pestrdup(conn->options->auth_protocol? conn->options->auth_protocol:"mysql_native_password", FALSE);
- if (!requested_protocol) {
- ret = FAIL;
- goto end;
- }
-
- do {
- struct st_mysqlnd_authentication_plugin * auth_plugin;
- {
- char * plugin_name = NULL;
-
- mnd_sprintf(&plugin_name, 0, "auth_plugin_%s", requested_protocol);
-
- DBG_INF_FMT("looking for %s auth plugin", plugin_name);
- auth_plugin = mysqlnd_plugin_find(plugin_name);
- mnd_sprintf_free(plugin_name);
-
- if (!auth_plugin) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "The server requested authentication method unknown to the client [%s]", requested_protocol);
- SET_CLIENT_ERROR(*conn->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, "The server requested authentication method unknown to the client");
- break;
- }
- }
- DBG_INF("plugin found");
-
- {
- zend_uchar * switch_to_auth_protocol_data = NULL;
- size_t switch_to_auth_protocol_data_len = 0;
- zend_uchar * scrambled_data = NULL;
- size_t scrambled_data_len = 0;
-
- switch_to_auth_protocol = NULL;
- switch_to_auth_protocol_len = 0;
-
- if (conn->auth_plugin_data) {
- mnd_pefree(conn->auth_plugin_data, conn->persistent);
- conn->auth_plugin_data = NULL;
- }
- conn->auth_plugin_data_len = plugin_data_len;
- conn->auth_plugin_data = mnd_pemalloc(conn->auth_plugin_data_len, conn->persistent);
- if (!conn->auth_plugin_data) {
- SET_OOM_ERROR(*conn->error_info);
- ret = FAIL;
- goto end;
- }
- memcpy(conn->auth_plugin_data, plugin_data, plugin_data_len);
-
- DBG_INF_FMT("salt=[%*.s]", plugin_data_len - 1, plugin_data);
-
- /* The data should be allocated with malloc() */
- scrambled_data =
- auth_plugin->methods.get_auth_data(NULL, &scrambled_data_len, conn, user, passwd, passwd_len,
- plugin_data, plugin_data_len, 0, conn->server_capabilities TSRMLS_CC);
-
-
- ret = mysqlnd_auth_change_user(conn, user, strlen(user), passwd, passwd_len, db, strlen(db), silent,
- first_call,
- requested_protocol,
- scrambled_data, scrambled_data_len,
- &switch_to_auth_protocol, &switch_to_auth_protocol_len,
- &switch_to_auth_protocol_data, &switch_to_auth_protocol_data_len
- TSRMLS_CC);
-
- first_call = FALSE;
- free(scrambled_data);
+ /* XXX: passwords that have \0 inside work during auth, but in this case won't work with change user */
+ ret = mysqlnd_run_authentication(conn, user, passwd, strlen(passwd), db, strlen(db),
+ conn->auth_plugin_data, conn->auth_plugin_data_len, conn->options->auth_protocol,
+ 0 /*charset not used*/, conn->options, conn->server_capabilities, silent, TRUE/*is_change*/ TSRMLS_CC);
- DBG_INF_FMT("switch_to_auth_protocol=%s", switch_to_auth_protocol? switch_to_auth_protocol:"n/a");
- if (requested_protocol) {
- mnd_efree(requested_protocol);
- }
- requested_protocol = switch_to_auth_protocol;
-
- if (plugin_data) {
- mnd_efree(plugin_data);
- }
- plugin_data_len = switch_to_auth_protocol_data_len;
- plugin_data = switch_to_auth_protocol_data;
- }
- DBG_INF_FMT("conn->error_info->error_no = %d", conn->error_info->error_no);
- } while (ret == FAIL && conn->error_info->error_no == 0 && switch_to_auth_protocol != NULL);
- if (plugin_data) {
- mnd_efree(plugin_data);
- }
- if (ret == PASS) {
- conn->m->set_client_option(conn, MYSQLND_OPT_AUTH_PROTOCOL, requested_protocol TSRMLS_CC);
- }
- if (requested_protocol) {
- mnd_efree(requested_protocol);
- }
- }
/*
Here we should close all statements. Unbuffered queries should not be a
problem as we won't allow sending COM_CHANGE_USER.
*/
+ conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
end:
- if (TRUE == local_tx_started) {
- conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
- }
DBG_INF(ret == PASS? "PASS":"FAIL");
DBG_RETURN(ret);
}
@@ -2281,13 +2300,9 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_client_option)(MYSQLND_CONN_DATA * const c
case MYSQL_OPT_CONNECT_TIMEOUT:
case MYSQLND_OPT_NET_CMD_BUFFER_SIZE:
case MYSQLND_OPT_NET_READ_BUFFER_SIZE:
- ret = conn->net->m.set_client_option(conn->net, option, value TSRMLS_CC);
+ case MYSQL_SERVER_PUBLIC_KEY:
+ ret = conn->net->data->m.set_client_option(conn->net, option, value TSRMLS_CC);
break;
-#if MYSQLND_UNICODE
- case MYSQLND_OPT_NUMERIC_AND_DATETIME_AS_UNICODE:
- conn->options->numeric_and_datetime_as_unicode = *(unsigned int*) value;
- break;
-#endif
#ifdef MYSQLND_STRING_TO_INT_CONVERSION
case MYSQLND_OPT_INT_AND_FLOAT_NATIVE:
conn->options->int_and_float_native = *(unsigned int*) value;
@@ -2392,6 +2407,19 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_client_option)(MYSQLND_CONN_DATA * const c
conn->options->flags &= ~CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS;
}
break;
+ case MYSQL_OPT_CONNECT_ATTR_RESET:
+ if (conn->options->connect_attr) {
+ DBG_INF_FMT("Before reset %d attribute(s)", zend_hash_num_elements(conn->options->connect_attr));
+ zend_hash_clean(conn->options->connect_attr);
+ }
+ break;
+ case MYSQL_OPT_CONNECT_ATTR_DELETE:
+ if (conn->options->connect_attr && value) {
+ DBG_INF_FMT("Before delete %d attribute(s)", zend_hash_num_elements(conn->options->connect_attr));
+ zend_hash_del(conn->options->connect_attr, value, strlen(value));
+ DBG_INF_FMT("%d left", zend_hash_num_elements(conn->options->connect_attr));
+ }
+ break;
#ifdef WHEN_SUPPORTED_BY_MYSQLI
case MYSQL_SHARED_MEMORY_BASE_NAME:
case MYSQL_OPT_USE_RESULT:
@@ -2412,6 +2440,83 @@ end:
/* }}} */
+/* {{{ connect_attr_item_edtor */
+static void
+connect_attr_item_edtor(void * pDest)
+{
+#ifdef ZTS
+ TSRMLS_FETCH();
+#endif
+ DBG_ENTER("connect_attr_item_edtor");
+ mnd_efree(*(char **) pDest);
+ DBG_VOID_RETURN;
+}
+/* }}} */
+
+
+/* {{{ connect_attr_item_pdtor */
+static void
+connect_attr_item_pdtor(void * pDest)
+{
+#ifdef ZTS
+ TSRMLS_FETCH();
+#endif
+ DBG_ENTER("connect_attr_item_pdtor");
+ mnd_pefree(*(char **) pDest, 1);
+ DBG_VOID_RETURN;
+}
+/* }}} */
+
+
+/* {{{ mysqlnd_conn_data::set_client_option_2d */
+static enum_func_status
+MYSQLND_METHOD(mysqlnd_conn_data, set_client_option_2d)(MYSQLND_CONN_DATA * const conn,
+ enum mysqlnd_option option,
+ const char * const key,
+ const char * const value
+ TSRMLS_DC)
+{
+ size_t this_func = STRUCT_OFFSET(struct st_mysqlnd_conn_data_methods, set_client_option_2d);
+ enum_func_status ret = PASS;
+ DBG_ENTER("mysqlnd_conn_data::set_client_option_2d");
+ DBG_INF_FMT("conn=%llu option=%u", conn->thread_id, option);
+
+ if (PASS != conn->m->local_tx_start(conn, this_func TSRMLS_CC)) {
+ goto end;
+ }
+ switch (option) {
+ case MYSQL_OPT_CONNECT_ATTR_ADD:
+ if (!conn->options->connect_attr) {
+ DBG_INF("Initializing connect_attr hash");
+ conn->options->connect_attr = mnd_pemalloc(sizeof(HashTable), conn->persistent);
+ if (!conn->options->connect_attr) {
+ goto oom;
+ }
+ zend_hash_init(conn->options->connect_attr, 0, NULL, conn->persistent? connect_attr_item_pdtor:connect_attr_item_edtor, conn->persistent);
+ }
+ DBG_INF_FMT("Adding [%s][%s]", key, value);
+ {
+ const char * copyv = mnd_pestrdup(value, conn->persistent);
+ if (!copyv) {
+ goto oom;
+ }
+ zend_hash_update(conn->options->connect_attr, key, strlen(key), &copyv, sizeof(char *), NULL);
+ }
+ break;
+ default:
+ ret = FAIL;
+ }
+ conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
+ DBG_RETURN(ret);
+oom:
+ SET_OOM_ERROR(*conn->error_info);
+ conn->m->local_tx_end(conn, this_func, FAIL TSRMLS_CC);
+end:
+ DBG_RETURN(FAIL);
+}
+/* }}} */
+
+
/* {{{ mysqlnd_conn_data::use_result */
static MYSQLND_RES *
MYSQLND_METHOD(mysqlnd_conn_data, use_result)(MYSQLND_CONN_DATA * const conn TSRMLS_DC)
@@ -2462,7 +2567,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, store_result)(MYSQLND_CONN_DATA * const conn T
MYSQLND_RES * result = NULL;
DBG_ENTER("mysqlnd_conn_data::store_result");
- DBG_INF_FMT("conn=%llu", conn->thread_id);
+ DBG_INF_FMT("conn=%llu conn=%p", conn->thread_id, conn);
if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) {
do {
@@ -2527,12 +2632,85 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_autocommit)(MYSQLND_CONN_DATA * conn, unsi
static enum_func_status
MYSQLND_METHOD(mysqlnd_conn_data, tx_commit)(MYSQLND_CONN_DATA * conn TSRMLS_DC)
{
- size_t this_func = STRUCT_OFFSET(struct st_mysqlnd_conn_data_methods, tx_commit);
+ return conn->m->tx_commit_or_rollback(conn, TRUE, TRANS_COR_NO_OPT, NULL TSRMLS_CC);
+}
+/* }}} */
+
+
+/* {{{ mysqlnd_conn_data::tx_rollback */
+static enum_func_status
+MYSQLND_METHOD(mysqlnd_conn_data, tx_rollback)(MYSQLND_CONN_DATA * conn TSRMLS_DC)
+{
+ return conn->m->tx_commit_or_rollback(conn, FALSE, TRANS_COR_NO_OPT, NULL TSRMLS_CC);
+}
+/* }}} */
+
+
+/* {{{ mysqlnd_tx_cor_options_to_string */
+static void
+MYSQLND_METHOD(mysqlnd_conn_data, tx_cor_options_to_string)(const MYSQLND_CONN_DATA * const conn, smart_str * str, const unsigned int mode TSRMLS_DC)
+{
+ if (mode & TRANS_COR_AND_CHAIN && !(mode & TRANS_COR_AND_NO_CHAIN)) {
+ if (str->len) {
+ smart_str_appendl(str, ", ", sizeof(", ") - 1);
+ }
+ smart_str_appendl(str, "AND CHAIN", sizeof("AND CHAIN") - 1);
+ } else if (mode & TRANS_COR_AND_NO_CHAIN && !(mode & TRANS_COR_AND_CHAIN)) {
+ if (str->len) {
+ smart_str_appendl(str, ", ", sizeof(", ") - 1);
+ }
+ smart_str_appendl(str, "AND NO CHAIN", sizeof("AND NO CHAIN") - 1);
+ }
+
+ if (mode & TRANS_COR_RELEASE && !(mode & TRANS_COR_NO_RELEASE)) {
+ if (str->len) {
+ smart_str_appendl(str, ", ", sizeof(", ") - 1);
+ }
+ smart_str_appendl(str, "RELEASE", sizeof("RELEASE") - 1);
+ } else if (mode & TRANS_COR_NO_RELEASE && !(mode & TRANS_COR_RELEASE)) {
+ if (str->len) {
+ smart_str_appendl(str, ", ", sizeof(", ") - 1);
+ }
+ smart_str_appendl(str, "NO RELEASE", sizeof("NO RELEASE") - 1);
+ }
+ smart_str_0(str);
+}
+/* }}} */
+
+
+/* {{{ mysqlnd_conn_data::tx_commit_ex */
+static enum_func_status
+MYSQLND_METHOD(mysqlnd_conn_data, tx_commit_or_rollback)(MYSQLND_CONN_DATA * conn, const zend_bool commit, const unsigned int flags, const char * const name TSRMLS_DC)
+{
+ size_t this_func = STRUCT_OFFSET(struct st_mysqlnd_conn_data_methods, tx_commit_or_rollback);
enum_func_status ret = FAIL;
- DBG_ENTER("mysqlnd_conn_data::tx_commit");
+ DBG_ENTER("mysqlnd_conn_data::tx_commit_or_rollback");
if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) {
- ret = conn->m->query(conn, "COMMIT", sizeof("COMMIT") - 1 TSRMLS_CC);
+ do {
+ smart_str tmp_str = {0, 0, 0};
+ conn->m->tx_cor_options_to_string(conn, &tmp_str, flags TSRMLS_CC);
+ smart_str_0(&tmp_str);
+
+ {
+ char * commented_name = NULL;
+ unsigned int commented_name_len = name? mnd_sprintf(&commented_name, 0, " /*%s*/", name):0;
+ char * query;
+ unsigned int query_len = mnd_sprintf(&query, 0, (commit? "COMMIT%s %s":"ROLLBACK%s %s"),
+ commented_name? commented_name:"", tmp_str.c? tmp_str.c:"");
+ smart_str_free(&tmp_str);
+
+ if (!query) {
+ SET_OOM_ERROR(*conn->error_info);
+ break;
+ }
+ ret = conn->m->query(conn, query, query_len TSRMLS_CC);
+ mnd_sprintf_free(query);
+ if (commented_name) {
+ mnd_sprintf_free(commented_name);
+ }
+ }
+ } while (0);
conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
}
@@ -2541,16 +2719,119 @@ MYSQLND_METHOD(mysqlnd_conn_data, tx_commit)(MYSQLND_CONN_DATA * conn TSRMLS_DC)
/* }}} */
-/* {{{ mysqlnd_conn_data::tx_rollback */
+/* {{{ mysqlnd_conn_data::tx_begin */
static enum_func_status
-MYSQLND_METHOD(mysqlnd_conn_data, tx_rollback)(MYSQLND_CONN_DATA * conn TSRMLS_DC)
+MYSQLND_METHOD(mysqlnd_conn_data, tx_begin)(MYSQLND_CONN_DATA * conn, const unsigned int mode, const char * const name TSRMLS_DC)
+{
+ size_t this_func = STRUCT_OFFSET(struct st_mysqlnd_conn_data_methods, tx_begin);
+ enum_func_status ret = FAIL;
+ DBG_ENTER("mysqlnd_conn_data::tx_begin");
+
+ if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) {
+ do {
+ smart_str tmp_str = {0, 0, 0};
+ if (mode & TRANS_START_WITH_CONSISTENT_SNAPSHOT) {
+ if (tmp_str.len) {
+ smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
+ }
+ smart_str_appendl(&tmp_str, "WITH CONSISTENT SNAPSHOT", sizeof("WITH CONSISTENT SNAPSHOT") - 1);
+ }
+ if (mode & TRANS_START_READ_WRITE) {
+ if (tmp_str.len) {
+ smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
+ }
+ smart_str_appendl(&tmp_str, "READ WRITE", sizeof("READ WRITE") - 1);
+ }
+ if (mode & TRANS_START_READ_ONLY) {
+ if (tmp_str.len) {
+ smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1);
+ }
+ smart_str_appendl(&tmp_str, "READ ONLY", sizeof("READ ONLY") - 1);
+ }
+ smart_str_0(&tmp_str);
+
+ {
+ char * commented_name = NULL;
+ unsigned int commented_name_len = name? mnd_sprintf(&commented_name, 0, " /*%s*/", name):0;
+ char * query;
+ unsigned int query_len = mnd_sprintf(&query, 0, "START TRANSACTION%s %s", commented_name? commented_name:"", tmp_str.c? tmp_str.c:"");
+ smart_str_free(&tmp_str);
+
+ if (!query) {
+ SET_OOM_ERROR(*conn->error_info);
+ break;
+ }
+ ret = conn->m->query(conn, query, query_len TSRMLS_CC);
+ mnd_sprintf_free(query);
+ if (commented_name) {
+ mnd_sprintf_free(commented_name);
+ }
+ }
+ } while (0);
+ conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
+ }
+
+ DBG_RETURN(ret);
+}
+/* }}} */
+
+
+/* {{{ mysqlnd_conn_data::tx_savepoint */
+static enum_func_status
+MYSQLND_METHOD(mysqlnd_conn_data, tx_savepoint)(MYSQLND_CONN_DATA * conn, const char * const name TSRMLS_DC)
+{
+ size_t this_func = STRUCT_OFFSET(struct st_mysqlnd_conn_data_methods, tx_savepoint);
+ enum_func_status ret = FAIL;
+ DBG_ENTER("mysqlnd_conn_data::tx_savepoint");
+
+ if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) {
+ do {
+ char * query;
+ unsigned int query_len;
+ if (!name) {
+ SET_CLIENT_ERROR(*conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, "Savepoint name not provided");
+ break;
+ }
+ query_len = mnd_sprintf(&query, 0, "SAVEPOINT `%s`", name);
+ if (!query) {
+ SET_OOM_ERROR(*conn->error_info);
+ break;
+ }
+ ret = conn->m->query(conn, query, query_len TSRMLS_CC);
+ mnd_sprintf_free(query);
+ } while (0);
+ conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
+ }
+
+ DBG_RETURN(ret);
+}
+/* }}} */
+
+
+/* {{{ mysqlnd_conn_data::tx_savepoint_release */
+static enum_func_status
+MYSQLND_METHOD(mysqlnd_conn_data, tx_savepoint_release)(MYSQLND_CONN_DATA * conn, const char * const name TSRMLS_DC)
{
- size_t this_func = STRUCT_OFFSET(struct st_mysqlnd_conn_data_methods, tx_rollback);
+ size_t this_func = STRUCT_OFFSET(struct st_mysqlnd_conn_data_methods, tx_savepoint_release);
enum_func_status ret = FAIL;
- DBG_ENTER("mysqlnd_conn_data::tx_rollback");
+ DBG_ENTER("mysqlnd_conn_data::tx_savepoint_release");
if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) {
- ret = conn->m->query(conn, "ROLLBACK", sizeof("ROLLBACK") - 1 TSRMLS_CC);
+ do {
+ char * query;
+ unsigned int query_len;
+ if (!name) {
+ SET_CLIENT_ERROR(*conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, "Savepoint name not provided");
+ break;
+ }
+ query_len = mnd_sprintf(&query, 0, "RELEASE SAVEPOINT `%s`", name);
+ if (!query) {
+ SET_OOM_ERROR(*conn->error_info);
+ break;
+ }
+ ret = conn->m->query(conn, query, query_len TSRMLS_CC);
+ mnd_sprintf_free(query);
+ } while (0);
conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
}
@@ -2673,8 +2954,21 @@ MYSQLND_CLASS_METHODS_START(mysqlnd_conn_data)
MYSQLND_METHOD(mysqlnd_conn_data, set_autocommit),
MYSQLND_METHOD(mysqlnd_conn_data, tx_commit),
MYSQLND_METHOD(mysqlnd_conn_data, tx_rollback),
+ MYSQLND_METHOD(mysqlnd_conn_data, tx_begin),
+ MYSQLND_METHOD(mysqlnd_conn_data, tx_commit_or_rollback),
+ MYSQLND_METHOD(mysqlnd_conn_data, tx_cor_options_to_string),
+ MYSQLND_METHOD(mysqlnd_conn_data, tx_savepoint),
+ MYSQLND_METHOD(mysqlnd_conn_data, tx_savepoint_release),
+
MYSQLND_METHOD(mysqlnd_conn_data, local_tx_start),
- MYSQLND_METHOD(mysqlnd_conn_data, local_tx_end)
+ MYSQLND_METHOD(mysqlnd_conn_data, local_tx_end),
+ MYSQLND_METHOD(mysqlnd_conn_data, execute_init_commands),
+ MYSQLND_METHOD(mysqlnd_conn_data, get_updated_connect_flags),
+ MYSQLND_METHOD(mysqlnd_conn_data, connect_handshake),
+ MYSQLND_METHOD(mysqlnd_conn_data, simple_command_send_request),
+ MYSQLND_METHOD(mysqlnd_conn_data, fetch_auth_plugin_by_name),
+
+ MYSQLND_METHOD(mysqlnd_conn_data, set_client_option_2d)
MYSQLND_CLASS_METHODS_END;
diff --git a/ext/mysqlnd/mysqlnd.h b/ext/mysqlnd/mysqlnd.h
index c85105d7c6..bf9ad53b11 100644
--- a/ext/mysqlnd/mysqlnd.h
+++ b/ext/mysqlnd/mysqlnd.h
@@ -22,10 +22,10 @@
#ifndef MYSQLND_H
#define MYSQLND_H
-#define MYSQLND_VERSION "mysqlnd 5.0.10 - 20111026 - $Id$"
-#define MYSQLND_VERSION_ID 50010
+#define MYSQLND_VERSION "mysqlnd 5.0.11-dev - 20120503 - $Id$"
+#define MYSQLND_VERSION_ID 50011
-#define MYSQLND_PLUGIN_API_VERSION 1
+#define MYSQLND_PLUGIN_API_VERSION 2
#define MYSQLND_STRING_TO_INT_CONVERSION
/*
@@ -192,8 +192,11 @@ PHPAPI void mysqlnd_set_local_infile_handler(MYSQLND_CONN_DATA * const conn, con
/* Simple commands */
#define mysqlnd_autocommit(conn, mode) ((conn)->data)->m->set_autocommit((conn)->data, (mode) TSRMLS_CC)
-#define mysqlnd_commit(conn) ((conn)->data)->m->tx_commit((conn)->data TSRMLS_CC)
-#define mysqlnd_rollback(conn) ((conn)->data)->m->tx_rollback((conn)->data TSRMLS_CC)
+#define mysqlnd_begin_transaction(conn,flags,name) ((conn)->data)->m->tx_begin((conn)->data, (flags), (name) TSRMLS_CC)
+#define mysqlnd_commit(conn, flags, name) ((conn)->data)->m->tx_commit_or_rollback((conn)->data, TRUE, (flags), (name) TSRMLS_CC)
+#define mysqlnd_rollback(conn, flags, name) ((conn)->data)->m->tx_commit_or_rollback((conn)->data, FALSE, (flags), (name) TSRMLS_CC)
+#define mysqlnd_savepoint(conn, name) ((conn)->data)->m->tx_savepoint((conn)->data, (name) TSRMLS_CC)
+#define mysqlnd_release_savepoint(conn, name) ((conn)->data)->m->tx_savepoint_release((conn)->data, (name) TSRMLS_CC)
#define mysqlnd_list_dbs(conn, wild) ((conn)->data)->m->list_method((conn)->data, wild? "SHOW DATABASES LIKE %s":"SHOW DATABASES", (wild), NULL TSRMLS_CC)
#define mysqlnd_list_fields(conn, tab,wild) ((conn)->data)->m->list_fields((conn)->data, (tab), (wild) TSRMLS_CC)
#define mysqlnd_list_processes(conn) ((conn)->data)->m->list_method((conn)->data, "SHOW PROCESSLIST", NULL, NULL TSRMLS_CC)
@@ -207,6 +210,7 @@ PHPAPI void mysqlnd_set_local_infile_handler(MYSQLND_CONN_DATA * const conn, con
#define mysqlnd_set_character_set(conn, cs) ((conn)->data)->m->set_charset((conn)->data, (cs) TSRMLS_CC)
#define mysqlnd_stat(conn, msg, msg_len) ((conn)->data)->m->get_server_statistics(((conn)->data), (msg), (msg_len) TSRMLS_CC)
#define mysqlnd_options(conn, opt, value) ((conn)->data)->m->set_client_option((conn)->data, (opt), (value) TSRMLS_CC)
+#define mysqlnd_options4(conn, opt, k, v) ((conn)->data)->m->set_client_option_2d((conn)->data, (opt), (k), (v) TSRMLS_CC)
#define mysqlnd_set_server_option(conn, op) ((conn)->data)->m->set_server_option((conn)->data, (op) TSRMLS_CC)
/* Escaping */
@@ -262,8 +266,10 @@ PHPAPI void _mysqlnd_get_client_stats(zval *return_value TSRMLS_DC ZEND_FILE_L
ZEND_BEGIN_MODULE_GLOBALS(mysqlnd)
zend_bool collect_statistics;
zend_bool collect_memory_statistics;
- char* debug; /* The actual string */
- MYSQLND_DEBUG *dbg; /* The DBG object */
+ char * debug; /* The actual string */
+ char * trace_alloc_settings; /* The actual string */
+ MYSQLND_DEBUG * dbg; /* The DBG object for standard tracing */
+ MYSQLND_DEBUG * trace_alloc; /* The DBG object for allocation tracing */
long net_cmd_buffer_size;
long net_read_buffer_size;
long log_mask;
@@ -275,6 +281,7 @@ ZEND_BEGIN_MODULE_GLOBALS(mysqlnd)
long debug_malloc_fail_threshold;
long debug_calloc_fail_threshold;
long debug_realloc_fail_threshold;
+ char * sha256_server_public_key;
ZEND_END_MODULE_GLOBALS(mysqlnd)
PHPAPI ZEND_EXTERN_MODULE_GLOBALS(mysqlnd)
diff --git a/ext/mysqlnd/mysqlnd_alloc.c b/ext/mysqlnd/mysqlnd_alloc.c
index a72423f4fb..42ce55a36a 100644
--- a/ext/mysqlnd/mysqlnd_alloc.c
+++ b/ext/mysqlnd/mysqlnd_alloc.c
@@ -65,8 +65,8 @@ PHPAPI const char * mysqlnd_debug_std_no_trace_funcs[] =
#if ZEND_DEBUG
#else
-#define __zend_filename "/unknown/unknown"
-#define __zend_lineno 0
+#define __zend_orig_filename "/unknown/unknown"
+#define __zend_orig_lineno 0
#endif
#define REAL_SIZE(s) (collect_memory_statistics? (s) + sizeof(size_t) : (s))
@@ -81,12 +81,12 @@ void * _mysqlnd_emalloc(size_t size MYSQLND_MEM_D)
#if PHP_DEBUG
long * threshold = &MYSQLND_G(debug_emalloc_fail_threshold);
#endif
- DBG_ENTER(mysqlnd_emalloc_name);
+ TRACE_ALLOC_ENTER(mysqlnd_emalloc_name);
#if PHP_DEBUG
{
- char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR);
- DBG_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno);
+ char * fn = strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR);
+ TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_orig_filename, __zend_orig_lineno);
}
#endif
@@ -94,7 +94,7 @@ void * _mysqlnd_emalloc(size_t size MYSQLND_MEM_D)
/* -1 is also "true" */
if (*threshold) {
#endif
- ret = emalloc(REAL_SIZE(size));
+ ret = _emalloc(REAL_SIZE(size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
#if PHP_DEBUG
--*threshold;
} else if (*threshold == 0) {
@@ -102,13 +102,13 @@ void * _mysqlnd_emalloc(size_t size MYSQLND_MEM_D)
}
#endif
- DBG_INF_FMT("size=%lu ptr=%p", size, ret);
+ TRACE_ALLOC_INF_FMT("size=%lu ptr=%p", size, ret);
if (ret && collect_memory_statistics) {
*(size_t *) ret = size;
MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_EMALLOC_COUNT, 1, STAT_MEM_EMALLOC_AMOUNT, size);
}
- DBG_RETURN(FAKE_PTR(ret));
+ TRACE_ALLOC_RETURN(FAKE_PTR(ret));
}
/* }}} */
@@ -121,11 +121,12 @@ void * _mysqlnd_pemalloc(size_t size, zend_bool persistent MYSQLND_MEM_D)
#if PHP_DEBUG
long * threshold = persistent? &MYSQLND_G(debug_malloc_fail_threshold):&MYSQLND_G(debug_emalloc_fail_threshold);
#endif
- DBG_ENTER(mysqlnd_pemalloc_name);
+ TRACE_ALLOC_ENTER(mysqlnd_pemalloc_name);
+
#if PHP_DEBUG
{
- char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR);
- DBG_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno);
+ char * fn = strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR);
+ TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_orig_filename, __zend_orig_lineno);
}
#endif
@@ -133,7 +134,7 @@ void * _mysqlnd_pemalloc(size_t size, zend_bool persistent MYSQLND_MEM_D)
/* -1 is also "true" */
if (*threshold) {
#endif
- ret = pemalloc(REAL_SIZE(size), persistent);
+ ret = (persistent) ? __zend_malloc(REAL_SIZE(size)) : _emalloc(REAL_SIZE(size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
#if PHP_DEBUG
--*threshold;
} else if (*threshold == 0) {
@@ -141,7 +142,7 @@ void * _mysqlnd_pemalloc(size_t size, zend_bool persistent MYSQLND_MEM_D)
}
#endif
- DBG_INF_FMT("size=%lu ptr=%p persistent=%u", size, ret, persistent);
+ TRACE_ALLOC_INF_FMT("size=%lu ptr=%p persistent=%u", size, ret, persistent);
if (ret && collect_memory_statistics) {
enum mysqlnd_collected_stats s1 = persistent? STAT_MEM_MALLOC_COUNT:STAT_MEM_EMALLOC_COUNT;
@@ -150,7 +151,7 @@ void * _mysqlnd_pemalloc(size_t size, zend_bool persistent MYSQLND_MEM_D)
MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(s1, 1, s2, size);
}
- DBG_RETURN(FAKE_PTR(ret));
+ TRACE_ALLOC_RETURN(FAKE_PTR(ret));
}
/* }}} */
@@ -163,20 +164,21 @@ void * _mysqlnd_ecalloc(unsigned int nmemb, size_t size MYSQLND_MEM_D)
#if PHP_DEBUG
long * threshold = &MYSQLND_G(debug_ecalloc_fail_threshold);
#endif
- DBG_ENTER(mysqlnd_ecalloc_name);
+ TRACE_ALLOC_ENTER(mysqlnd_ecalloc_name);
+
#if PHP_DEBUG
{
- char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR);
- DBG_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno);
+ char * fn = strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR);
+ TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_orig_filename, __zend_orig_lineno);
}
#endif
- DBG_INF_FMT("before: %lu", zend_memory_usage(FALSE TSRMLS_CC));
+ TRACE_ALLOC_INF_FMT("before: %lu", zend_memory_usage(FALSE TSRMLS_CC));
#if PHP_DEBUG
/* -1 is also "true" */
if (*threshold) {
#endif
- ret = ecalloc(nmemb, REAL_SIZE(size));
+ ret = _ecalloc(nmemb, REAL_SIZE(size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
#if PHP_DEBUG
--*threshold;
} else if (*threshold == 0) {
@@ -184,13 +186,13 @@ void * _mysqlnd_ecalloc(unsigned int nmemb, size_t size MYSQLND_MEM_D)
}
#endif
- DBG_INF_FMT("after : %lu", zend_memory_usage(FALSE TSRMLS_CC));
- DBG_INF_FMT("size=%lu ptr=%p", size, ret);
+ TRACE_ALLOC_INF_FMT("after : %lu", zend_memory_usage(FALSE TSRMLS_CC));
+ TRACE_ALLOC_INF_FMT("size=%lu ptr=%p", size, ret);
if (ret && collect_memory_statistics) {
*(size_t *) ret = size;
MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_ECALLOC_COUNT, 1, STAT_MEM_ECALLOC_AMOUNT, size);
}
- DBG_RETURN(FAKE_PTR(ret));
+ TRACE_ALLOC_RETURN(FAKE_PTR(ret));
}
/* }}} */
@@ -203,11 +205,11 @@ void * _mysqlnd_pecalloc(unsigned int nmemb, size_t size, zend_bool persistent M
#if PHP_DEBUG
long * threshold = persistent? &MYSQLND_G(debug_calloc_fail_threshold):&MYSQLND_G(debug_ecalloc_fail_threshold);
#endif
- DBG_ENTER(mysqlnd_pecalloc_name);
+ TRACE_ALLOC_ENTER(mysqlnd_pecalloc_name);
#if PHP_DEBUG
{
- char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR);
- DBG_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno);
+ char * fn = strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR);
+ TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_orig_filename, __zend_orig_lineno);
}
#endif
@@ -215,7 +217,7 @@ void * _mysqlnd_pecalloc(unsigned int nmemb, size_t size, zend_bool persistent M
/* -1 is also "true" */
if (*threshold) {
#endif
- ret = pecalloc(nmemb, REAL_SIZE(size), persistent);
+ ret = (persistent) ? __zend_calloc(nmemb, REAL_SIZE(size)) : _ecalloc(nmemb, REAL_SIZE(size) ZEND_FILE_LINE_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
#if PHP_DEBUG
--*threshold;
} else if (*threshold == 0) {
@@ -223,7 +225,7 @@ void * _mysqlnd_pecalloc(unsigned int nmemb, size_t size, zend_bool persistent M
}
#endif
- DBG_INF_FMT("size=%lu ptr=%p", size, ret);
+ TRACE_ALLOC_INF_FMT("size=%lu ptr=%p", size, ret);
if (ret && collect_memory_statistics) {
enum mysqlnd_collected_stats s1 = persistent? STAT_MEM_CALLOC_COUNT:STAT_MEM_ECALLOC_COUNT;
@@ -232,7 +234,7 @@ void * _mysqlnd_pecalloc(unsigned int nmemb, size_t size, zend_bool persistent M
MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(s1, 1, s2, size);
}
- DBG_RETURN(FAKE_PTR(ret));
+ TRACE_ALLOC_RETURN(FAKE_PTR(ret));
}
/* }}} */
@@ -246,20 +248,21 @@ void * _mysqlnd_erealloc(void *ptr, size_t new_size MYSQLND_MEM_D)
#if PHP_DEBUG
long * threshold = &MYSQLND_G(debug_erealloc_fail_threshold);
#endif
- DBG_ENTER(mysqlnd_erealloc_name);
+ TRACE_ALLOC_ENTER(mysqlnd_erealloc_name);
+
#if PHP_DEBUG
{
- char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR);
- DBG_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno);
+ char * fn = strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR);
+ TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_orig_filename, __zend_orig_lineno);
}
#endif
- DBG_INF_FMT("ptr=%p old_size=%lu, new_size=%lu", ptr, old_size, new_size);
+ TRACE_ALLOC_INF_FMT("ptr=%p old_size=%lu, new_size=%lu", ptr, old_size, new_size);
#if PHP_DEBUG
/* -1 is also "true" */
if (*threshold) {
#endif
- ret = erealloc(REAL_PTR(ptr), REAL_SIZE(new_size));
+ ret = _erealloc(REAL_PTR(ptr), REAL_SIZE(new_size), 0 ZEND_FILE_LINE_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
#if PHP_DEBUG
--*threshold;
} else if (*threshold == 0) {
@@ -267,12 +270,12 @@ void * _mysqlnd_erealloc(void *ptr, size_t new_size MYSQLND_MEM_D)
}
#endif
- DBG_INF_FMT("new_ptr=%p", (char*)ret);
+ TRACE_ALLOC_INF_FMT("new_ptr=%p", (char*)ret);
if (ret && collect_memory_statistics) {
*(size_t *) ret = new_size;
MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_EREALLOC_COUNT, 1, STAT_MEM_EREALLOC_AMOUNT, new_size);
}
- DBG_RETURN(FAKE_PTR(ret));
+ TRACE_ALLOC_RETURN(FAKE_PTR(ret));
}
/* }}} */
@@ -286,14 +289,15 @@ void * _mysqlnd_perealloc(void *ptr, size_t new_size, zend_bool persistent MYSQL
#if PHP_DEBUG
long * threshold = persistent? &MYSQLND_G(debug_realloc_fail_threshold):&MYSQLND_G(debug_erealloc_fail_threshold);
#endif
- DBG_ENTER(mysqlnd_perealloc_name);
+ TRACE_ALLOC_ENTER(mysqlnd_perealloc_name);
+
#if PHP_DEBUG
{
- char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR);
- DBG_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno);
+ char * fn = strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR);
+ TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_orig_filename, __zend_orig_lineno);
}
#endif
- DBG_INF_FMT("ptr=%p old_size=%lu new_size=%lu persistent=%u", ptr, old_size, new_size, persistent);
+ TRACE_ALLOC_INF_FMT("ptr=%p old_size=%lu new_size=%lu persistent=%u", ptr, old_size, new_size, persistent);
#if PHP_DEBUG
/* -1 is also "true" */
@@ -307,7 +311,7 @@ void * _mysqlnd_perealloc(void *ptr, size_t new_size, zend_bool persistent MYSQL
}
#endif
- DBG_INF_FMT("new_ptr=%p", (char*)ret);
+ TRACE_ALLOC_INF_FMT("new_ptr=%p", (char*)ret);
if (ret && collect_memory_statistics) {
enum mysqlnd_collected_stats s1 = persistent? STAT_MEM_REALLOC_COUNT:STAT_MEM_EREALLOC_COUNT;
@@ -315,7 +319,7 @@ void * _mysqlnd_perealloc(void *ptr, size_t new_size, zend_bool persistent MYSQL
*(size_t *) ret = new_size;
MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(s1, 1, s2, new_size);
}
- DBG_RETURN(FAKE_PTR(ret));
+ TRACE_ALLOC_RETURN(FAKE_PTR(ret));
}
/* }}} */
@@ -325,27 +329,28 @@ void _mysqlnd_efree(void *ptr MYSQLND_MEM_D)
{
size_t free_amount = 0;
zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
- DBG_ENTER(mysqlnd_efree_name);
+ TRACE_ALLOC_ENTER(mysqlnd_efree_name);
+
#if PHP_DEBUG
{
- char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR);
- DBG_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno);
+ char * fn = strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR);
+ TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_orig_filename, __zend_orig_lineno);
}
#endif
- DBG_INF_FMT("ptr=%p", ptr);
+ TRACE_ALLOC_INF_FMT("ptr=%p", ptr);
if (ptr) {
if (collect_memory_statistics) {
free_amount = *(size_t *)(((char*)ptr) - sizeof(size_t));
- DBG_INF_FMT("ptr=%p size=%u", ((char*)ptr) - sizeof(size_t), (unsigned int) free_amount);
+ TRACE_ALLOC_INF_FMT("ptr=%p size=%u", ((char*)ptr) - sizeof(size_t), (unsigned int) free_amount);
}
- efree(REAL_PTR(ptr));
+ _efree(REAL_PTR(ptr) ZEND_FILE_LINE_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
}
if (collect_memory_statistics) {
MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_EFREE_COUNT, 1, STAT_MEM_EFREE_AMOUNT, free_amount);
}
- DBG_VOID_RETURN;
+ TRACE_ALLOC_VOID_RETURN;
}
/* }}} */
@@ -355,29 +360,31 @@ void _mysqlnd_pefree(void *ptr, zend_bool persistent MYSQLND_MEM_D)
{
size_t free_amount = 0;
zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
- DBG_ENTER(mysqlnd_pefree_name);
+ TRACE_ALLOC_ENTER(mysqlnd_pefree_name);
+
#if PHP_DEBUG
{
- char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR);
- DBG_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno);
+ char * fn = strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR);
+ TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_orig_filename, __zend_orig_lineno);
}
#endif
- DBG_INF_FMT("ptr=%p persistent=%u", ptr, persistent);
+ TRACE_ALLOC_INF_FMT("ptr=%p persistent=%u", ptr, persistent);
if (ptr) {
if (collect_memory_statistics) {
free_amount = *(size_t *)(((char*)ptr) - sizeof(size_t));
- DBG_INF_FMT("ptr=%p size=%u", ((char*)ptr) - sizeof(size_t), (unsigned int) free_amount);
+ TRACE_ALLOC_INF_FMT("ptr=%p size=%u", ((char*)ptr) - sizeof(size_t), (unsigned int) free_amount);
}
- pefree(REAL_PTR(ptr), persistent);
+ (persistent) ? free(REAL_PTR(ptr)) : _efree(REAL_PTR(ptr) ZEND_FILE_LINE_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
}
if (collect_memory_statistics) {
MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(persistent? STAT_MEM_FREE_COUNT:STAT_MEM_EFREE_COUNT, 1,
persistent? STAT_MEM_FREE_AMOUNT:STAT_MEM_EFREE_AMOUNT, free_amount);
}
- DBG_VOID_RETURN;
+ TRACE_ALLOC_VOID_RETURN;
}
+/* }}} */
/* {{{ _mysqlnd_malloc */
@@ -388,11 +395,12 @@ void * _mysqlnd_malloc(size_t size MYSQLND_MEM_D)
#if PHP_DEBUG
long * threshold = &MYSQLND_G(debug_malloc_fail_threshold);
#endif
- DBG_ENTER(mysqlnd_malloc_name);
+ TRACE_ALLOC_ENTER(mysqlnd_malloc_name);
+
#if PHP_DEBUG
{
- char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR);
- DBG_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno);
+ char * fn = strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR);
+ TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_orig_filename, __zend_orig_lineno);
}
#endif
@@ -408,12 +416,12 @@ void * _mysqlnd_malloc(size_t size MYSQLND_MEM_D)
}
#endif
- DBG_INF_FMT("size=%lu ptr=%p", size, ret);
+ TRACE_ALLOC_INF_FMT("size=%lu ptr=%p", size, ret);
if (ret && collect_memory_statistics) {
*(size_t *) ret = size;
MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_MALLOC_COUNT, 1, STAT_MEM_MALLOC_AMOUNT, size);
}
- DBG_RETURN(FAKE_PTR(ret));
+ TRACE_ALLOC_RETURN(FAKE_PTR(ret));
}
/* }}} */
@@ -426,11 +434,12 @@ void * _mysqlnd_calloc(unsigned int nmemb, size_t size MYSQLND_MEM_D)
#if PHP_DEBUG
long * threshold = &MYSQLND_G(debug_calloc_fail_threshold);
#endif
- DBG_ENTER(mysqlnd_calloc_name);
+ TRACE_ALLOC_ENTER(mysqlnd_calloc_name);
+
#if PHP_DEBUG
{
- char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR);
- DBG_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno);
+ char * fn = strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR);
+ TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_orig_filename, __zend_orig_lineno);
}
#endif
@@ -446,12 +455,12 @@ void * _mysqlnd_calloc(unsigned int nmemb, size_t size MYSQLND_MEM_D)
}
#endif
- DBG_INF_FMT("size=%lu ptr=%p", size, ret);
+ TRACE_ALLOC_INF_FMT("size=%lu ptr=%p", size, ret);
if (ret && collect_memory_statistics) {
*(size_t *) ret = size;
MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_CALLOC_COUNT, 1, STAT_MEM_CALLOC_AMOUNT, size);
}
- DBG_RETURN(FAKE_PTR(ret));
+ TRACE_ALLOC_RETURN(FAKE_PTR(ret));
}
/* }}} */
@@ -464,15 +473,16 @@ void * _mysqlnd_realloc(void *ptr, size_t new_size MYSQLND_MEM_D)
#if PHP_DEBUG
long * threshold = &MYSQLND_G(debug_realloc_fail_threshold);
#endif
- DBG_ENTER(mysqlnd_realloc_name);
+ TRACE_ALLOC_ENTER(mysqlnd_realloc_name);
+
#if PHP_DEBUG
{
- char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR);
- DBG_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno);
+ char * fn = strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR);
+ TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_orig_filename, __zend_orig_lineno);
}
#endif
- DBG_INF_FMT("ptr=%p new_size=%lu ", new_size, ptr);
- DBG_INF_FMT("before: %lu", zend_memory_usage(TRUE TSRMLS_CC));
+ TRACE_ALLOC_INF_FMT("ptr=%p new_size=%lu ", new_size, ptr);
+ TRACE_ALLOC_INF_FMT("before: %lu", zend_memory_usage(TRUE TSRMLS_CC));
#if PHP_DEBUG
/* -1 is also "true" */
@@ -486,13 +496,13 @@ void * _mysqlnd_realloc(void *ptr, size_t new_size MYSQLND_MEM_D)
}
#endif
- DBG_INF_FMT("new_ptr=%p", (char*)ret);
+ TRACE_ALLOC_INF_FMT("new_ptr=%p", (char*)ret);
if (ret && collect_memory_statistics) {
*(size_t *) ret = new_size;
MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_REALLOC_COUNT, 1, STAT_MEM_REALLOC_AMOUNT, new_size);
}
- DBG_RETURN(FAKE_PTR(ret));
+ TRACE_ALLOC_RETURN(FAKE_PTR(ret));
}
/* }}} */
@@ -502,19 +512,20 @@ void _mysqlnd_free(void *ptr MYSQLND_MEM_D)
{
size_t free_amount = 0;
zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
- DBG_ENTER(mysqlnd_free_name);
+ TRACE_ALLOC_ENTER(mysqlnd_free_name);
+
#if PHP_DEBUG
{
- char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR);
- DBG_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno);
+ char * fn = strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR);
+ TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_orig_filename, __zend_orig_lineno);
}
#endif
- DBG_INF_FMT("ptr=%p", ptr);
+ TRACE_ALLOC_INF_FMT("ptr=%p", ptr);
if (ptr) {
if (collect_memory_statistics) {
free_amount = *(size_t *)(((char*)ptr) - sizeof(size_t));
- DBG_INF_FMT("ptr=%p size=%u", ((char*)ptr) - sizeof(size_t), (unsigned int) free_amount);
+ TRACE_ALLOC_INF_FMT("ptr=%p size=%u", ((char*)ptr) - sizeof(size_t), (unsigned int) free_amount);
}
free(REAL_PTR(ptr));
}
@@ -522,7 +533,7 @@ void _mysqlnd_free(void *ptr MYSQLND_MEM_D)
if (collect_memory_statistics) {
MYSQLND_INC_GLOBAL_STATISTIC_W_VALUE2(STAT_MEM_FREE_COUNT, 1, STAT_MEM_FREE_AMOUNT, free_amount);
}
- DBG_VOID_RETURN;
+ TRACE_ALLOC_VOID_RETURN;
}
/* }}} */
@@ -536,16 +547,17 @@ char * _mysqlnd_pestrndup(const char * const ptr, size_t length, zend_bool persi
{
char * ret;
zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
- DBG_ENTER(mysqlnd_pestrndup_name);
+ TRACE_ALLOC_ENTER(mysqlnd_pestrndup_name);
+
#if PHP_DEBUG
{
- char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR);
- DBG_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno);
+ char * fn = strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR);
+ TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_orig_filename, __zend_orig_lineno);
}
#endif
- DBG_INF_FMT("ptr=%p", ptr);
+ TRACE_ALLOC_INF_FMT("ptr=%p", ptr);
- ret = pemalloc(REAL_SIZE(length) + 1, persistent);
+ ret = (persistent) ? __zend_malloc(REAL_SIZE(length + 1)) : _emalloc(REAL_SIZE(length + 1) ZEND_FILE_LINE_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
{
size_t l = length;
char * p = (char *) ptr;
@@ -561,7 +573,7 @@ char * _mysqlnd_pestrndup(const char * const ptr, size_t length, zend_bool persi
MYSQLND_INC_GLOBAL_STATISTIC(persistent? STAT_MEM_STRNDUP_COUNT : STAT_MEM_ESTRNDUP_COUNT);
}
- DBG_RETURN(FAKE_PTR(ret));
+ TRACE_ALLOC_RETURN(FAKE_PTR(ret));
}
/* }}} */
@@ -573,19 +585,19 @@ char * _mysqlnd_pestrdup(const char * const ptr, zend_bool persistent MYSQLND_ME
smart_str tmp_str = {0, 0, 0};
const char * p = ptr;
zend_bool collect_memory_statistics = MYSQLND_G(collect_memory_statistics);
- DBG_ENTER(mysqlnd_pestrdup_name);
+ TRACE_ALLOC_ENTER(mysqlnd_pestrdup_name);
#if PHP_DEBUG
{
- char * fn = strrchr(__zend_filename, PHP_DIR_SEPARATOR);
- DBG_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_filename, __zend_lineno);
+ char * fn = strrchr(__zend_orig_filename, PHP_DIR_SEPARATOR);
+ TRACE_ALLOC_INF_FMT("file=%-15s line=%4d", fn? fn + 1:__zend_orig_filename, __zend_orig_lineno);
}
#endif
- DBG_INF_FMT("ptr=%p", ptr);
+ TRACE_ALLOC_INF_FMT("ptr=%p", ptr);
do {
smart_str_appendc(&tmp_str, *p);
} while (*p++);
- ret = pemalloc(tmp_str.len + sizeof(size_t), persistent);
+ ret = (persistent) ? __zend_malloc(tmp_str.len + sizeof(size_t)) : _emalloc(REAL_SIZE(tmp_str.len + sizeof(size_t)) ZEND_FILE_LINE_CC ZEND_FILE_LINE_ORIG_RELAY_CC);
memcpy(FAKE_PTR(ret), tmp_str.c, tmp_str.len);
if (ret && collect_memory_statistics) {
@@ -594,7 +606,7 @@ char * _mysqlnd_pestrdup(const char * const ptr, zend_bool persistent MYSQLND_ME
}
smart_str_free(&tmp_str);
- DBG_RETURN(FAKE_PTR(ret));
+ TRACE_ALLOC_RETURN(FAKE_PTR(ret));
}
/* }}} */
@@ -619,7 +631,7 @@ PHPAPI void _mysqlnd_sprintf_free(char * p)
}
/* }}} */
-
+/* {{{ _mysqlnd_vsprintf */
PHPAPI int _mysqlnd_vsprintf(char ** pbuf, size_t max_len, const char * format, va_list ap)
{
return vspprintf(pbuf, max_len, format, ap);
diff --git a/ext/mysqlnd/mysqlnd_alloc.h b/ext/mysqlnd/mysqlnd_alloc.h
index f567314358..eef5988829 100644
--- a/ext/mysqlnd/mysqlnd_alloc.h
+++ b/ext/mysqlnd/mysqlnd_alloc.h
@@ -26,8 +26,8 @@
PHPAPI extern const char * mysqlnd_debug_std_no_trace_funcs[];
-#define MYSQLND_MEM_D TSRMLS_DC ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC
-#define MYSQLND_MEM_C TSRMLS_CC ZEND_FILE_LINE_CC ZEND_FILE_LINE_EMPTY_CC
+#define MYSQLND_MEM_D TSRMLS_DC ZEND_FILE_LINE_ORIG_DC
+#define MYSQLND_MEM_C TSRMLS_CC ZEND_FILE_LINE_CC
struct st_mysqlnd_allocator_methods
{
diff --git a/ext/mysqlnd/mysqlnd_auth.c b/ext/mysqlnd/mysqlnd_auth.c
index 5efc5d345e..7f554dcb7b 100644
--- a/ext/mysqlnd/mysqlnd_auth.c
+++ b/ext/mysqlnd/mysqlnd_auth.c
@@ -28,7 +28,6 @@
#include "mysqlnd_charset.h"
#include "mysqlnd_debug.h"
-
/* {{{ mysqlnd_auth_handshake */
enum_func_status
mysqlnd_auth_handshake(MYSQLND_CONN_DATA * conn,
@@ -88,11 +87,7 @@ mysqlnd_auth_handshake(MYSQLND_CONN_DATA * conn,
if (options->charset_name && (charset = mysqlnd_find_charset_name(options->charset_name))) {
auth_packet->charset_no = charset->nr;
} else {
-#if MYSQLND_UNICODE
- auth_packet->charset_no = 200;/* utf8 - swedish collation, check mysqlnd_charset.c */
-#else
auth_packet->charset_no = server_charset_no;
-#endif
}
auth_packet->send_auth_data = TRUE;
@@ -103,6 +98,10 @@ mysqlnd_auth_handshake(MYSQLND_CONN_DATA * conn,
auth_packet->auth_data = auth_plugin_data;
auth_packet->auth_data_len = auth_plugin_data_len;
auth_packet->auth_plugin_name = auth_protocol;
+
+ if (conn->server_capabilities & CLIENT_CONNECT_ATTRS) {
+ auth_packet->connect_attr = conn->options->connect_attr;
+ }
if (!PACKET_WRITE(auth_packet, conn)) {
goto end;
@@ -360,7 +359,9 @@ mysqlnd_native_auth_get_auth_data(struct st_mysqlnd_authentication_plugin * self
size_t * auth_data_len,
MYSQLND_CONN_DATA * conn, const char * const user, const char * const passwd,
const size_t passwd_len, zend_uchar * auth_plugin_data, size_t auth_plugin_data_len,
- const MYSQLND_OPTIONS * const options, unsigned long mysql_flags
+ const MYSQLND_OPTIONS * const options,
+ const MYSQLND_NET_OPTIONS * const net_options,
+ unsigned long mysql_flags
TSRMLS_DC)
{
zend_uchar * ret = NULL;
@@ -418,7 +419,9 @@ mysqlnd_pam_auth_get_auth_data(struct st_mysqlnd_authentication_plugin * self,
size_t * auth_data_len,
MYSQLND_CONN_DATA * conn, const char * const user, const char * const passwd,
const size_t passwd_len, zend_uchar * auth_plugin_data, size_t auth_plugin_data_len,
- const MYSQLND_OPTIONS * const options, unsigned long mysql_flags
+ const MYSQLND_OPTIONS * const options,
+ const MYSQLND_NET_OPTIONS * const net_options,
+ unsigned long mysql_flags
TSRMLS_DC)
{
zend_uchar * ret = NULL;
@@ -442,7 +445,7 @@ static struct st_mysqlnd_authentication_plugin mysqlnd_pam_authentication_plugin
MYSQLND_VERSION_ID,
MYSQLND_VERSION,
"PHP License 3.01",
- "Andrey Hristov <andrey@mysql.com>, Ulf Wendel <uwendel@mysql.com>, Georg Richter <georg@mysql.com>",
+ "Andrey Hristov <andrey@php.net>, Ulf Wendel <uw@php.net>, Georg Richter <georg@php.net>",
{
NULL, /* no statistics , will be filled later if there are some */
NULL, /* no statistics */
@@ -457,12 +460,202 @@ static struct st_mysqlnd_authentication_plugin mysqlnd_pam_authentication_plugin
};
+/******************************************* SHA256 Password ***********************************/
+#ifdef MYSQLND_HAVE_SSL
+static void
+mysqlnd_xor_string(char * dst, const size_t dst_len, const char * xor_str, const size_t xor_str_len)
+{
+ unsigned int i;
+ for (i = 0; i <= dst_len; ++i) {
+ dst[i] ^= xor_str[i % xor_str_len];
+ }
+}
+
+
+#include <openssl/rsa.h>
+#include <openssl/pem.h>
+#include <openssl/err.h>
+
+
+/* {{{ mysqlnd_sha256_get_rsa_key */
+static RSA *
+mysqlnd_sha256_get_rsa_key(MYSQLND_CONN_DATA * conn,
+ const MYSQLND_OPTIONS * const options,
+ const MYSQLND_NET_OPTIONS * const net_options
+ TSRMLS_DC)
+{
+ RSA * ret = NULL;
+ int len;
+ const char * fname = (net_options->sha256_server_public_key && net_options->sha256_server_public_key[0] != '\0')?
+ net_options->sha256_server_public_key:
+ MYSQLND_G(sha256_server_public_key);
+ php_stream * stream;
+ DBG_ENTER("mysqlnd_sha256_get_rsa_key");
+ DBG_INF_FMT("options_s256_pk=[%s] MYSQLND_G(sha256_server_public_key)=[%s]",
+ net_options->sha256_server_public_key? net_options->sha256_server_public_key:"n/a",
+ MYSQLND_G(sha256_server_public_key)? MYSQLND_G(sha256_server_public_key):"n/a");
+ if (!fname || fname[0] == '\0') {
+ MYSQLND_PACKET_SHA256_PK_REQUEST * pk_req_packet = NULL;
+ MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE * pk_resp_packet = NULL;
+
+ do {
+ DBG_INF("requesting the public key from the server");
+ pk_req_packet = conn->protocol->m.get_sha256_pk_request_packet(conn->protocol, FALSE TSRMLS_CC);
+ if (!pk_req_packet) {
+ SET_OOM_ERROR(*conn->error_info);
+ break;
+ }
+ pk_resp_packet = conn->protocol->m.get_sha256_pk_request_response_packet(conn->protocol, FALSE TSRMLS_CC);
+ if (!pk_resp_packet) {
+ SET_OOM_ERROR(*conn->error_info);
+ PACKET_FREE(pk_req_packet);
+ break;
+ }
+
+ if (! PACKET_WRITE(pk_req_packet, conn)) {
+ DBG_ERR_FMT("Error while sending public key request packet");
+ php_error(E_WARNING, "Error while sending public key request packet. PID=%d", getpid());
+ CONN_SET_STATE(conn, CONN_QUIT_SENT);
+ break;
+ }
+ if (FAIL == PACKET_READ(pk_resp_packet, conn) || NULL == pk_resp_packet->public_key) {
+ DBG_ERR_FMT("Error while receiving public key");
+ php_error(E_WARNING, "Error while receiving public key. PID=%d", getpid());
+ CONN_SET_STATE(conn, CONN_QUIT_SENT);
+ break;
+ }
+ DBG_INF_FMT("Public key(%d):\n%s", pk_resp_packet->public_key_len, pk_resp_packet->public_key);
+ /* now extract the public key */
+ {
+ BIO * bio = BIO_new_mem_buf(pk_resp_packet->public_key, pk_resp_packet->public_key_len);
+ ret = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL);
+ BIO_free(bio);
+ }
+ } while (0);
+ PACKET_FREE(pk_req_packet);
+ PACKET_FREE(pk_resp_packet);
+
+ DBG_INF_FMT("ret=%p", ret);
+ DBG_RETURN(ret);
+
+ SET_CLIENT_ERROR(*conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE,
+ "sha256_server_public_key is not set for the connection or as mysqlnd.sha256_server_public_key");
+ DBG_ERR("server_public_key is not set");
+ DBG_RETURN(NULL);
+ } else {
+ char * key_str = NULL;
+ DBG_INF_FMT("Key in a file. [%s]", fname);
+ stream = php_stream_open_wrapper((char *) fname, "rb", REPORT_ERRORS, NULL);
+
+ if (stream) {
+ if ((len = php_stream_copy_to_mem(stream, &key_str, PHP_STREAM_COPY_ALL, 0)) >= 0 ) {
+ BIO * bio = BIO_new_mem_buf(key_str, len);
+ ret = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL);
+ BIO_free(bio);
+ DBG_INF("Successfully loaded");
+ }
+ if (key_str) {
+ DBG_INF_FMT("Public key:%*.s", len, key_str);
+ efree(key_str);
+ }
+ php_stream_free(stream, PHP_STREAM_FREE_CLOSE);
+ }
+ }
+ DBG_RETURN(ret);
+}
+/* }}} */
+
+
+/* {{{ mysqlnd_sha256_auth_get_auth_data */
+static zend_uchar *
+mysqlnd_sha256_auth_get_auth_data(struct st_mysqlnd_authentication_plugin * self,
+ size_t * auth_data_len,
+ MYSQLND_CONN_DATA * conn, const char * const user, const char * const passwd,
+ const size_t passwd_len, zend_uchar * auth_plugin_data, size_t auth_plugin_data_len,
+ const MYSQLND_OPTIONS * const options,
+ const MYSQLND_NET_OPTIONS * const net_options,
+ unsigned long mysql_flags
+ TSRMLS_DC)
+{
+ RSA * server_public_key;
+ zend_uchar * ret = NULL;
+ DBG_ENTER("mysqlnd_sha256_auth_get_auth_data");
+ DBG_INF_FMT("salt(%d)=[%.*s]", auth_plugin_data_len, auth_plugin_data_len, auth_plugin_data);
+
+
+ if (conn->net->data->ssl) {
+ DBG_INF("simple clear text under SSL");
+ /* clear text under SSL */
+ *auth_data_len = passwd_len;
+ ret = malloc(passwd_len);
+ memcpy(ret, passwd, passwd_len);
+ } else {
+ *auth_data_len = 0;
+ server_public_key = mysqlnd_sha256_get_rsa_key(conn, options, net_options TSRMLS_CC);
+
+ if (server_public_key) {
+ int server_public_key_len;
+ char xor_str[passwd_len + 1];
+ memcpy(xor_str, passwd, passwd_len);
+ xor_str[passwd_len] = '\0';
+ mysqlnd_xor_string(xor_str, passwd_len, (char *) auth_plugin_data, auth_plugin_data_len);
+
+ server_public_key_len = RSA_size(server_public_key);
+ /*
+ Because RSA_PKCS1_OAEP_PADDING is used there is a restriction on the passwd_len.
+ RSA_PKCS1_OAEP_PADDING is recommended for new applications. See more here:
+ http://www.openssl.org/docs/crypto/RSA_public_encrypt.html
+ */
+ if ((size_t) server_public_key_len - 41 <= passwd_len) {
+ /* password message is to long */
+ SET_CLIENT_ERROR(*conn->error_info, CR_UNKNOWN_ERROR, UNKNOWN_SQLSTATE, "password is too long");
+ DBG_ERR("password is too long");
+ DBG_RETURN(NULL);
+ }
+
+ *auth_data_len = server_public_key_len;
+ ret = malloc(*auth_data_len);
+ RSA_public_encrypt(passwd_len + 1, (zend_uchar *) xor_str, ret, server_public_key, RSA_PKCS1_OAEP_PADDING);
+ }
+ }
+
+ DBG_RETURN(ret);
+}
+/* }}} */
+
+
+static struct st_mysqlnd_authentication_plugin mysqlnd_sha256_authentication_plugin =
+{
+ {
+ MYSQLND_PLUGIN_API_VERSION,
+ "auth_plugin_sha256_password",
+ MYSQLND_VERSION_ID,
+ MYSQLND_VERSION,
+ "PHP License 3.01",
+ "Andrey Hristov <andrey@mysql.com>, Ulf Wendel <uwendel@mysql.com>",
+ {
+ NULL, /* no statistics , will be filled later if there are some */
+ NULL, /* no statistics */
+ },
+ {
+ NULL /* plugin shutdown */
+ }
+ },
+ {/* methods */
+ mysqlnd_sha256_auth_get_auth_data
+ }
+};
+#endif
+
/* {{{ mysqlnd_register_builtin_authentication_plugins */
void
mysqlnd_register_builtin_authentication_plugins(TSRMLS_D)
{
mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_native_auth_plugin TSRMLS_CC);
mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_pam_authentication_plugin TSRMLS_CC);
+#ifdef MYSQLND_HAVE_SSL
+ mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_sha256_authentication_plugin TSRMLS_CC);
+#endif
}
/* }}} */
diff --git a/ext/mysqlnd/mysqlnd_bt.c b/ext/mysqlnd/mysqlnd_bt.c
index 8fa7bb316d..a93af6b395 100644
--- a/ext/mysqlnd/mysqlnd_bt.c
+++ b/ext/mysqlnd/mysqlnd_bt.c
@@ -25,252 +25,6 @@
/* Follows code borrowed from zend_builtin_functions.c because the functions there are static */
-#if MYSQLND_UNICODE
-/* {{{ gettraceasstring() macros */
-#define TRACE_APPEND_CHR(chr) \
- *str = (char*)erealloc(*str, *len + 1 + 1); \
- (*str)[(*len)++] = chr
-
-#define TRACE_APPEND_STRL(val, vallen) \
- { \
- int l = vallen; \
- *str = (char*)erealloc(*str, *len + l + 1); \
- memcpy((*str) + *len, val, l); \
- *len += l; \
- }
-
-#define TRACE_APPEND_USTRL(val, vallen) \
- { \
- zval tmp, copy; \
- int use_copy; \
- ZVAL_UNICODEL(&tmp, val, vallen, 1); \
- zend_make_printable_zval(&tmp, &copy, &use_copy); \
- TRACE_APPEND_STRL(Z_STRVAL(copy), Z_STRLEN(copy)); \
- zval_dtor(&copy); \
- zval_dtor(&tmp); \
- }
-
-#define TRACE_APPEND_ZVAL(zv) \
- if (Z_TYPE_P((zv)) == IS_UNICODE) { \
- zval copy; \
- int use_copy; \
- zend_make_printable_zval((zv), &copy, &use_copy); \
- TRACE_APPEND_STRL(Z_STRVAL(copy), Z_STRLEN(copy)); \
- zval_dtor(&copy); \
- } else { \
- TRACE_APPEND_STRL(Z_STRVAL_P((zv)), Z_STRLEN_P((zv))); \
- }
-
-#define TRACE_APPEND_STR(val) \
- TRACE_APPEND_STRL(val, sizeof(val)-1)
-
-#define TRACE_APPEND_KEY(key) \
- if (zend_ascii_hash_find(ht, key, sizeof(key), (void**)&tmp) == SUCCESS) { \
- if (Z_TYPE_PP(tmp) == IS_UNICODE) { \
- zval copy; \
- int use_copy; \
- zend_make_printable_zval(*tmp, &copy, &use_copy); \
- TRACE_APPEND_STRL(Z_STRVAL(copy), Z_STRLEN(copy)); \
- zval_dtor(&copy); \
- } else { \
- TRACE_APPEND_STRL(Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp)); \
- } \
- }
-/* }}} */
-
-
-/* {{{ mysqlnd_build_trace_args */
-static int mysqlnd_build_trace_args(zval **arg TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key)
-{
- char **str;
- int *len;
-
- str = va_arg(args, char**);
- len = va_arg(args, int*);
-
- /* the trivial way would be to do:
- * conver_to_string_ex(arg);
- * append it and kill the now tmp arg.
- * but that could cause some E_NOTICE and also damn long lines.
- */
-
- switch (Z_TYPE_PP(arg)) {
- case IS_NULL:
- TRACE_APPEND_STR("NULL, ");
- break;
- case IS_STRING: {
- int l_added;
- TRACE_APPEND_CHR('\'');
- if (Z_STRLEN_PP(arg) > 15) {
- TRACE_APPEND_STRL(Z_STRVAL_PP(arg), 15);
- TRACE_APPEND_STR("...', ");
- l_added = 15 + 6 + 1; /* +1 because of while (--l_added) */
- } else {
- l_added = Z_STRLEN_PP(arg);
- TRACE_APPEND_STRL(Z_STRVAL_PP(arg), l_added);
- TRACE_APPEND_STR("', ");
- l_added += 3 + 1;
- }
- while (--l_added) {
- if ((unsigned char)(*str)[*len - l_added] < 32) {
- (*str)[*len - l_added] = '?';
- }
- }
- break;
- }
- case IS_UNICODE: {
- int l_added;
-
- /*
- * We do not want to apply current error mode here, since
- * zend_make_printable_zval() uses output encoding converter.
- * Temporarily set output encoding converter to escape offending
- * chars with \uXXXX notation.
- */
- zend_set_converter_error_mode(ZEND_U_CONVERTER(UG(output_encoding_conv)), ZEND_FROM_UNICODE, ZEND_CONV_ERROR_ESCAPE_JAVA);
- TRACE_APPEND_CHR('\'');
- if (Z_USTRLEN_PP(arg) > 15) {
- TRACE_APPEND_USTRL(Z_USTRVAL_PP(arg), 15);
- TRACE_APPEND_STR("...', ");
- l_added = 15 + 6 + 1; /* +1 because of while (--l_added) */
- } else {
- l_added = Z_USTRLEN_PP(arg);
- TRACE_APPEND_USTRL(Z_USTRVAL_PP(arg), l_added);
- TRACE_APPEND_STR("', ");
- l_added += 3 + 1;
- }
- /*
- * Reset output encoding converter error mode.
- */
- zend_set_converter_error_mode(ZEND_U_CONVERTER(UG(output_encoding_conv)), ZEND_FROM_UNICODE, UG(from_error_mode));
- while (--l_added) {
- if ((unsigned char)(*str)[*len - l_added] < 32) {
- (*str)[*len - l_added] = '?';
- }
- }
- break;
- }
- case IS_BOOL:
- if (Z_LVAL_PP(arg)) {
- TRACE_APPEND_STR("true, ");
- } else {
- TRACE_APPEND_STR("false, ");
- }
- break;
- case IS_RESOURCE:
- TRACE_APPEND_STR("Resource id #");
- /* break; */
- case IS_LONG: {
- long lval = Z_LVAL_PP(arg);
- char s_tmp[MAX_LENGTH_OF_LONG + 1];
- int l_tmp = zend_sprintf(s_tmp, "%ld", lval); /* SAFE */
- TRACE_APPEND_STRL(s_tmp, l_tmp);
- TRACE_APPEND_STR(", ");
- break;
- }
- case IS_DOUBLE: {
- double dval = Z_DVAL_PP(arg);
- char *s_tmp;
- int l_tmp;
-
- s_tmp = emalloc(MAX_LENGTH_OF_DOUBLE + EG(precision) + 1);
- l_tmp = zend_sprintf(s_tmp, "%.*G", (int) EG(precision), dval); /* SAFE */
- TRACE_APPEND_STRL(s_tmp, l_tmp);
- /* %G already handles removing trailing zeros from the fractional part, yay */
- efree(s_tmp);
- TRACE_APPEND_STR(", ");
- break;
- }
- case IS_ARRAY:
- TRACE_APPEND_STR("Array, ");
- break;
- case IS_OBJECT: {
- zval tmp;
- zstr class_name;
- zend_uint class_name_len;
- int dup;
-
- TRACE_APPEND_STR("Object(");
-
- dup = zend_get_object_classname(*arg, &class_name, &class_name_len TSRMLS_CC);
-
- ZVAL_UNICODEL(&tmp, class_name.u, class_name_len, 1);
- convert_to_string_with_converter(&tmp, ZEND_U_CONVERTER(UG(output_encoding_conv)));
- TRACE_APPEND_STRL(Z_STRVAL(tmp), Z_STRLEN(tmp));
- zval_dtor(&tmp);
-
- if(!dup) {
- efree(class_name.v);
- }
-
- TRACE_APPEND_STR("), ");
- break;
- }
- default:
- break;
- }
- return ZEND_HASH_APPLY_KEEP;
-}
-/* }}} */
-
-
-static int mysqlnd_build_trace_string(zval **frame TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
-{
- char *s_tmp, **str;
- int *len, *num;
- long line;
- HashTable *ht = Z_ARRVAL_PP(frame);
- zval **file, **tmp;
- uint * level;
-
- level = va_arg(args, uint *);
- str = va_arg(args, char**);
- len = va_arg(args, int*);
- num = va_arg(args, int*);
-
- if (!*level) {
- return ZEND_HASH_APPLY_KEEP;
- }
- --*level;
-
- s_tmp = emalloc(1 + MAX_LENGTH_OF_LONG + 1 + 1);
- sprintf(s_tmp, "#%d ", (*num)++);
- TRACE_APPEND_STRL(s_tmp, strlen(s_tmp));
- efree(s_tmp);
- if (zend_ascii_hash_find(ht, "file", sizeof("file"), (void**)&file) == SUCCESS) {
- if (zend_ascii_hash_find(ht, "line", sizeof("line"), (void**)&tmp) == SUCCESS) {
- line = Z_LVAL_PP(tmp);
- } else {
- line = 0;
- }
- TRACE_APPEND_ZVAL(*file);
- s_tmp = emalloc(MAX_LENGTH_OF_LONG + 2 + 1);
- sprintf(s_tmp, "(%ld): ", line);
- TRACE_APPEND_STRL(s_tmp, strlen(s_tmp));
- efree(s_tmp);
- } else {
- TRACE_APPEND_STR("[internal function]: ");
- }
- TRACE_APPEND_KEY("class");
- TRACE_APPEND_KEY("type");
- TRACE_APPEND_KEY("function");
- TRACE_APPEND_CHR('(');
- if (zend_ascii_hash_find(ht, "args", sizeof("args"), (void**)&tmp) == SUCCESS) {
- int last_len = *len;
- zend_hash_apply_with_arguments(Z_ARRVAL_PP(tmp) TSRMLS_CC, (apply_func_args_t)mysqlnd_build_trace_args, 2, str, len);
- if (last_len != *len) {
- *len -= 2; /* remove last ', ' */
- }
- }
- TRACE_APPEND_STR(")\n");
- return ZEND_HASH_APPLY_KEEP;
-}
-/* }}} */
-
-
-#else /* PHP 5*/
-
-
/* {{{ gettraceasstring() macros */
#define TRACE_APPEND_CHR(chr) \
*str = (char*)erealloc(*str, *len + 1 + 1); \
@@ -295,7 +49,8 @@ static int mysqlnd_build_trace_string(zval **frame TSRMLS_DC, int num_args, va_l
/* }}} */
-static int mysqlnd_build_trace_args(zval **arg TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
+static int
+mysqlnd_build_trace_args(zval **arg TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
{
char **str;
int *len;
@@ -391,7 +146,8 @@ static int mysqlnd_build_trace_args(zval **arg TSRMLS_DC, int num_args, va_list
}
/* }}} */
-static int mysqlnd_build_trace_string(zval **frame TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
+static int
+mysqlnd_build_trace_string(zval **frame TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
{
char *s_tmp, **str;
int *len, *num;
@@ -442,10 +198,10 @@ static int mysqlnd_build_trace_string(zval **frame TSRMLS_DC, int num_args, va_l
return ZEND_HASH_APPLY_KEEP;
}
/* }}} */
-#endif
-PHPAPI char * mysqlnd_get_backtrace(uint max_levels, size_t * length TSRMLS_DC)
+PHPAPI char *
+mysqlnd_get_backtrace(uint max_levels, size_t * length TSRMLS_DC)
{
zval *trace;
char *res = estrdup(""), **str = &res, *s_tmp;
diff --git a/ext/mysqlnd/mysqlnd_charset.c b/ext/mysqlnd/mysqlnd_charset.c
index cb4ae3266a..c2f2b8890e 100644
--- a/ext/mysqlnd/mysqlnd_charset.c
+++ b/ext/mysqlnd/mysqlnd_charset.c
@@ -445,12 +445,12 @@ mysqlnd_mbcharlen_utf32(unsigned int utf32 __attribute((unused)))
const MYSQLND_CHARSET mysqlnd_charsets[] =
{
{ 1, "big5","big5_chinese_ci", 1, 2, "", mysqlnd_mbcharlen_big5, check_mb_big5},
- { 3, "dec8", "dec8_swedisch_ci", 1, 1, "", NULL, NULL},
+ { 3, "dec8", "dec8_swedish_ci", 1, 1, "", NULL, NULL},
{ 4, "cp850", "cp850_general_ci", 1, 1, "", NULL, NULL},
{ 6, "hp8", "hp8_english_ci", 1, 1, "", NULL, NULL},
{ 7, "koi8r", "koi8r_general_ci", 1, 1, "", NULL, NULL},
{ 8, "latin1", "latin1_swedish_ci", 1, 1, "", NULL, NULL},
- { 5, "latin1", "latin1_german_ci", 1, 1, "", NULL, NULL}, /* should be after 0x9 because swedish_ci is the default collation */
+ { 5, "latin1", "latin1_german1_ci", 1, 1, "", NULL, NULL}, /* should be after 0x8 because swedish_ci is the default collation */
{ 9, "latin2", "latin2_general_ci", 1, 1, "", NULL, NULL},
{ 2, "latin2", "latin2_czech_cs", 1, 1, "", NULL, NULL}, /* should be after 0x9 because general_ci is the default collation */
{ 10, "swe7", "swe7_swedish_ci", 1, 1, "", NULL, NULL},
@@ -485,7 +485,7 @@ const MYSQLND_CHARSET mysqlnd_charsets[] =
{ 59, "cp1257", "cp1257_general_ci", 1, 1, "", NULL, NULL},
{ 63, "binary", "binary", 1, 1, "", NULL, NULL},
{ 97, "eucjpms", "eucjpms_japanese_ci", 1, 3, "", mysqlnd_mbcharlen_eucjpms, check_mb_eucjpms},
- { 29, "cp1257", "cp1257_lithunian_ci", 1, 1, "", NULL, NULL},
+ { 29, "cp1257", "cp1257_lithuanian_ci", 1, 1, "", NULL, NULL},
{ 31, "latin1", "latin1_german2_ci", 1, 1, "", NULL, NULL},
{ 34, "cp1250", "cp1250_czech_cs", 1, 1, "", NULL, NULL},
{ 42, "latin7", "latin7_general_cs", 1, 1, "", NULL, NULL},
@@ -506,19 +506,17 @@ const MYSQLND_CHARSET mysqlnd_charsets[] =
{ 55, "utf16", "utf16_bin", 2, 4, "UTF-16 Unicode", mysqlnd_mbcharlen_utf16, check_mb_utf16},
{ 56, "utf16le", "utf16le_general_ci", 2, 4, "UTF-16LE Unicode", mysqlnd_mbcharlen_utf16, check_mb_utf16},
{ 58, "cp1257", "cp1257_bin", 1, 1, "", NULL, NULL},
-#ifdef USED_TO_BE_SO_BEFORE_MYSQL_5_5
- { 60, "armascii8", "armascii8_bin", 1, 1, "", NULL, NULL},
-#endif
/*55*/{ 60, "utf32", "utf32_general_ci", 4, 4, "UTF-32 Unicode", mysqlnd_mbcharlen_utf32, check_mb_utf32},
/*55*/{ 61, "utf32", "utf32_bin", 4, 4, "UTF-32 Unicode", mysqlnd_mbcharlen_utf32, check_mb_utf32},
{ 62, "utf16le", "utf16le_bin", 2, 4, "UTF-16LE Unicode", mysqlnd_mbcharlen_utf16, check_mb_utf16},
+ { 64, "armscii8", "armscii8_bin", 1, 1, "", NULL, NULL},
{ 65, "ascii", "ascii_bin", 1, 1, "", NULL, NULL},
{ 66, "cp1250", "cp1250_bin", 1, 1, "", NULL, NULL},
{ 67, "cp1256", "cp1256_bin", 1, 1, "", NULL, NULL},
{ 68, "cp866", "cp866_bin", 1, 1, "", NULL, NULL},
{ 69, "dec8", "dec8_bin", 1, 1, "", NULL, NULL},
{ 70, "greek", "greek_bin", 1, 1, "", NULL, NULL},
- { 71, "hebew", "hebrew_bin", 1, 1, "", NULL, NULL},
+ { 71, "hebrew", "hebrew_bin", 1, 1, "", NULL, NULL},
{ 72, "hp8", "hp8_bin", 1, 1, "", NULL, NULL},
{ 73, "keybcs2", "keybcs2_bin", 1, 1, "", NULL, NULL},
{ 74, "koi8r", "koi8r_bin", 1, 1, "", NULL, NULL},
@@ -558,7 +556,7 @@ const MYSQLND_CHARSET mysqlnd_charsets[] =
{ 137, "ucs2", "ucs2_turkish_ci", 2, 2, "", mysqlnd_mbcharlen_ucs2, check_mb_ucs2},
{ 138, "ucs2", "ucs2_czech_ci", 2, 2, "", mysqlnd_mbcharlen_ucs2, check_mb_ucs2},
{ 139, "ucs2", "ucs2_danish_ci", 2, 2, "", mysqlnd_mbcharlen_ucs2, check_mb_ucs2},
- { 140, "ucs2", "ucs2_lithunian_ci", 2, 2, "", mysqlnd_mbcharlen_ucs2, check_mb_ucs2},
+ { 140, "ucs2", "ucs2_lithuanian_ci", 2, 2, "", mysqlnd_mbcharlen_ucs2, check_mb_ucs2},
{ 141, "ucs2", "ucs2_slovak_ci", 2, 2, "", mysqlnd_mbcharlen_ucs2, check_mb_ucs2},
{ 142, "ucs2", "ucs2_spanish2_ci", 2, 2, "", mysqlnd_mbcharlen_ucs2, check_mb_ucs2},
{ 143, "ucs2", "ucs2_roman_ci", 2, 2, "", mysqlnd_mbcharlen_ucs2, check_mb_ucs2},
@@ -596,7 +594,7 @@ const MYSQLND_CHARSET mysqlnd_charsets[] =
/*56*/{182, "utf32", "utf32_unicode_520_ci", 4, 4, "UTF-32 Unicode", mysqlnd_mbcharlen_utf32, check_mb_utf32},
/*56*/{183, "utf32", "utf32_vietnamese_ci", 4, 4, "UTF-32 Unicode", mysqlnd_mbcharlen_utf32, check_mb_utf32},
- { 192, UTF8_MB3, UTF8_MB3"_general_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
+ { 192, UTF8_MB3, UTF8_MB3"_unicode_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
{ 193, UTF8_MB3, UTF8_MB3"_icelandic_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
{ 194, UTF8_MB3, UTF8_MB3"_latvian_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
{ 195, UTF8_MB3, UTF8_MB3"_romanian_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
@@ -608,7 +606,7 @@ const MYSQLND_CHARSET mysqlnd_charsets[] =
{ 201, UTF8_MB3, UTF8_MB3"_turkish_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
{ 202, UTF8_MB3, UTF8_MB3"_czech_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
{ 203, UTF8_MB3, UTF8_MB3"_danish_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3, check_mb_utf8mb3_valid },
- { 204, UTF8_MB3, UTF8_MB3"_lithunian_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3, check_mb_utf8mb3_valid },
+ { 204, UTF8_MB3, UTF8_MB3"_lithuanian_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3, check_mb_utf8mb3_valid },
{ 205, UTF8_MB3, UTF8_MB3"_slovak_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
{ 206, UTF8_MB3, UTF8_MB3"_spanish2_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
{ 207, UTF8_MB3, UTF8_MB3"_roman_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
@@ -616,7 +614,7 @@ const MYSQLND_CHARSET mysqlnd_charsets[] =
{ 209, UTF8_MB3, UTF8_MB3"_esperanto_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
{ 210, UTF8_MB3, UTF8_MB3"_hungarian_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
{ 211, UTF8_MB3, UTF8_MB3"_sinhala_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
- { 211, UTF8_MB3, UTF8_MB3"_german2_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
+ { 212, UTF8_MB3, UTF8_MB3"_german2_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
{ 213, UTF8_MB3, UTF8_MB3"_croatian_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
{ 214, UTF8_MB3, UTF8_MB3"_unicode_520_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
{ 215, UTF8_MB3, UTF8_MB3"_vietnamese_ci", 1, 3, "", mysqlnd_mbcharlen_utf8mb3, check_mb_utf8mb3_valid},
diff --git a/ext/mysqlnd/mysqlnd_debug.c b/ext/mysqlnd/mysqlnd_debug.c
index fe459a1b38..9fbcc4768f 100644
--- a/ext/mysqlnd/mysqlnd_debug.c
+++ b/ext/mysqlnd/mysqlnd_debug.c
@@ -747,21 +747,26 @@ mysqlnd_debug_init(const char * skip_functions[] TSRMLS_DC)
PHPAPI void _mysqlnd_debug(const char * mode TSRMLS_DC)
{
#if PHP_DEBUG
- MYSQLND_DEBUG *dbg = MYSQLND_G(dbg);
+ MYSQLND_DEBUG * dbg = MYSQLND_G(dbg);
if (!dbg) {
- MYSQLND_G(dbg) = dbg = mysqlnd_debug_init(mysqlnd_debug_std_no_trace_funcs TSRMLS_CC);
- if (!dbg) {
- return;
+ struct st_mysqlnd_plugin_trace_log * trace_log_plugin = mysqlnd_plugin_find("debug_trace");
+ if (trace_log_plugin) {
+ dbg = trace_log_plugin->methods.trace_instance_init(mysqlnd_debug_std_no_trace_funcs TSRMLS_CC);
+ if (!dbg) {
+ return;
+ }
+ MYSQLND_G(dbg) = dbg;
}
}
-
- dbg->m->close(dbg);
- dbg->m->set_mode(dbg, mode);
- while (zend_stack_count(&dbg->call_stack)) {
- zend_stack_del_top(&dbg->call_stack);
- }
- while (zend_stack_count(&dbg->call_time_stack)) {
- zend_stack_del_top(&dbg->call_time_stack);
+ if (dbg) {
+ dbg->m->close(dbg);
+ dbg->m->set_mode(dbg, mode);
+ while (zend_stack_count(&dbg->call_stack)) {
+ zend_stack_del_top(&dbg->call_stack);
+ }
+ while (zend_stack_count(&dbg->call_time_stack)) {
+ zend_stack_del_top(&dbg->call_time_stack);
+ }
}
#endif
}
diff --git a/ext/mysqlnd/mysqlnd_debug.h b/ext/mysqlnd/mysqlnd_debug.h
index 0db5ef9fe7..861851378b 100644
--- a/ext/mysqlnd/mysqlnd_debug.h
+++ b/ext/mysqlnd/mysqlnd_debug.h
@@ -96,52 +96,72 @@ PHPAPI char * mysqlnd_get_backtrace(uint max_levels, size_t * length TSRMLS_DC);
#define DBG_PROFILE_END_TIME(duration)
#endif
-#define DBG_INF_EX(dbg_obj, msg) do { if (dbg_skip_trace == FALSE) (dbg_obj)->m->log((dbg_obj), __LINE__, __FILE__, -1, "info : ", (msg)); } while (0)
-#define DBG_ERR_EX(dbg_obj, msg) do { if (dbg_skip_trace == FALSE) (dbg_obj)->m->log((dbg_obj), __LINE__, __FILE__, -1, "error: ", (msg)); } while (0)
-#define DBG_INF_FMT_EX(dbg_obj, ...) do { if (dbg_skip_trace == FALSE) (dbg_obj)->m->log_va((dbg_obj), __LINE__, __FILE__, -1, "info : ", __VA_ARGS__); } while (0)
-#define DBG_ERR_FMT_EX(dbg_obj, ...) do { if (dbg_skip_trace == FALSE) (dbg_obj)->m->log_va((dbg_obj), __LINE__, __FILE__, -1, "error: ", __VA_ARGS__); } while (0)
+#define DBG_INF_EX(dbg_obj, msg) do { if (dbg_skip_trace == FALSE && (dbg_obj)) (dbg_obj)->m->log((dbg_obj), __LINE__, __FILE__, -1, "info : ", (msg)); } while (0)
+#define DBG_ERR_EX(dbg_obj, msg) do { if (dbg_skip_trace == FALSE && (dbg_obj)) (dbg_obj)->m->log((dbg_obj), __LINE__, __FILE__, -1, "error: ", (msg)); } while (0)
+#define DBG_INF_FMT_EX(dbg_obj, ...) do { if (dbg_skip_trace == FALSE && (dbg_obj)) (dbg_obj)->m->log_va((dbg_obj), __LINE__, __FILE__, -1, "info : ", __VA_ARGS__); } while (0)
+#define DBG_ERR_FMT_EX(dbg_obj, ...) do { if (dbg_skip_trace == FALSE && (dbg_obj)) (dbg_obj)->m->log_va((dbg_obj), __LINE__, __FILE__, -1, "error: ", __VA_ARGS__); } while (0)
-#define DBG_BLOCK_ENTER_EX(dbg_obj, block_name) \
+#define DBG_BLOCK_ENTER_EX(dbg_obj, block_name) DBG_BLOCK_ENTER_EX2((dbg_obj), (MYSQLND_DEBUG *) NULL, (block_name))
+#define DBG_BLOCK_LEAVE_EX(dbg_obj) DBG_BLOCK_LEAVE_EX2((dbg_obj), (MYSQLND_DEBUG *) NULL)
+
+#define DBG_BLOCK_ENTER_EX2(dbg_obj1, dbg_obj2, block_name) \
{ \
- DBG_ENTER_EX(dbg_obj, (block_name));
+ DBG_ENTER_EX2((dbg_obj1), (dbg_obj2), (block_name));
-#define DBG_BLOCK_LEAVE_EX(dbg_obj) \
- DBG_LEAVE_EX((dbg_obj), ;) \
+#define DBG_BLOCK_LEAVE_EX2(dbg_obj1, dbg_obj2) \
+ DBG_LEAVE_EX2((dbg_obj1), (dbg_obj2), ;) \
} \
-#define DBG_ENTER_EX(dbg_obj, func_name) \
+#define DBG_ENTER_EX(dbg_obj, func_name) DBG_ENTER_EX2((dbg_obj), (MYSQLND_DEBUG *) NULL, (func_name))
+#define DBG_LEAVE_EX(dbg_obj, leave) DBG_LEAVE_EX2((dbg_obj), (MYSQLND_DEBUG *) NULL, leave)
+
+#define DBG_ENTER_EX2(dbg_obj1, dbg_obj2, func_name) \
struct timeval __dbg_prof_tp = {0}; \
uint64_t __dbg_prof_start = 0; /* initialization is needed */ \
zend_bool dbg_skip_trace = TRUE; \
- if ((dbg_obj)) { \
- dbg_skip_trace = !(dbg_obj)->m->func_enter((dbg_obj), __LINE__, __FILE__, func_name, strlen(func_name)); \
+ if ((dbg_obj1)) { \
+ dbg_skip_trace = !(dbg_obj1)->m->func_enter((dbg_obj1), __LINE__, __FILE__, func_name, strlen(func_name)); \
} \
+ if ((dbg_obj2)) { \
+ dbg_skip_trace |= !(dbg_obj2)->m->func_enter((dbg_obj2), __LINE__, __FILE__, func_name, strlen(func_name)); \
+ } \
+ if (dbg_skip_trace); /* shut compiler's mouth */\
do { \
- if ((dbg_obj) && (dbg_obj)->flags & MYSQLND_DEBUG_PROFILE_CALLS) { \
+ if (((dbg_obj1) && (dbg_obj1)->flags & MYSQLND_DEBUG_PROFILE_CALLS) || \
+ ((dbg_obj2) && (dbg_obj2)->flags & MYSQLND_DEBUG_PROFILE_CALLS)) \
+ { \
DBG_PROFILE_START_TIME(); \
} \
} while (0);
-#define DBG_LEAVE_EX(dbg_obj, leave) \
+#define DBG_LEAVE_EX2(dbg_obj1, dbg_obj2, leave) \
do {\
- if ((dbg_obj)) { \
- uint64_t this_call_duration = 0; \
- if ((dbg_obj)->flags & MYSQLND_DEBUG_PROFILE_CALLS) { \
- DBG_PROFILE_END_TIME(this_call_duration); \
- } \
- (dbg_obj)->m->func_leave((dbg_obj), __LINE__, __FILE__, this_call_duration); \
+ uint64_t this_call_duration = 0; \
+ if (((dbg_obj1) && (dbg_obj1)->flags & MYSQLND_DEBUG_PROFILE_CALLS) || \
+ ((dbg_obj2) && (dbg_obj2)->flags & MYSQLND_DEBUG_PROFILE_CALLS)) \
+ { \
+ DBG_PROFILE_END_TIME(this_call_duration); \
+ } \
+ if ((dbg_obj1)) { \
+ (dbg_obj1)->m->func_leave((dbg_obj1), __LINE__, __FILE__, this_call_duration); \
+ } \
+ if ((dbg_obj2)) { \
+ (dbg_obj2)->m->func_leave((dbg_obj2), __LINE__, __FILE__, this_call_duration); \
} \
leave \
} while (0);
-#define DBG_RETURN_EX(dbg_obj, value) DBG_LEAVE_EX(dbg_obj, return (value);)
-#define DBG_VOID_RETURN_EX(dbg_obj) DBG_LEAVE_EX(dbg_obj, return;)
+#define DBG_RETURN_EX(dbg_obj, value) DBG_LEAVE_EX((dbg_obj), return (value);)
+#define DBG_VOID_RETURN_EX(dbg_obj) DBG_LEAVE_EX((dbg_obj), return;)
+#define DBG_RETURN_EX2(dbg_obj1, dbg_obj2, value) DBG_LEAVE_EX2((dbg_obj1), (dbg_obj2), return (value);)
+#define DBG_VOID_RETURN_EX2(dbg_obj1, dbg_obj2) DBG_LEAVE_EX2((dbg_obj1), (dbg_obj2), return;)
-#else
+
+#else /* defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER >= 1400)) */
static inline void DBG_INF_EX(MYSQLND_DEBUG * dbg_obj, const char * const msg) {}
static inline void DBG_ERR_EX(MYSQLND_DEBUG * dbg_obj, const char * const msg) {}
static inline void DBG_INF_FMT_EX(MYSQLND_DEBUG * dbg_obj, ...) {}
@@ -167,6 +187,18 @@ static inline void DBG_ENTER_EX(MYSQLND_DEBUG * dbg_obj, const char * const func
#define DBG_VOID_RETURN DBG_VOID_RETURN_EX(MYSQLND_G(dbg))
#define DBG_BLOCK_LEAVE DBG_BLOCK_LEAVE_EX(MYSQLND_G(dbg))
+
+#define TRACE_ALLOC_INF(msg) DBG_INF_EX(MYSQLND_G(trace_alloc), (msg))
+#define TRACE_ALLOC_ERR(msg) DBG_ERR_EX(MYSQLND_G(trace_alloc), (msg))
+#define TRACE_ALLOC_INF_FMT(...) DBG_INF_FMT_EX(MYSQLND_G(trace_alloc), __VA_ARGS__)
+#define TRACE_ALLOC_ERR_FMT(...) DBG_ERR_FMT_EX(MYSQLND_G(trace_alloc), __VA_ARGS__)
+
+#define TRACE_ALLOC_ENTER(func_name) DBG_ENTER_EX2(MYSQLND_G(dbg), MYSQLND_G(trace_alloc), (func_name))
+#define TRACE_ALLOC_BLOCK_ENTER(bname) DBG_BLOCK_ENTER_EX2(MYSQLND_G(dbg), MYSQLND_G(trace_alloc), (bname))
+#define TRACE_ALLOC_RETURN(value) DBG_RETURN_EX2(MYSQLND_G(dbg), MYSQLND_G(trace_alloc), (value))
+#define TRACE_ALLOC_VOID_RETURN DBG_VOID_RETURN_EX2(MYSQLND_G(dbg), MYSQLND_G(trace_alloc))
+#define TRACE_ALLOC_BLOCK_LEAVE DBG_BLOCK_LEAVE_EX2(MYSQLND_G(dbg), MYSQLND_G(trace_alloc))
+
#elif MYSQLND_DBG_ENABLED == 0
static inline void DBG_INF(const char * const msg) {}
@@ -175,10 +207,21 @@ static inline void DBG_INF_FMT(const char * const format, ...) {}
static inline void DBG_ERR_FMT(const char * const format, ...) {}
static inline void DBG_ENTER(const char * const func_name) {}
#define DBG_BLOCK_ENTER(bname) {
-#define DBG_RETURN(value) return (value)
-#define DBG_VOID_RETURN return
+#define DBG_RETURN(value) return (value)
+#define DBG_VOID_RETURN return
#define DBG_BLOCK_LEAVE }
+
+static inline void TRACE_ALLOC_INF(const char * const msg) {}
+static inline void TRACE_ALLOC_ERR(const char * const msg) {}
+static inline void TRACE_ALLOC_INF_FMT(const char * const format, ...) {}
+static inline void TRACE_ALLOC_ERR_FMT(const char * const format, ...) {}
+static inline void TRACE_ALLOC_ENTER(const char * const func_name) {}
+#define TRACE_ALLOC_BLOCK_ENTER(bname) {
+#define TRACE_ALLOC_RETURN(value) return (value)
+#define TRACE_ALLOC_VOID_RETURN return
+#define TRACE_ALLOC_BLOCK_LEAVE }
+
#endif
#endif /* MYSQLND_DEBUG_H */
diff --git a/ext/mysqlnd/mysqlnd_driver.c b/ext/mysqlnd/mysqlnd_driver.c
index cfe5316e87..98826b9ce3 100644
--- a/ext/mysqlnd/mysqlnd_driver.c
+++ b/ext/mysqlnd/mysqlnd_driver.c
@@ -81,7 +81,9 @@ PHPAPI void mysqlnd_library_init(TSRMLS_D)
mysqlnd_plugin_core.plugin_header.plugin_stats.values = mysqlnd_global_stats;
mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_plugin_core TSRMLS_CC);
}
+#if defined(MYSQLND_DBG_ENABLED) && MYSQLND_DBG_ENABLED == 1
mysqlnd_example_plugin_register(TSRMLS_C);
+#endif
mysqlnd_debug_trace_plugin_register(TSRMLS_C);
mysqlnd_register_builtin_authentication_plugins(TSRMLS_C);
@@ -91,6 +93,7 @@ PHPAPI void mysqlnd_library_init(TSRMLS_D)
/* }}} */
+
/* {{{ mysqlnd_error_list_pdtor */
static void
mysqlnd_error_list_pdtor(void * pDest)
@@ -250,17 +253,29 @@ MYSQLND_METHOD(mysqlnd_object_factory, get_prepared_statement)(MYSQLND_CONN_DATA
PHPAPI MYSQLND_NET *
MYSQLND_METHOD(mysqlnd_object_factory, get_io_channel)(zend_bool persistent, MYSQLND_STATS * stats, MYSQLND_ERROR_INFO * error_info TSRMLS_DC)
{
- size_t alloc_size = sizeof(MYSQLND_NET) + mysqlnd_plugin_count() * sizeof(void *);
- MYSQLND_NET * net = mnd_pecalloc(1, alloc_size, persistent);
+ size_t net_alloc_size = sizeof(MYSQLND_NET) + mysqlnd_plugin_count() * sizeof(void *);
+ size_t net_data_alloc_size = sizeof(MYSQLND_NET_DATA) + mysqlnd_plugin_count() * sizeof(void *);
+ MYSQLND_NET * net = mnd_pecalloc(1, net_alloc_size, persistent);
+ MYSQLND_NET_DATA * net_data = mnd_pecalloc(1, net_data_alloc_size, persistent);
DBG_ENTER("mysqlnd_object_factory::get_io_channel");
DBG_INF_FMT("persistent=%u", persistent);
- if (net) {
- net->persistent = persistent;
- net->m = *mysqlnd_net_get_methods();
+ if (net && net_data) {
+ net->data = net_data;
+ net->persistent = net->data->persistent = persistent;
+ net->data->m = *mysqlnd_net_get_methods();
- if (PASS != net->m.init(net, stats, error_info TSRMLS_CC)) {
- net->m.dtor(net, stats, error_info TSRMLS_CC);
+ if (PASS != net->data->m.init(net, stats, error_info TSRMLS_CC)) {
+ net->data->m.dtor(net, stats, error_info TSRMLS_CC);
+ net = NULL;
+ }
+ } else {
+ if (net_data) {
+ mnd_pefree(net_data, persistent);
+ net_data = NULL;
+ }
+ if (net) {
+ mnd_pefree(net, persistent);
net = NULL;
}
}
@@ -270,7 +285,7 @@ MYSQLND_METHOD(mysqlnd_object_factory, get_io_channel)(zend_bool persistent, MYS
/* {{{ mysqlnd_object_factory::get_protocol_decoder */
-PHPAPI MYSQLND_PROTOCOL *
+static MYSQLND_PROTOCOL *
MYSQLND_METHOD(mysqlnd_object_factory, get_protocol_decoder)(zend_bool persistent TSRMLS_DC)
{
size_t alloc_size = sizeof(MYSQLND_PROTOCOL) + mysqlnd_plugin_count() * sizeof(void *);
@@ -288,7 +303,7 @@ MYSQLND_METHOD(mysqlnd_object_factory, get_protocol_decoder)(zend_bool persisten
/* }}} */
-MYSQLND_CLASS_METHODS_START(mysqlnd_object_factory)
+PHPAPI MYSQLND_CLASS_METHODS_START(mysqlnd_object_factory)
MYSQLND_METHOD(mysqlnd_object_factory, get_connection),
MYSQLND_METHOD(mysqlnd_object_factory, clone_connection_object),
MYSQLND_METHOD(mysqlnd_object_factory, get_prepared_statement),
diff --git a/ext/mysqlnd/mysqlnd_enum_n_def.h b/ext/mysqlnd/mysqlnd_enum_n_def.h
index aea7f2e427..13e8c20a15 100644
--- a/ext/mysqlnd/mysqlnd_enum_n_def.h
+++ b/ext/mysqlnd/mysqlnd_enum_n_def.h
@@ -37,6 +37,8 @@
#define MYSQLND_ASSEMBLED_PACKET_MAX_SIZE 3UL*1024UL*1024UL*1024UL
+#define MYSQLND_DEFAULT_AUTH_PROTOCOL "mysql_native_password"
+
#define MYSQLND_ERRMSG_SIZE 512
#define MYSQLND_SQLSTATE_LENGTH 5
#define MYSQLND_SQLSTATE_NULL "00000"
@@ -106,6 +108,18 @@
#define MYSQLND_NET_FLAG_USE_COMPRESSION 1
+
+#define TRANS_START_NO_OPT 0
+#define TRANS_START_WITH_CONSISTENT_SNAPSHOT 1
+#define TRANS_START_READ_WRITE 2
+#define TRANS_START_READ_ONLY 4
+
+#define TRANS_COR_NO_OPT 0
+#define TRANS_COR_AND_CHAIN 1
+#define TRANS_COR_AND_NO_CHAIN 2
+#define TRANS_COR_RELEASE 4
+#define TRANS_COR_NO_RELEASE 8
+
typedef enum mysqlnd_extension
{
MYSQLND_MYSQL = 0,
@@ -166,12 +180,13 @@ typedef enum mysqlnd_option
MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
MYSQL_PLUGIN_DIR,
MYSQL_DEFAULT_AUTH,
+ MYSQL_OPT_CONNECT_ATTR_RESET,
+ MYSQL_OPT_CONNECT_ATTR_ADD,
+ MYSQL_OPT_CONNECT_ATTR_DELETE,
MYSQL_SERVER_PUBLIC_KEY,
MYSQL_ENABLE_CLEARTEXT_PLUGIN,
MYSQL_OPT_CAN_HANDLE_EXPIRED_PASSWORDS,
-#if MYSQLND_UNICODE
- MYSQLND_OPT_NUMERIC_AND_DATETIME_AS_UNICODE = 200,
-#endif
+ MYSQLND_DEPRECATED_ENUM1 = 200,
#ifdef MYSQLND_STRING_TO_INT_CONVERSION
MYSQLND_OPT_INT_AND_FLOAT_NATIVE = 201,
#endif
@@ -540,6 +555,8 @@ enum mysqlnd_packet_type
PROT_STATS_PACKET,
PROT_PREPARE_RESP_PACKET,
PROT_CHG_USER_RESP_PACKET,
+ PROT_SHA256_PK_REQUEST_PACKET,
+ PROT_SHA256_PK_REQUEST_RESPONSE_PACKET,
PROT_LAST /* should always be last */
};
diff --git a/ext/mysqlnd/mysqlnd_ext_plugin.c b/ext/mysqlnd/mysqlnd_ext_plugin.c
index acc9970d0d..f40688b272 100644
--- a/ext/mysqlnd/mysqlnd_ext_plugin.c
+++ b/ext/mysqlnd/mysqlnd_ext_plugin.c
@@ -215,7 +215,6 @@ mysqlnd_net_set_methods(struct st_mysqlnd_net_methods * methods)
/* }}} */
-
/*
* Local variables:
* tab-width: 4
diff --git a/ext/mysqlnd/mysqlnd_libmysql_compat.h b/ext/mysqlnd/mysqlnd_libmysql_compat.h
index 28edecd24c..b8ff959d18 100644
--- a/ext/mysqlnd/mysqlnd_libmysql_compat.h
+++ b/ext/mysqlnd/mysqlnd_libmysql_compat.h
@@ -44,7 +44,7 @@
#define mysql_change_user(r,a,b,c) mysqlnd_change_user((r), (a), (b), (c), FALSE)
#define mysql_character_set_name(c) mysqlnd_character_set_name((c))
#define mysql_close(r) mysqlnd_close((r), MYSQLND_CLOSE_EXPLICIT)
-#define mysql_commit(r) mysqlnd_commit((r))
+#define mysql_commit(r) mysqlnd_commit((r), TRANS_COR_NO_OPT, NULL)
#define mysql_data_seek(r,o) mysqlnd_data_seek((r),(o))
#define mysql_debug(x) mysqlnd_debug((x))
#define mysql_dump_debug_info(r) mysqlnd_dump_debug_info((r))
@@ -74,7 +74,7 @@
#define mysql_real_escape_string(r,a,b,c) mysqlnd_real_escape_string((r), (a), (b), (c))
#define mysql_real_query(r,a,b) mysqlnd_query((r), (a), (b))
#define mysql_refresh(conn, options) mysqlnd_refresh((conn), (options))
-#define mysql_rollback(r) mysqlnd_rollback((r))
+#define mysql_rollback(r) mysqlnd_rollback((r), TRANS_COR_NO_OPT, NULL)
#define mysql_select_db(r,a) mysqlnd_select_db((r), (a) ,strlen((a)))
#define mysql_set_server_option(r,o) mysqlnd_set_server_option((r), (o))
#define mysql_set_character_set(r,a) mysqlnd_set_character_set((r), (a))
@@ -106,7 +106,8 @@
#define mysql_stmt_more_results(s) mysqlnd_stmt_more_results((s))
#define mysql_thread_safe() mysqlnd_thread_safe()
#define mysql_info(r) mysqlnd_info((r))
-#define mysql_options(r,a,b) mysqlnd_options((r), (a), (b))
+#define mysql_options(c,a,v) mysqlnd_options((c), (a), (v))
+#define mysql_options4(c,a,k,v) mysqlnd_options4((c), (a), (k), (v))
#define mysql_stmt_init(r) mysqlnd_stmt_init((r))
#define mysql_free_result(r) mysqlnd_free_result((r), FALSE)
#define mysql_store_result(r) mysqlnd_store_result((r))
diff --git a/ext/mysqlnd/mysqlnd_loaddata.c b/ext/mysqlnd/mysqlnd_loaddata.c
index 9f128e17e1..94d69a4008 100644
--- a/ext/mysqlnd/mysqlnd_loaddata.c
+++ b/ext/mysqlnd/mysqlnd_loaddata.c
@@ -172,7 +172,7 @@ mysqlnd_handle_local_infile(MYSQLND_CONN_DATA * conn, const char * filename, zen
if (!(conn->options->flags & CLIENT_LOCAL_FILES)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "LOAD DATA LOCAL INFILE forbidden");
/* write empty packet to server */
- ret = net->m.send_ex(net, empty_packet, 0, conn->stats, conn->error_info TSRMLS_CC);
+ ret = net->data->m.send_ex(net, empty_packet, 0, conn->stats, conn->error_info TSRMLS_CC);
*is_warning = TRUE;
goto infile_error;
}
@@ -192,13 +192,13 @@ mysqlnd_handle_local_infile(MYSQLND_CONN_DATA * conn, const char * filename, zen
tmp_error_no = infile.local_infile_error(info, tmp_buf, sizeof(tmp_buf) TSRMLS_CC);
SET_CLIENT_ERROR(*conn->error_info, tmp_error_no, UNKNOWN_SQLSTATE, tmp_buf);
/* write empty packet to server */
- ret = net->m.send_ex(net, empty_packet, 0, conn->stats, conn->error_info TSRMLS_CC);
+ ret = net->data->m.send_ex(net, empty_packet, 0, conn->stats, conn->error_info TSRMLS_CC);
goto infile_error;
}
/* read data */
while ((bufsize = infile.local_infile_read (info, buf + MYSQLND_HEADER_SIZE, buflen - MYSQLND_HEADER_SIZE TSRMLS_CC)) > 0) {
- if ((ret = net->m.send_ex(net, buf, bufsize, conn->stats, conn->error_info TSRMLS_CC)) == 0) {
+ if ((ret = net->data->m.send_ex(net, buf, bufsize, conn->stats, conn->error_info TSRMLS_CC)) == 0) {
DBG_ERR_FMT("Error during read : %d %s %s", CR_SERVER_LOST, UNKNOWN_SQLSTATE, lost_conn);
SET_CLIENT_ERROR(*conn->error_info, CR_SERVER_LOST, UNKNOWN_SQLSTATE, lost_conn);
goto infile_error;
@@ -206,7 +206,7 @@ mysqlnd_handle_local_infile(MYSQLND_CONN_DATA * conn, const char * filename, zen
}
/* send empty packet for eof */
- if ((ret = net->m.send_ex(net, empty_packet, 0, conn->stats, conn->error_info TSRMLS_CC)) == 0) {
+ if ((ret = net->data->m.send_ex(net, empty_packet, 0, conn->stats, conn->error_info TSRMLS_CC)) == 0) {
SET_CLIENT_ERROR(*conn->error_info, CR_SERVER_LOST, UNKNOWN_SQLSTATE, lost_conn);
goto infile_error;
}
diff --git a/ext/mysqlnd/mysqlnd_net.c b/ext/mysqlnd/mysqlnd_net.c
index f7de43746b..fadcbd87f6 100644
--- a/ext/mysqlnd/mysqlnd_net.c
+++ b/ext/mysqlnd/mysqlnd_net.c
@@ -67,16 +67,17 @@ MYSQLND_METHOD(mysqlnd_net, network_read_ex)(MYSQLND_NET * const net, zend_uchar
MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info TSRMLS_DC)
{
enum_func_status return_value = PASS;
+ php_stream * net_stream = net->data->m.get_stream(net TSRMLS_CC);
+ size_t old_chunk_size = net_stream->chunk_size;
size_t to_read = count, ret;
- size_t old_chunk_size = net->stream->chunk_size;
zend_uchar * p = buffer;
DBG_ENTER("mysqlnd_net::network_read_ex");
DBG_INF_FMT("count="MYSQLND_SZ_T_SPEC, count);
- net->stream->chunk_size = MIN(to_read, net->options.net_read_buffer_size);
+ net_stream->chunk_size = MIN(to_read, net->data->options.net_read_buffer_size);
while (to_read) {
- if (!(ret = php_stream_read(net->stream, (char *) p, to_read))) {
+ if (!(ret = php_stream_read(net_stream, (char *) p, to_read))) {
DBG_ERR_FMT("Error while reading header from socket");
return_value = FAIL;
break;
@@ -85,7 +86,7 @@ MYSQLND_METHOD(mysqlnd_net, network_read_ex)(MYSQLND_NET * const net, zend_uchar
to_read -= ret;
}
MYSQLND_INC_CONN_STATISTIC_W_VALUE(stats, STAT_BYTES_RECEIVED, count - to_read);
- net->stream->chunk_size = old_chunk_size;
+ net_stream->chunk_size = old_chunk_size;
DBG_RETURN(return_value);
}
/* }}} */
@@ -98,13 +99,13 @@ MYSQLND_METHOD(mysqlnd_net, network_write_ex)(MYSQLND_NET * const net, const zen
{
size_t ret;
DBG_ENTER("mysqlnd_net::network_write_ex");
- ret = php_stream_write(net->stream, (char *)buffer, count);
+ ret = php_stream_write(net->data->m.get_stream(net TSRMLS_CC), (char *)buffer, count);
DBG_RETURN(ret);
}
/* }}} */
/* {{{ mysqlnd_net::open_pipe */
-static enum_func_status
+static php_stream *
MYSQLND_METHOD(mysqlnd_net, open_pipe)(MYSQLND_NET * const net, const char * const scheme, const size_t scheme_len,
const zend_bool persistent,
MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info TSRMLS_DC)
@@ -114,32 +115,35 @@ MYSQLND_METHOD(mysqlnd_net, open_pipe)(MYSQLND_NET * const net, const char * con
#else
unsigned int streams_options = 0;
#endif
+ php_stream * net_stream = NULL;
+
DBG_ENTER("mysqlnd_net::open_pipe");
if (persistent) {
streams_options |= STREAM_OPEN_PERSISTENT;
}
streams_options |= IGNORE_URL;
- net->stream = php_stream_open_wrapper((char*) scheme + sizeof("pipe://") - 1, "r+", streams_options, NULL);
- if (!net->stream) {
+ net_stream = php_stream_open_wrapper((char*) scheme + sizeof("pipe://") - 1, "r+", streams_options, NULL);
+ if (!net_stream) {
SET_CLIENT_ERROR(*error_info, CR_CONNECTION_ERROR, UNKNOWN_SQLSTATE, "Unknown errror while connecting");
- DBG_RETURN(FAIL);
+ DBG_RETURN(NULL);
}
/*
Streams are not meant for C extensions! Thus we need a hack. Every connected stream will
be registered as resource (in EG(regular_list). So far, so good. However, it won't be
unregistered yntil the script ends. So, we need to take care of that.
*/
- net->stream->in_free = 1;
- zend_hash_index_del(&EG(regular_list), net->stream->rsrc_id);
- net->stream->in_free = 0;
+ net_stream->in_free = 1;
+ zend_hash_index_del(&EG(regular_list), net_stream->rsrc_id);
+ net_stream->in_free = 0;
- DBG_RETURN(PASS);
+
+ DBG_RETURN(net_stream);
}
/* }}} */
/* {{{ mysqlnd_net::open_tcp_or_unix */
-static enum_func_status
+static php_stream *
MYSQLND_METHOD(mysqlnd_net, open_tcp_or_unix)(MYSQLND_NET * const net, const char * const scheme, const size_t scheme_len,
const zend_bool persistent,
MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info TSRMLS_DC)
@@ -155,24 +159,27 @@ MYSQLND_METHOD(mysqlnd_net, open_tcp_or_unix)(MYSQLND_NET * const net, const cha
char * errstr = NULL;
int errcode = 0;
struct timeval tv;
+ php_stream * net_stream = NULL;
DBG_ENTER("mysqlnd_net::open_tcp_or_unix");
+ net->data->stream = NULL;
+
if (persistent) {
hashed_details_len = mnd_sprintf(&hashed_details, 0, "%p", net);
DBG_INF_FMT("hashed_details=%s", hashed_details);
}
- if (net->options.timeout_connect) {
- tv.tv_sec = net->options.timeout_connect;
+ if (net->data->options.timeout_connect) {
+ tv.tv_sec = net->data->options.timeout_connect;
tv.tv_usec = 0;
}
DBG_INF_FMT("calling php_stream_xport_create");
- net->stream = php_stream_xport_create(scheme, scheme_len, streams_options, streams_flags,
- hashed_details, (net->options.timeout_connect) ? &tv : NULL,
+ net_stream = php_stream_xport_create(scheme, scheme_len, streams_options, streams_flags,
+ hashed_details, (net->data->options.timeout_connect) ? &tv : NULL,
NULL /*ctx*/, &errstr, &errcode);
- if (errstr || !net->stream) {
+ if (errstr || !net_stream) {
DBG_ERR("Error");
if (hashed_details) {
mnd_sprintf_free(hashed_details);
@@ -183,7 +190,7 @@ MYSQLND_METHOD(mysqlnd_net, open_tcp_or_unix)(MYSQLND_NET * const net, const cha
/* no mnd_ since we don't allocate it */
efree(errstr);
}
- DBG_RETURN(FAIL);
+ DBG_RETURN(NULL);
}
if (hashed_details) {
/*
@@ -199,13 +206,13 @@ MYSQLND_METHOD(mysqlnd_net, open_tcp_or_unix)(MYSQLND_NET * const net, const cha
but STREAMS suck big time regarding persistent streams.
Just not compatible for extensions that need persistency.
*/
- net->stream->in_free = 1;
+ net_stream->in_free = 1;
zend_hash_del(&EG(persistent_list), hashed_details, hashed_details_len + 1);
- net->stream->in_free = 0;
+ net_stream->in_free = 0;
}
#if ZEND_DEBUG
/* Shut-up the streams, they don't know what they are doing */
- net->stream->__exposed = 1;
+ net_stream->__exposed = 1;
#endif
mnd_sprintf_free(hashed_details);
}
@@ -215,33 +222,36 @@ MYSQLND_METHOD(mysqlnd_net, open_tcp_or_unix)(MYSQLND_NET * const net, const cha
be registered as resource (in EG(regular_list). So far, so good. However, it won't be
unregistered yntil the script ends. So, we need to take care of that.
*/
- net->stream->in_free = 1;
- zend_hash_index_del(&EG(regular_list), net->stream->rsrc_id);
- net->stream->in_free = 0;
+ net_stream->in_free = 1;
+ zend_hash_index_del(&EG(regular_list), net_stream->rsrc_id);
+ net_stream->in_free = 0;
- DBG_RETURN(PASS);
+ DBG_RETURN(net_stream);
}
/* }}} */
-/* {{{ mysqlnd_net::connect_ex */
+/* {{{ mysqlnd_net::post_connect_set_opt */
static void
MYSQLND_METHOD(mysqlnd_net, post_connect_set_opt)(MYSQLND_NET * const net,
const char * const scheme, const size_t scheme_len,
MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info TSRMLS_DC)
{
+ php_stream * net_stream = net->data->m.get_stream(net TSRMLS_CC);
DBG_ENTER("mysqlnd_net::post_connect_set_opt");
- if (net->options.timeout_read) {
- struct timeval tv;
- DBG_INF_FMT("setting %u as PHP_STREAM_OPTION_READ_TIMEOUT", net->options.timeout_read);
- tv.tv_sec = net->options.timeout_read;
- tv.tv_usec = 0;
- php_stream_set_option(net->stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &tv);
- }
+ if (net_stream) {
+ if (net->data->options.timeout_read) {
+ struct timeval tv;
+ DBG_INF_FMT("setting %u as PHP_STREAM_OPTION_READ_TIMEOUT", net->data->options.timeout_read);
+ tv.tv_sec = net->data->options.timeout_read;
+ tv.tv_usec = 0;
+ php_stream_set_option(net_stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &tv);
+ }
- if (!memcmp(scheme, "tcp://", sizeof("tcp://") - 1)) {
- /* TCP -> Set TCP_NODELAY */
- mysqlnd_set_sock_no_delay(net->stream TSRMLS_CC);
+ if (!memcmp(scheme, "tcp://", sizeof("tcp://") - 1)) {
+ /* TCP -> Set TCP_NODELAY */
+ mysqlnd_set_sock_no_delay(net_stream TSRMLS_CC);
+ }
}
DBG_VOID_RETURN;
@@ -249,6 +259,31 @@ MYSQLND_METHOD(mysqlnd_net, post_connect_set_opt)(MYSQLND_NET * const net,
/* }}} */
+/* {{{ mysqlnd_net::get_open_stream */
+static func_mysqlnd_net__open_stream
+MYSQLND_METHOD(mysqlnd_net, get_open_stream)(MYSQLND_NET * const net, const char * const scheme, const size_t scheme_len,
+ MYSQLND_ERROR_INFO * const error_info TSRMLS_DC)
+{
+ func_mysqlnd_net__open_stream ret = NULL;
+ DBG_ENTER("mysqlnd_net::get_open_stream");
+ if (scheme_len > (sizeof("pipe://") - 1) && !memcmp(scheme, "pipe://", sizeof("pipe://") - 1)) {
+ ret = net->data->m.open_pipe;
+ } else if ((scheme_len > (sizeof("tcp://") - 1) && !memcmp(scheme, "tcp://", sizeof("tcp://") - 1))
+ ||
+ (scheme_len > (sizeof("unix://") - 1) && !memcmp(scheme, "unix://", sizeof("unix://") - 1)))
+ {
+ ret = net->data->m.open_tcp_or_unix;
+ }
+
+ if (!ret) {
+ SET_CLIENT_ERROR(*error_info, CR_CONNECTION_ERROR, UNKNOWN_SQLSTATE, "No handler for this scheme");
+ }
+
+ DBG_RETURN(ret);
+}
+/* }}} */
+
+
/* {{{ mysqlnd_net::connect_ex */
static enum_func_status
MYSQLND_METHOD(mysqlnd_net, connect_ex)(MYSQLND_NET * const net, const char * const scheme, const size_t scheme_len,
@@ -261,13 +296,16 @@ MYSQLND_METHOD(mysqlnd_net, connect_ex)(MYSQLND_NET * const net, const char * co
net->packet_no = net->compressed_envelope_packet_no = 0;
- net->m.close_stream(net, conn_stats, error_info TSRMLS_CC);
+ net->data->m.close_stream(net, conn_stats, error_info TSRMLS_CC);
- open_stream = (scheme_len > (sizeof("pipe://") - 1) && !memcmp(scheme, "pipe://", sizeof("pipe://") - 1))? net->m.open_pipe:
- net->m.open_tcp_or_unix;
-
- if (PASS == (ret = open_stream(net, scheme, scheme_len, persistent, conn_stats, error_info TSRMLS_CC))) {
- net->m.post_connect_set_opt(net, scheme, scheme_len, conn_stats, error_info TSRMLS_CC);
+ open_stream = net->data->m.get_open_stream(net, scheme, scheme_len, error_info TSRMLS_CC);
+ if (open_stream) {
+ php_stream * net_stream = open_stream(net, scheme, scheme_len, persistent, conn_stats, error_info TSRMLS_CC);
+ if (net_stream) {
+ (void) net->data->m.set_stream(net, net_stream TSRMLS_CC);
+ net->data->m.post_connect_set_opt(net, scheme, scheme_len, conn_stats, error_info TSRMLS_CC);
+ ret = PASS;
+ }
}
DBG_RETURN(ret);
@@ -309,9 +347,9 @@ MYSQLND_METHOD(mysqlnd_net, send_ex)(MYSQLND_NET * const net, zend_uchar * const
size_t to_be_sent;
DBG_ENTER("mysqlnd_net::send_ex");
- DBG_INF_FMT("count=" MYSQLND_SZ_T_SPEC " compression=%u", count, net->compressed);
+ DBG_INF_FMT("count=" MYSQLND_SZ_T_SPEC " compression=%u", count, net->data->compressed);
- if (net->compressed == TRUE) {
+ if (net->data->compressed == TRUE) {
size_t comp_buf_size = MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE + MYSQLND_HEADER_SIZE + MIN(left, MYSQLND_MAX_PACKET_SIZE);
DBG_INF_FMT("compress_buf_size="MYSQLND_SZ_T_SPEC, comp_buf_size);
compress_buf = mnd_emalloc(comp_buf_size);
@@ -320,7 +358,7 @@ MYSQLND_METHOD(mysqlnd_net, send_ex)(MYSQLND_NET * const net, zend_uchar * const
do {
to_be_sent = MIN(left, MYSQLND_MAX_PACKET_SIZE);
#ifdef MYSQLND_COMPRESSION_ENABLED
- if (net->compressed == TRUE) {
+ if (net->data->compressed == TRUE) {
/* here we need to compress the data and then write it, first comes the compressed header */
size_t tmp_complen = to_be_sent;
size_t payload_size;
@@ -329,7 +367,7 @@ MYSQLND_METHOD(mysqlnd_net, send_ex)(MYSQLND_NET * const net, zend_uchar * const
STORE_HEADER_SIZE(safe_storage, uncompressed_payload);
int3store(uncompressed_payload, to_be_sent);
int1store(uncompressed_payload + 3, net->packet_no);
- if (PASS == net->m.encode((compress_buf + COMPRESSED_HEADER_SIZE + MYSQLND_HEADER_SIZE), &tmp_complen,
+ if (PASS == net->data->m.encode((compress_buf + COMPRESSED_HEADER_SIZE + MYSQLND_HEADER_SIZE), &tmp_complen,
uncompressed_payload, to_be_sent + MYSQLND_HEADER_SIZE TSRMLS_CC))
{
int3store(compress_buf + MYSQLND_HEADER_SIZE, to_be_sent + MYSQLND_HEADER_SIZE);
@@ -344,14 +382,14 @@ MYSQLND_METHOD(mysqlnd_net, send_ex)(MYSQLND_NET * const net, zend_uchar * const
int3store(compress_buf, payload_size);
int1store(compress_buf + 3, net->packet_no);
DBG_INF_FMT("writing "MYSQLND_SZ_T_SPEC" bytes to the network", payload_size + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE);
- bytes_sent = net->m.network_write_ex(net, compress_buf, payload_size + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE,
+ bytes_sent = net->data->m.network_write_ex(net, compress_buf, payload_size + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE,
conn_stats, error_info TSRMLS_CC);
net->compressed_envelope_packet_no++;
#if WHEN_WE_NEED_TO_CHECK_WHETHER_COMPRESSION_WORKS_CORRECTLY
if (res == Z_OK) {
size_t decompressed_size = left + MYSQLND_HEADER_SIZE;
zend_uchar * decompressed_data = mnd_malloc(decompressed_size);
- int error = net->m.decode(decompressed_data, decompressed_size,
+ int error = net->data->m.decode(decompressed_data, decompressed_size,
compress_buf + MYSQLND_HEADER_SIZE + COMPRESSED_HEADER_SIZE, payload_size);
if (error == Z_OK) {
int i;
@@ -376,7 +414,7 @@ MYSQLND_METHOD(mysqlnd_net, send_ex)(MYSQLND_NET * const net, zend_uchar * const
STORE_HEADER_SIZE(safe_storage, p);
int3store(p, to_be_sent);
int1store(p + 3, net->packet_no);
- bytes_sent = net->m.network_write_ex(net, p, to_be_sent + MYSQLND_HEADER_SIZE, conn_stats, error_info TSRMLS_CC);
+ bytes_sent = net->data->m.network_write_ex(net, p, to_be_sent + MYSQLND_HEADER_SIZE, conn_stats, error_info TSRMLS_CC);
RESTORE_HEADER_SIZE(p, safe_storage);
net->compressed_envelope_packet_no++;
}
@@ -486,13 +524,13 @@ MYSQLND_METHOD(mysqlnd_net, read_compressed_packet_from_stream_and_fill_read_buf
(MYSQLND_NET * net, size_t net_payload_size, MYSQLND_STATS * conn_stats, MYSQLND_ERROR_INFO * error_info TSRMLS_DC)
{
size_t decompressed_size;
- enum_func_status ret = PASS;
+ enum_func_status retval = PASS;
zend_uchar * compressed_data = NULL;
zend_uchar comp_header[COMPRESSED_HEADER_SIZE];
- DBG_ENTER("mysqlnd_net::read_compressed_packet_from_stream_and_fill_read_buffe");
+ DBG_ENTER("mysqlnd_net::read_compressed_packet_from_stream_and_fill_read_buffer");
/* Read the compressed header */
- if (FAIL == net->m.network_read_ex(net, comp_header, COMPRESSED_HEADER_SIZE, conn_stats, error_info TSRMLS_CC)) {
+ if (FAIL == net->data->m.network_read_ex(net, comp_header, COMPRESSED_HEADER_SIZE, conn_stats, error_info TSRMLS_CC)) {
DBG_RETURN(FAIL);
}
decompressed_size = uint3korr(comp_header);
@@ -502,20 +540,20 @@ MYSQLND_METHOD(mysqlnd_net, read_compressed_packet_from_stream_and_fill_read_buf
if (decompressed_size) {
compressed_data = mnd_emalloc(net_payload_size);
- if (FAIL == net->m.network_read_ex(net, compressed_data, net_payload_size, conn_stats, error_info TSRMLS_CC)) {
- ret = FAIL;
+ if (FAIL == net->data->m.network_read_ex(net, compressed_data, net_payload_size, conn_stats, error_info TSRMLS_CC)) {
+ retval = FAIL;
goto end;
}
net->uncompressed_data = mysqlnd_create_read_buffer(decompressed_size TSRMLS_CC);
- ret = net->m.decode(net->uncompressed_data->data, decompressed_size, compressed_data, net_payload_size TSRMLS_CC);
- if (ret == FAIL) {
+ retval = net->data->m.decode(net->uncompressed_data->data, decompressed_size, compressed_data, net_payload_size TSRMLS_CC);
+ if (FAIL == retval) {
goto end;
}
} else {
DBG_INF_FMT("The server decided not to compress the data. Our job is easy. Copying %u bytes", net_payload_size);
net->uncompressed_data = mysqlnd_create_read_buffer(net_payload_size TSRMLS_CC);
- if (FAIL == net->m.network_read_ex(net, net->uncompressed_data->data, net_payload_size, conn_stats, error_info TSRMLS_CC)) {
- ret = FAIL;
+ if (FAIL == net->data->m.network_read_ex(net, net->uncompressed_data->data, net_payload_size, conn_stats, error_info TSRMLS_CC)) {
+ retval = FAIL;
goto end;
}
}
@@ -523,7 +561,7 @@ end:
if (compressed_data) {
mnd_efree(compressed_data);
}
- DBG_RETURN(ret);
+ DBG_RETURN(retval);
}
/* }}} */
#endif /* MYSQLND_COMPRESSION_ENABLED */
@@ -590,16 +628,16 @@ MYSQLND_METHOD(mysqlnd_net, receive_ex)(MYSQLND_NET * const net, zend_uchar * co
DBG_ENTER("mysqlnd_net::receive_ex");
#ifdef MYSQLND_COMPRESSION_ENABLED
- if (net->compressed) {
+ if (net->data->compressed) {
if (net->uncompressed_data) {
size_t to_read_from_buffer = MIN(net->uncompressed_data->bytes_left(net->uncompressed_data), to_read);
- DBG_INF_FMT("reading %u from uncompressed_data buffer", to_read_from_buffer);
+ DBG_INF_FMT("reading "MYSQLND_SZ_T_SPEC" from uncompressed_data buffer", to_read_from_buffer);
if (to_read_from_buffer) {
net->uncompressed_data->read(net->uncompressed_data, to_read_from_buffer, (zend_uchar *) p);
p += to_read_from_buffer;
to_read -= to_read_from_buffer;
}
- DBG_INF_FMT("left %u to read", to_read);
+ DBG_INF_FMT("left "MYSQLND_SZ_T_SPEC" to read", to_read);
if (TRUE == net->uncompressed_data->is_empty(net->uncompressed_data)) {
/* Everything was consumed. This should never happen here, but for security */
net->uncompressed_data->free_buffer(&net->uncompressed_data TSRMLS_CC);
@@ -610,7 +648,7 @@ MYSQLND_METHOD(mysqlnd_net, receive_ex)(MYSQLND_NET * const net, zend_uchar * co
size_t net_payload_size;
zend_uchar packet_no;
- if (FAIL == net->m.network_read_ex(net, net_header, MYSQLND_HEADER_SIZE, conn_stats, error_info TSRMLS_CC)) {
+ if (FAIL == net->data->m.network_read_ex(net, net_header, MYSQLND_HEADER_SIZE, conn_stats, error_info TSRMLS_CC)) {
DBG_RETURN(FAIL);
}
net_payload_size = uint3korr(net_header);
@@ -628,7 +666,7 @@ MYSQLND_METHOD(mysqlnd_net, receive_ex)(MYSQLND_NET * const net, zend_uchar * co
DBG_INF_FMT("HEADER: hwd_packet_no=%u size=%3u", packet_no, (unsigned long) net_payload_size);
#endif
/* Now let's read from the wire, decompress it and fill the read buffer */
- net->m.read_compressed_packet_from_stream_and_fill_read_buffer(net, net_payload_size, conn_stats, error_info TSRMLS_CC);
+ net->data->m.read_compressed_packet_from_stream_and_fill_read_buffer(net, net_payload_size, conn_stats, error_info TSRMLS_CC);
/*
Now a bit of recursion - read from the read buffer,
@@ -636,12 +674,12 @@ MYSQLND_METHOD(mysqlnd_net, receive_ex)(MYSQLND_NET * const net, zend_uchar * co
is not enough, then the recursive call will try to
satisfy it until it is satisfied.
*/
- DBG_RETURN(net->m.receive_ex(net, p, to_read, conn_stats, error_info TSRMLS_CC));
+ DBG_RETURN(net->data->m.receive_ex(net, p, to_read, conn_stats, error_info TSRMLS_CC));
}
DBG_RETURN(PASS);
}
#endif /* MYSQLND_COMPRESSION_ENABLED */
- DBG_RETURN(net->m.network_read_ex(net, p, to_read, conn_stats, error_info TSRMLS_CC));
+ DBG_RETURN(net->data->m.network_read_ex(net, p, to_read, conn_stats, error_info TSRMLS_CC));
}
/* }}} */
@@ -659,7 +697,7 @@ MYSQLND_METHOD(mysqlnd_net, set_client_option)(MYSQLND_NET * const net, enum mys
DBG_RETURN(FAIL);
}
net->cmd_buffer.length = *(unsigned int*) value;
- DBG_INF_FMT("new_length=%u", net->cmd_buffer.length);
+ DBG_INF_FMT("new_length="MYSQLND_SZ_T_SPEC, net->cmd_buffer.length);
if (!net->cmd_buffer.buffer) {
net->cmd_buffer.buffer = mnd_pemalloc(net->cmd_buffer.length, net->persistent);
} else {
@@ -668,81 +706,90 @@ MYSQLND_METHOD(mysqlnd_net, set_client_option)(MYSQLND_NET * const net, enum mys
break;
case MYSQLND_OPT_NET_READ_BUFFER_SIZE:
DBG_INF("MYSQLND_OPT_NET_READ_BUFFER_SIZE");
- net->options.net_read_buffer_size = *(unsigned int*) value;
- DBG_INF_FMT("new_length=%u", net->options.net_read_buffer_size);
+ net->data->options.net_read_buffer_size = *(unsigned int*) value;
+ DBG_INF_FMT("new_length="MYSQLND_SZ_T_SPEC, net->data->options.net_read_buffer_size);
break;
case MYSQL_OPT_CONNECT_TIMEOUT:
DBG_INF("MYSQL_OPT_CONNECT_TIMEOUT");
- net->options.timeout_connect = *(unsigned int*) value;
+ net->data->options.timeout_connect = *(unsigned int*) value;
break;
case MYSQLND_OPT_SSL_KEY:
{
zend_bool pers = net->persistent;
- if (net->options.ssl_key) {
- mnd_pefree(net->options.ssl_key, pers);
+ if (net->data->options.ssl_key) {
+ mnd_pefree(net->data->options.ssl_key, pers);
}
- net->options.ssl_key = value? mnd_pestrdup(value, pers) : NULL;
+ net->data->options.ssl_key = value? mnd_pestrdup(value, pers) : NULL;
break;
}
case MYSQLND_OPT_SSL_CERT:
{
zend_bool pers = net->persistent;
- if (net->options.ssl_cert) {
- mnd_pefree(net->options.ssl_cert, pers);
+ if (net->data->options.ssl_cert) {
+ mnd_pefree(net->data->options.ssl_cert, pers);
}
- net->options.ssl_cert = value? mnd_pestrdup(value, pers) : NULL;
+ net->data->options.ssl_cert = value? mnd_pestrdup(value, pers) : NULL;
break;
}
case MYSQLND_OPT_SSL_CA:
{
zend_bool pers = net->persistent;
- if (net->options.ssl_ca) {
- mnd_pefree(net->options.ssl_ca, pers);
+ if (net->data->options.ssl_ca) {
+ mnd_pefree(net->data->options.ssl_ca, pers);
}
- net->options.ssl_ca = value? mnd_pestrdup(value, pers) : NULL;
+ net->data->options.ssl_ca = value? mnd_pestrdup(value, pers) : NULL;
break;
}
case MYSQLND_OPT_SSL_CAPATH:
{
zend_bool pers = net->persistent;
- if (net->options.ssl_capath) {
- mnd_pefree(net->options.ssl_capath, pers);
+ if (net->data->options.ssl_capath) {
+ mnd_pefree(net->data->options.ssl_capath, pers);
}
- net->options.ssl_capath = value? mnd_pestrdup(value, pers) : NULL;
+ net->data->options.ssl_capath = value? mnd_pestrdup(value, pers) : NULL;
break;
}
case MYSQLND_OPT_SSL_CIPHER:
{
zend_bool pers = net->persistent;
- if (net->options.ssl_cipher) {
- mnd_pefree(net->options.ssl_cipher, pers);
+ if (net->data->options.ssl_cipher) {
+ mnd_pefree(net->data->options.ssl_cipher, pers);
}
- net->options.ssl_cipher = value? mnd_pestrdup(value, pers) : NULL;
+ net->data->options.ssl_cipher = value? mnd_pestrdup(value, pers) : NULL;
break;
}
case MYSQLND_OPT_SSL_PASSPHRASE:
{
zend_bool pers = net->persistent;
- if (net->options.ssl_passphrase) {
- mnd_pefree(net->options.ssl_passphrase, pers);
+ if (net->data->options.ssl_passphrase) {
+ mnd_pefree(net->data->options.ssl_passphrase, pers);
}
- net->options.ssl_passphrase = value? mnd_pestrdup(value, pers) : NULL;
+ net->data->options.ssl_passphrase = value? mnd_pestrdup(value, pers) : NULL;
break;
}
case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
- net->options.ssl_verify_peer = value? ((*(zend_bool *)value)? TRUE:FALSE): FALSE;
+ net->data->options.ssl_verify_peer = value? ((*(zend_bool *)value)? TRUE:FALSE): FALSE;
break;
case MYSQL_OPT_READ_TIMEOUT:
- net->options.timeout_read = *(unsigned int*) value;
+ net->data->options.timeout_read = *(unsigned int*) value;
break;
#ifdef WHEN_SUPPORTED_BY_MYSQLI
case MYSQL_OPT_WRITE_TIMEOUT:
- net->options.timeout_write = *(unsigned int*) value;
+ net->data->options.timeout_write = *(unsigned int*) value;
break;
#endif
case MYSQL_OPT_COMPRESS:
- net->options.flags |= MYSQLND_NET_FLAG_USE_COMPRESSION;
+ net->data->options.flags |= MYSQLND_NET_FLAG_USE_COMPRESSION;
break;
+ case MYSQL_SERVER_PUBLIC_KEY:
+ {
+ zend_bool pers = net->persistent;
+ if (net->data->options.sha256_server_public_key) {
+ mnd_pefree(net->data->options.sha256_server_public_key, pers);
+ }
+ net->data->options.sha256_server_public_key = value? mnd_pestrdup(value, pers) : NULL;
+ break;
+ }
default:
DBG_RETURN(FAIL);
}
@@ -765,7 +812,8 @@ MYSQLND_METHOD(mysqlnd_net, consume_uneaten_data)(MYSQLND_NET * const net, enum
char tmp_buf[256];
size_t skipped_bytes = 0;
int opt = PHP_STREAM_OPTION_BLOCKING;
- int was_blocked = net->stream->ops->set_option(net->stream, opt, 0, NULL TSRMLS_CC);
+ php_stream * net_stream = net->data->get_stream(net TSRMLS_CC);
+ int was_blocked = net_stream->ops->set_option(net_stream, opt, 0, NULL TSRMLS_CC);
DBG_ENTER("mysqlnd_net::consume_uneaten_data");
@@ -774,11 +822,11 @@ MYSQLND_METHOD(mysqlnd_net, consume_uneaten_data)(MYSQLND_NET * const net, enum
int bytes_consumed;
do {
- skipped_bytes += (bytes_consumed = php_stream_read(net->stream, tmp_buf, sizeof(tmp_buf)));
+ skipped_bytes += (bytes_consumed = php_stream_read(net_stream, tmp_buf, sizeof(tmp_buf)));
} while (bytes_consumed == sizeof(tmp_buf));
if (was_blocked) {
- net->stream->ops->set_option(net->stream, opt, 1, NULL TSRMLS_CC);
+ net_stream->ops->set_option(net_stream, opt, 1, NULL TSRMLS_CC);
}
if (bytes_consumed) {
@@ -806,58 +854,61 @@ static enum_func_status
MYSQLND_METHOD(mysqlnd_net, enable_ssl)(MYSQLND_NET * const net TSRMLS_DC)
{
#ifdef MYSQLND_SSL_SUPPORTED
- php_stream_context *context = php_stream_context_alloc(TSRMLS_C);
+ php_stream_context * context = php_stream_context_alloc(TSRMLS_C);
+ php_stream * net_stream = net->data->m.get_stream(net TSRMLS_CC);
+
DBG_ENTER("mysqlnd_net::enable_ssl");
if (!context) {
DBG_RETURN(FAIL);
}
- if (net->options.ssl_key) {
+ if (net->data->options.ssl_key) {
zval key_zval;
- ZVAL_STRING(&key_zval, net->options.ssl_key, 0);
+ ZVAL_STRING(&key_zval, net->data->options.ssl_key, 0);
php_stream_context_set_option(context, "ssl", "local_pk", &key_zval);
}
- if (net->options.ssl_verify_peer) {
+ if (net->data->options.ssl_verify_peer) {
zval verify_peer_zval;
ZVAL_TRUE(&verify_peer_zval);
php_stream_context_set_option(context, "ssl", "verify_peer", &verify_peer_zval);
}
- if (net->options.ssl_cert) {
+ if (net->data->options.ssl_cert) {
zval cert_zval;
- ZVAL_STRING(&cert_zval, net->options.ssl_cert, 0);
+ ZVAL_STRING(&cert_zval, net->data->options.ssl_cert, 0);
php_stream_context_set_option(context, "ssl", "local_cert", &cert_zval);
- if (!net->options.ssl_key) {
+ if (!net->data->options.ssl_key) {
php_stream_context_set_option(context, "ssl", "local_pk", &cert_zval);
}
}
- if (net->options.ssl_ca) {
+ if (net->data->options.ssl_ca) {
zval cafile_zval;
- ZVAL_STRING(&cafile_zval, net->options.ssl_ca, 0);
+ ZVAL_STRING(&cafile_zval, net->data->options.ssl_ca, 0);
php_stream_context_set_option(context, "ssl", "cafile", &cafile_zval);
}
- if (net->options.ssl_capath) {
+ if (net->data->options.ssl_capath) {
zval capath_zval;
- ZVAL_STRING(&capath_zval, net->options.ssl_capath, 0);
+ ZVAL_STRING(&capath_zval, net->data->options.ssl_capath, 0);
php_stream_context_set_option(context, "ssl", "cafile", &capath_zval);
}
- if (net->options.ssl_passphrase) {
+ if (net->data->options.ssl_passphrase) {
zval passphrase_zval;
- ZVAL_STRING(&passphrase_zval, net->options.ssl_passphrase, 0);
+ ZVAL_STRING(&passphrase_zval, net->data->options.ssl_passphrase, 0);
php_stream_context_set_option(context, "ssl", "passphrase", &passphrase_zval);
}
- if (net->options.ssl_cipher) {
+ if (net->data->options.ssl_cipher) {
zval cipher_zval;
- ZVAL_STRING(&cipher_zval, net->options.ssl_cipher, 0);
+ ZVAL_STRING(&cipher_zval, net->data->options.ssl_cipher, 0);
php_stream_context_set_option(context, "ssl", "ciphers", &cipher_zval);
}
- php_stream_context_set(net->stream, context);
- if (php_stream_xport_crypto_setup(net->stream, STREAM_CRYPTO_METHOD_TLS_CLIENT, NULL TSRMLS_CC) < 0 ||
- php_stream_xport_crypto_enable(net->stream, 1 TSRMLS_CC) < 0)
+ php_stream_context_set(net_stream, context);
+ if (php_stream_xport_crypto_setup(net_stream, STREAM_CRYPTO_METHOD_TLS_CLIENT, NULL TSRMLS_CC) < 0 ||
+ php_stream_xport_crypto_enable(net_stream, 1 TSRMLS_CC) < 0)
{
DBG_ERR("Cannot connect to MySQL by using SSL");
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot connect to MySQL by using SSL");
DBG_RETURN(FAIL);
}
+ net->data->ssl = TRUE;
/*
get rid of the context. we are persistent and if this is a real pconn used by mysql/mysqli,
then the context would not survive cleaning of EG(regular_list), where it is registered, as a
@@ -865,19 +916,20 @@ MYSQLND_METHOD(mysqlnd_net, enable_ssl)(MYSQLND_NET * const net TSRMLS_DC)
of the context, which means usage of already freed memory, bad. Actually we don't need this
context anymore after we have enabled SSL on the connection. Thus it is very simple, we remove it.
*/
- php_stream_context_set(net->stream, NULL);
+ php_stream_context_set(net_stream, NULL);
- if (net->options.timeout_read) {
+ if (net->data->options.timeout_read) {
struct timeval tv;
- DBG_INF_FMT("setting %u as PHP_STREAM_OPTION_READ_TIMEOUT", net->options.timeout_read);
- tv.tv_sec = net->options.timeout_read;
+ DBG_INF_FMT("setting %u as PHP_STREAM_OPTION_READ_TIMEOUT", net->data->options.timeout_read);
+ tv.tv_sec = net->data->options.timeout_read;
tv.tv_usec = 0;
- php_stream_set_option(net->stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &tv);
+ php_stream_set_option(net_stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &tv);
}
DBG_RETURN(PASS);
#else
DBG_ENTER("mysqlnd_net::enable_ssl");
+ DBG_INFO("MYSQLND_SSL_SUPPORTED is not defined");
DBG_RETURN(PASS);
#endif
}
@@ -906,25 +958,29 @@ MYSQLND_METHOD(mysqlnd_net, free_contents)(MYSQLND_NET * net TSRMLS_DC)
net->uncompressed_data->free_buffer(&net->uncompressed_data TSRMLS_CC);
}
#endif
- if (net->options.ssl_key) {
- mnd_pefree(net->options.ssl_key, pers);
- net->options.ssl_key = NULL;
+ if (net->data->options.ssl_key) {
+ mnd_pefree(net->data->options.ssl_key, pers);
+ net->data->options.ssl_key = NULL;
+ }
+ if (net->data->options.ssl_cert) {
+ mnd_pefree(net->data->options.ssl_cert, pers);
+ net->data->options.ssl_cert = NULL;
}
- if (net->options.ssl_cert) {
- mnd_pefree(net->options.ssl_cert, pers);
- net->options.ssl_cert = NULL;
+ if (net->data->options.ssl_ca) {
+ mnd_pefree(net->data->options.ssl_ca, pers);
+ net->data->options.ssl_ca = NULL;
}
- if (net->options.ssl_ca) {
- mnd_pefree(net->options.ssl_ca, pers);
- net->options.ssl_ca = NULL;
+ if (net->data->options.ssl_capath) {
+ mnd_pefree(net->data->options.ssl_capath, pers);
+ net->data->options.ssl_capath = NULL;
}
- if (net->options.ssl_capath) {
- mnd_pefree(net->options.ssl_capath, pers);
- net->options.ssl_capath = NULL;
+ if (net->data->options.ssl_cipher) {
+ mnd_pefree(net->data->options.ssl_cipher, pers);
+ net->data->options.ssl_cipher = NULL;
}
- if (net->options.ssl_cipher) {
- mnd_pefree(net->options.ssl_cipher, pers);
- net->options.ssl_cipher = NULL;
+ if (net->data->options.sha256_server_public_key) {
+ mnd_pefree(net->data->options.sha256_server_public_key, pers);
+ net->data->options.sha256_server_public_key = NULL;
}
DBG_VOID_RETURN;
@@ -936,24 +992,25 @@ MYSQLND_METHOD(mysqlnd_net, free_contents)(MYSQLND_NET * net TSRMLS_DC)
static void
MYSQLND_METHOD(mysqlnd_net, close_stream)(MYSQLND_NET * const net, MYSQLND_STATS * const stats, MYSQLND_ERROR_INFO * const error_info TSRMLS_DC)
{
+ php_stream * net_stream;
DBG_ENTER("mysqlnd_net::close_stream");
- if (net && net->stream) {
+ if (net && (net_stream = net->data->m.get_stream(net TSRMLS_CC))) {
zend_bool pers = net->persistent;
- DBG_INF_FMT("Freeing stream. abstract=%p", net->stream->abstract);
+ DBG_INF_FMT("Freeing stream. abstract=%p", net_stream->abstract);
if (pers) {
if (EG(active)) {
- php_stream_free(net->stream, PHP_STREAM_FREE_CLOSE_PERSISTENT | PHP_STREAM_FREE_RSRC_DTOR);
+ php_stream_free(net_stream, PHP_STREAM_FREE_CLOSE_PERSISTENT | PHP_STREAM_FREE_RSRC_DTOR);
} else {
/*
otherwise we will crash because the EG(persistent_list) has been freed already,
before the modules are shut down
*/
- php_stream_free(net->stream, PHP_STREAM_FREE_CLOSE | PHP_STREAM_FREE_RSRC_DTOR);
+ php_stream_free(net_stream, PHP_STREAM_FREE_CLOSE | PHP_STREAM_FREE_RSRC_DTOR);
}
} else {
- php_stream_free(net->stream, PHP_STREAM_FREE_CLOSE);
+ php_stream_free(net_stream, PHP_STREAM_FREE_CLOSE);
}
- net->stream = NULL;
+ (void) net->data->m.set_stream(net, NULL TSRMLS_CC);
}
DBG_VOID_RETURN;
@@ -969,13 +1026,13 @@ MYSQLND_METHOD(mysqlnd_net, init)(MYSQLND_NET * const net, MYSQLND_STATS * const
DBG_ENTER("mysqlnd_net::init");
buf_size = MYSQLND_G(net_cmd_buffer_size); /* this is long, cast to unsigned int*/
- net->m.set_client_option(net, MYSQLND_OPT_NET_CMD_BUFFER_SIZE, (char *) &buf_size TSRMLS_CC);
+ net->data->m.set_client_option(net, MYSQLND_OPT_NET_CMD_BUFFER_SIZE, (char *) &buf_size TSRMLS_CC);
buf_size = MYSQLND_G(net_read_buffer_size); /* this is long, cast to unsigned int*/
- net->m.set_client_option(net, MYSQLND_OPT_NET_READ_BUFFER_SIZE, (char *)&buf_size TSRMLS_CC);
+ net->data->m.set_client_option(net, MYSQLND_OPT_NET_READ_BUFFER_SIZE, (char *)&buf_size TSRMLS_CC);
buf_size = MYSQLND_G(net_read_timeout); /* this is long, cast to unsigned int*/
- net->m.set_client_option(net, MYSQL_OPT_READ_TIMEOUT, (char *)&buf_size TSRMLS_CC);
+ net->data->m.set_client_option(net, MYSQL_OPT_READ_TIMEOUT, (char *)&buf_size TSRMLS_CC);
DBG_RETURN(PASS);
}
@@ -988,22 +1045,49 @@ MYSQLND_METHOD(mysqlnd_net, dtor)(MYSQLND_NET * const net, MYSQLND_STATS * const
{
DBG_ENTER("mysqlnd_net::dtor");
if (net) {
- zend_bool pers = net->persistent;
-
- net->m.free_contents(net TSRMLS_CC);
- net->m.close_stream(net, stats, error_info TSRMLS_CC);
+ net->data->m.free_contents(net TSRMLS_CC);
+ net->data->m.close_stream(net, stats, error_info TSRMLS_CC);
+
if (net->cmd_buffer.buffer) {
DBG_INF("Freeing cmd buffer");
- mnd_pefree(net->cmd_buffer.buffer, pers);
+ mnd_pefree(net->cmd_buffer.buffer, net->persistent);
net->cmd_buffer.buffer = NULL;
}
- mnd_pefree(net, pers);
+
+ mnd_pefree(net->data, net->data->persistent);
+ mnd_pefree(net, net->persistent);
}
DBG_VOID_RETURN;
}
/* }}} */
+/* {{{ mysqlnd_net::get_stream */
+static php_stream *
+MYSQLND_METHOD(mysqlnd_net, get_stream)(const MYSQLND_NET * const net TSRMLS_DC)
+{
+ DBG_ENTER("mysqlnd_net::get_stream");
+ DBG_INF_FMT("%p", net? net->data->stream:NULL);
+ DBG_RETURN(net? net->data->stream:NULL);
+}
+/* }}} */
+
+
+/* {{{ mysqlnd_net::set_stream */
+static php_stream *
+MYSQLND_METHOD(mysqlnd_net, set_stream)(MYSQLND_NET * const net, php_stream * net_stream TSRMLS_DC)
+{
+ php_stream * ret = NULL;
+ DBG_ENTER("mysqlnd_net::set_stream");
+ if (net) {
+ net->data->stream = net_stream;
+ ret = net->data->stream;
+ }
+ DBG_RETURN(ret);
+}
+/* }}} */
+
+
MYSQLND_CLASS_METHODS_START(mysqlnd_net)
MYSQLND_METHOD(mysqlnd_net, init),
MYSQLND_METHOD(mysqlnd_net, dtor),
@@ -1011,8 +1095,9 @@ MYSQLND_CLASS_METHODS_START(mysqlnd_net)
MYSQLND_METHOD(mysqlnd_net, close_stream),
MYSQLND_METHOD(mysqlnd_net, open_pipe),
MYSQLND_METHOD(mysqlnd_net, open_tcp_or_unix),
- NULL, /* unused 1 */
- NULL, /* unused 2 */
+ MYSQLND_METHOD(mysqlnd_net, get_stream),
+ MYSQLND_METHOD(mysqlnd_net, set_stream),
+ MYSQLND_METHOD(mysqlnd_net, get_open_stream),
MYSQLND_METHOD(mysqlnd_net, post_connect_set_opt),
MYSQLND_METHOD(mysqlnd_net, set_client_option),
MYSQLND_METHOD(mysqlnd_net, decode),
@@ -1026,10 +1111,15 @@ MYSQLND_CLASS_METHODS_START(mysqlnd_net)
MYSQLND_METHOD(mysqlnd_net, send_ex),
MYSQLND_METHOD(mysqlnd_net, receive_ex),
#ifdef MYSQLND_COMPRESSION_ENABLED
- MYSQLND_METHOD(mysqlnd_net, read_compressed_packet_from_stream_and_fill_read_buffer)
+ MYSQLND_METHOD(mysqlnd_net, read_compressed_packet_from_stream_and_fill_read_buffer),
#else
- NULL
+ NULL,
#endif
+ NULL, /* unused 1 */
+ NULL, /* unused 2 */
+ NULL, /* unused 3 */
+ NULL, /* unused 4 */
+ NULL /* unused 5 */
MYSQLND_CLASS_METHODS_END;
@@ -1051,7 +1141,7 @@ mysqlnd_net_free(MYSQLND_NET * const net, MYSQLND_STATS * stats, MYSQLND_ERROR_I
{
DBG_ENTER("mysqlnd_net_free");
if (net) {
- net->m.dtor(net, stats, error_info TSRMLS_CC);
+ net->data->m.dtor(net, stats, error_info TSRMLS_CC);
}
DBG_VOID_RETURN;
}
diff --git a/ext/mysqlnd/mysqlnd_plugin.c b/ext/mysqlnd/mysqlnd_plugin.c
index 3ae0e7d8bd..86543a05c2 100644
--- a/ext/mysqlnd/mysqlnd_plugin.c
+++ b/ext/mysqlnd/mysqlnd_plugin.c
@@ -26,7 +26,7 @@
#include "mysqlnd_debug.h"
/*--------------------------------------------------------------------*/
-
+#if defined(MYSQLND_DBG_ENABLED) && MYSQLND_DBG_ENABLED == 1
static enum_func_status mysqlnd_example_plugin_end(void * p TSRMLS_DC);
static MYSQLND_STATS * mysqlnd_plugin_example_stats = NULL;
@@ -87,7 +87,7 @@ mysqlnd_example_plugin_register(TSRMLS_D)
mysqlnd_plugin_register_ex((struct st_mysqlnd_plugin_header *) &mysqlnd_example_plugin TSRMLS_CC);
}
/* }}} */
-
+#endif /* defined(MYSQLND_DBG_ENABLED) && MYSQLND_DBG_ENABLED == 1 */
/*--------------------------------------------------------------------*/
static HashTable mysqlnd_registered_plugins;
diff --git a/ext/mysqlnd/mysqlnd_priv.h b/ext/mysqlnd/mysqlnd_priv.h
index f52c2a99b9..deb0bdc8c8 100644
--- a/ext/mysqlnd/mysqlnd_priv.h
+++ b/ext/mysqlnd/mysqlnd_priv.h
@@ -33,12 +33,6 @@
#define Z_DELREF_PP(ppz) Z_DELREF_P(*(ppz))
#endif
-#if PHP_MAJOR_VERSION >= 6
-#define MYSQLND_UNICODE 1
-#else
-#define MYSQLND_UNICODE 0
-#endif
-
#ifdef ZTS
#include "TSRM.h"
#endif
@@ -47,21 +41,12 @@
#define pestrndup(s, length, persistent) ((persistent)?zend_strndup((s),(length)):estrndup((s),(length)))
#endif
-#if MYSQLND_UNICODE
-#define mysqlnd_array_init(arg, field_count) \
-{ \
- ALLOC_HASHTABLE_REL(Z_ARRVAL_P(arg));\
- zend_u_hash_init(Z_ARRVAL_P(arg), (field_count), NULL, ZVAL_PTR_DTOR, 0, 0);\
- Z_TYPE_P(arg) = IS_ARRAY;\
-}
-#else
#define mysqlnd_array_init(arg, field_count) \
{ \
ALLOC_HASHTABLE_REL(Z_ARRVAL_P(arg));\
zend_hash_init(Z_ARRVAL_P(arg), (field_count), NULL, ZVAL_PTR_DTOR, 0); \
Z_TYPE_P(arg) = IS_ARRAY;\
}
-#endif
#define MYSQLND_STR_W_LEN(str) str, (sizeof(str) - 1)
@@ -174,9 +159,7 @@
#define CONN_SET_STATE(c, s) (c)->m->set_state((c), (s) TSRMLS_CC)
/* PS stuff */
-typedef void (*ps_field_fetch_func)(zval *zv, const MYSQLND_FIELD * const field,
- unsigned int pack_len, zend_uchar **row,
- zend_bool everything_as_unicode TSRMLS_DC);
+typedef void (*ps_field_fetch_func)(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC);
struct st_mysqlnd_perm_bind {
ps_field_fetch_func func;
/* should be signed int */
@@ -193,23 +176,21 @@ PHPAPI extern const char * const mysqlnd_out_of_sync;
PHPAPI extern const char * const mysqlnd_server_gone;
PHPAPI extern const char * const mysqlnd_out_of_memory;
-extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_object_factory);
-extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_conn);
-extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_conn_data);
-extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_res);
-extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_protocol);
-extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_net);
+PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_object_factory);
+PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_conn);
+PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_conn_data);
+PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_res);
+PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_protocol);
+PHPAPI extern MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(mysqlnd_net);
-enum_func_status mysqlnd_handle_local_infile(MYSQLND_CONN_DATA * conn, const char *filename, zend_bool *is_warning TSRMLS_DC);
+enum_func_status mysqlnd_handle_local_infile(MYSQLND_CONN_DATA * conn, const char * filename, zend_bool * is_warning TSRMLS_DC);
void _mysqlnd_init_ps_subsystem();/* This one is private, mysqlnd_library_init() will call it */
void _mysqlnd_init_ps_fetch_subsystem();
-void ps_fetch_from_1_to_8_bytes(zval *zv, const MYSQLND_FIELD * const field,
- unsigned int pack_len, zend_uchar **row, zend_bool as_unicode,
- unsigned int byte_count TSRMLS_DC);
+void ps_fetch_from_1_to_8_bytes(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row, unsigned int byte_count TSRMLS_DC);
void mysqlnd_plugin_subsystem_init(TSRMLS_D);
void mysqlnd_plugin_subsystem_end(TSRMLS_D);
diff --git a/ext/mysqlnd/mysqlnd_ps.c b/ext/mysqlnd/mysqlnd_ps.c
index 23a0f8a687..8096cbbbd9 100644
--- a/ext/mysqlnd/mysqlnd_ps.c
+++ b/ext/mysqlnd/mysqlnd_ps.c
@@ -307,6 +307,7 @@ mysqlnd_stmt_read_prepare_response(MYSQLND_STMT * s TSRMLS_DC)
stmt->warning_count = stmt->conn->upsert_status->warning_count = prepare_resp->warning_count;
stmt->field_count = stmt->conn->field_count = prepare_resp->field_count;
stmt->param_count = prepare_resp->param_count;
+ stmt->upsert_status->affected_rows = 0; /* be like libmysql */
done:
PACKET_FREE(prepare_resp);
@@ -735,7 +736,6 @@ mysqlnd_stmt_fetch_row_buffered(MYSQLND_RES *result, void *param, unsigned int f
current_row,
meta->field_count,
meta->fields,
- result->conn->options->numeric_and_datetime_as_unicode,
result->conn->options->int_and_float_native,
result->conn->stats TSRMLS_CC);
if (PASS != rc) {
@@ -854,7 +854,6 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES *result, void *param, unsigned int
result->unbuf->last_row_data,
row_packet->field_count,
row_packet->fields_metadata,
- result->conn->options->numeric_and_datetime_as_unicode,
result->conn->options->int_and_float_native,
result->conn->stats TSRMLS_CC))
{
@@ -872,14 +871,7 @@ mysqlnd_stmt_fetch_row_unbuffered(MYSQLND_RES *result, void *param, unsigned int
zval_dtor(stmt->result_bind[i].zv);
#endif
if (IS_NULL != (Z_TYPE_P(stmt->result_bind[i].zv) = Z_TYPE_P(data)) ) {
- if (
- (Z_TYPE_P(data) == IS_STRING
-#if MYSQLND_UNICODE
- || Z_TYPE_P(data) == IS_UNICODE
-#endif
- )
- && (result->meta->fields[i].max_length < (unsigned long) Z_STRLEN_P(data)))
- {
+ if ((Z_TYPE_P(data) == IS_STRING) && (result->meta->fields[i].max_length < (unsigned long) Z_STRLEN_P(data))) {
result->meta->fields[i].max_length = Z_STRLEN_P(data);
}
stmt->result_bind[i].zv->value = data->value;
@@ -1040,7 +1032,6 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES *result, void *param, unsigned int fla
result->unbuf->last_row_data,
row_packet->field_count,
row_packet->fields_metadata,
- result->conn->options->numeric_and_datetime_as_unicode,
result->conn->options->int_and_float_native,
result->conn->stats TSRMLS_CC))
{
@@ -1061,13 +1052,7 @@ mysqlnd_fetch_stmt_row_cursor(MYSQLND_RES *result, void *param, unsigned int fla
DBG_INF_FMT("i=%u bound_var=%p type=%u refc=%u", i, stmt->result_bind[i].zv,
Z_TYPE_P(data), Z_REFCOUNT_P(stmt->result_bind[i].zv));
if (IS_NULL != (Z_TYPE_P(stmt->result_bind[i].zv) = Z_TYPE_P(data))) {
- if ((Z_TYPE_P(data) == IS_STRING
-#if MYSQLND_UNICODE
- || Z_TYPE_P(data) == IS_UNICODE
-#endif
- )
- && (result->meta->fields[i].max_length < (unsigned long) Z_STRLEN_P(data)))
- {
+ if ((Z_TYPE_P(data) == IS_STRING) && (result->meta->fields[i].max_length < (unsigned long) Z_STRLEN_P(data))) {
result->meta->fields[i].max_length = Z_STRLEN_P(data);
}
stmt->result_bind[i].zv->value = data->value;
diff --git a/ext/mysqlnd/mysqlnd_ps_codec.c b/ext/mysqlnd/mysqlnd_ps_codec.c
index e2640c775b..d0e44fa275 100644
--- a/ext/mysqlnd/mysqlnd_ps_codec.c
+++ b/ext/mysqlnd/mysqlnd_ps_codec.c
@@ -53,9 +53,9 @@ struct st_mysqlnd_perm_bind mysqlnd_ps_fetch_functions[MYSQL_TYPE_LAST + 1];
#define MYSQLND_PS_SKIP_RESULT_STR -2
/* {{{ ps_fetch_from_1_to_8_bytes */
-void ps_fetch_from_1_to_8_bytes(zval *zv, const MYSQLND_FIELD * const field,
- unsigned int pack_len, zend_uchar **row, zend_bool as_unicode,
- unsigned int byte_count TSRMLS_DC)
+void
+ps_fetch_from_1_to_8_bytes(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len,
+ zend_uchar ** row, unsigned int byte_count TSRMLS_DC)
{
char tmp[22];
size_t tmp_len = 0;
@@ -117,16 +117,7 @@ void ps_fetch_from_1_to_8_bytes(zval *zv, const MYSQLND_FIELD * const field,
}
if (tmp_len) {
-#if MYSQLND_UNICODE
- if (as_unicode) {
- DBG_INF("stringify");
- ZVAL_UTF8_STRINGL(zv, tmp, tmp_len, ZSTR_DUPLICATE);
- } else
-#endif
- {
- DBG_INF("stringify");
- ZVAL_STRINGL(zv, tmp, tmp_len, 1);
- }
+ ZVAL_STRINGL(zv, tmp, tmp_len, 1);
}
(*row)+= byte_count;
DBG_VOID_RETURN;
@@ -135,10 +126,8 @@ void ps_fetch_from_1_to_8_bytes(zval *zv, const MYSQLND_FIELD * const field,
/* {{{ ps_fetch_null */
-static
-void ps_fetch_null(zval *zv, const MYSQLND_FIELD * const field,
- unsigned int pack_len, zend_uchar **row,
- zend_bool as_unicode TSRMLS_DC)
+static void
+ps_fetch_null(zval *zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC)
{
ZVAL_NULL(zv);
}
@@ -146,54 +135,44 @@ void ps_fetch_null(zval *zv, const MYSQLND_FIELD * const field,
/* {{{ ps_fetch_int8 */
-static
-void ps_fetch_int8(zval *zv, const MYSQLND_FIELD * const field,
- unsigned int pack_len, zend_uchar **row,
- zend_bool as_unicode TSRMLS_DC)
+static void
+ps_fetch_int8(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC)
{
- ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, as_unicode, 1 TSRMLS_CC);
+ ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, 1 TSRMLS_CC);
}
/* }}} */
/* {{{ ps_fetch_int16 */
-static
-void ps_fetch_int16(zval *zv, const MYSQLND_FIELD * const field,
- unsigned int pack_len, zend_uchar **row,
- zend_bool as_unicode TSRMLS_DC)
+static void
+ps_fetch_int16(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC)
{
- ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, as_unicode, 2 TSRMLS_CC);
+ ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, 2 TSRMLS_CC);
}
/* }}} */
/* {{{ ps_fetch_int32 */
-static
-void ps_fetch_int32(zval *zv, const MYSQLND_FIELD * const field,
- unsigned int pack_len, zend_uchar **row,
- zend_bool as_unicode TSRMLS_DC)
+static void
+ps_fetch_int32(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC)
{
- ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, as_unicode, 4 TSRMLS_CC);
+ ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, 4 TSRMLS_CC);
}
/* }}} */
/* {{{ ps_fetch_int64 */
-static
-void ps_fetch_int64(zval *zv, const MYSQLND_FIELD * const field,
- unsigned int pack_len, zend_uchar **row,
- zend_bool as_unicode TSRMLS_DC)
+static void
+ps_fetch_int64(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC)
{
- ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, as_unicode, 8 TSRMLS_CC);
+ ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, 8 TSRMLS_CC);
}
/* }}} */
/* {{{ ps_fetch_float */
-static
-void ps_fetch_float(zval *zv, const MYSQLND_FIELD * const field,
- unsigned int pack_len, zend_uchar **row,
- zend_bool as_unicode TSRMLS_DC)
+static void
+ps_fetch_float(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC)
{
float value;
DBG_ENTER("ps_fetch_float");
@@ -207,10 +186,8 @@ void ps_fetch_float(zval *zv, const MYSQLND_FIELD * const field,
/* {{{ ps_fetch_double */
-static
-void ps_fetch_double(zval *zv, const MYSQLND_FIELD * const field,
- unsigned int pack_len, zend_uchar **row,
- zend_bool as_unicode TSRMLS_DC)
+static void
+ps_fetch_double(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC)
{
double value;
DBG_ENTER("ps_fetch_double");
@@ -224,18 +201,16 @@ void ps_fetch_double(zval *zv, const MYSQLND_FIELD * const field,
/* {{{ ps_fetch_time */
-static
-void ps_fetch_time(zval *zv, const MYSQLND_FIELD * const field,
- unsigned int pack_len, zend_uchar **row,
- zend_bool as_unicode TSRMLS_DC)
+static void
+ps_fetch_time(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC)
{
struct st_mysqlnd_time t;
- unsigned int length; /* First byte encodes the length*/
+ unsigned long length; /* First byte encodes the length*/
char * value;
DBG_ENTER("ps_fetch_time");
if ((length = php_mysqlnd_net_field_length(row))) {
- zend_uchar *to= *row;
+ zend_uchar * to= *row;
t.time_type = MYSQLND_TIMESTAMP_TIME;
t.neg = (zend_bool) to[0];
@@ -261,29 +236,19 @@ void ps_fetch_time(zval *zv, const MYSQLND_FIELD * const field,
length = mnd_sprintf(&value, 0, "%s%02u:%02u:%02u", (t.neg ? "-" : ""), t.hour, t.minute, t.second);
DBG_INF_FMT("%s", value);
-#if MYSQLND_UNICODE
- if (!as_unicode) {
-#endif
- ZVAL_STRINGL(zv, value, length, 1);
- mnd_sprintf_free(value);
-#if MYSQLND_UNICODE
- } else {
- ZVAL_UTF8_STRINGL(zv, value, length, ZSTR_AUTOFREE);
- }
-#endif
+ ZVAL_STRINGL(zv, value, length, 1);
+ mnd_sprintf_free(value);
DBG_VOID_RETURN;
}
/* }}} */
/* {{{ ps_fetch_date */
-static
-void ps_fetch_date(zval *zv, const MYSQLND_FIELD * const field,
- unsigned int pack_len, zend_uchar **row,
- zend_bool as_unicode TSRMLS_DC)
+static void
+ps_fetch_date(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC)
{
struct st_mysqlnd_time t = {0};
- unsigned int length; /* First byte encodes the length*/
+ unsigned long length; /* First byte encodes the length*/
char * value;
DBG_ENTER("ps_fetch_date");
@@ -308,34 +273,24 @@ void ps_fetch_date(zval *zv, const MYSQLND_FIELD * const field,
length = mnd_sprintf(&value, 0, "%04u-%02u-%02u", t.year, t.month, t.day);
DBG_INF_FMT("%s", value);
-#if MYSQLND_UNICODE
- if (!as_unicode) {
-#endif
- ZVAL_STRINGL(zv, value, length, 1);
- mnd_sprintf_free(value);
-#if MYSQLND_UNICODE
- } else {
- ZVAL_UTF8_STRINGL(zv, value, length, ZSTR_AUTOFREE);
- }
-#endif
+ ZVAL_STRINGL(zv, value, length, 1);
+ mnd_sprintf_free(value);
DBG_VOID_RETURN;
}
/* }}} */
/* {{{ ps_fetch_datetime */
-static
-void ps_fetch_datetime(zval *zv, const MYSQLND_FIELD * const field,
- unsigned int pack_len, zend_uchar **row,
- zend_bool as_unicode TSRMLS_DC)
+static void
+ps_fetch_datetime(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC)
{
struct st_mysqlnd_time t;
- unsigned int length; /* First byte encodes the length*/
+ unsigned long length; /* First byte encodes the length*/
char * value;
DBG_ENTER("ps_fetch_datetime");
if ((length = php_mysqlnd_net_field_length(row))) {
- zend_uchar *to= *row;
+ zend_uchar * to = *row;
t.time_type = MYSQLND_TIMESTAMP_DATETIME;
t.neg = 0;
@@ -362,46 +317,26 @@ void ps_fetch_datetime(zval *zv, const MYSQLND_FIELD * const field,
length = mnd_sprintf(&value, 0, "%04u-%02u-%02u %02u:%02u:%02u", t.year, t.month, t.day, t.hour, t.minute, t.second);
DBG_INF_FMT("%s", value);
-#if MYSQLND_UNICODE
- if (!as_unicode) {
-#endif
- ZVAL_STRINGL(zv, value, length, 1);
- mnd_sprintf_free(value);
-#if MYSQLND_UNICODE
- } else {
- ZVAL_UTF8_STRINGL(zv, to, length, ZSTR_AUTOFREE);
- }
-#endif
+ ZVAL_STRINGL(zv, value, length, 1);
+ mnd_sprintf_free(value);
DBG_VOID_RETURN;
}
/* }}} */
/* {{{ ps_fetch_string */
-static
-void ps_fetch_string(zval *zv, const MYSQLND_FIELD * const field,
- unsigned int pack_len, zend_uchar **row,
- zend_bool as_unicode TSRMLS_DC)
+static void
+ps_fetch_string(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC)
{
/*
For now just copy, before we make it possible
to write \0 to the row buffer
*/
- unsigned long length = php_mysqlnd_net_field_length(row);
+ const unsigned long length = php_mysqlnd_net_field_length(row);
DBG_ENTER("ps_fetch_string");
DBG_INF_FMT("len = %lu", length);
-#if MYSQLND_UNICODE
- if (field->charsetnr == MYSQLND_BINARY_CHARSET_NR) {
- DBG_INF("Binary charset");
- ZVAL_STRINGL(zv, (char *)*row, length, 1);
- } else {
- DBG_INF_FMT("copying from the row buffer");
- ZVAL_UTF8_STRINGL(zv, (char*)*row, length, ZSTR_DUPLICATE);
- }
-#else
DBG_INF("copying from the row buffer");
ZVAL_STRINGL(zv, (char *)*row, length, 1);
-#endif
(*row) += length;
DBG_VOID_RETURN;
@@ -410,13 +345,11 @@ void ps_fetch_string(zval *zv, const MYSQLND_FIELD * const field,
/* {{{ ps_fetch_bit */
-static
-void ps_fetch_bit(zval *zv, const MYSQLND_FIELD * const field,
- unsigned int pack_len, zend_uchar **row,
- zend_bool as_unicode TSRMLS_DC)
+static void
+ps_fetch_bit(zval * zv, const MYSQLND_FIELD * const field, unsigned int pack_len, zend_uchar ** row TSRMLS_DC)
{
- unsigned long length= php_mysqlnd_net_field_length(row);
- ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, as_unicode, length TSRMLS_CC);
+ unsigned long length = php_mysqlnd_net_field_length(row);
+ ps_fetch_from_1_to_8_bytes(zv, field, pack_len, row, length TSRMLS_CC);
}
/* }}} */
@@ -566,7 +499,7 @@ void _mysqlnd_init_ps_fetch_subsystem()
/* {{{ mysqlnd_stmt_copy_it */
static enum_func_status
-mysqlnd_stmt_copy_it(zval *** copies, zval *original, unsigned int param_count, unsigned int current TSRMLS_DC)
+mysqlnd_stmt_copy_it(zval *** copies, zval * original, unsigned int param_count, unsigned int current TSRMLS_DC)
{
if (!*copies) {
*copies = mnd_ecalloc(param_count, sizeof(zval *));
@@ -806,12 +739,7 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT * s, zend_uchar **buf, zend_uchar
case MYSQL_TYPE_VAR_STRING:
use_string:
data_size += 8; /* max 8 bytes for size */
-#if MYSQLND_UNICODE
- if (Z_TYPE_P(the_var) != IS_STRING || Z_TYPE_P(the_var) == IS_UNICODE)
-#else
- if (Z_TYPE_P(the_var) != IS_STRING)
-#endif
- {
+ if (Z_TYPE_P(the_var) != IS_STRING) {
if (!copies || !copies[i]) {
if (PASS != mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i TSRMLS_CC)) {
SET_OOM_ERROR(*stmt->error_info);
@@ -819,11 +747,6 @@ use_string:
}
}
the_var = copies[i];
-#if MYSQLND_UNICODE
- if (Z_TYPE_P(the_var) == IS_UNICODE) {
- zval_unicode_to_string_ex(the_var, UG(utf8_conv) TSRMLS_CC);
- }
-#endif
}
convert_to_string_ex(&the_var);
data_size += Z_STRLEN_P(the_var);
diff --git a/ext/mysqlnd/mysqlnd_result.c b/ext/mysqlnd/mysqlnd_result.c
index cb15657601..74019b55bf 100644
--- a/ext/mysqlnd/mysqlnd_result.c
+++ b/ext/mysqlnd/mysqlnd_result.c
@@ -55,7 +55,6 @@ MYSQLND_METHOD(mysqlnd_res, initialize_result_set_rest)(MYSQLND_RES * const resu
data_cursor,
result->meta->field_count,
result->meta->fields,
- result->conn->options->numeric_and_datetime_as_unicode,
result->conn->options->int_and_float_native,
result->conn->stats TSRMLS_CC);
if (rc != PASS) {
@@ -106,16 +105,6 @@ mysqlnd_rset_zval_ptr_dtor(zval **zv, enum_mysqlnd_res_type type, zend_bool * co
/*
Not a prepared statement, then we have to
call copy_ctor and then zval_ptr_dtor()
-
- In Unicode mode the destruction of the zvals should not call
- zval_copy_ctor() because then we will leak.
- I suppose we can use UG(unicode) in mysqlnd.c when freeing a result set
- to check if we need to call copy_ctor().
-
- If the type is IS_UNICODE, which can happen with PHP6, then we don't
- need to copy_ctor, as the data doesn't point to our internal buffers.
- If it's string (in PHP5 always) and in PHP6 if data is binary, then
- it still points to internal buffers and has to be copied.
*/
if (Z_TYPE_PP(zv) == IS_STRING) {
zval_copy_ctor(*zv);
@@ -670,7 +659,6 @@ mysqlnd_fetch_row_unbuffered_c(MYSQLND_RES * result TSRMLS_DC)
result->unbuf->last_row_data,
row_packet->field_count,
row_packet->fields_metadata,
- result->conn->options->numeric_and_datetime_as_unicode,
result->conn->options->int_and_float_native,
result->conn->stats TSRMLS_CC);
if (PASS != rc) {
@@ -786,7 +774,6 @@ mysqlnd_fetch_row_unbuffered(MYSQLND_RES * result, void *param, unsigned int fla
result->unbuf->last_row_data,
field_count,
row_packet->fields_metadata,
- result->conn->options->numeric_and_datetime_as_unicode,
result->conn->options->int_and_float_native,
result->conn->stats TSRMLS_CC);
if (PASS != rc) {
@@ -814,19 +801,11 @@ mysqlnd_fetch_row_unbuffered(MYSQLND_RES * result, void *param, unsigned int fla
*/
Z_ADDREF_P(data);
if (hash_key->is_numeric == FALSE) {
-#if MYSQLND_UNICODE
- zend_u_hash_quick_update(Z_ARRVAL_P(row), IS_UNICODE,
- hash_key->ustr,
- hash_key->ulen + 1,
- hash_key->key,
- (void *) &data, sizeof(zval *), NULL);
-#else
zend_hash_quick_update(Z_ARRVAL_P(row),
field->name,
field->name_length + 1,
hash_key->key,
(void *) &data, sizeof(zval *), NULL);
-#endif
} else {
zend_hash_index_update(Z_ARRVAL_P(row),
hash_key->key,
@@ -953,7 +932,6 @@ mysqlnd_fetch_row_buffered_c(MYSQLND_RES * result TSRMLS_DC)
current_row,
result->meta->field_count,
result->meta->fields,
- result->conn->options->numeric_and_datetime_as_unicode,
result->conn->options->int_and_float_native,
result->conn->stats TSRMLS_CC);
if (rc != PASS) {
@@ -1026,7 +1004,6 @@ mysqlnd_fetch_row_buffered(MYSQLND_RES * result, void *param, unsigned int flags
current_row,
result->meta->field_count,
result->meta->fields,
- result->conn->options->numeric_and_datetime_as_unicode,
result->conn->options->int_and_float_native,
result->conn->stats TSRMLS_CC);
if (rc != PASS) {
@@ -1065,19 +1042,11 @@ mysqlnd_fetch_row_buffered(MYSQLND_RES * result, void *param, unsigned int flags
*/
Z_ADDREF_P(data);
if (hash_key->is_numeric == FALSE) {
-#if MYSQLND_UNICODE
- zend_u_hash_quick_update(Z_ARRVAL_P(row), IS_UNICODE,
- hash_key->ustr,
- hash_key->ulen + 1,
- hash_key->key,
- (void *) &data, sizeof(zval *), NULL);
-#else
zend_hash_quick_update(Z_ARRVAL_P(row),
field->name,
field->name_length + 1,
hash_key->key,
(void *) &data, sizeof(zval *), NULL);
-#endif
} else {
zend_hash_index_update(Z_ARRVAL_P(row),
hash_key->key,
diff --git a/ext/mysqlnd/mysqlnd_result_meta.c b/ext/mysqlnd/mysqlnd_result_meta.c
index 52bb0bdadf..6523a431ca 100644
--- a/ext/mysqlnd/mysqlnd_result_meta.c
+++ b/ext/mysqlnd/mysqlnd_result_meta.c
@@ -92,60 +92,12 @@ mysqlnd_is_key_numeric(const char * key, size_t length, long *idx)
/* }}} */
-#if MYSQLND_UNICODE
-/* {{{ mysqlnd_unicode_is_key_numeric */
-static zend_bool
-mysqlnd_unicode_is_key_numeric(UChar *key, size_t length, long *idx)
-{
- register UChar * tmp=key;
-
- if (*tmp==0x2D /*'-'*/) {
- tmp++;
- }
- if ((*tmp>=0x30 /*'0'*/ && *tmp<=0x39 /*'9'*/)) { /* possibly a numeric index */
- do {
- UChar *end=key+length-1;
-
- if (*tmp++==0x30 && length>2) { /* don't accept numbers with leading zeros */
- break;
- }
- while (tmp<end) {
- if (!(*tmp>=0x30 /*'0'*/ && *tmp<=0x39 /*'9'*/)) {
- break;
- }
- tmp++;
- }
- if (tmp==end && *tmp==0) { /* a numeric index */
- if (*key==0x2D /*'-'*/) {
- *idx = zend_u_strtol(key, NULL, 10);
- if (*idx!=LONG_MIN) {
- return TRUE;
- }
- } else {
- *idx = zend_u_strtol(key, NULL, 10);
- if (*idx!=LONG_MAX) {
- return TRUE;
- }
- }
- }
- } while (0);
- }
- return FALSE;
-}
-/* }}} */
-#endif
-
-
/* {{{ mysqlnd_res_meta::read_metadata */
static enum_func_status
MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const meta, MYSQLND_CONN_DATA * conn TSRMLS_DC)
{
unsigned int i = 0;
MYSQLND_PACKET_RES_FIELD * field_packet;
-#if MYSQLND_UNICODE
- UChar *ustr;
- int ulen;
-#endif
DBG_ENTER("mysqlnd_res_meta::read_metadata");
@@ -226,21 +178,6 @@ MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const met
}
}
-#if MYSQLND_UNICODE
- zend_string_to_unicode(UG(utf8_conv), &ustr, &ulen,
- meta->fields[i].name,
- meta->fields[i].name_length TSRMLS_CC);
- if ((meta->zend_hash_keys[i].is_numeric =
- mysqlnd_unicode_is_key_numeric(ustr, ulen + 1, &idx)))
- {
- meta->zend_hash_keys[i].key = idx;
- mnd_efree(ustr);
- } else {
- meta->zend_hash_keys[i].ustr.u = ustr;
- meta->zend_hash_keys[i].ulen = ulen;
- meta->zend_hash_keys[i].key = zend_u_get_hash_value(IS_UNICODE, ZSTR(ustr), ulen + 1);
- }
-#else
/* For BC we have to check whether the key is numeric and use it like this */
if ((meta->zend_hash_keys[i].is_numeric =
mysqlnd_is_key_numeric(field_packet->metadata->name,
@@ -253,7 +190,6 @@ MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const met
zend_get_hash_value(field_packet->metadata->name,
field_packet->metadata->name_length + 1);
}
-#endif
}
PACKET_FREE(field_packet);
@@ -283,15 +219,6 @@ MYSQLND_METHOD(mysqlnd_res_meta, free)(MYSQLND_RES_METADATA * meta TSRMLS_DC)
if (meta->zend_hash_keys) {
DBG_INF("Freeing zend_hash_keys");
-#if MYSQLND_UNICODE
- if (UG(unicode)) {
- for (i = 0; i < meta->field_count; i++) {
- if (meta->zend_hash_keys[i].ustr.v) {
- mnd_pefree(meta->zend_hash_keys[i].ustr.v, meta->persistent);
- }
- }
- }
-#endif
mnd_pefree(meta->zend_hash_keys, meta->persistent);
meta->zend_hash_keys = NULL;
}
@@ -379,15 +306,6 @@ MYSQLND_METHOD(mysqlnd_res_meta, clone_metadata)(const MYSQLND_RES_METADATA * co
/* copy the trailing \0 too */
memcpy(new_fields[i].def, orig_fields[i].def, orig_fields[i].def_length + 1);
}
-#if MYSQLND_UNICODE
- if (new_meta->zend_hash_keys[i].ustr.u) {
- new_meta->zend_hash_keys[i].ustr.u =
- eustrndup(new_meta->zend_hash_keys[i].ustr.u, new_meta->zend_hash_keys[i].ulen);
- if (!new_meta->zend_hash_keys[i].ustr.u) {
- goto oom;
- }
- }
-#endif
}
new_meta->current_field = 0;
new_meta->field_count = meta->field_count;
diff --git a/ext/mysqlnd/mysqlnd_reverse_api.h b/ext/mysqlnd/mysqlnd_reverse_api.h
index df1dbf8fb8..028a1f6b13 100644
--- a/ext/mysqlnd/mysqlnd_reverse_api.h
+++ b/ext/mysqlnd/mysqlnd_reverse_api.h
@@ -47,4 +47,3 @@ PHPAPI MYSQLND * zval_to_mysqlnd(zval * zv TSRMLS_DC);
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
-
diff --git a/ext/mysqlnd/mysqlnd_statistics.c b/ext/mysqlnd/mysqlnd_statistics.c
index 2045bebb1e..ce193275ec 100644
--- a/ext/mysqlnd/mysqlnd_statistics.c
+++ b/ext/mysqlnd/mysqlnd_statistics.c
@@ -203,22 +203,10 @@ mysqlnd_fill_stats_hash(const MYSQLND_STATS * const stats, const MYSQLND_STRING
mysqlnd_array_init(return_value, stats->count);
for (i = 0; i < stats->count; i++) {
-#if MYSQLND_UNICODE
- UChar *ustr, *tstr;
- int ulen, tlen;
-#endif
char tmp[25];
sprintf((char *)&tmp, MYSQLND_LLU_SPEC, stats->values[i]);
-#if MYSQLND_UNICODE
- zend_string_to_unicode(UG(utf8_conv), &ustr, &ulen, names[i].s, names[i].l + 1 TSRMLS_CC);
- zend_string_to_unicode(UG(utf8_conv), &tstr, &tlen, tmp, strlen(tmp) + 1 TSRMLS_CC);
- add_u_assoc_unicode_ex(return_value, IS_UNICODE, ZSTR(ustr), ulen, tstr, 1);
- efree(ustr);
- efree(tstr);
-#else
add_assoc_string_ex(return_value, names[i].s, names[i].l + 1, tmp, 1);
-#endif
}
}
/* }}} */
diff --git a/ext/mysqlnd/mysqlnd_structs.h b/ext/mysqlnd/mysqlnd_structs.h
index f25492e13d..a9048b2b13 100644
--- a/ext/mysqlnd/mysqlnd_structs.h
+++ b/ext/mysqlnd/mysqlnd_structs.h
@@ -23,6 +23,8 @@
#ifndef MYSQLND_STRUCTS_H
#define MYSQLND_STRUCTS_H
+#include "ext/standard/php_smart_str_public.h"
+
#define MYSQLND_TYPEDEFED_METHODS
#define MYSQLND_CLASS_METHOD_TABLE_NAME(class) mysqlnd_##class##_methods
@@ -31,6 +33,7 @@
#define MYSQLND_CLASS_METHODS_START(class) MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(class) = {
#define MYSQLND_CLASS_METHODS_END }
+
typedef struct st_mysqlnd_memory_pool MYSQLND_MEMORY_POOL;
typedef struct st_mysqlnd_memory_pool_chunk MYSQLND_MEMORY_POOL_CHUNK;
typedef struct st_mysqlnd_memory_pool_chunk_llist MYSQLND_MEMORY_POOL_CHUNK_LLIST;
@@ -172,7 +175,7 @@ typedef struct st_mysqlnd_options
The ABI will be broken and the methods structure will be somewhere else
in the memory which can crash external code. Feel free to reuse these.
*/
- char * unused2;
+ HashTable * connect_attr;
char * unused3;
char * unused4;
char * unused5;
@@ -183,7 +186,6 @@ typedef struct st_mysqlnd_options
/* maximum allowed packet size for communication */
ulong max_allowed_packet;
- zend_bool numeric_and_datetime_as_unicode;
#ifdef MYSQLND_STRING_TO_INT_CONVERSION
zend_bool int_and_float_native;
#endif
@@ -196,7 +198,7 @@ typedef struct st_mysqlnd_net_options
unsigned int timeout_read;
unsigned int timeout_write;
- unsigned int net_read_buffer_size;
+ size_t net_read_buffer_size;
/* SSL information */
char *ssl_key;
@@ -207,12 +209,20 @@ typedef struct st_mysqlnd_net_options
char *ssl_passphrase;
zend_bool ssl_verify_peer;
uint64_t flags;
+
+ char * sha256_server_public_key;
+
+ char * unused1;
+ char * unused2;
+ char * unused3;
+ char * unused4;
} MYSQLND_NET_OPTIONS;
typedef struct st_mysqlnd_connection MYSQLND;
typedef struct st_mysqlnd_connection_data MYSQLND_CONN_DATA;
typedef struct st_mysqlnd_net MYSQLND_NET;
+typedef struct st_mysqlnd_net_data MYSQLND_NET_DATA;
typedef struct st_mysqlnd_protocol MYSQLND_PROTOCOL;
typedef struct st_mysqlnd_res MYSQLND_RES;
typedef char** MYSQLND_ROW_C; /* return data as array of strings */
@@ -282,7 +292,10 @@ typedef enum_func_status (*func_mysqlnd_net__init)(MYSQLND_NET * const net, MYSQ
typedef void (*func_mysqlnd_net__dtor)(MYSQLND_NET * const net, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info TSRMLS_DC);
typedef enum_func_status (*func_mysqlnd_net__connect_ex)(MYSQLND_NET * const net, const char * const scheme, const size_t scheme_len, const zend_bool persistent, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info TSRMLS_DC);
typedef void (*func_mysqlnd_net__close_stream)(MYSQLND_NET * const net, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info TSRMLS_DC);
-typedef enum_func_status (*func_mysqlnd_net__open_stream)(MYSQLND_NET * const net, const char * const scheme, const size_t scheme_len, const zend_bool persistent, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info TSRMLS_DC);
+typedef php_stream * (*func_mysqlnd_net__open_stream)(MYSQLND_NET * const net, const char * const scheme, const size_t scheme_len, const zend_bool persistent, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info TSRMLS_DC);
+typedef php_stream * (*func_mysqlnd_net__get_stream)(const MYSQLND_NET * const net TSRMLS_DC);
+typedef php_stream * (*func_mysqlnd_net__set_stream)(MYSQLND_NET * const net, php_stream * net_stream TSRMLS_DC);
+typedef func_mysqlnd_net__open_stream (*func_mysqlnd_net__get_open_stream)(MYSQLND_NET * const net, const char * const scheme, const size_t scheme_len, MYSQLND_ERROR_INFO * const error_info TSRMLS_DC);
typedef void (*func_mysqlnd_net__post_connect_set_opt)(MYSQLND_NET * const net, const char * const scheme, const size_t scheme_len, MYSQLND_STATS * const conn_stats, MYSQLND_ERROR_INFO * const error_info TSRMLS_DC);
typedef enum_func_status (*func_mysqlnd_net__read_compressed_packet_from_stream_and_fill_read_buffer)(MYSQLND_NET * net, size_t net_payload_size, MYSQLND_STATS * conn_stats, MYSQLND_ERROR_INFO * error_info TSRMLS_DC);
@@ -295,8 +308,10 @@ struct st_mysqlnd_net_methods
func_mysqlnd_net__open_stream open_pipe;
func_mysqlnd_net__open_stream open_tcp_or_unix;
- void * unused1;
- void * unused2;
+ func_mysqlnd_net__get_stream get_stream;
+ func_mysqlnd_net__set_stream set_stream;
+ func_mysqlnd_net__get_open_stream get_open_stream;
+
func_mysqlnd_net__post_connect_set_opt post_connect_set_opt;
func_mysqlnd_net__set_client_option set_client_option;
@@ -314,11 +329,11 @@ struct st_mysqlnd_net_methods
func_mysqlnd_net__read_compressed_packet_from_stream_and_fill_read_buffer read_compressed_packet_from_stream_and_fill_read_buffer;
+ void * unused1;
+ void * unused2;
void * unused3;
void * unused4;
void * unused5;
- void * unused6;
- void * unused7;
};
@@ -335,6 +350,8 @@ struct st_mysqlnd_packet_stats;
struct st_mysqlnd_packet_prepare_response;
struct st_mysqlnd_packet_chg_user_resp;
struct st_mysqlnd_packet_auth_pam;
+struct st_mysqlnd_packet_sha256_pk_request;
+struct st_mysqlnd_packet_sha256_pk_request_response;
typedef struct st_mysqlnd_packet_greet * (*func_mysqlnd_protocol__get_greet_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC);
typedef struct st_mysqlnd_packet_auth * (*func_mysqlnd_protocol__get_auth_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC);
@@ -349,6 +366,8 @@ typedef struct st_mysqlnd_packet_row * (*func_mysqlnd_protocol__get_row_packet
typedef struct st_mysqlnd_packet_stats * (*func_mysqlnd_protocol__get_stats_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC);
typedef struct st_mysqlnd_packet_prepare_response *(*func_mysqlnd_protocol__get_prepare_response_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC);
typedef struct st_mysqlnd_packet_chg_user_resp*(*func_mysqlnd_protocol__get_change_user_response_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC);
+typedef struct st_mysqlnd_packet_sha256_pk_request *(*func_mysqlnd_protocol__get_sha256_pk_request_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC);
+typedef struct st_mysqlnd_packet_sha256_pk_request_response *(*func_mysqlnd_protocol__get_sha256_pk_request_response_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC);
struct st_mysqlnd_protocol_methods
{
@@ -365,12 +384,12 @@ struct st_mysqlnd_protocol_methods
func_mysqlnd_protocol__get_stats_packet get_stats_packet;
func_mysqlnd_protocol__get_prepare_response_packet get_prepare_response_packet;
func_mysqlnd_protocol__get_change_user_response_packet get_change_user_response_packet;
+ func_mysqlnd_protocol__get_sha256_pk_request_packet get_sha256_pk_request_packet;
+ func_mysqlnd_protocol__get_sha256_pk_request_response_packet get_sha256_pk_request_response_packet;
void * unused1;
void * unused2;
void * unused3;
- void * unused4;
- void * unused5;
};
@@ -447,7 +466,7 @@ typedef enum_func_status (*func_mysqlnd_conn_data__query_read_result_set_header)
typedef MYSQLND_CONN_DATA * (*func_mysqlnd_conn_data__get_reference)(MYSQLND_CONN_DATA * const conn TSRMLS_DC);
typedef enum_func_status (*func_mysqlnd_conn_data__free_reference)(MYSQLND_CONN_DATA * const conn TSRMLS_DC);
-typedef enum mysqlnd_connection_state (*func_mysqlnd_conn_data__get_state)(MYSQLND_CONN_DATA * const conn TSRMLS_DC);
+typedef enum mysqlnd_connection_state (*func_mysqlnd_conn_data__get_state)(const MYSQLND_CONN_DATA * const conn TSRMLS_DC);
typedef void (*func_mysqlnd_conn_data__set_state)(MYSQLND_CONN_DATA * const conn, enum mysqlnd_connection_state new_state TSRMLS_DC);
typedef enum_func_status (*func_mysqlnd_conn_data__simple_command)(MYSQLND_CONN_DATA * conn, enum php_mysqlnd_server_command command, const zend_uchar * const arg, size_t arg_len, enum mysqlnd_packet_type ok_packet, zend_bool silent, zend_bool ignore_upsert_status TSRMLS_DC);
@@ -464,10 +483,21 @@ typedef MYSQLND_RES * (*func_mysqlnd_conn_data__result_init)(unsigned int fiel
typedef enum_func_status (*func_mysqlnd_conn_data__set_autocommit)(MYSQLND_CONN_DATA * conn, unsigned int mode TSRMLS_DC);
typedef enum_func_status (*func_mysqlnd_conn_data__tx_commit)(MYSQLND_CONN_DATA * conn TSRMLS_DC);
typedef enum_func_status (*func_mysqlnd_conn_data__tx_rollback)(MYSQLND_CONN_DATA * conn TSRMLS_DC);
+typedef enum_func_status (*func_mysqlnd_conn_data__tx_begin)(MYSQLND_CONN_DATA * conn, const unsigned int mode, const char * const name TSRMLS_DC);
+typedef enum_func_status (*func_mysqlnd_conn_data__tx_commit_or_rollback)(MYSQLND_CONN_DATA * conn, const zend_bool commit, const unsigned int flags, const char * const name TSRMLS_DC);
+typedef void (*func_mysqlnd_conn_data__tx_cor_options_to_string)(const MYSQLND_CONN_DATA * const conn, smart_str * tmp_str, const unsigned int mode TSRMLS_DC);
+typedef enum_func_status (*func_mysqlnd_conn_data__tx_savepoint)(MYSQLND_CONN_DATA * conn, const char * const name TSRMLS_DC);
+typedef enum_func_status (*func_mysqlnd_conn_data__tx_savepoint_release)(MYSQLND_CONN_DATA * conn, const char * const name TSRMLS_DC);
typedef enum_func_status (*func_mysqlnd_conn_data__local_tx_start)(MYSQLND_CONN_DATA * conn, size_t this_func TSRMLS_DC);
typedef enum_func_status (*func_mysqlnd_conn_data__local_tx_end)(MYSQLND_CONN_DATA * conn, size_t this_func, enum_func_status status TSRMLS_DC);
+typedef enum_func_status (*func_mysqlnd_conn_data__execute_init_commands)(MYSQLND_CONN_DATA * conn TSRMLS_DC);
+typedef unsigned int (*func_mysqlnd_conn_data__get_updated_connect_flags)(MYSQLND_CONN_DATA * conn, unsigned int mysql_flags TSRMLS_DC);
+typedef enum_func_status (*func_mysqlnd_conn_data__connect_handshake)(MYSQLND_CONN_DATA * conn, const char * const host, const char * const user, const char * const passwd, const unsigned int passwd_len, const char * const db, const unsigned int db_len, const unsigned int mysql_flags TSRMLS_DC);
+typedef enum_func_status (*func_mysqlnd_conn_data__simple_command_send_request)(MYSQLND_CONN_DATA * conn, enum php_mysqlnd_server_command command, const zend_uchar * const arg, size_t arg_len, zend_bool silent, zend_bool ignore_upsert_status TSRMLS_DC);
+typedef struct st_mysqlnd_authentication_plugin * (*func_mysqlnd_conn_data__fetch_auth_plugin_by_name)(const char * const requested_protocol TSRMLS_DC);
+typedef enum_func_status (*func_mysqlnd_conn_data__set_client_option_2d)(MYSQLND_CONN_DATA * const conn, enum mysqlnd_option option, const char * const key, const char * const value TSRMLS_DC);
struct st_mysqlnd_conn_data_methods
{
@@ -544,9 +574,22 @@ struct st_mysqlnd_conn_data_methods
func_mysqlnd_conn_data__set_autocommit set_autocommit;
func_mysqlnd_conn_data__tx_commit tx_commit;
func_mysqlnd_conn_data__tx_rollback tx_rollback;
+ func_mysqlnd_conn_data__tx_begin tx_begin;
+ func_mysqlnd_conn_data__tx_commit_or_rollback tx_commit_or_rollback;
+ func_mysqlnd_conn_data__tx_cor_options_to_string tx_cor_options_to_string;
+ func_mysqlnd_conn_data__tx_savepoint tx_savepoint;
+ func_mysqlnd_conn_data__tx_savepoint_release tx_savepoint_release;
func_mysqlnd_conn_data__local_tx_start local_tx_start;
func_mysqlnd_conn_data__local_tx_end local_tx_end;
+
+ func_mysqlnd_conn_data__execute_init_commands execute_init_commands;
+ func_mysqlnd_conn_data__get_updated_connect_flags get_updated_connect_flags;
+ func_mysqlnd_conn_data__connect_handshake connect_handshake;
+ func_mysqlnd_conn_data__simple_command_send_request simple_command_send_request;
+ func_mysqlnd_conn_data__fetch_auth_plugin_by_name fetch_auth_plugin_by_name;
+
+ func_mysqlnd_conn_data__set_client_option_2d set_client_option_2d;
};
@@ -598,9 +641,8 @@ typedef void (*func_mysqlnd_res__unbuffered_free_last_data)(MYSQLND_RES *resu
/* for decoding - binary or text protocol */
typedef enum_func_status (*func_mysqlnd_res__row_decoder)(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields,
- unsigned int field_count, MYSQLND_FIELD *fields_metadata,
- zend_bool as_unicode, zend_bool as_int_or_float,
- MYSQLND_STATS * stats TSRMLS_DC);
+ unsigned int field_count, const MYSQLND_FIELD * fields_metadata,
+ zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC);
typedef MYSQLND_RES_METADATA * (*func_mysqlnd_res__result_meta_init)(unsigned int field_count, zend_bool persistent TSRMLS_DC);
@@ -768,31 +810,44 @@ struct st_mysqlnd_stmt_methods
};
-struct st_mysqlnd_net
+struct st_mysqlnd_net_data
{
php_stream *stream;
+ zend_bool compressed;
+ zend_bool ssl;
+#ifdef MYSQLND_DO_WIRE_CHECK_BEFORE_COMMAND
+ zend_uchar last_command;
+#else
+ zend_uchar unused_pad1;
+#endif
+ MYSQLND_NET_OPTIONS options;
+
+ unsigned int refcount;
+
+ zend_bool persistent;
+
+ struct st_mysqlnd_net_methods m;
+};
+
+
+struct st_mysqlnd_net
+{
+ struct st_mysqlnd_net_data * data;
+
/* sequence for simple checking of correct packets */
zend_uchar packet_no;
- zend_bool compressed;
zend_uchar compressed_envelope_packet_no;
+
#ifdef MYSQLND_COMPRESSION_ENABLED
MYSQLND_READ_BUFFER * uncompressed_data;
#else
void * unused_pad1;
#endif
-#ifdef MYSQLND_DO_WIRE_CHECK_BEFORE_COMMAND
- zend_uchar last_command;
-#else
- zend_uchar unused_pad2;
-#endif
+
/* cmd buffer */
MYSQLND_CMD_BUFFER cmd_buffer;
- MYSQLND_NET_OPTIONS options;
-
- zend_bool persistent;
-
- struct st_mysqlnd_net_methods m;
+ zend_bool persistent;
};
@@ -893,10 +948,6 @@ struct mysqlnd_field_hash_key
{
zend_bool is_numeric;
unsigned long key;
-#if MYSQLND_UNICODE
- zstr ustr;
- unsigned int ulen;
-#endif
};
@@ -1070,7 +1121,8 @@ typedef zend_uchar * (*func_auth_plugin__get_auth_data)(struct st_mysqlnd_authen
size_t * auth_data_len,
MYSQLND_CONN_DATA * conn, const char * const user, const char * const passwd,
const size_t passwd_len, zend_uchar * auth_plugin_data, size_t auth_plugin_data_len,
- const MYSQLND_OPTIONS * const options, unsigned long mysql_flags
+ const MYSQLND_OPTIONS * const options,
+ const MYSQLND_NET_OPTIONS * const net_options, unsigned long mysql_flags
TSRMLS_DC);
struct st_mysqlnd_authentication_plugin
diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c
index d4642bc459..d78d29a2f1 100644
--- a/ext/mysqlnd/mysqlnd_wireprotocol.c
+++ b/ext/mysqlnd/mysqlnd_wireprotocol.c
@@ -47,7 +47,7 @@
(buf_size), (packet)->header.size, (packet)->header.size - (buf_size)); \
DBG_RETURN(FAIL); \
}\
- if (FAIL == conn->net->m.receive_ex((conn)->net, (buf), (packet)->header.size, (conn)->stats, ((conn)->error_info) TSRMLS_CC)) { \
+ if (FAIL == conn->net->data->m.receive_ex((conn)->net, (buf), (packet)->header.size, (conn)->stats, ((conn)->error_info) TSRMLS_CC)) { \
CONN_SET_STATE(conn, CONN_QUIT_SENT); \
SET_CLIENT_ERROR(*conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);\
php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", mysqlnd_server_gone); \
@@ -212,6 +212,24 @@ php_mysqlnd_net_store_length(zend_uchar *packet, uint64_t length)
/* }}} */
+/* {{{ php_mysqlnd_net_store_length_size */
+size_t
+php_mysqlnd_net_store_length_size(uint64_t length)
+{
+ if (length < (uint64_t) L64(251)) {
+ return 1;
+ }
+ if (length < (uint64_t) L64(65536)) {
+ return 3;
+ }
+ if (length < (uint64_t) L64(16777216)) {
+ return 4;
+ }
+ return 8;
+}
+/* }}} */
+
+
/* {{{ php_mysqlnd_read_error_from_line */
static enum_func_status
php_mysqlnd_read_error_from_line(zend_uchar *buf, size_t buf_len,
@@ -264,8 +282,8 @@ mysqlnd_read_header(MYSQLND_NET * net, MYSQLND_PACKET_HEADER * header,
zend_uchar buffer[MYSQLND_HEADER_SIZE];
DBG_ENTER(mysqlnd_read_header_name);
- DBG_INF_FMT("compressed=%u", net->compressed);
- if (FAIL == net->m.receive_ex(net, buffer, MYSQLND_HEADER_SIZE, conn_stats, error_info TSRMLS_CC)) {
+ DBG_INF_FMT("compressed=%u", net->data->compressed);
+ if (FAIL == net->data->m.receive_ex(net, buffer, MYSQLND_HEADER_SIZE, conn_stats, error_info TSRMLS_CC)) {
DBG_RETURN(FAIL);
}
@@ -279,7 +297,7 @@ mysqlnd_read_header(MYSQLND_NET * net, MYSQLND_PACKET_HEADER * header,
STAT_PROTOCOL_OVERHEAD_IN, MYSQLND_HEADER_SIZE,
STAT_PACKETS_RECEIVED, 1);
- if (net->compressed || net->packet_no == header->packet_no) {
+ if (net->data->compressed || net->packet_no == header->packet_no) {
/*
Have to increase the number, so we can send correct number back. It will
round at 255 as this is unsigned char. The server needs this for simple
@@ -459,7 +477,7 @@ void php_mysqlnd_greet_free_mem(void * _packet, zend_bool stack_allocation TSRML
/* }}} */
-#define AUTH_WRITE_BUFFER_LEN (MYSQLND_HEADER_SIZE + MYSQLND_MAX_ALLOWED_USER_LEN + SCRAMBLE_LENGTH + MYSQLND_MAX_ALLOWED_DB_LEN + 1 + 1024)
+#define AUTH_WRITE_BUFFER_LEN (MYSQLND_HEADER_SIZE + MYSQLND_MAX_ALLOWED_USER_LEN + SCRAMBLE_LENGTH + MYSQLND_MAX_ALLOWED_DB_LEN + 1 + 4096)
/* {{{ php_mysqlnd_auth_write */
static
@@ -540,6 +558,52 @@ size_t php_mysqlnd_auth_write(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC
p+= len;
*p++= '\0';
}
+
+ if (packet->connect_attr && zend_hash_num_elements(packet->connect_attr)) {
+ HashPosition pos_value;
+ const char ** entry_value;
+ size_t ca_payload_len = 0;
+ zend_hash_internal_pointer_reset_ex(packet->connect_attr, &pos_value);
+ while (SUCCESS == zend_hash_get_current_data_ex(packet->connect_attr, (void **)&entry_value, &pos_value)) {
+ char *s_key;
+ unsigned int s_len;
+ unsigned long num_key;
+ size_t value_len = strlen(*entry_value);
+
+ if (HASH_KEY_IS_STRING == zend_hash_get_current_key_ex(packet->connect_attr, &s_key, &s_len, &num_key, 0, &pos_value)) {
+ ca_payload_len += php_mysqlnd_net_store_length_size(s_len);
+ ca_payload_len += s_len;
+ ca_payload_len += php_mysqlnd_net_store_length_size(value_len);
+ ca_payload_len += value_len;
+ }
+ zend_hash_move_forward_ex(conn->options->connect_attr, &pos_value);
+ }
+
+ if ((sizeof(buffer) - (p - buffer)) >= (ca_payload_len + php_mysqlnd_net_store_length_size(ca_payload_len))) {
+ p = php_mysqlnd_net_store_length(p, ca_payload_len);
+
+ zend_hash_internal_pointer_reset_ex(packet->connect_attr, &pos_value);
+ while (SUCCESS == zend_hash_get_current_data_ex(packet->connect_attr, (void **)&entry_value, &pos_value)) {
+ char *s_key;
+ unsigned int s_len;
+ unsigned long num_key;
+ size_t value_len = strlen(*entry_value);
+ if (HASH_KEY_IS_STRING == zend_hash_get_current_key_ex(packet->connect_attr, &s_key, &s_len, &num_key, 0, &pos_value)) {
+ /* copy key */
+ p = php_mysqlnd_net_store_length(p, s_len);
+ memcpy(p, s_key, s_len);
+ p+= s_len;
+ /* copy value */
+ p = php_mysqlnd_net_store_length(p, value_len);
+ memcpy(p, *entry_value, value_len);
+ p+= value_len;
+ }
+ zend_hash_move_forward_ex(conn->options->connect_attr, &pos_value);
+ }
+ } else {
+ /* cannot put the data - skip */
+ }
+ }
}
if (packet->is_change_user_packet) {
if (PASS != conn->m->simple_command(conn, COM_CHANGE_USER, buffer + MYSQLND_HEADER_SIZE, p - buffer - MYSQLND_HEADER_SIZE,
@@ -549,7 +613,7 @@ size_t php_mysqlnd_auth_write(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC
}
DBG_RETURN(p - buffer - MYSQLND_HEADER_SIZE);
} else {
- size_t sent = conn->net->m.send_ex(conn->net, buffer, p - buffer - MYSQLND_HEADER_SIZE, conn->stats, conn->error_info TSRMLS_CC);
+ size_t sent = conn->net->data->m.send_ex(conn->net, buffer, p - buffer - MYSQLND_HEADER_SIZE, conn->stats, conn->error_info TSRMLS_CC);
if (!sent) {
CONN_SET_STATE(conn, CONN_QUIT_SENT);
}
@@ -623,7 +687,7 @@ php_mysqlnd_auth_response_read(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_D
memcpy(packet->new_auth_protocol_data, p, packet->new_auth_protocol_data_len);
}
DBG_INF_FMT("The server requested switching auth plugin to : %s", packet->new_auth_protocol);
- DBG_INF_FMT("Server salt : [%*s]", packet->new_auth_protocol_data_len, packet->new_auth_protocol_data);
+ DBG_INF_FMT("Server salt : [%d][%.*s]", packet->new_auth_protocol_data_len, packet->new_auth_protocol_data_len, packet->new_auth_protocol_data);
}
} else {
/* Everything was fine! */
@@ -709,7 +773,7 @@ php_mysqlnd_change_auth_response_write(void * _packet, MYSQLND_CONN_DATA * conn
}
{
- size_t sent = conn->net->m.send_ex(conn->net, buffer, p - buffer - MYSQLND_HEADER_SIZE, conn->stats, conn->error_info TSRMLS_CC);
+ size_t sent = conn->net->data->m.send_ex(conn->net, buffer, p - buffer - MYSQLND_HEADER_SIZE, conn->stats, conn->error_info TSRMLS_CC);
if (buffer != conn->net->cmd_buffer.buffer) {
mnd_efree(buffer);
}
@@ -924,14 +988,14 @@ size_t php_mysqlnd_cmd_write(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC)
MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_PACKETS_SENT_CMD);
#ifdef MYSQLND_DO_WIRE_CHECK_BEFORE_COMMAND
- net->m.consume_uneaten_data(net, packet->command TSRMLS_CC);
+ net->data->m.consume_uneaten_data(net, packet->command TSRMLS_CC);
#endif
if (!packet->argument || !packet->arg_len) {
zend_uchar buffer[MYSQLND_HEADER_SIZE + 1];
int1store(buffer + MYSQLND_HEADER_SIZE, packet->command);
- sent = net->m.send_ex(net, buffer, 1, conn->stats, conn->error_info TSRMLS_CC);
+ sent = net->data->m.send_ex(net, buffer, 1, conn->stats, conn->error_info TSRMLS_CC);
} else {
size_t tmp_len = packet->arg_len + 1 + MYSQLND_HEADER_SIZE;
zend_uchar *tmp, *p;
@@ -946,7 +1010,7 @@ size_t php_mysqlnd_cmd_write(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC)
memcpy(p, packet->argument, packet->arg_len);
- sent = net->m.send_ex(net, tmp, tmp_len - MYSQLND_HEADER_SIZE, conn->stats, conn->error_info TSRMLS_CC);
+ sent = net->data->m.send_ex(net, tmp, tmp_len - MYSQLND_HEADER_SIZE, conn->stats, conn->error_info TSRMLS_CC);
if (tmp != net->cmd_buffer.buffer) {
MYSQLND_INC_CONN_STATISTIC(conn->stats, STAT_CMD_BUFFER_TOO_SMALL);
mnd_efree(tmp);
@@ -1390,7 +1454,7 @@ php_mysqlnd_read_row_ex(MYSQLND_CONN_DATA * conn, MYSQLND_MEMORY_POOL * result_s
p = (*buffer)->ptr + (*data_size - header.size);
}
- if (PASS != (ret = conn->net->m.receive_ex(conn->net, p, header.size, conn->stats, conn->error_info TSRMLS_CC))) {
+ if (PASS != (ret = conn->net->data->m.receive_ex(conn->net, p, header.size, conn->stats, conn->error_info TSRMLS_CC))) {
DBG_ERR("Empty row packet body");
php_error(E_WARNING, "Empty row packet body");
break;
@@ -1413,9 +1477,8 @@ php_mysqlnd_read_row_ex(MYSQLND_CONN_DATA * conn, MYSQLND_MEMORY_POOL * result_s
/* {{{ php_mysqlnd_rowp_read_binary_protocol */
enum_func_status
php_mysqlnd_rowp_read_binary_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields,
- unsigned int field_count, MYSQLND_FIELD *fields_metadata,
- zend_bool as_unicode, zend_bool as_int_or_float,
- MYSQLND_STATS * stats TSRMLS_DC)
+ unsigned int field_count, const MYSQLND_FIELD * fields_metadata,
+ zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC)
{
unsigned int i;
zend_uchar * p = row_buffer->ptr;
@@ -1448,17 +1511,17 @@ php_mysqlnd_rowp_read_binary_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zv
enum_mysqlnd_collected_stats statistic;
zend_uchar * orig_p = p;
- DBG_INF_FMT("Into zval=%p decoding column %u [%s.%s.%s] type=%u field->flags&unsigned=%u flags=%u is_bit=%u as_unicode=%u",
+ DBG_INF_FMT("Into zval=%p decoding column %u [%s.%s.%s] type=%u field->flags&unsigned=%u flags=%u is_bit=%u",
*current_field, i,
fields_metadata[i].db, fields_metadata[i].table, fields_metadata[i].name, fields_metadata[i].type,
- fields_metadata[i].flags & UNSIGNED_FLAG, fields_metadata[i].flags, fields_metadata[i].type == MYSQL_TYPE_BIT, as_unicode);
+ fields_metadata[i].flags & UNSIGNED_FLAG, fields_metadata[i].flags, fields_metadata[i].type == MYSQL_TYPE_BIT);
if (*null_ptr & bit) {
DBG_INF("It's null");
ZVAL_NULL(*current_field);
statistic = STAT_BINARY_TYPE_FETCHED_NULL;
} else {
enum_mysqlnd_field_types type = fields_metadata[i].type;
- mysqlnd_ps_fetch_functions[type].func(*current_field, &fields_metadata[i], 0, &p, as_unicode TSRMLS_CC);
+ mysqlnd_ps_fetch_functions[type].func(*current_field, &fields_metadata[i], 0, &p TSRMLS_CC);
if (MYSQLND_G(collect_statistics)) {
switch (fields_metadata[i].type) {
@@ -1512,9 +1575,8 @@ php_mysqlnd_rowp_read_binary_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zv
/* {{{ php_mysqlnd_rowp_read_text_protocol */
enum_func_status
php_mysqlnd_rowp_read_text_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields,
- unsigned int field_count, MYSQLND_FIELD *fields_metadata,
- zend_bool as_unicode, zend_bool as_int_or_float,
- MYSQLND_STATS * stats TSRMLS_DC)
+ unsigned int field_count, const MYSQLND_FIELD * fields_metadata,
+ zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC)
{
unsigned int i;
zend_bool last_field_was_string = FALSE;
@@ -1566,7 +1628,7 @@ php_mysqlnd_rowp_read_text_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval
ZVAL_NULL(*current_field);
last_field_was_string = FALSE;
} else {
-#if MYSQLND_UNICODE || defined(MYSQLND_STRING_TO_INT_CONVERSION)
+#if defined(MYSQLND_STRING_TO_INT_CONVERSION)
struct st_mysqlnd_perm_bind perm_bind =
mysqlnd_ps_fetch_functions[fields_metadata[i].type];
#endif
@@ -1662,7 +1724,7 @@ php_mysqlnd_rowp_read_text_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval
Definitely not nice, _hackish_ :(, but works.
*/
zend_uchar *start = bit_area;
- ps_fetch_from_1_to_8_bytes(*current_field, &(fields_metadata[i]), 0, &p, as_unicode, len TSRMLS_CC);
+ ps_fetch_from_1_to_8_bytes(*current_field, &(fields_metadata[i]), 0, &p, len TSRMLS_CC);
/*
We have advanced in ps_fetch_from_1_to_8_bytes. We should go back because
later in this function there will be an advancement.
@@ -1670,60 +1732,16 @@ php_mysqlnd_rowp_read_text_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval
p -= len;
if (Z_TYPE_PP(current_field) == IS_LONG) {
bit_area += 1 + sprintf((char *)start, "%ld", Z_LVAL_PP(current_field));
-#if MYSQLND_UNICODE
- if (as_unicode) {
- ZVAL_UTF8_STRINGL(*current_field, start, bit_area - start - 1, 0);
- } else
-#endif
- {
- ZVAL_STRINGL(*current_field, (char *) start, bit_area - start - 1, 0);
- }
+ ZVAL_STRINGL(*current_field, (char *) start, bit_area - start - 1, 0);
} else if (Z_TYPE_PP(current_field) == IS_STRING){
memcpy(bit_area, Z_STRVAL_PP(current_field), Z_STRLEN_PP(current_field));
bit_area += Z_STRLEN_PP(current_field);
*bit_area++ = '\0';
zval_dtor(*current_field);
-#if MYSQLND_UNICODE
- if (as_unicode) {
- ZVAL_UTF8_STRINGL(*current_field, start, bit_area - start - 1, 0);
- } else
-#endif
- {
- ZVAL_STRINGL(*current_field, (char *) start, bit_area - start - 1, 0);
- }
+ ZVAL_STRINGL(*current_field, (char *) start, bit_area - start - 1, 0);
}
- /*
- IS_UNICODE should not be specially handled. In unicode mode
- the buffers are not referenced - everything is copied.
- */
} else
-#if MYSQLND_UNICODE == 0
- {
- ZVAL_STRINGL(*current_field, (char *)p, len, 0);
- }
-#else
- /*
- Here we have to convert to UTF16, which means not reusing the buffer.
- Which in turn means that we can free the buffers once we have
- stored the result set, if we use store_result().
-
- Also the destruction of the zvals should not call zval_copy_ctor()
- because then we will leak.
-
- XXX: Keep in mind that up there there is an open `else` in
- #ifdef MYSQLND_STRING_TO_INT_CONVERSION
- which will make with this `if` an `else if`.
- */
- if ((perm_bind.is_possibly_blob == TRUE &&
- fields_metadata[i].charsetnr == MYSQLND_BINARY_CHARSET_NR) ||
- (!as_unicode && perm_bind.can_ret_as_str_in_uni == TRUE))
- {
- /* BLOB - no conversion please */
- ZVAL_STRINGL(*current_field, (char *)p, len, 0);
- } else {
- ZVAL_UTF8_STRINGL(*current_field, (char *)p, len, 0);
- }
-#endif
+ ZVAL_STRINGL(*current_field, (char *)p, len, 0);
p += len;
last_field_was_string = TRUE;
}
@@ -1746,10 +1764,8 @@ php_mysqlnd_rowp_read_text_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval
static enum_func_status
php_mysqlnd_rowp_read(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC)
{
- MYSQLND_NET * net = conn->net;
zend_uchar *p;
enum_func_status ret = PASS;
- size_t old_chunk_size = net->stream->chunk_size;
MYSQLND_PACKET_ROW *packet= (MYSQLND_PACKET_ROW *) _packet;
size_t post_alloc_for_bit_fields = 0;
size_t data_size = 0;
@@ -1831,7 +1847,6 @@ php_mysqlnd_rowp_read(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC)
}
end:
- net->stream->chunk_size = old_chunk_size;
DBG_RETURN(ret);
}
/* }}} */
@@ -2083,6 +2098,89 @@ php_mysqlnd_chg_user_free_mem(void * _packet, zend_bool stack_allocation TSRMLS_
/* }}} */
+/* {{{ php_mysqlnd_sha256_pk_request_write */
+static
+size_t php_mysqlnd_sha256_pk_request_write(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC)
+{
+ zend_uchar buffer[MYSQLND_HEADER_SIZE + 1];
+ size_t sent;
+
+ DBG_ENTER("php_mysqlnd_sha256_pk_request_write");
+
+ int1store(buffer + MYSQLND_HEADER_SIZE, '\1');
+ sent = conn->net->data->m.send_ex(conn->net, buffer, 1, conn->stats, conn->error_info TSRMLS_CC);
+
+ DBG_RETURN(sent);
+}
+/* }}} */
+
+
+/* {{{ php_mysqlnd_sha256_pk_request_free_mem */
+static
+void php_mysqlnd_sha256_pk_request_free_mem(void * _packet, zend_bool stack_allocation TSRMLS_DC)
+{
+ if (!stack_allocation) {
+ MYSQLND_PACKET_SHA256_PK_REQUEST * p = (MYSQLND_PACKET_SHA256_PK_REQUEST *) _packet;
+ mnd_pefree(p, p->header.persistent);
+ }
+}
+/* }}} */
+
+
+#define SHA256_PK_REQUEST_RESP_BUFFER_SIZE 2048
+
+/* {{{ php_mysqlnd_sha256_pk_request_response_read */
+static enum_func_status
+php_mysqlnd_sha256_pk_request_response_read(void * _packet, MYSQLND_CONN_DATA * conn TSRMLS_DC)
+{
+ zend_uchar buf[SHA256_PK_REQUEST_RESP_BUFFER_SIZE];
+ zend_uchar *p = buf;
+ zend_uchar *begin = buf;
+ MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE * packet= (MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE *) _packet;
+
+ DBG_ENTER("php_mysqlnd_sha256_pk_request_response_read");
+
+ /* leave space for terminating safety \0 */
+ PACKET_READ_HEADER_AND_BODY(packet, conn, buf, sizeof(buf), "SHA256_PK_REQUEST_RESPONSE", PROT_SHA256_PK_REQUEST_RESPONSE_PACKET);
+ BAIL_IF_NO_MORE_DATA;
+
+ p++;
+ BAIL_IF_NO_MORE_DATA;
+
+ packet->public_key_len = packet->header.size - (p - buf);
+ packet->public_key = mnd_emalloc(packet->public_key_len + 1);
+ memcpy(packet->public_key, p, packet->public_key_len);
+ packet->public_key[packet->public_key_len] = '\0';
+
+ DBG_RETURN(PASS);
+
+premature_end:
+ DBG_ERR_FMT("OK packet %d bytes shorter than expected", p - begin - packet->header.size);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "SHA256_PK_REQUEST_RESPONSE packet "MYSQLND_SZ_T_SPEC" bytes shorter than expected",
+ p - begin - packet->header.size);
+ DBG_RETURN(FAIL);
+}
+/* }}} */
+
+
+/* {{{ php_mysqlnd_sha256_pk_request_response_free_mem */
+static void
+php_mysqlnd_sha256_pk_request_response_free_mem(void * _packet, zend_bool stack_allocation TSRMLS_DC)
+{
+ MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE * p = (MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE *) _packet;
+ if (p->public_key) {
+ mnd_efree(p->public_key);
+ p->public_key = NULL;
+ }
+ p->public_key_len = 0;
+
+ if (!stack_allocation) {
+ mnd_pefree(p, p->header.persistent);
+ }
+}
+/* }}} */
+
+
/* {{{ packet_methods */
static
mysqlnd_packet_methods packet_methods[PROT_LAST] =
@@ -2164,7 +2262,19 @@ mysqlnd_packet_methods packet_methods[PROT_LAST] =
php_mysqlnd_chg_user_read, /* read */
NULL, /* write */
php_mysqlnd_chg_user_free_mem,
- } /* PROT_CHG_USER_RESP_PACKET */
+ }, /* PROT_CHG_USER_RESP_PACKET */
+ {
+ sizeof(MYSQLND_PACKET_SHA256_PK_REQUEST),
+ NULL, /* read */
+ php_mysqlnd_sha256_pk_request_write,
+ php_mysqlnd_sha256_pk_request_free_mem,
+ }, /* PROT_SHA256_PK_REQUEST_PACKET */
+ {
+ sizeof(MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE),
+ php_mysqlnd_sha256_pk_request_response_read,
+ NULL, /* write */
+ php_mysqlnd_sha256_pk_request_response_free_mem,
+ } /* PROT_SHA256_PK_REQUEST_RESPONSE_PACKET */
};
/* }}} */
@@ -2364,6 +2474,37 @@ MYSQLND_METHOD(mysqlnd_protocol, get_change_user_response_packet)(MYSQLND_PROTOC
/* }}} */
+/* {{{ mysqlnd_protocol::get_sha256_pk_request_packet */
+static struct st_mysqlnd_packet_sha256_pk_request *
+MYSQLND_METHOD(mysqlnd_protocol, get_sha256_pk_request_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC)
+{
+ struct st_mysqlnd_packet_sha256_pk_request * packet = mnd_pecalloc(1, packet_methods[PROT_SHA256_PK_REQUEST_PACKET].struct_size, persistent);
+ DBG_ENTER("mysqlnd_protocol::get_sha256_pk_request_packet");
+ if (packet) {
+ packet->header.m = &packet_methods[PROT_SHA256_PK_REQUEST_PACKET];
+ packet->header.persistent = persistent;
+ }
+ DBG_RETURN(packet);
+}
+/* }}} */
+
+
+/* {{{ mysqlnd_protocol::get_sha256_pk_request_response_packet */
+static struct st_mysqlnd_packet_sha256_pk_request_response *
+MYSQLND_METHOD(mysqlnd_protocol, get_sha256_pk_request_response_packet)(MYSQLND_PROTOCOL * const protocol, zend_bool persistent TSRMLS_DC)
+{
+ struct st_mysqlnd_packet_sha256_pk_request_response * packet = mnd_pecalloc(1, packet_methods[PROT_SHA256_PK_REQUEST_RESPONSE_PACKET].struct_size, persistent);
+ DBG_ENTER("mysqlnd_protocol::get_sha256_pk_request_response_packet");
+ if (packet) {
+ packet->header.m = &packet_methods[PROT_SHA256_PK_REQUEST_RESPONSE_PACKET];
+ packet->header.persistent = persistent;
+ }
+ DBG_RETURN(packet);
+}
+/* }}} */
+
+
+
MYSQLND_CLASS_METHODS_START(mysqlnd_protocol)
MYSQLND_METHOD(mysqlnd_protocol, get_greet_packet),
MYSQLND_METHOD(mysqlnd_protocol, get_auth_packet),
@@ -2377,7 +2518,9 @@ MYSQLND_CLASS_METHODS_START(mysqlnd_protocol)
MYSQLND_METHOD(mysqlnd_protocol, get_row_packet),
MYSQLND_METHOD(mysqlnd_protocol, get_stats_packet),
MYSQLND_METHOD(mysqlnd_protocol, get_prepare_response_packet),
- MYSQLND_METHOD(mysqlnd_protocol, get_change_user_response_packet)
+ MYSQLND_METHOD(mysqlnd_protocol, get_change_user_response_packet),
+ MYSQLND_METHOD(mysqlnd_protocol, get_sha256_pk_request_packet),
+ MYSQLND_METHOD(mysqlnd_protocol, get_sha256_pk_request_response_packet)
MYSQLND_CLASS_METHODS_END;
diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.h b/ext/mysqlnd/mysqlnd_wireprotocol.h
index 8f48374b1b..4bd33592bf 100644
--- a/ext/mysqlnd/mysqlnd_wireprotocol.h
+++ b/ext/mysqlnd/mysqlnd_wireprotocol.h
@@ -103,7 +103,7 @@ typedef struct st_mysqlnd_packet_auth {
zend_bool send_auth_data;
zend_bool is_change_user_packet;
zend_bool silent;
-
+ HashTable *connect_attr;
} MYSQLND_PACKET_AUTH;
/* Auth response packet */
@@ -286,6 +286,18 @@ typedef struct st_mysqlnd_packet_chg_user_resp {
} MYSQLND_PACKET_CHG_USER_RESPONSE;
+/* Command packet */
+typedef struct st_mysqlnd_packet_sha256_pk_request {
+ MYSQLND_PACKET_HEADER header;
+} MYSQLND_PACKET_SHA256_PK_REQUEST;
+
+typedef struct st_mysqlnd_packet_sha256_pk_request_response {
+ MYSQLND_PACKET_HEADER header;
+ zend_uchar *public_key;
+ size_t public_key_len;
+} MYSQLND_PACKET_SHA256_PK_REQUEST_RESPONSE;
+
+
PHPAPI void php_mysqlnd_scramble(zend_uchar * const buffer, const zend_uchar * const scramble, const zend_uchar * const pass, size_t pass_len);
unsigned long php_mysqlnd_net_field_length(zend_uchar **packet);
@@ -295,15 +307,13 @@ PHPAPI const extern char * const mysqlnd_empty_string;
enum_func_status php_mysqlnd_rowp_read_binary_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields,
- unsigned int field_count, MYSQLND_FIELD *fields_metadata,
- zend_bool as_unicode, zend_bool as_int_or_float,
- MYSQLND_STATS * stats TSRMLS_DC);
+ unsigned int field_count, const MYSQLND_FIELD * fields_metadata,
+ zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC);
enum_func_status php_mysqlnd_rowp_read_text_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffer, zval ** fields,
- unsigned int field_count, MYSQLND_FIELD *fields_metadata,
- zend_bool as_unicode, zend_bool as_int_or_float,
- MYSQLND_STATS * stats TSRMLS_DC);
+ unsigned int field_count, const MYSQLND_FIELD * fields_metadata,
+ zend_bool as_int_or_float, MYSQLND_STATS * stats TSRMLS_DC);
PHPAPI MYSQLND_PROTOCOL * mysqlnd_protocol_init(zend_bool persistent TSRMLS_DC);
diff --git a/ext/mysqlnd/php_mysqlnd.c b/ext/mysqlnd/php_mysqlnd.c
index 353710bedb..7712f1ecb8 100644
--- a/ext/mysqlnd/php_mysqlnd.c
+++ b/ext/mysqlnd/php_mysqlnd.c
@@ -40,39 +40,8 @@ static zend_function_entry mysqlnd_functions[] = {
/* {{{ mysqlnd_minfo_print_hash */
-#if MYSQLND_UNICODE
-PHPAPI void mysqlnd_minfo_print_hash(zval *values)
-{
- zval **values_entry;
- HashPosition pos_values;
-
- zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(values), &pos_values);
- while (zend_hash_get_current_data_ex(Z_ARRVAL_P(values),
- (void **)&values_entry, &pos_values) == SUCCESS) {
- zstr string_key;
- uint string_key_len;
- ulong num_key;
- int s_len;
- char *s = NULL;
-
- TSRMLS_FETCH();
- zend_hash_get_current_key_ex(Z_ARRVAL_P(values), &string_key, &string_key_len, &num_key, 0, &pos_values);
-
- convert_to_string(*values_entry);
-
- if (zend_unicode_to_string(ZEND_U_CONVERTER(UG(runtime_encoding_conv)),
- &s, &s_len, string_key.u, string_key_len TSRMLS_CC) == SUCCESS) {
- php_info_print_table_row(2, s, Z_STRVAL_PP(values_entry));
- }
- if (s) {
- mnd_efree(s);
- }
-
- zend_hash_move_forward_ex(Z_ARRVAL_P(values), &pos_values);
- }
-}
-#else
-PHPAPI void mysqlnd_minfo_print_hash(zval *values)
+PHPAPI void
+mysqlnd_minfo_print_hash(zval *values)
{
zval **values_entry;
HashPosition pos_values;
@@ -91,7 +60,6 @@ PHPAPI void mysqlnd_minfo_print_hash(zval *values)
zend_hash_move_forward_ex(Z_ARRVAL_P(values), &pos_values);
}
}
-#endif
/* }}} */
@@ -170,12 +138,18 @@ PHP_MINFO_FUNCTION(mysqlnd)
#else
"not supported");
#endif
- php_info_print_table_row(2, "SSL",
+ php_info_print_table_row(2, "core SSL",
#ifdef MYSQLND_SSL_SUPPORTED
"supported");
#else
"not supported");
#endif
+ php_info_print_table_row(2, "extended SSL",
+#ifdef MYSQLND_HAVE_SSL
+ "supported");
+#else
+ "not supported");
+#endif
snprintf(buf, sizeof(buf), "%ld", MYSQLND_G(net_cmd_buffer_size));
php_info_print_table_row(2, "Command buffer size", buf);
snprintf(buf, sizeof(buf), "%ld", MYSQLND_G(net_read_buffer_size));
@@ -221,6 +195,8 @@ 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->trace_alloc_settings = NULL;
+ mysqlnd_globals->trace_alloc = NULL;
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;
@@ -232,6 +208,7 @@ static PHP_GINIT_FUNCTION(mysqlnd)
mysqlnd_globals->debug_malloc_fail_threshold = -1;
mysqlnd_globals->debug_calloc_fail_threshold = -1;
mysqlnd_globals->debug_realloc_fail_threshold = -1;
+ mysqlnd_globals->sha256_server_public_key = NULL;
}
/* }}} */
@@ -253,11 +230,13 @@ 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.trace_alloc", NULL, PHP_INI_SYSTEM, OnUpdateString, trace_alloc_settings, 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)
STD_PHP_INI_ENTRY("mysqlnd.mempool_default_size","16000", PHP_INI_ALL, OnUpdateLong, mempool_default_size, zend_mysqlnd_globals, mysqlnd_globals)
+ STD_PHP_INI_ENTRY("mysqlnd.sha256_server_public_key",NULL, PHP_INI_PERDIR, OnUpdateString, sha256_server_public_key, zend_mysqlnd_globals, mysqlnd_globals)
#if PHP_DEBUG
STD_PHP_INI_ENTRY("mysqlnd.debug_emalloc_fail_threshold","-1", PHP_INI_SYSTEM, OnUpdateLong, debug_emalloc_fail_threshold, zend_mysqlnd_globals, mysqlnd_globals)
@@ -306,11 +285,14 @@ static PHP_RINIT_FUNCTION(mysqlnd)
MYSQLND_G(dbg) = NULL;
if (trace_log_plugin) {
MYSQLND_DEBUG * dbg = trace_log_plugin->methods.trace_instance_init(mysqlnd_debug_std_no_trace_funcs TSRMLS_CC);
- if (!dbg) {
+ MYSQLND_DEBUG * trace_alloc = trace_log_plugin->methods.trace_instance_init(NULL TSRMLS_CC);
+ if (!dbg || !trace_alloc) {
return FAILURE;
}
dbg->m->set_mode(dbg, MYSQLND_G(debug));
+ trace_alloc->m->set_mode(trace_alloc, MYSQLND_G(trace_alloc_settings));
MYSQLND_G(dbg) = dbg;
+ MYSQLND_G(trace_alloc) = trace_alloc;
}
}
return SUCCESS;
@@ -324,13 +306,19 @@ static PHP_RINIT_FUNCTION(mysqlnd)
*/
static PHP_RSHUTDOWN_FUNCTION(mysqlnd)
{
- MYSQLND_DEBUG *dbg = MYSQLND_G(dbg);
+ MYSQLND_DEBUG * dbg = MYSQLND_G(dbg);
+ MYSQLND_DEBUG * trace_alloc = MYSQLND_G(trace_alloc);
DBG_ENTER("RSHUTDOWN");
if (dbg) {
dbg->m->close(dbg);
dbg->m->free_handle(dbg);
MYSQLND_G(dbg) = NULL;
}
+ if (trace_alloc) {
+ trace_alloc->m->close(trace_alloc);
+ trace_alloc->m->free_handle(trace_alloc);
+ MYSQLND_G(trace_alloc) = NULL;
+ }
return SUCCESS;
}
/* }}} */
diff --git a/ext/oci8/config.m4 b/ext/oci8/config.m4
index 34ae76c44b..39c037548a 100644
--- a/ext/oci8/config.m4
+++ b/ext/oci8/config.m4
@@ -103,7 +103,7 @@ dnl --with-oci8=shared,instantclient,/path/to/client/dir/lib
dnl or
dnl --with-oci8=shared,/path/to/oracle/home
PHP_ARG_WITH(oci8, for Oracle Database OCI8 support,
-[ --with-oci8[=DIR] Include Oracle Database OCI8 support. DIR defaults to \$ORACLE_HOME.
+[ --with-oci8[=DIR] Include Oracle Database OCI8 support. DIR defaults to \$ORACLE_HOME.
Use --with-oci8=instantclient,/path/to/instant/client/lib
to use an Oracle Instant Client installation])
diff --git a/ext/oci8/package.xml b/ext/oci8/package.xml
index c51d216f32..feadf1907b 100644
--- a/ext/oci8/package.xml
+++ b/ext/oci8/package.xml
@@ -6,7 +6,7 @@ http://pear.php.net/dtd/package-2.0.xsd">
<name>oci8</name>
<channel>pecl.php.net</channel>
<summary>Extension for Oracle Database</summary>
- <description>This extension allows you to access Oracle databases. It can be built with PHP 4.3.9 to 5.x. It can be linked with Oracle 9.2, 10.2, 11.1, or 11.2 client libraries.
+ <description>This extension allows you to access Oracle databases. It can be built with PHP 4.3.9 to 5.x. It can be linked with Oracle 9.2, 10, 11, or 12.1 client libraries.
</description>
<lead>
<name>Christopher Jones</name>
@@ -33,12 +33,12 @@ http://pear.php.net/dtd/package-2.0.xsd">
<active>no</active>
</lead>
- <date>2012-10-21</date>
+ <date>2013-07-08</date>
<time>12:00:00</time>
<version>
- <release>1.4.9</release>
- <api>1.4.9</api>
+ <release>1.4.10</release>
+ <api>1.4.10</api>
</version>
<stability>
<release>stable</release>
@@ -46,7 +46,7 @@ http://pear.php.net/dtd/package-2.0.xsd">
</stability>
<license uri="http://www.php.net/license">PHP</license>
<notes>
- Re-fixed bug #60901 (Improve "tail" syntax for AIX installation)
+ Bump PECL package info version check to allow PECL installs with PHP 5.5+
</notes>
<contents>
<dir name="/">
@@ -397,7 +397,7 @@ http://pear.php.net/dtd/package-2.0.xsd">
<required>
<php>
<min>4.3.9</min>
- <max>5.4.99</max>
+ <max>6.0.0</max>
</php>
<pearinstaller>
<min>1.4.0b1</min>
@@ -412,6 +412,21 @@ http://pear.php.net/dtd/package-2.0.xsd">
<release>
<version>
+ <release>1.4.9</release>
+ <api>1.4.9</api>
+ </version>
+ <stability>
+ <release>stable</release>
+ <api>stable</api>
+ </stability>
+ <license uri="http://www.php.net/license">PHP</license>
+ <notes>
+ Re-fixed bug #60901 (Improve "tail" syntax for AIX installation)
+ </notes>
+</release>
+
+<release>
+ <version>
<release>1.4.8</release>
<api>1.4.8</api>
</version>
diff --git a/ext/oci8/php_oci8.h b/ext/oci8/php_oci8.h
index 1c7507ae05..65b8851ed0 100644
--- a/ext/oci8/php_oci8.h
+++ b/ext/oci8/php_oci8.h
@@ -46,7 +46,7 @@
*/
#undef PHP_OCI8_VERSION
#endif
-#define PHP_OCI8_VERSION "1.4.9"
+#define PHP_OCI8_VERSION "1.4.10"
extern zend_module_entry oci8_module_entry;
#define phpext_oci8_ptr &oci8_module_entry
diff --git a/ext/oci8/php_oci8_int.h b/ext/oci8/php_oci8_int.h
index 6671573969..0bc80c3d9c 100644
--- a/ext/oci8/php_oci8_int.h
+++ b/ext/oci8/php_oci8_int.h
@@ -191,7 +191,7 @@ typedef struct { /* php_oci_statement {{{ */
sword errcode; /* last errcode*/
OCIError *err; /* private error handle */
OCIStmt *stmt; /* statement handle */
- char *last_query; /* last query issued. also used to determine if this is a statement or a refcursor recieved from Oracle */
+ char *last_query; /* last query issued. also used to determine if this is a statement or a refcursor received from Oracle */
long last_query_len; /* last query length */
HashTable *columns; /* hash containing all the result columns */
HashTable *binds; /* binds hash */
diff --git a/ext/odbc/config.m4 b/ext/odbc/config.m4
index a1201db57c..eaed212cd7 100644
--- a/ext/odbc/config.m4
+++ b/ext/odbc/config.m4
@@ -101,7 +101,7 @@ dnl configure options
dnl
if test -z "$ODBC_TYPE"; then
PHP_ARG_WITH(adabas,,
-[ --with-adabas[=DIR] Include Adabas D support [/usr/local]])
+[ --with-adabas[=DIR] Include Adabas D support [/usr/local]])
if test "$PHP_ADABAS" != "no"; then
AC_MSG_CHECKING([for Adabas support])
@@ -128,7 +128,7 @@ fi
if test -z "$ODBC_TYPE"; then
PHP_ARG_WITH(sapdb,,
-[ --with-sapdb[=DIR] Include SAP DB support [/usr/local]])
+[ --with-sapdb[=DIR] Include SAP DB support [/usr/local]])
if test "$PHP_SAPDB" != "no"; then
AC_MSG_CHECKING([for SAP DB support])
@@ -146,7 +146,7 @@ fi
if test -z "$ODBC_TYPE"; then
PHP_ARG_WITH(solid,,
-[ --with-solid[=DIR] Include Solid support [/usr/local/solid]])
+[ --with-solid[=DIR] Include Solid support [/usr/local/solid]])
if test "$PHP_SOLID" != "no"; then
AC_MSG_CHECKING(for Solid support)
@@ -171,7 +171,7 @@ fi
if test -z "$ODBC_TYPE"; then
PHP_ARG_WITH(ibm-db2,,
-[ --with-ibm-db2[=DIR] Include IBM DB2 support [/home/db2inst1/sqllib]])
+[ --with-ibm-db2[=DIR] Include IBM DB2 support [/home/db2inst1/sqllib]])
if test "$PHP_IBM_DB2" != "no"; then
AC_MSG_CHECKING(for IBM DB2 support)
@@ -208,7 +208,7 @@ fi
if test -z "$ODBC_TYPE"; then
PHP_ARG_WITH(ODBCRouter,,
-[ --with-ODBCRouter[=DIR] Include ODBCRouter.com support [/usr]])
+[ --with-ODBCRouter[=DIR] Include ODBCRouter.com support [/usr]])
if test "$PHP_ODBCROUTER" != "no"; then
AC_MSG_CHECKING(for ODBCRouter.com support)
@@ -228,7 +228,7 @@ fi
if test -z "$ODBC_TYPE"; then
PHP_ARG_WITH(empress,,
-[ --with-empress[=DIR] Include Empress support [\$EMPRESSPATH]
+[ --with-empress[=DIR] Include Empress support [\$EMPRESSPATH]
(Empress Version >= 8.60 required)])
if test "$PHP_EMPRESS" != "no"; then
@@ -291,7 +291,7 @@ fi
if test -z "$ODBC_TYPE"; then
PHP_ARG_WITH(birdstep,,
-[ --with-birdstep[=DIR] Include Birdstep support [/usr/local/birdstep]])
+[ --with-birdstep[=DIR] Include Birdstep support [/usr/local/birdstep]])
if test "$PHP_BIRDSTEP" != "no"; then
AC_MSG_CHECKING(for Birdstep support)
@@ -338,15 +338,14 @@ fi
if test -z "$ODBC_TYPE"; then
PHP_ARG_WITH(custom-odbc,,
-[ --with-custom-odbc[=DIR]
- Include user defined ODBC support. DIR is ODBC install base
+[ --with-custom-odbc[=DIR] Include user defined ODBC support. DIR is ODBC install base
directory [/usr/local]. Make sure to define CUSTOM_ODBC_LIBS and
have some odbc.h in your include dirs. f.e. you should define
following for Sybase SQL Anywhere 5.5.00 on QNX, prior to
running this configure script:
- CPPFLAGS=\"-DODBC_QNX -DSQLANY_BUG\"
- LDFLAGS=-lunix
- CUSTOM_ODBC_LIBS=\"-ldblib -lodbc\"])
+ CPPFLAGS=\"-DODBC_QNX -DSQLANY_BUG\"
+ LDFLAGS=-lunix
+ CUSTOM_ODBC_LIBS=\"-ldblib -lodbc\"])
if test "$PHP_CUSTOM_ODBC" != "no"; then
AC_MSG_CHECKING(for a custom ODBC support)
@@ -360,13 +359,13 @@ PHP_ARG_WITH(custom-odbc,,
ODBC_LIBS=$CUSTOM_ODBC_LIBS
ODBC_TYPE=custom-odbc
AC_DEFINE(HAVE_CODBC,1,[ ])
- AC_MSG_RESULT([$ext_ouput])
+ AC_MSG_RESULT([$ext_output])
fi
fi
if test -z "$ODBC_TYPE"; then
PHP_ARG_WITH(iodbc,,
-[ --with-iodbc[=DIR] Include iODBC support [/usr/local]])
+[ --with-iodbc[=DIR] Include iODBC support [/usr/local]])
if test "$PHP_IODBC" != "no"; then
AC_MSG_CHECKING(for iODBC support)
@@ -402,7 +401,7 @@ fi
if test -z "$ODBC_TYPE"; then
PHP_ARG_WITH(esoob,,
-[ --with-esoob[=DIR] Include Easysoft OOB support [/usr/local/easysoft/oob/client]])
+[ --with-esoob[=DIR] Include Easysoft OOB support [/usr/local/easysoft/oob/client]])
if test "$PHP_ESOOB" != "no"; then
AC_MSG_CHECKING(for Easysoft ODBC-ODBC Bridge support)
@@ -422,7 +421,7 @@ fi
if test -z "$ODBC_TYPE"; then
PHP_ARG_WITH(unixODBC,,
-[ --with-unixODBC[=DIR] Include unixODBC support [/usr/local]])
+[ --with-unixODBC[=DIR] Include unixODBC support [/usr/local]])
if test "$PHP_UNIXODBC" != "no"; then
AC_MSG_CHECKING(for unixODBC support)
@@ -443,7 +442,7 @@ fi
if test -z "$ODBC_TYPE"; then
PHP_ARG_WITH(dbmaker,,
-[ --with-dbmaker[=DIR] Include DBMaker support])
+[ --with-dbmaker[=DIR] Include DBMaker support])
if test "$PHP_DBMAKER" != "no"; then
AC_MSG_CHECKING(for DBMaker support)
diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c
new file mode 100644
index 0000000000..79eee8bcc1
--- /dev/null
+++ b/ext/opcache/Optimizer/block_pass.c
@@ -0,0 +1,2091 @@
+#define DEBUG_BLOCKPASS 0
+
+/* Checks if a constant (like "true") may be replaced by its value */
+static int zend_get_persistent_constant(char *name, uint name_len, zval *result, int copy TSRMLS_DC ELS_DC)
+{
+ zend_constant *c;
+ char *lookup_name;
+ int retval = 1;
+ ALLOCA_FLAG(use_heap);
+
+ if (zend_hash_find(EG(zend_constants), name, name_len + 1, (void **) &c) == FAILURE) {
+ lookup_name = DO_ALLOCA(name_len + 1);
+ memcpy(lookup_name, name, name_len + 1);
+ zend_str_tolower(lookup_name, name_len);
+
+ if (zend_hash_find(EG(zend_constants), lookup_name, name_len + 1, (void **) &c) == SUCCESS) {
+ if (!(c->flags & CONST_CT_SUBST) || (c->flags & CONST_CS)) {
+ retval = 0;
+ }
+ } else {
+ retval = 0;
+ }
+ FREE_ALLOCA(lookup_name);
+ }
+
+ if (retval) {
+ if (c->flags & CONST_PERSISTENT) {
+ *result = c->value;
+ if (copy) {
+ zval_copy_ctor(result);
+ }
+ } else {
+ retval = 0;
+ }
+ }
+
+ return retval;
+}
+
+#if DEBUG_BLOCKPASS
+# define BLOCK_REF(b) b?op_array->opcodes-b->start_opline:-1
+
+static inline void print_block(zend_code_block *block, zend_op *opcodes, char *txt)
+{
+ fprintf(stderr, "%sBlock: %d-%d (%d)", txt, block->start_opline - opcodes, block->start_opline - opcodes + block->len - 1, block->len);
+ if (!block->access) {
+ fprintf(stderr, " unused");
+ }
+ if (block->op1_to) {
+ fprintf(stderr, " 1: %d", block->op1_to->start_opline - opcodes);
+ }
+ if (block->op2_to) {
+ fprintf(stderr, " 2: %d", block->op2_to->start_opline - opcodes);
+ }
+ if (block->ext_to) {
+ fprintf(stderr, " e: %d", block->ext_to->start_opline - opcodes);
+ }
+ if (block->follow_to) {
+ fprintf(stderr, " f: %d", block->follow_to->start_opline - opcodes);
+ }
+
+ if (block->sources) {
+ zend_block_source *bs = block->sources;
+ fprintf(stderr, " s:");
+ while (bs) {
+ fprintf(stderr, " %d", bs->from->start_opline - opcodes);
+ bs = bs->next;
+ }
+ }
+
+ fprintf(stderr, "\n");
+ fflush(stderr);
+}
+#else
+#define print_block(a,b,c)
+#endif
+
+#define START_BLOCK_OP(opno) blocks[opno].start_opline = &op_array->opcodes[opno]; blocks[opno].start_opline_no = opno; blocks[opno].access = 1
+
+/* find code blocks in op_array
+ code block is a set of opcodes with single flow of control, i.e. without jmps,
+ branches, etc. */
+static int find_code_blocks(zend_op_array *op_array, zend_cfg *cfg)
+{
+ zend_op *opline;
+ zend_op *end = op_array->opcodes + op_array->last;
+ zend_code_block *blocks, *cur_block;
+ zend_uint opno = 0;
+
+ memset(cfg, 0, sizeof(zend_cfg));
+ blocks = cfg->blocks = ecalloc(op_array->last + 2, sizeof(zend_code_block));
+ opline = op_array->opcodes;
+ blocks[0].start_opline = opline;
+ blocks[0].start_opline_no = 0;
+ while (opline < end) {
+ switch((unsigned)opline->opcode) {
+ case ZEND_BRK:
+ case ZEND_CONT:
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+ case ZEND_GOTO:
+#endif
+ /* would not optimize non-optimized BRK/CONTs - we cannot
+ really know where it jumps, so these optimizations are
+ too dangerous */
+ efree(blocks);
+ return 0;
+#if ZEND_EXTENSION_API_NO > PHP_5_4_X_API_NO
+ case ZEND_FAST_CALL:
+ START_BLOCK_OP(ZEND_OP1(opline).opline_num);
+ if (opline->extended_value) {
+ START_BLOCK_OP(ZEND_OP2(opline).opline_num);
+ }
+ START_BLOCK_OP(opno + 1);
+ break;
+ case ZEND_FAST_RET:
+ if (opline->extended_value) {
+ START_BLOCK_OP(ZEND_OP2(opline).opline_num);
+ }
+ START_BLOCK_OP(opno + 1);
+ break;
+#endif
+ case ZEND_JMP:
+ START_BLOCK_OP(ZEND_OP1(opline).opline_num);
+ /* break missing intentionally */
+ case ZEND_RETURN:
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ case ZEND_RETURN_BY_REF:
+#endif
+#if ZEND_EXTENSION_API_NO > PHP_5_4_X_API_NO
+ case ZEND_GENERATOR_RETURN:
+#endif
+ case ZEND_EXIT:
+ case ZEND_THROW:
+ /* start new block from this+1 */
+ START_BLOCK_OP(opno + 1);
+ break;
+ /* TODO: if conditional jmp depends on constant,
+ don't start block that won't be executed */
+ case ZEND_CATCH:
+ START_BLOCK_OP(opline->extended_value);
+ START_BLOCK_OP(opno + 1);
+ break;
+ case ZEND_JMPZNZ:
+ START_BLOCK_OP(opline->extended_value);
+ case ZEND_JMPZ:
+ case ZEND_JMPNZ:
+ case ZEND_JMPZ_EX:
+ case ZEND_JMPNZ_EX:
+ case ZEND_FE_RESET:
+ case ZEND_NEW:
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+ case ZEND_JMP_SET:
+#endif
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ case ZEND_JMP_SET_VAR:
+#endif
+ START_BLOCK_OP(ZEND_OP2(opline).opline_num);
+ START_BLOCK_OP(opno + 1);
+ break;
+ case ZEND_FE_FETCH:
+ START_BLOCK_OP(ZEND_OP2(opline).opline_num);
+ START_BLOCK_OP(opno + 2);
+ break;
+ }
+ opno++;
+ opline++;
+ }
+
+ /* first find block start points */
+ if (op_array->last_try_catch) {
+ int i;
+ cfg->try = ecalloc(op_array->last_try_catch, sizeof(zend_code_block *));
+ cfg->catch = ecalloc(op_array->last_try_catch, sizeof(zend_code_block *));
+ for (i = 0; i< op_array->last_try_catch; i++) {
+ cfg->try[i] = &blocks[op_array->try_catch_array[i].try_op];
+ cfg->catch[i] = &blocks[op_array->try_catch_array[i].catch_op];
+ START_BLOCK_OP(op_array->try_catch_array[i].try_op);
+ START_BLOCK_OP(op_array->try_catch_array[i].catch_op);
+ blocks[op_array->try_catch_array[i].try_op].protected = 1;
+ }
+ }
+ /* Currently, we don't optimize op_arrays with BRK/CONT/GOTO opcodes,
+ * but, we have to keep brk_cont_array to avoid memory leaks during
+ * exception handling */
+ if (op_array->last_brk_cont) {
+ int i, j;
+
+ j = 0;
+ for (i = 0; i< op_array->last_brk_cont; i++) {
+ if (op_array->brk_cont_array[i].start >= 0 &&
+ (op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_FREE ||
+ op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_SWITCH_FREE)) {
+ int parent = op_array->brk_cont_array[i].parent;
+
+ while (parent >= 0 &&
+ op_array->brk_cont_array[parent].start < 0 &&
+ op_array->opcodes[op_array->brk_cont_array[parent].brk].opcode != ZEND_FREE &&
+ op_array->opcodes[op_array->brk_cont_array[parent].brk].opcode != ZEND_SWITCH_FREE) {
+ parent = op_array->brk_cont_array[parent].parent;
+ }
+ op_array->brk_cont_array[i].parent = parent;
+ j++;
+ }
+ }
+ if (j) {
+ cfg->loop_start = ecalloc(op_array->last_brk_cont, sizeof(zend_code_block *));
+ cfg->loop_cont = ecalloc(op_array->last_brk_cont, sizeof(zend_code_block *));
+ cfg->loop_brk = ecalloc(op_array->last_brk_cont, sizeof(zend_code_block *));
+ j = 0;
+ for (i = 0; i< op_array->last_brk_cont; i++) {
+ if (op_array->brk_cont_array[i].start >= 0 &&
+ (op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_FREE ||
+ op_array->opcodes[op_array->brk_cont_array[i].brk].opcode == ZEND_SWITCH_FREE)) {
+ if (i != j) {
+ op_array->brk_cont_array[j] = op_array->brk_cont_array[i];
+ }
+ cfg->loop_start[j] = &blocks[op_array->brk_cont_array[j].start];
+ cfg->loop_cont[j] = &blocks[op_array->brk_cont_array[j].cont];
+ cfg->loop_brk[j] = &blocks[op_array->brk_cont_array[j].brk];
+ START_BLOCK_OP(op_array->brk_cont_array[j].start);
+ START_BLOCK_OP(op_array->brk_cont_array[j].cont);
+ START_BLOCK_OP(op_array->brk_cont_array[j].brk);
+ blocks[op_array->brk_cont_array[j].start].protected = 1;
+ blocks[op_array->brk_cont_array[j].brk].protected = 1;
+ j++;
+ }
+ }
+ op_array->last_brk_cont = j;
+ } else {
+ efree(op_array->brk_cont_array);
+ op_array->brk_cont_array = NULL;
+ op_array->last_brk_cont = 0;
+ }
+ }
+
+ /* Build CFG (Control Flow Graph) */
+ cur_block = blocks;
+ for (opno = 1; opno < op_array->last; opno++) {
+ if (blocks[opno].start_opline) {
+ /* found new block start */
+ cur_block->len = blocks[opno].start_opline - cur_block->start_opline;
+ cur_block->next = &blocks[opno];
+ /* what is the last OP of previous block? */
+ opline = blocks[opno].start_opline - 1;
+ if (opline->opcode == ZEND_OP_DATA) {
+ opline--;
+ }
+ switch((unsigned)opline->opcode) {
+ case ZEND_RETURN:
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ case ZEND_RETURN_BY_REF:
+#endif
+#if ZEND_EXTENSION_API_NO > PHP_5_4_X_API_NO
+ case ZEND_GENERATOR_RETURN:
+#endif
+ case ZEND_EXIT:
+ case ZEND_THROW:
+ break;
+#if ZEND_EXTENSION_API_NO > PHP_5_4_X_API_NO
+ case ZEND_FAST_CALL:
+ if (opline->extended_value) {
+ cur_block->op2_to = &blocks[ZEND_OP2(opline).opline_num];
+ }
+ cur_block->op1_to = &blocks[ZEND_OP1(opline).opline_num];
+ break;
+ case ZEND_FAST_RET:
+ if (opline->extended_value) {
+ cur_block->op2_to = &blocks[ZEND_OP2(opline).opline_num];
+ }
+ break;
+#endif
+ case ZEND_JMP:
+ cur_block->op1_to = &blocks[ZEND_OP1(opline).opline_num];
+ break;
+ case ZEND_JMPZNZ:
+ cur_block->op2_to = &blocks[ZEND_OP2(opline).opline_num];
+ cur_block->ext_to = &blocks[opline->extended_value];
+ break;
+ case ZEND_CATCH:
+ cur_block->ext_to = &blocks[opline->extended_value];
+ cur_block->follow_to = &blocks[opno];
+ break;
+ case ZEND_JMPZ:
+ case ZEND_JMPNZ:
+ case ZEND_JMPZ_EX:
+ case ZEND_JMPNZ_EX:
+ case ZEND_FE_RESET:
+ case ZEND_NEW:
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+ case ZEND_JMP_SET:
+#endif
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ case ZEND_JMP_SET_VAR:
+#endif
+ case ZEND_FE_FETCH:
+ cur_block->op2_to = &blocks[ZEND_OP2(opline).opline_num];
+ /* break missing intentionally */
+ default:
+ /* next block follows this */
+ cur_block->follow_to = &blocks[opno];
+ break;
+ }
+ print_block(cur_block, op_array->opcodes, "");
+ cur_block = cur_block->next;
+ }
+ }
+ cur_block->len = end - cur_block->start_opline;
+ cur_block->next = &blocks[op_array->last + 1];
+ print_block(cur_block, op_array->opcodes, "");
+
+ return 1;
+}
+
+/* CFG back references management */
+
+#define ADD_SOURCE(fromb, tob) { \
+ zend_block_source *__s = tob->sources; \
+ while (__s && __s->from != fromb) __s = __s->next; \
+ if (__s == NULL) { \
+ zend_block_source *__t = emalloc(sizeof(zend_block_source)); \
+ __t->next = tob->sources; \
+ tob->sources = __t; \
+ __t->from = fromb; \
+ } \
+}
+
+#define DEL_SOURCE(cs) { \
+ zend_block_source *__ns = (*cs)->next; \
+ efree(*cs); \
+ *cs = __ns; \
+}
+
+
+static inline void replace_source(zend_block_source *list, zend_code_block *old, zend_code_block *new)
+{
+ /* replace all references to 'old' in 'list' with 'new' */
+ zend_block_source **cs;
+ int found = 0;
+
+ for (cs = &list; *cs; cs = &((*cs)->next)) {
+ if ((*cs)->from == new) {
+ if (found) {
+ DEL_SOURCE(cs);
+ } else {
+ found = 1;
+ }
+ }
+
+ if ((*cs)->from == old) {
+ if (found) {
+ DEL_SOURCE(cs);
+ } else {
+ (*cs)->from = new;
+ found = 1;
+ }
+ }
+ }
+}
+
+static inline void del_source(zend_code_block *from, zend_code_block *to)
+{
+ /* delete source 'from' from 'to'-s sources list */
+ zend_block_source **cs = &to->sources;
+
+ if (to->sources == NULL) {
+ to->access = 0;
+ return;
+ }
+
+ while (*cs) {
+ if ((*cs)->from == from) {
+ DEL_SOURCE(cs);
+ break;
+ }
+ cs = &((*cs)->next);
+ }
+
+ if (to->sources == NULL) {
+ /* 'to' has no more sources - it's unused, will be stripped */
+ to->access = 0;
+ return;
+ }
+
+ if (to->sources->next == NULL) {
+ /* source to only one block */
+ zend_code_block *from_block = to->sources->from;
+
+ if (from_block->access && from_block->follow_to == to &&
+ from_block->op1_to == NULL &&
+ from_block->op2_to == NULL &&
+ from_block->ext_to == NULL) {
+ /* this block follows it's only predecessor - we can join them */
+ zend_op *new_to = from_block->start_opline + from_block->len;
+ if (new_to != to->start_opline) {
+ /* move block to new location */
+ memmove(new_to, to->start_opline, sizeof(zend_op)*to->len);
+ }
+ /* join blocks' lengths */
+ from_block->len += to->len;
+ /* move 'to'`s references to 'from' */
+ to->start_opline = NULL;
+ to->access = 0;
+ efree(to->sources);
+ to->sources = NULL;
+ from_block->follow_to = to->follow_to;
+ if (to->op1_to) {
+ from_block->op1_to = to->op1_to;
+ replace_source(to->op1_to->sources, to, from_block);
+ }
+ if (to->op2_to) {
+ from_block->op2_to = to->op2_to;
+ replace_source(to->op2_to->sources, to, from_block);
+ }
+ if (to->ext_to) {
+ from_block->ext_to = to->ext_to;
+ replace_source(to->ext_to->sources, to, from_block);
+ }
+ if (to->follow_to) {
+ replace_source(to->follow_to->sources, to, from_block);
+ }
+ /* remove "to" from list */
+ }
+ }
+}
+
+static void delete_code_block(zend_code_block *block)
+{
+ if (block->protected) {
+ return;
+ }
+ if (block->follow_to) {
+ zend_block_source *bs = block->sources;
+ while (bs) {
+ zend_code_block *from_block = bs->from;
+ zend_code_block *to = block->follow_to;
+ if (from_block->op1_to == block) {
+ from_block->op1_to = to;
+ ADD_SOURCE(from_block, to);
+ }
+ if (from_block->op2_to == block) {
+ from_block->op2_to = to;
+ ADD_SOURCE(from_block, to);
+ }
+ if (from_block->ext_to == block) {
+ from_block->ext_to = to;
+ ADD_SOURCE(from_block, to);
+ }
+ if (from_block->follow_to == block) {
+ from_block->follow_to = to;
+ ADD_SOURCE(from_block, to);
+ }
+ bs = bs->next;
+ }
+ }
+ block->access = 0;
+}
+
+static void zend_access_path(zend_code_block *block)
+{
+ if (block->access) {
+ return;
+ }
+
+ block->access = 1;
+ if (block->op1_to) {
+ zend_access_path(block->op1_to);
+ ADD_SOURCE(block, block->op1_to);
+ }
+ if (block->op2_to) {
+ zend_access_path(block->op2_to);
+ ADD_SOURCE(block, block->op2_to);
+ }
+ if (block->ext_to) {
+ zend_access_path(block->ext_to);
+ ADD_SOURCE(block, block->ext_to);
+ }
+ if (block->follow_to) {
+ zend_access_path(block->follow_to);
+ ADD_SOURCE(block, block->follow_to);
+ }
+}
+
+/* Traverse CFG, mark reachable basic blocks and build back references */
+static void zend_rebuild_access_path(zend_cfg *cfg, zend_op_array *op_array, int find_start)
+{
+ zend_code_block *blocks = cfg->blocks;
+ zend_code_block *start = find_start? NULL : blocks;
+ zend_code_block *b;
+
+ /* Mark all blocks as unaccessible and destroy back references */
+ b = blocks;
+ while (b != NULL) {
+ zend_block_source *cs;
+ if (!start && b->access) {
+ start = b;
+ }
+ b->access = 0;
+ cs = b->sources;
+ while (cs) {
+ zend_block_source *n = cs->next;
+ efree(cs);
+ cs = n;
+ }
+ b->sources = NULL;
+ b = b->next;
+ }
+
+ /* Walk thorough all paths */
+ zend_access_path(start);
+
+ /* Add brk/cont paths */
+ if (op_array->last_brk_cont) {
+ int i;
+ for (i=0; i< op_array->last_brk_cont; i++) {
+ zend_access_path(cfg->loop_start[i]);
+ zend_access_path(cfg->loop_cont[i]);
+ zend_access_path(cfg->loop_brk[i]);
+ }
+ }
+
+ /* Add exception paths */
+ if (op_array->last_try_catch) {
+ int i;
+ for (i=0; i< op_array->last_try_catch; i++) {
+ if (!cfg->catch[i]->access) {
+ zend_access_path(cfg->catch[i]);
+ }
+ }
+ }
+}
+
+/* Data dependencies macros */
+
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+
+# define VAR_NUM_EX(op) ((op ## _type & (IS_TMP_VAR|IS_VAR))?VAR_NUM((op).var):(op).var)
+
+# define VAR_SOURCE(op) Tsource[VAR_NUM(op.var)]
+# define SET_VAR_SOURCE(opline) Tsource[VAR_NUM(opline->result.var)] = opline
+
+# define VAR_UNSET(op) do { if (op ## _type & (IS_TMP_VAR|IS_VAR)) {VAR_SOURCE(op) = NULL;}} while (0)
+
+#else
+
+# define VAR_NUM_EX(op) ((op).op_type == IS_TMP_VAR || (op).op_type == IS_VAR? VAR_NUM((op).u.var) : (op).u.var)
+
+# define VAR_SOURCE(op) Tsource[VAR_NUM(op.u.var)]
+# define SET_VAR_SOURCE(opline) Tsource[VAR_NUM(ZEND_RESULT(opline).var)] = opline
+
+# define VAR_UNSET(op) do { if ((op).op_type == IS_TMP_VAR || (op).op_type == IS_VAR) {VAR_SOURCE(op) = NULL;}} while (0)
+
+#endif
+
+#define convert_to_string_safe(v) \
+ if (Z_TYPE_P((v)) == IS_NULL) { \
+ ZVAL_STRINGL((v), "", 0, 1); \
+ } else { \
+ convert_to_string((v)); \
+ }
+
+static void strip_nop(zend_code_block *block)
+{
+ zend_op *opline = block->start_opline;
+ zend_op *end, *new_end;
+
+ /* remove leading NOPs */
+ while (block->len > 0 && block->start_opline->opcode == ZEND_NOP) {
+ if (block->len == 1) {
+ /* this block is all NOPs, join with following block */
+ if (block->follow_to) {
+ delete_code_block(block);
+ }
+ return;
+ }
+ block->start_opline++;
+ block->start_opline_no++;
+ block->len--;
+ }
+
+ /* strip the inside NOPs */
+ opline = new_end = block->start_opline;
+ end = opline + block->len;
+
+ while (opline < end) {
+ zend_op *src;
+ int len = 0;
+
+ while (opline < end && opline->opcode == ZEND_NOP) {
+ opline++;
+ }
+ src = opline;
+
+ while (opline < end && opline->opcode != ZEND_NOP) {
+ opline++;
+ }
+ len = opline - src;
+
+ /* move up non-NOP opcodes */
+ memmove(new_end, src, len*sizeof(zend_op));
+
+ new_end += len;
+ }
+ block->len = new_end - block->start_opline;
+}
+
+static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array, char *used_ext TSRMLS_DC)
+{
+ zend_op *opline = block->start_opline;
+ zend_op *end, *last_op = NULL;
+ zend_op **Tsource = NULL;
+
+ print_block(block, op_array->opcodes, "Opt ");
+
+ /* remove leading NOPs */
+ while (block->len > 0 && block->start_opline->opcode == ZEND_NOP) {
+ if (block->len == 1) {
+ /* this block is all NOPs, join with following block */
+ if (block->follow_to) {
+ delete_code_block(block);
+ }
+ return;
+ }
+ block->start_opline++;
+ block->start_opline_no++;
+ block->len--;
+ }
+
+ /* we track data dependencies only insight a single basic block */
+ if (op_array->T) {
+ Tsource = ecalloc(op_array->T, sizeof(zend_op *));
+ }
+ opline = block->start_opline;
+ end = opline + block->len;
+ while ((op_array->T) && (opline < end)) {
+ /* strip X = QM_ASSIGN(const) */
+ if (ZEND_OP1_TYPE(opline) == IS_TMP_VAR &&
+ VAR_SOURCE(opline->op1) &&
+ VAR_SOURCE(opline->op1)->opcode == ZEND_QM_ASSIGN &&
+ ZEND_OP1_TYPE(VAR_SOURCE(opline->op1)) == IS_CONST &&
+ opline->opcode != ZEND_CASE && /* CASE _always_ expects variable */
+ opline->opcode != ZEND_FETCH_DIM_TMP_VAR && /* in 5.1, FETCH_DIM_TMP_VAR expects T */
+ opline->opcode != ZEND_FE_RESET &&
+ opline->opcode != ZEND_FREE
+ ) {
+ zend_op *src = VAR_SOURCE(opline->op1);
+ zval c = ZEND_OP1_LITERAL(src);
+ VAR_UNSET(opline->op1);
+ zval_copy_ctor(&c);
+ update_op1_const(op_array, opline, &c TSRMLS_CC);
+ literal_dtor(&ZEND_OP1_LITERAL(src));
+ MAKE_NOP(src);
+ }
+
+ /* T = QM_ASSIGN(C), F(T) => NOP, F(C) */
+ if (ZEND_OP2_TYPE(opline) == IS_TMP_VAR &&
+ VAR_SOURCE(opline->op2) &&
+ VAR_SOURCE(opline->op2)->opcode == ZEND_QM_ASSIGN &&
+ ZEND_OP1_TYPE(VAR_SOURCE(opline->op2)) == IS_CONST) {
+ zend_op *src = VAR_SOURCE(opline->op2);
+ zval c = ZEND_OP1_LITERAL(src);
+ VAR_UNSET(opline->op2);
+ zval_copy_ctor(&c);
+ update_op2_const(op_array, opline, &c TSRMLS_CC);
+ literal_dtor(&ZEND_OP1_LITERAL(src));
+ MAKE_NOP(src);
+ }
+
+ /* T = PRINT(X), F(T) => ECHO(X), F(1) */
+ if (ZEND_OP1_TYPE(opline) == IS_TMP_VAR &&
+ VAR_SOURCE(opline->op1) &&
+ VAR_SOURCE(opline->op1)->opcode == ZEND_PRINT &&
+ opline->opcode != ZEND_CASE && opline->opcode != ZEND_FREE) {
+ ZEND_OP1_TYPE(opline) = IS_CONST;
+ LITERAL_LONG(opline->op1, 1);
+ }
+
+ if (ZEND_OP2_TYPE(opline) == IS_TMP_VAR &&
+ VAR_SOURCE(opline->op2) &&
+ VAR_SOURCE(opline->op2)->opcode == ZEND_PRINT) {
+ ZEND_OP2_TYPE(opline) = IS_CONST;
+ LITERAL_LONG(opline->op2, 1);
+ }
+
+ /* T = CAST(X, String), ECHO(T) => NOP, ECHO(X) */
+ if ((opline->opcode == ZEND_ECHO || opline->opcode == ZEND_PRINT) &&
+ ZEND_OP1_TYPE(opline) == IS_TMP_VAR &&
+ VAR_SOURCE(opline->op1) &&
+ VAR_SOURCE(opline->op1)->opcode == ZEND_CAST &&
+ VAR_SOURCE(opline->op1)->extended_value == IS_STRING) {
+ zend_op *src = VAR_SOURCE(opline->op1);
+ COPY_NODE(opline->op1, src->op1);
+ MAKE_NOP(src);
+ }
+
+ /* T = PRINT(X), FREE(T) => ECHO(X) */
+ if (opline->opcode == ZEND_FREE &&
+ ZEND_OP1_TYPE(opline) == IS_TMP_VAR &&
+ VAR_SOURCE(opline->op1)) {
+ zend_op *src = VAR_SOURCE(opline->op1);
+ if (src->opcode == ZEND_PRINT) {
+ src->opcode = ZEND_ECHO;
+ ZEND_RESULT_TYPE(src) = IS_UNUSED;
+ MAKE_NOP(opline);
+ }
+ }
+
+ /* T = BOOL(X), FREE(T) => NOP */
+ if (opline->opcode == ZEND_FREE &&
+ ZEND_OP1_TYPE(opline) == IS_TMP_VAR &&
+ VAR_SOURCE(opline->op1)) {
+ zend_op *src = VAR_SOURCE(opline->op1);
+ if (src->opcode == ZEND_BOOL) {
+ if (ZEND_OP1_TYPE(src) == IS_CONST) {
+ literal_dtor(&ZEND_OP1_LITERAL(src));
+ }
+ MAKE_NOP(src);
+ MAKE_NOP(opline);
+ }
+ }
+
+#if 0
+ /* pre-evaluate functions:
+ constant(x)
+ defined(x)
+ function_exists(x)
+ extension_loaded(x)
+ BAD: interacts badly with Accelerator
+ */
+ if((ZEND_OP1_TYPE(opline) & IS_VAR) &&
+ VAR_SOURCE(opline->op1) && VAR_SOURCE(opline->op1)->opcode == ZEND_DO_CF_FCALL &&
+ VAR_SOURCE(opline->op1)->extended_value == 1) {
+ zend_op *fcall = VAR_SOURCE(opline->op1);
+ zend_op *sv = fcall-1;
+ if(sv >= block->start_opline && sv->opcode == ZEND_SEND_VAL &&
+ ZEND_OP1_TYPE(sv) == IS_CONST && Z_TYPE(OPLINE_OP1_LITERAL(sv)) == IS_STRING &&
+ Z_LVAL(OPLINE_OP2_LITERAL(sv)) == 1
+ ) {
+ zval *arg = &OPLINE_OP1_LITERAL(sv);
+ char *fname = FUNCTION_CACHE->funcs[Z_LVAL(ZEND_OP1_LITERAL(fcall))].function_name;
+ int flen = FUNCTION_CACHE->funcs[Z_LVAL(ZEND_OP1_LITERAL(fcall))].name_len;
+ if(flen == sizeof("defined")-1 && zend_binary_strcasecmp(fname, flen, "defined", sizeof("defined")-1) == 0) {
+ zval c;
+ if(zend_get_persistent_constant(Z_STRVAL_P(arg), Z_STRLEN_P(arg), &c, 0 TSRMLS_CC ELS_CC) != 0) {
+ literal_dtor(arg);
+ MAKE_NOP(sv);
+ MAKE_NOP(fcall);
+ LITERAL_BOOL(opline->op1, 1);
+ ZEND_OP1_TYPE(opline) = IS_CONST;
+ }
+ } else if((flen == sizeof("function_exists")-1 && zend_binary_strcasecmp(fname, flen, "function_exists", sizeof("function_exists")-1) == 0) ||
+ (flen == sizeof("is_callable")-1 && zend_binary_strcasecmp(fname, flen, "is_callable", sizeof("is_callable")-1) == 0)
+ ) {
+ zend_function *function;
+ if(zend_hash_find(EG(function_table), Z_STRVAL_P(arg), Z_STRLEN_P(arg)+1, (void **)&function) == SUCCESS) {
+ literal_dtor(arg);
+ MAKE_NOP(sv);
+ MAKE_NOP(fcall);
+ LITERAL_BOOL(opline->op1, 1);
+ ZEND_OP1_TYPE(opline) = IS_CONST;
+ }
+ } else if(flen == sizeof("constant")-1 && zend_binary_strcasecmp(fname, flen, "constant", sizeof("constant")-1) == 0) {
+ zval c;
+ if(zend_get_persistent_constant(Z_STRVAL_P(arg), Z_STRLEN_P(arg), &c, 1 TSRMLS_CC ELS_CC) != 0) {
+ literal_dtor(arg);
+ MAKE_NOP(sv);
+ MAKE_NOP(fcall);
+ ZEND_OP1_LITERAL(opline) = zend_optimizer_add_literal(op_array, &c TSRMLS_CC);
+ /* no copy ctor - get already copied it */
+ ZEND_OP1_TYPE(opline) = IS_CONST;
+ }
+ } else if(flen == sizeof("extension_loaded")-1 && zend_binary_strcasecmp(fname, flen, "extension_loaded", sizeof("extension_loaded")-1) == 0) {
+ if(zend_hash_exists(&module_registry, Z_STRVAL_P(arg), Z_STRLEN_P(arg)+1)) {
+ literal_dtor(arg);
+ MAKE_NOP(sv);
+ MAKE_NOP(fcall);
+ LITERAL_BOOL(opline->op1, 1);
+ ZEND_OP1_TYPE(opline) = IS_CONST;
+ }
+ }
+ }
+ }
+#endif
+
+ /* IS_EQ(TRUE, X) => BOOL(X)
+ * IS_EQ(FALSE, X) => BOOL_NOT(X)
+ * IS_NOT_EQ(TRUE, X) => BOOL_NOT(X)
+ * IS_NOT_EQ(FALSE, X) => BOOL(X)
+ */
+ if (opline->opcode == ZEND_IS_EQUAL ||
+ opline->opcode == ZEND_IS_NOT_EQUAL) {
+ if (ZEND_OP1_TYPE(opline) == IS_CONST &&
+ Z_TYPE(ZEND_OP1_LITERAL(opline)) == IS_BOOL) {
+ opline->opcode =
+ ((opline->opcode == ZEND_IS_EQUAL) == Z_LVAL(ZEND_OP1_LITERAL(opline)))?
+ ZEND_BOOL : ZEND_BOOL_NOT;
+ COPY_NODE(opline->op1, opline->op2);
+ SET_UNUSED(opline->op2);
+ } else if (ZEND_OP2_TYPE(opline) == IS_CONST &&
+ Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_BOOL) {
+ opline->opcode =
+ ((opline->opcode == ZEND_IS_EQUAL) == Z_LVAL(ZEND_OP2_LITERAL(opline)))?
+ ZEND_BOOL : ZEND_BOOL_NOT;
+ SET_UNUSED(opline->op2);
+ }
+ }
+
+ if ((opline->opcode == ZEND_BOOL ||
+ opline->opcode == ZEND_BOOL_NOT ||
+ opline->opcode == ZEND_JMPZ ||
+ opline->opcode == ZEND_JMPNZ ||
+ opline->opcode == ZEND_JMPZNZ) &&
+ ZEND_OP1_TYPE(opline) == IS_TMP_VAR &&
+ VAR_SOURCE(opline->op1) != NULL &&
+ !used_ext[VAR_NUM(ZEND_OP1(opline).var)] &&
+ VAR_SOURCE(opline->op1)->opcode == ZEND_BOOL_NOT) {
+ /* T = BOOL_NOT(X) + JMPZ(T) -> NOP, JMPNZ(X) */
+ zend_op *src = VAR_SOURCE(opline->op1);
+
+ COPY_NODE(opline->op1, src->op1);
+
+ switch (opline->opcode) {
+ case ZEND_BOOL:
+ /* T = BOOL_NOT(X) + BOOL(T) -> NOP, BOOL_NOT(X) */
+ opline->opcode = ZEND_BOOL_NOT;
+ break;
+ case ZEND_BOOL_NOT:
+ /* T = BOOL_NOT(X) + BOOL_BOOL(T) -> NOP, BOOL(X) */
+ opline->opcode = ZEND_BOOL;
+ break;
+ case ZEND_JMPZ:
+ /* T = BOOL_NOT(X) + JMPZ(T,L) -> NOP, JMPNZ(X,L) */
+ opline->opcode = ZEND_JMPNZ;
+ break;
+ case ZEND_JMPNZ:
+ /* T = BOOL_NOT(X) + JMPNZ(T,L) -> NOP, JMPZ(X,L) */
+ opline->opcode = ZEND_JMPZ;
+ break;
+ case ZEND_JMPZNZ:
+ {
+ /* T = BOOL_NOT(X) + JMPZNZ(T,L1,L2) -> NOP, JMPZNZ(X,L2,L1) */
+ int op_t;
+ zend_code_block *op_b;
+
+ op_t = opline->extended_value;
+ opline->extended_value = ZEND_OP2(opline).opline_num;
+ ZEND_OP2(opline).opline_num = op_t;
+
+ op_b = block->ext_to;
+ block->ext_to = block->op2_to;
+ block->op2_to = op_b;
+ }
+ break;
+ }
+
+ VAR_UNSET(opline->op1);
+ MAKE_NOP(src);
+ continue;
+ } else
+#if 0
+ /* T = BOOL_NOT(X) + T = JMPZ_EX(T, X) -> T = BOOL_NOT(X), JMPNZ(X) */
+ if(0 && (opline->opcode == ZEND_JMPZ_EX ||
+ opline->opcode == ZEND_JMPNZ_EX) &&
+ ZEND_OP1_TYPE(opline) == IS_TMP_VAR &&
+ VAR_SOURCE(opline->op1) != NULL &&
+ VAR_SOURCE(opline->op1)->opcode == ZEND_BOOL_NOT &&
+ ZEND_OP1(opline).var == ZEND_RESULT(opline).var
+ ) {
+ zend_op *src = VAR_SOURCE(opline->op1);
+ if(opline->opcode == ZEND_JMPZ_EX) {
+ opline->opcode = ZEND_JMPNZ;
+ } else {
+ opline->opcode = ZEND_JMPZ;
+ }
+ COPY_NODE(opline->op1, src->op1);
+ SET_UNUSED(opline->result);
+ continue;
+ } else
+#endif
+ /* T = BOOL(X) + JMPZ(T) -> NOP, JMPZ(X) */
+ if ((opline->opcode == ZEND_BOOL ||
+ opline->opcode == ZEND_BOOL_NOT ||
+ opline->opcode == ZEND_JMPZ ||
+ opline->opcode == ZEND_JMPZ_EX ||
+ opline->opcode == ZEND_JMPNZ_EX ||
+ opline->opcode == ZEND_JMPNZ ||
+ opline->opcode == ZEND_JMPZNZ) &&
+ ZEND_OP1_TYPE(opline) == IS_TMP_VAR &&
+ VAR_SOURCE(opline->op1) != NULL &&
+ (!used_ext[VAR_NUM(ZEND_OP1(opline).var)] ||
+ (ZEND_RESULT_TYPE(opline) == IS_TMP_VAR &&
+ ZEND_RESULT(opline).var == ZEND_OP1(opline).var)) &&
+ (VAR_SOURCE(opline->op1)->opcode == ZEND_BOOL ||
+ VAR_SOURCE(opline->op1)->opcode == ZEND_QM_ASSIGN)) {
+ zend_op *src = VAR_SOURCE(opline->op1);
+ COPY_NODE(opline->op1, src->op1);
+
+ VAR_UNSET(opline->op1);
+ MAKE_NOP(src);
+ continue;
+ } else if (last_op && opline->opcode == ZEND_ECHO &&
+ last_op->opcode == ZEND_ECHO &&
+ ZEND_OP1_TYPE(opline) == IS_CONST &&
+ Z_TYPE(ZEND_OP1_LITERAL(opline)) != IS_DOUBLE &&
+ ZEND_OP1_TYPE(last_op) == IS_CONST &&
+ Z_TYPE(ZEND_OP1_LITERAL(last_op)) != IS_DOUBLE) {
+ /* compress consecutive ECHO's.
+ * Float to string conversion may be affected by current
+ * locale setting.
+ */
+ int l;
+
+ if (Z_TYPE(ZEND_OP1_LITERAL(opline)) != IS_STRING) {
+ convert_to_string_safe(&ZEND_OP1_LITERAL(opline));
+ }
+ if (Z_TYPE(ZEND_OP1_LITERAL(last_op)) != IS_STRING) {
+ convert_to_string_safe(&ZEND_OP1_LITERAL(last_op));
+ }
+ l = Z_STRLEN(ZEND_OP1_LITERAL(opline)) + Z_STRLEN(ZEND_OP1_LITERAL(last_op));
+ if (IS_INTERNED(Z_STRVAL(ZEND_OP1_LITERAL(last_op)))) {
+ char *tmp = emalloc(l + 1);
+ memcpy(tmp, Z_STRVAL(ZEND_OP1_LITERAL(last_op)), l + 1);
+ Z_STRVAL(ZEND_OP1_LITERAL(last_op)) = tmp;
+ } else {
+ Z_STRVAL(ZEND_OP1_LITERAL(last_op)) = erealloc(Z_STRVAL(ZEND_OP1_LITERAL(last_op)), l + 1);
+ }
+ memcpy(Z_STRVAL(ZEND_OP1_LITERAL(last_op))+Z_STRLEN(ZEND_OP1_LITERAL(last_op)), Z_STRVAL(ZEND_OP1_LITERAL(opline)), Z_STRLEN(ZEND_OP1_LITERAL(opline)));
+ Z_STRVAL(ZEND_OP1_LITERAL(last_op))[l] = '\0';
+ zval_dtor(&ZEND_OP1_LITERAL(opline));
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ Z_STRVAL(ZEND_OP1_LITERAL(opline)) = (char*)zend_new_interned_string(Z_STRVAL(ZEND_OP1_LITERAL(last_op)), l + 1, 1 TSRMLS_CC);
+ Z_TYPE(ZEND_OP1_LITERAL(last_op)) = IS_NULL;
+#else
+ Z_STRVAL(ZEND_OP1_LITERAL(opline)) = Z_STRVAL(ZEND_OP1_LITERAL(last_op));
+#endif
+ Z_STRLEN(ZEND_OP1_LITERAL(opline)) = l;
+ MAKE_NOP(last_op);
+ } else if (opline->opcode == ZEND_CONCAT &&
+ ZEND_OP2_TYPE(opline) == IS_CONST &&
+ ZEND_OP1_TYPE(opline) == IS_TMP_VAR &&
+ VAR_SOURCE(opline->op1) &&
+ (VAR_SOURCE(opline->op1)->opcode == ZEND_CONCAT ||
+ VAR_SOURCE(opline->op1)->opcode == ZEND_ADD_STRING) &&
+ ZEND_OP2_TYPE(VAR_SOURCE(opline->op1)) == IS_CONST &&
+ ZEND_RESULT(VAR_SOURCE(opline->op1)).var == ZEND_OP1(opline).var) {
+ /* compress consecutive CONCATs */
+ zend_op *src = VAR_SOURCE(opline->op1);
+ int l;
+
+ if (Z_TYPE(ZEND_OP2_LITERAL(opline)) != IS_STRING) {
+ convert_to_string_safe(&ZEND_OP2_LITERAL(opline));
+ }
+ if (Z_TYPE(ZEND_OP2_LITERAL(src)) != IS_STRING) {
+ convert_to_string_safe(&ZEND_OP2_LITERAL(src));
+ }
+
+ VAR_UNSET(opline->op1);
+ if (ZEND_OP1_TYPE(src) == IS_UNUSED) {
+ /* 5.3 may use IS_UNUSED as first argument to ZEND_ADD_... */
+ opline->opcode = ZEND_ADD_STRING;
+ }
+ COPY_NODE(opline->op1, src->op1);
+ l = Z_STRLEN(ZEND_OP2_LITERAL(opline)) + Z_STRLEN(ZEND_OP2_LITERAL(src));
+ if (IS_INTERNED(Z_STRVAL(ZEND_OP2_LITERAL(src)))) {
+ char *tmp = emalloc(l + 1);
+ memcpy(tmp, Z_STRVAL(ZEND_OP2_LITERAL(src)), l + 1);
+ Z_STRVAL(ZEND_OP2_LITERAL(src)) = tmp;
+ } else {
+ Z_STRVAL(ZEND_OP2_LITERAL(src)) = erealloc(Z_STRVAL(ZEND_OP2_LITERAL(src)), l + 1);
+ }
+ memcpy(Z_STRVAL(ZEND_OP2_LITERAL(src))+Z_STRLEN(ZEND_OP2_LITERAL(src)), Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline)));
+ Z_STRVAL(ZEND_OP2_LITERAL(src))[l] = '\0';
+ if (!IS_INTERNED(Z_STRVAL(ZEND_OP2_LITERAL(opline)))) {
+ efree(Z_STRVAL(ZEND_OP2_LITERAL(opline)));
+ }
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ Z_STRVAL(ZEND_OP2_LITERAL(opline)) = (char*)zend_new_interned_string(Z_STRVAL(ZEND_OP2_LITERAL(src)), l + 1, 1 TSRMLS_CC);
+ Z_TYPE(ZEND_OP2_LITERAL(src)) = IS_NULL;
+#else
+ Z_STRVAL(ZEND_OP2_LITERAL(opline)) = Z_STRVAL(ZEND_OP2_LITERAL(src));
+#endif
+ Z_STRLEN(ZEND_OP2_LITERAL(opline)) = l;
+ MAKE_NOP(src);
+ } else if ((opline->opcode == ZEND_ADD_STRING || opline->opcode == ZEND_ADD_VAR) && ZEND_OP1_TYPE(opline) == IS_CONST) {
+ /* convert ADD_STRING(C1, C2) to CONCAT(C1, C2) */
+ opline->opcode = ZEND_CONCAT;
+ continue;
+ } else if (opline->opcode == ZEND_ADD_CHAR && ZEND_OP1_TYPE(opline) == IS_CONST && ZEND_OP2_TYPE(opline) == IS_CONST) {
+ /* convert ADD_CHAR(C1, C2) to CONCAT(C1, C2) */
+ char c = (char)Z_LVAL(ZEND_OP2_LITERAL(opline));
+ ZVAL_STRINGL(&ZEND_OP2_LITERAL(opline), &c, 1, 1);
+ opline->opcode = ZEND_CONCAT;
+ continue;
+ } else if ((opline->opcode == ZEND_ADD ||
+ opline->opcode == ZEND_SUB ||
+ opline->opcode == ZEND_MUL ||
+ opline->opcode == ZEND_DIV ||
+ opline->opcode == ZEND_MOD ||
+ opline->opcode == ZEND_SL ||
+ opline->opcode == ZEND_SR ||
+ opline->opcode == ZEND_CONCAT ||
+ opline->opcode == ZEND_IS_EQUAL ||
+ opline->opcode == ZEND_IS_NOT_EQUAL ||
+ opline->opcode == ZEND_IS_SMALLER ||
+ opline->opcode == ZEND_IS_SMALLER_OR_EQUAL ||
+ opline->opcode == ZEND_IS_IDENTICAL ||
+ opline->opcode == ZEND_IS_NOT_IDENTICAL ||
+ opline->opcode == ZEND_BOOL_XOR ||
+ opline->opcode == ZEND_BW_OR ||
+ opline->opcode == ZEND_BW_AND ||
+ opline->opcode == ZEND_BW_XOR) &&
+ ZEND_OP1_TYPE(opline)==IS_CONST &&
+ ZEND_OP2_TYPE(opline)==IS_CONST) {
+ /* evaluate constant expressions */
+ int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC) = get_binary_op(opline->opcode);
+ zval result;
+ int er;
+
+ if ((opline->opcode == ZEND_DIV || opline->opcode == ZEND_MOD) &&
+ ((Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_LONG &&
+ Z_LVAL(ZEND_OP2_LITERAL(opline)) == 0) ||
+ (Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_DOUBLE &&
+ Z_DVAL(ZEND_OP2_LITERAL(opline)) == 0.0))) {
+ if (RESULT_USED(opline)) {
+ SET_VAR_SOURCE(opline);
+ }
+ opline++;
+ continue;
+ }
+ er = EG(error_reporting);
+ EG(error_reporting) = 0;
+ if (binary_op(&result, &ZEND_OP1_LITERAL(opline), &ZEND_OP2_LITERAL(opline) TSRMLS_CC) == SUCCESS) {
+ PZ_SET_REFCOUNT_P(&result, 1);
+ PZ_UNSET_ISREF_P(&result);
+
+ literal_dtor(&ZEND_OP1_LITERAL(opline));
+ literal_dtor(&ZEND_OP2_LITERAL(opline));
+ opline->opcode = ZEND_QM_ASSIGN;
+ SET_UNUSED(opline->op2);
+ update_op1_const(op_array, opline, &result TSRMLS_CC);
+ }
+ EG(error_reporting) = er;
+ } else if ((opline->opcode == ZEND_BOOL ||
+ opline->opcode == ZEND_BOOL_NOT ||
+ opline->opcode == ZEND_BW_NOT) && ZEND_OP1_TYPE(opline) == IS_CONST) {
+ /* evaluate constant unary ops */
+ unary_op_type unary_op = get_unary_op(opline->opcode);
+ zval result;
+
+ if (unary_op) {
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+ unary_op(&result, &ZEND_OP1_LITERAL(opline));
+#else
+ unary_op(&result, &ZEND_OP1_LITERAL(opline) TSRMLS_CC);
+#endif
+ literal_dtor(&ZEND_OP1_LITERAL(opline));
+ } else {
+ /* BOOL */
+ result = ZEND_OP1_LITERAL(opline);
+ convert_to_boolean(&result);
+ Z_TYPE(ZEND_OP1_LITERAL(opline)) = IS_NULL;
+ }
+ PZ_SET_REFCOUNT_P(&result, 1);
+ PZ_UNSET_ISREF_P(&result);
+ opline->opcode = ZEND_QM_ASSIGN;
+ update_op1_const(op_array, opline, &result TSRMLS_CC);
+ } else if ((opline->opcode == ZEND_RETURN || opline->opcode == ZEND_EXIT) &&
+ ZEND_OP1_TYPE(opline) == IS_TMP_VAR &&
+ VAR_SOURCE(opline->op1) &&
+ VAR_SOURCE(opline->op1)->opcode == ZEND_QM_ASSIGN) {
+ /* T = QM_ASSIGN(X), RETURN(T) to RETURN(X) */
+ zend_op *src = VAR_SOURCE(opline->op1);
+ VAR_UNSET(opline->op1);
+ COPY_NODE(opline->op1, src->op1);
+ MAKE_NOP(src);
+ } else if ((opline->opcode == ZEND_ADD_STRING ||
+ opline->opcode == ZEND_ADD_CHAR) &&
+ ZEND_OP1_TYPE(opline) == IS_TMP_VAR &&
+ VAR_SOURCE(opline->op1) &&
+ VAR_SOURCE(opline->op1)->opcode == ZEND_INIT_STRING) {
+ /* convert T = INIT_STRING(), T = ADD_STRING(T, X) to T = QM_ASSIGN(X) */
+ /* CHECKME: Remove ZEND_ADD_VAR optimization, since some conversions -
+ namely, BOOL(false)->string - don't allocate memory but use empty_string
+ and ADD_CHAR fails */
+ zend_op *src = VAR_SOURCE(opline->op1);
+ VAR_UNSET(opline->op1);
+ COPY_NODE(opline->op1, opline->op2);
+ if (opline->opcode == ZEND_ADD_CHAR) {
+ char c = (char)Z_LVAL(ZEND_OP2_LITERAL(opline));
+ ZVAL_STRINGL(&ZEND_OP1_LITERAL(opline), &c, 1, 1);
+ }
+ SET_UNUSED(opline->op2);
+ MAKE_NOP(src);
+ opline->opcode = ZEND_QM_ASSIGN;
+ } else if ((opline->opcode == ZEND_ADD_STRING ||
+ opline->opcode == ZEND_ADD_CHAR ||
+ opline->opcode == ZEND_ADD_VAR ||
+ opline->opcode == ZEND_CONCAT) &&
+ ZEND_OP1_TYPE(opline) == IS_TMP_VAR &&
+ VAR_SOURCE(opline->op1) &&
+ VAR_SOURCE(opline->op1)->opcode == ZEND_CONCAT &&
+ ZEND_OP2_TYPE(VAR_SOURCE(opline->op1)) == IS_CONST &&
+ Z_TYPE(ZEND_OP2_LITERAL(VAR_SOURCE(opline->op1))) == IS_STRING &&
+ Z_STRLEN(ZEND_OP2_LITERAL(VAR_SOURCE(opline->op1))) == 0) {
+ /* convert T = CONCAT(X,''), T = ADD_STRING(T, Y) to T = CONCAT(X,Y) */
+ zend_op *src = VAR_SOURCE(opline->op1);
+ VAR_UNSET(opline->op1);
+ COPY_NODE(opline->op1, src->op1);
+ if (opline->opcode == ZEND_ADD_CHAR) {
+ char c = (char)Z_LVAL(ZEND_OP2_LITERAL(opline));
+ ZVAL_STRINGL(&ZEND_OP2_LITERAL(opline), &c, 1, 1);
+ }
+ opline->opcode = ZEND_CONCAT;
+ literal_dtor(&ZEND_OP2_LITERAL(src)); /* will take care of empty_string too */
+ MAKE_NOP(src);
+ } else if (opline->opcode == ZEND_ADD_VAR &&
+ ZEND_OP1_TYPE(opline) == IS_TMP_VAR &&
+ VAR_SOURCE(opline->op1) &&
+ VAR_SOURCE(opline->op1)->opcode == ZEND_INIT_STRING) {
+ /* convert T = INIT_STRING(), T = ADD_VAR(T, X) to T = CAST(STRING, X) */
+ zend_op *src = VAR_SOURCE(opline->op1);
+ VAR_UNSET(opline->op1);
+ COPY_NODE(opline->op1, opline->op2);
+ SET_UNUSED(opline->op2);
+ MAKE_NOP(src);
+ opline->opcode = ZEND_CAST;
+ opline->extended_value = IS_STRING;
+ } else if ((opline->opcode == ZEND_ADD_STRING ||
+ opline->opcode == ZEND_ADD_CHAR ||
+ opline->opcode == ZEND_ADD_VAR ||
+ opline->opcode == ZEND_CONCAT) &&
+ ZEND_OP1_TYPE(opline) == IS_TMP_VAR &&
+ VAR_SOURCE(opline->op1) &&
+ VAR_SOURCE(opline->op1)->opcode == ZEND_CAST &&
+ VAR_SOURCE(opline->op1)->extended_value == IS_STRING) {
+ /* convert T1 = CAST(STRING, X), T2 = CONCAT(T1, Y) to T2 = CONCAT(X,Y) */
+ zend_op *src = VAR_SOURCE(opline->op1);
+ VAR_UNSET(opline->op1);
+ COPY_NODE(opline->op1, src->op1);
+ if (opline->opcode == ZEND_ADD_CHAR) {
+ char c = (char)Z_LVAL(ZEND_OP2_LITERAL(opline));
+ ZVAL_STRINGL(&ZEND_OP2_LITERAL(opline), &c, 1, 1);
+ }
+ opline->opcode = ZEND_CONCAT;
+ MAKE_NOP(src);
+ } else if (opline->opcode == ZEND_QM_ASSIGN &&
+ ZEND_OP1_TYPE(opline) == IS_TMP_VAR &&
+ ZEND_RESULT_TYPE(opline) == IS_TMP_VAR &&
+ ZEND_OP1(opline).var == ZEND_RESULT(opline).var) {
+ /* strip T = QM_ASSIGN(T) */
+ MAKE_NOP(opline);
+ } else if (opline->opcode == ZEND_BOOL &&
+ ZEND_OP1_TYPE(opline) == IS_TMP_VAR &&
+ VAR_SOURCE(opline->op1) &&
+ (VAR_SOURCE(opline->op1)->opcode == ZEND_IS_EQUAL ||
+ VAR_SOURCE(opline->op1)->opcode == ZEND_IS_NOT_EQUAL ||
+ VAR_SOURCE(opline->op1)->opcode == ZEND_IS_SMALLER ||
+ VAR_SOURCE(opline->op1)->opcode == ZEND_IS_SMALLER_OR_EQUAL ||
+ VAR_SOURCE(opline->op1)->opcode == ZEND_BOOL ||
+ VAR_SOURCE(opline->op1)->opcode == ZEND_IS_IDENTICAL ||
+ VAR_SOURCE(opline->op1)->opcode == ZEND_IS_NOT_IDENTICAL ||
+ VAR_SOURCE(opline->op1)->opcode == ZEND_ISSET_ISEMPTY_VAR ||
+ VAR_SOURCE(opline->op1)->opcode == ZEND_ISSET_ISEMPTY_DIM_OBJ) &&
+ !used_ext[VAR_NUM(ZEND_OP1(opline).var)]) {
+ /* T = IS_SMALLER(X, Y), T1 = BOOL(T) => T = IS_SMALLER(X, Y), T1 = QM_ASSIGN(T) */
+ zend_op *src = VAR_SOURCE(opline->op1);
+ COPY_NODE(src->result, opline->result);
+ SET_VAR_SOURCE(src);
+ MAKE_NOP(opline);
+ }
+ /* get variable source */
+ if (RESULT_USED(opline)) {
+ SET_VAR_SOURCE(opline);
+ }
+ if (opline->opcode != ZEND_NOP) {
+ last_op = opline;
+ }
+ opline++;
+ }
+
+ strip_nop(block);
+
+ if (op_array->T) {
+ efree(Tsource);
+ }
+}
+
+/* Rebuild plain (optimized) op_array from CFG */
+static void assemble_code_blocks(zend_cfg *cfg, zend_op_array *op_array)
+{
+ zend_code_block *blocks = cfg->blocks;
+ zend_op *new_opcodes = emalloc(op_array->last * sizeof(zend_op));
+ zend_op *opline = new_opcodes;
+ zend_code_block *cur_block = blocks;
+
+ /* Copy code of reachable blocks into a single buffer */
+ while (cur_block) {
+ if (cur_block->access) {
+ memcpy(opline, cur_block->start_opline, cur_block->len * sizeof(zend_op));
+ cur_block->start_opline = opline;
+ opline += cur_block->len;
+ if ((opline - 1)->opcode == ZEND_JMP) {
+ zend_code_block *next;
+ next = cur_block->next;
+ while (next && !next->access) {
+ next = next->next;
+ }
+ if (next && next == cur_block->op1_to) {
+ /* JMP to the next block - strip it */
+ cur_block->follow_to = cur_block->op1_to;
+ cur_block->op1_to = NULL;
+ MAKE_NOP((opline - 1));
+ opline--;
+ cur_block->len--;
+ }
+ }
+ } else {
+ /* this block will not be used, delete all constants there */
+ zend_op *_opl;
+ zend_op *end = cur_block->start_opline + cur_block->len;
+ for (_opl = cur_block->start_opline; _opl && _opl < end; _opl++) {
+ if (ZEND_OP1_TYPE(_opl) == IS_CONST) {
+ literal_dtor(&ZEND_OP1_LITERAL(_opl));
+ }
+ if (ZEND_OP2_TYPE(_opl) == IS_CONST) {
+ literal_dtor(&ZEND_OP2_LITERAL(_opl));
+ }
+ }
+ }
+ cur_block = cur_block->next;
+ }
+
+ if ((opline-1)->opcode == ZEND_THROW) {
+ /* if we finished with THROW, we need to add space between THROW and HANDLE to not confuse
+ zend_throw_internal */
+ MAKE_NOP(opline);
+ opline->lineno = opline[-1].lineno;
+ opline++;
+ }
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+ MAKE_NOP(opline);
+ opline->opcode = ZEND_HANDLE_EXCEPTION;
+ opline->lineno = opline[-1].lineno;
+ opline++;
+#endif
+
+ op_array->last = opline-new_opcodes;
+
+ /* adjust exception jump targets */
+ if (op_array->last_try_catch) {
+ int i, j;
+ for (i = 0, j = 0; i< op_array->last_try_catch; i++) {
+ if (cfg->try[i]->access) {
+ op_array->try_catch_array[j].try_op = cfg->try[i]->start_opline - new_opcodes;
+ op_array->try_catch_array[j].catch_op = cfg->catch[i]->start_opline - new_opcodes;
+ j++;
+ }
+ }
+ op_array->last_try_catch = j;
+ efree(cfg->try);
+ efree(cfg->catch);
+ }
+
+ /* adjust loop jump targets */
+ if (op_array->last_brk_cont) {
+ int i;
+ for (i = 0; i< op_array->last_brk_cont; i++) {
+ op_array->brk_cont_array[i].start = cfg->loop_start[i]->start_opline - new_opcodes;
+ op_array->brk_cont_array[i].cont = cfg->loop_cont[i]->start_opline - new_opcodes;
+ op_array->brk_cont_array[i].brk = cfg->loop_brk[i]->start_opline - new_opcodes;
+ }
+ efree(cfg->loop_start);
+ efree(cfg->loop_cont);
+ efree(cfg->loop_brk);
+ }
+
+ /* adjust jump targets */
+ for (cur_block = blocks; cur_block; cur_block = cur_block->next) {
+ if (!cur_block->access) {
+ continue;
+ }
+ opline = cur_block->start_opline + cur_block->len - 1;
+ if (opline->opcode == ZEND_OP_DATA) {
+ opline--;
+ }
+ if (cur_block->op1_to) {
+ ZEND_OP1(opline).opline_num = cur_block->op1_to->start_opline - new_opcodes;
+ }
+ if (cur_block->op2_to) {
+ ZEND_OP2(opline).opline_num = cur_block->op2_to->start_opline - new_opcodes;
+ }
+ if (cur_block->ext_to) {
+ opline->extended_value = cur_block->ext_to->start_opline - new_opcodes;
+ }
+ print_block(cur_block, new_opcodes, "Out ");
+ }
+ efree(op_array->opcodes);
+ op_array->opcodes = erealloc(new_opcodes, op_array->last * sizeof(zend_op));
+
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+ /* adjust early binding list */
+ if (op_array->early_binding != (zend_uint)-1) {
+ zend_uint *opline_num = &op_array->early_binding;
+ zend_op *end;
+
+ opline = op_array->opcodes;
+ end = opline + op_array->last;
+ while (opline < end) {
+ if (opline->opcode == ZEND_DECLARE_INHERITED_CLASS_DELAYED) {
+ *opline_num = opline - op_array->opcodes;
+ opline_num = &ZEND_RESULT(opline).opline_num;
+ }
+ ++opline;
+ }
+ *opline_num = -1;
+ }
+#endif
+}
+
+static void zend_jmp_optimization(zend_code_block *block, zend_op_array *op_array, zend_code_block *blocks TSRMLS_DC)
+{
+ /* last_op is the last opcode of the current block */
+ zend_op *last_op = (block->start_opline + block->len - 1);
+
+ if (!block->len) {
+ return;
+ }
+ switch (last_op->opcode) {
+ case ZEND_JMP:
+ {
+ zend_op *target = block->op1_to->start_opline;
+ zend_code_block *next = block->next;
+
+ while (next && !next->access) {
+ /* find used one */
+ next = next->next;
+ }
+
+ /* JMP(next) -> NOP */
+ if (block->op1_to == next) {
+ block->follow_to = block->op1_to;
+ block->op1_to = NULL;
+ MAKE_NOP(last_op);
+ block->len--;
+ if (block->len == 0) {
+ /* this block is nothing but NOP now */
+ delete_code_block(block);
+ }
+ break;
+ }
+
+ if (((target->opcode == ZEND_JMP &&
+ block->op1_to != block->op1_to->op1_to) ||
+ target->opcode == ZEND_JMPZNZ) &&
+ !block->op1_to->protected) {
+ /* JMP L, L: JMP L1 -> JMP L1 */
+ /* JMP L, L: JMPZNZ L1,L2 -> JMPZNZ L1,L2 */
+ *last_op = *target;
+#if ZEND_EXTENSION_API_NO < PHP_5_4_X_API_NO
+ if (ZEND_OP1_TYPE(last_op) == IS_CONST) {
+ zval_copy_ctor(&ZEND_OP1_LITERAL(last_op));
+ }
+#else
+ if (ZEND_OP1_TYPE(last_op) == IS_CONST) {
+ zval zv = ZEND_OP1_LITERAL(last_op);
+ zval_copy_ctor(&zv);
+ last_op->op1.constant = zend_optimizer_add_literal(op_array, &zv TSRMLS_CC);
+ }
+#endif
+ del_source(block, block->op1_to);
+ if (block->op1_to->op2_to) {
+ block->op2_to = block->op1_to->op2_to;
+ ADD_SOURCE(block, block->op2_to);
+ }
+ if (block->op1_to->ext_to) {
+ block->ext_to = block->op1_to->ext_to;
+ ADD_SOURCE(block, block->ext_to);
+ }
+ if (block->op1_to->op1_to) {
+ block->op1_to = block->op1_to->op1_to;
+ ADD_SOURCE(block, block->op1_to);
+ } else {
+ block->op1_to = NULL;
+ }
+ } else if (target->opcode == ZEND_RETURN ||
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ target->opcode == ZEND_RETURN_BY_REF ||
+#endif
+#if ZEND_EXTENSION_API_NO > PHP_5_4_X_API_NO
+ target->opcode == ZEND_FAST_RET ||
+#endif
+ target->opcode == ZEND_EXIT) {
+ /* JMP L, L: RETURN to immediate RETURN */
+ *last_op = *target;
+#if ZEND_EXTENSION_API_NO < PHP_5_4_X_API_NO
+ if (ZEND_OP1_TYPE(last_op) == IS_CONST) {
+ zval_copy_ctor(&ZEND_OP1_LITERAL(last_op));
+ }
+#else
+ if (ZEND_OP1_TYPE(last_op) == IS_CONST) {
+ zval zv = ZEND_OP1_LITERAL(last_op);
+ zval_copy_ctor(&zv);
+ last_op->op1.constant = zend_optimizer_add_literal(op_array, &zv TSRMLS_CC);
+ }
+#endif
+ del_source(block, block->op1_to);
+ block->op1_to = NULL;
+#if 0
+ /* Temporarily disabled - see bug #0025274 */
+ } else if (0&& block->op1_to != block &&
+ block->op1_to != blocks &&
+ op_array->last_try_catch == 0 &&
+ target->opcode != ZEND_FREE &&
+ target->opcode != ZEND_SWITCH_FREE) {
+ /* Block Reordering (saves one JMP on each "for" loop iteration)
+ * It is disabled for some cases (ZEND_FREE/ZEND_SWITCH_FREE)
+ * which may break register allocation.
+ */
+ zend_bool can_reorder = 0;
+ zend_block_source *cs = block->op1_to->sources;
+
+ /* the "target" block doesn't had any followed block */
+ while(cs) {
+ if (cs->from->follow_to == block->op1_to) {
+ can_reorder = 0;
+ break;
+ }
+ cs = cs->next;
+ }
+ if (can_reorder) {
+ next = block->op1_to;
+ /* the "target" block is not followed by current "block" */
+ while (next->follow_to != NULL) {
+ if (next->follow_to == block) {
+ can_reorder = 0;
+ break;
+ }
+ next = next->follow_to;
+ }
+ if (can_reorder) {
+ zend_code_block *prev = blocks;
+
+ while (prev->next != block->op1_to) {
+ prev = prev->next;
+ }
+ prev->next = next->next;
+ next->next = block->next;
+ block->next = block->op1_to;
+
+ block->follow_to = block->op1_to;
+ block->op1_to = NULL;
+ MAKE_NOP(last_op);
+ block->len--;
+ if(block->len == 0) {
+ /* this block is nothing but NOP now */
+ delete_code_block(block);
+ }
+ break;
+ }
+ }
+#endif
+ }
+ }
+ break;
+
+ case ZEND_JMPZ:
+ case ZEND_JMPNZ:
+ /* constant conditional JMPs */
+ if (ZEND_OP1_TYPE(last_op) == IS_CONST) {
+ int should_jmp = zend_is_true(&ZEND_OP1_LITERAL(last_op));
+ if (last_op->opcode == ZEND_JMPZ) {
+ should_jmp = !should_jmp;
+ }
+ literal_dtor(&ZEND_OP1_LITERAL(last_op));
+ ZEND_OP1_TYPE(last_op) = IS_UNUSED;
+ if (should_jmp) {
+ /* JMPNZ(true) -> JMP */
+ last_op->opcode = ZEND_JMP;
+ COPY_NODE(last_op->op1, last_op->op2);
+ block->op1_to = block->op2_to;
+ del_source(block, block->follow_to);
+ block->op2_to = NULL;
+ block->follow_to = NULL;
+ } else {
+ /* JMPNZ(false) -> NOP */
+ MAKE_NOP(last_op);
+ del_source(block, block->op2_to);
+ block->op2_to = NULL;
+ }
+ break;
+ }
+
+ if (block->op2_to) {
+ zend_uchar same_type = ZEND_OP1_TYPE(last_op);
+ zend_uint same_var = VAR_NUM_EX(last_op->op1);
+ zend_op *target;
+ zend_op *target_end;
+ zend_code_block *target_block = block->op2_to;;
+
+next_target:
+ target = target_block->start_opline;
+ target_end = target_block->start_opline + target_block->len;
+ while (target < target_end && target->opcode == ZEND_NOP) {
+ target++;
+ }
+
+ /* next block is only NOP's */
+ if (target == target_end) {
+ target_block = target_block->follow_to;
+ goto next_target;
+ } else if (target->opcode == INV_COND(last_op->opcode) &&
+ /* JMPZ(X, L), L: JMPNZ(X, L2) -> JMPZ(X, L+1) */
+ (ZEND_OP1_TYPE(target) & (IS_TMP_VAR|IS_CV)) &&
+ same_type == ZEND_OP1_TYPE(target) &&
+ same_var == VAR_NUM_EX(target->op1) &&
+ target_block->follow_to &&
+ !target_block->protected
+ ) {
+ del_source(block, block->op2_to);
+ block->op2_to = target_block->follow_to;
+ ADD_SOURCE(block, block->op2_to);
+ } else if (target->opcode == INV_COND_EX(last_op->opcode) &&
+ (ZEND_OP1_TYPE(target) & (IS_TMP_VAR|IS_CV)) &&
+ same_type == ZEND_OP1_TYPE(target) &&
+ same_var == VAR_NUM_EX(target->op1) &&
+ target_block->follow_to &&
+ !target_block->protected) {
+ /* JMPZ(X, L), L: X = JMPNZ_EX(X, L2) -> JMPZ(X, L+1) */
+ last_op->opcode += 3;
+ last_op->result = target->result;
+ del_source(block, block->op2_to);
+ block->op2_to = target_block->follow_to;
+ ADD_SOURCE(block, block->op2_to);
+ } else if (target_block->op2_to &&
+ target->opcode == last_op->opcode &&
+ (ZEND_OP1_TYPE(target) & (IS_TMP_VAR|IS_CV)) &&
+ same_type == ZEND_OP1_TYPE(target) &&
+ same_var == VAR_NUM_EX(target->op1) &&
+ !target_block->protected) {
+ /* JMPZ(X, L), L: JMPZ(X, L2) -> JMPZ(X, L2) */
+ del_source(block, block->op2_to);
+ block->op2_to = target_block->op2_to;
+ ADD_SOURCE(block, block->op2_to);
+ } else if (target_block->op1_to &&
+ target->opcode == ZEND_JMP &&
+ !target_block->protected) {
+ /* JMPZ(X, L), L: JMP(L2) -> JMPZ(X, L2) */
+ del_source(block, block->op2_to);
+ block->op2_to = target_block->op1_to;
+ ADD_SOURCE(block, block->op2_to);
+ } else if (target_block->op2_to &&
+ target_block->ext_to &&
+ target->opcode == ZEND_JMPZNZ &&
+ (ZEND_OP1_TYPE(target) & (IS_TMP_VAR|IS_CV)) &&
+ same_type == ZEND_OP1_TYPE(target) &&
+ same_var == VAR_NUM_EX(target->op1) &&
+ !target_block->protected) {
+ /* JMPZ(X, L), L: JMPZNZ(X, L2, L3) -> JMPZ(X, L2) */
+ del_source(block, block->op2_to);
+ if (last_op->opcode == ZEND_JMPZ) {
+ block->op2_to = target_block->op2_to;
+ } else {
+ block->op2_to = target_block->ext_to;
+ }
+ ADD_SOURCE(block, block->op2_to);
+ }
+ }
+
+ if (block->follow_to &&
+ (last_op->opcode == ZEND_JMPZ || last_op->opcode == ZEND_JMPNZ)) {
+ zend_op *target;
+ zend_op *target_end;
+
+ while (1) {
+ target = block->follow_to->start_opline;
+ target_end = block->follow_to->start_opline + block->follow_to->len;
+ while (target < target_end && target->opcode == ZEND_NOP) {
+ target++;
+ }
+
+ /* next block is only NOP's */
+ if (target == target_end) {
+ del_source(block, block->follow_to);
+ block->follow_to = block->follow_to->follow_to;
+ ADD_SOURCE(block, block->follow_to);
+ } else {
+ break;
+ }
+ }
+ /* JMPZ(X,L1), JMP(L2) -> JMPZNZ(X,L1,L2) */
+ if (target->opcode == ZEND_JMP &&
+ block->follow_to->op1_to &&
+ !block->follow_to->protected) {
+ del_source(block, block->follow_to);
+ if (last_op->opcode == ZEND_JMPZ) {
+ block->ext_to = block->follow_to->op1_to;
+ ADD_SOURCE(block, block->ext_to);
+ } else {
+ block->ext_to = block->op2_to;
+ block->op2_to = block->follow_to->op1_to;
+ ADD_SOURCE(block, block->op2_to);
+ }
+ block->follow_to = NULL;
+ last_op->opcode = ZEND_JMPZNZ;
+ }
+ }
+ break;
+
+ case ZEND_JMPNZ_EX:
+ case ZEND_JMPZ_EX:
+ /* constant conditional JMPs */
+ if (ZEND_OP1_TYPE(last_op) == IS_CONST) {
+ int should_jmp = zend_is_true(&ZEND_OP1_LITERAL(last_op));
+ if (last_op->opcode == ZEND_JMPZ_EX) {
+ should_jmp = !should_jmp;
+ }
+ if (!should_jmp) {
+ /* T = JMPZ_EX(true,L) -> T = QM_ASSIGN(true)
+ * T = JMPNZ_EX(false,L) -> T = QM_ASSIGN(false)
+ */
+ last_op->opcode = ZEND_QM_ASSIGN;
+ SET_UNUSED(last_op->op2);
+ del_source(block, block->op2_to);
+ block->op2_to = NULL;
+ }
+ break;
+ }
+
+ if (block->op2_to) {
+ zend_op *target, *target_end;
+ char *same_t=NULL;
+ zend_code_block *target_block;
+ int var_num = 0;
+ if (op_array->T >= (zend_uint)op_array->last_var) {
+ var_num = op_array->T;
+ } else {
+ var_num = op_array->last_var;
+ }
+ if (var_num <= 0) {
+ return;
+ }
+ same_t = ecalloc(var_num, sizeof(char));
+ if (same_t == NULL) {
+ return;
+ }
+ same_t[VAR_NUM_EX(last_op->op1)] |= ZEND_OP1_TYPE(last_op);
+ same_t[VAR_NUM_EX(last_op->result)] |= ZEND_RESULT_TYPE(last_op);
+ target_block = block->op2_to;
+next_target_ex:
+ target = target_block->start_opline;
+ target_end = target_block->start_opline + target_block->len;
+ while (target < target_end && target->opcode == ZEND_NOP) {
+ target++;
+ }
+ /* next block is only NOP's */
+ if (target == target_end) {
+ target_block = target_block->follow_to;
+ goto next_target_ex;
+ } else if (target_block->op2_to &&
+ target->opcode == last_op->opcode-3 &&
+ (ZEND_OP1_TYPE(target) & (IS_TMP_VAR|IS_CV)) &&
+ (same_t[VAR_NUM_EX(target->op1)] & ZEND_OP1_TYPE(target)) != 0 &&
+ !target_block->protected) {
+ /* T = JMPZ_EX(X, L1), L1: JMPZ({X|T}, L2) -> T = JMPZ_EX(X, L2) */
+ del_source(block, block->op2_to);
+ block->op2_to = target_block->op2_to;
+ ADD_SOURCE(block, block->op2_to);
+ } else if (target_block->op2_to &&
+ target->opcode == INV_EX_COND(last_op->opcode) &&
+ (ZEND_OP1_TYPE(target) & (IS_TMP_VAR|IS_CV)) &&
+ (same_t[VAR_NUM_EX(target->op1)] & ZEND_OP1_TYPE(target)) != 0 &&
+ !target_block->protected) {
+ /* T = JMPZ_EX(X, L1), L1: JMPNZ({X|T1}, L2) -> T = JMPZ_EX(X, L1+1) */
+ del_source(block, block->op2_to);
+ block->op2_to = target_block->follow_to;
+ ADD_SOURCE(block, block->op2_to);
+ } else if (target_block->op2_to &&
+ target->opcode == INV_EX_COND_EX(last_op->opcode) &&
+ (ZEND_OP1_TYPE(target) & (IS_TMP_VAR|IS_CV)) &&
+ (same_t[VAR_NUM_EX(target->op1)] & ZEND_OP1_TYPE(target)) != 0 &&
+ (same_t[VAR_NUM_EX(target->result)] & ZEND_RESULT_TYPE(target)) != 0 &&
+ !target_block->protected) {
+ /* T = JMPZ_EX(X, L1), L1: T = JMPNZ_EX(T, L2) -> T = JMPZ_EX(X, L1+1) */
+ del_source(block, block->op2_to);
+ block->op2_to = target_block->follow_to;
+ ADD_SOURCE(block, block->op2_to);
+ } else if (target_block->op2_to &&
+ target->opcode == last_op->opcode &&
+ (ZEND_OP1_TYPE(target) & (IS_TMP_VAR|IS_CV)) &&
+ (same_t[VAR_NUM_EX(target->op1)] & ZEND_OP1_TYPE(target)) != 0 &&
+ (same_t[VAR_NUM_EX(target->result)] & ZEND_RESULT_TYPE(target)) != 0 &&
+ !target_block->protected) {
+ /* T = JMPZ_EX(X, L1), L1: T = JMPZ({X|T}, L2) -> T = JMPZ_EX(X, L2) */
+ del_source(block, block->op2_to);
+ block->op2_to = target_block->op2_to;
+ ADD_SOURCE(block, block->op2_to);
+ } else if (target_block->op1_to &&
+ target->opcode == ZEND_JMP &&
+ !target_block->protected) {
+ /* T = JMPZ_EX(X, L), L: JMP(L2) -> T = JMPZ(X, L2) */
+ del_source(block, block->op2_to);
+ block->op2_to = target_block->op1_to;
+ ADD_SOURCE(block, block->op2_to);
+ } else if (target_block->op2_to &&
+ target_block->ext_to &&
+ target->opcode == ZEND_JMPZNZ &&
+ (ZEND_OP1_TYPE(target) & (IS_TMP_VAR|IS_CV)) &&
+ (same_t[VAR_NUM_EX(target->op1)] & ZEND_OP1_TYPE(target)) != 0 &&
+ !target_block->protected) {
+ /* T = JMPZ_EX(X, L), L: JMPZNZ({X|T}, L2, L3) -> T = JMPZ_EX(X, L2) */
+ del_source(block, block->op2_to);
+ if (last_op->opcode == ZEND_JMPZ_EX) {
+ block->op2_to = target_block->op2_to;
+ } else {
+ block->op2_to = target_block->ext_to;
+ }
+ ADD_SOURCE(block, block->op2_to);
+ }
+ if (same_t != NULL) {
+ efree(same_t);
+ }
+ }
+ break;
+
+ case ZEND_JMPZNZ: {
+ zend_code_block *next = block->next;
+
+ while (next && !next->access) {
+ /* find first accessed one */
+ next = next->next;
+ }
+
+ if (ZEND_OP1_TYPE(last_op) == IS_CONST) {
+ if (!zend_is_true(&ZEND_OP1_LITERAL(last_op))) {
+ /* JMPZNZ(false,L1,L2) -> JMP(L1) */
+ zend_code_block *todel;
+
+ literal_dtor(&ZEND_OP1_LITERAL(last_op));
+ last_op->opcode = ZEND_JMP;
+ SET_UNUSED(last_op->op1);
+ SET_UNUSED(last_op->op2);
+ block->op1_to = block->op2_to;
+ todel = block->ext_to;
+ block->op2_to = NULL;
+ block->ext_to = NULL;
+ del_source(block, todel);
+ } else {
+ /* JMPZNZ(true,L1,L2) -> JMP(L2) */
+ zend_code_block *todel;
+
+ literal_dtor(&ZEND_OP1_LITERAL(last_op));
+ last_op->opcode = ZEND_JMP;
+ SET_UNUSED(last_op->op1);
+ SET_UNUSED(last_op->op2);
+ block->op1_to = block->ext_to;
+ todel = block->op2_to;
+ block->op2_to = NULL;
+ block->ext_to = NULL;
+ del_source(block, todel);
+ }
+ } else if (block->op2_to == block->ext_to) {
+ /* both goto the same one - it's JMP */
+ /* JMPZNZ(?,L,L) -> JMP(L) */
+ last_op->opcode = ZEND_JMP;
+ SET_UNUSED(last_op->op1);
+ SET_UNUSED(last_op->op2);
+ block->op1_to = block->op2_to;
+ block->op2_to = NULL;
+ block->ext_to = NULL;
+ } else if (block->op2_to == next) {
+ /* jumping to next on Z - can follow to it and jump only on NZ */
+ /* JMPZNZ(X,L1,L2) L1: -> JMPNZ(X,L2) */
+ last_op->opcode = ZEND_JMPNZ;
+ block->op2_to = block->ext_to;
+ block->follow_to = next;
+ block->ext_to = NULL;
+ /* no need to add source - it's block->op2_to */
+ } else if (block->ext_to == next) {
+ /* jumping to next on NZ - can follow to it and jump only on Z */
+ /* JMPZNZ(X,L1,L2) L2: -> JMPZ(X,L1) */
+ last_op->opcode = ZEND_JMPZ;
+ block->follow_to = next;
+ block->ext_to = NULL;
+ /* no need to add source - it's block->ext_to */
+ }
+
+ if (last_op->opcode == ZEND_JMPZNZ && block->op2_to) {
+ zend_uchar same_type = ZEND_OP1_TYPE(last_op);
+ zend_uchar same_var = VAR_NUM_EX(last_op->op1);
+ zend_op *target;
+ zend_op *target_end;
+ zend_code_block *target_block = block->op2_to;
+
+next_target_znz:
+ target = target_block->start_opline;
+ target_end = target_block->start_opline + target_block->len;
+ while (target < target_end && target->opcode == ZEND_NOP) {
+ target++;
+ }
+ /* next block is only NOP's */
+ if (target == target_end) {
+ target_block = target_block->follow_to;
+ goto next_target_znz;
+ } else if (target_block->op2_to &&
+ (target->opcode == ZEND_JMPZ || target->opcode == ZEND_JMPZNZ) &&
+ (ZEND_OP1_TYPE(target) & (IS_TMP_VAR|IS_CV)) &&
+ same_type == ZEND_OP1_TYPE(target) &&
+ same_var == VAR_NUM_EX(target->op1) &&
+ !target_block->protected) {
+ /* JMPZNZ(X, L1, L2), L1: JMPZ(X, L3) -> JMPZNZ(X, L3, L2) */
+ del_source(block, block->op2_to);
+ block->op2_to = target_block->op2_to;
+ ADD_SOURCE(block, block->op2_to);
+ } else if (target->opcode == ZEND_JMPNZ &&
+ (ZEND_OP1_TYPE(target) & (IS_TMP_VAR|IS_CV)) &&
+ same_type == ZEND_OP1_TYPE(target) &&
+ same_var == VAR_NUM_EX(target->op1) &&
+ target_block->follow_to &&
+ !target_block->protected) {
+ /* JMPZNZ(X, L1, L2), L1: X = JMPNZ(X, L3) -> JMPZNZ(X, L1+1, L2) */
+ del_source(block, block->op2_to);
+ block->op2_to = target_block->follow_to;
+ ADD_SOURCE(block, block->op2_to);
+ } else if (target_block->op1_to &&
+ target->opcode == ZEND_JMP &&
+ !target_block->protected) {
+ /* JMPZNZ(X, L1, L2), L1: JMP(L3) -> JMPZNZ(X, L3, L2) */
+ del_source(block, block->op2_to);
+ block->op2_to = target_block->op1_to;
+ ADD_SOURCE(block, block->op2_to);
+ }
+ }
+ break;
+ }
+ }
+}
+
+/* Global data dependencies */
+
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+
+# define T_USAGE(op) do { \
+ if ((op ## _type & (IS_VAR | IS_TMP_VAR)) && \
+ !defined_here[VAR_NUM(op.var)] && !used_ext[VAR_NUM(op.var)]) { \
+ used_ext[VAR_NUM(op.var)] = 1; \
+ } \
+ } while (0)
+
+# define NEVER_USED(op) ((op ## _type & (IS_VAR | IS_TMP_VAR)) && !usage[VAR_NUM(op.var)]) /* !used_ext[op.var] && */
+# define RES_NEVER_USED(opline) (opline->result_type == IS_UNUSED || NEVER_USED(opline->result))
+
+#else
+
+# define T_USAGE(op) do { \
+ if ((op.op_type == IS_VAR || op.op_type == IS_TMP_VAR) && \
+ !defined_here[VAR_NUM(op.u.var)] && !used_ext[VAR_NUM(op.u.var)]) { \
+ used_ext[VAR_NUM(op.u.var)] = 1; \
+ } \
+ } while (0)
+
+# define NEVER_USED(op) ((op.op_type == IS_VAR || op.op_type == IS_TMP_VAR) && !usage[VAR_NUM(op.u.var)]) /* !used_ext[op.u.var] && */
+# define RES_NEVER_USED(opline) (ZEND_RESULT_TYPE(opline) == IS_UNUSED || NEVER_USED(opline->result))
+
+#endif
+
+/* Find a set of variables which are used outside of the block where they are
+ * defined. We won't apply some optimization patterns for sush variables. */
+static void zend_t_usage(zend_code_block *block, zend_op_array *op_array, char *used_ext)
+{
+ zend_code_block *next_block = block->next;
+ char *usage;
+ char *defined_here;
+
+ if (op_array->T == 0) {
+ /* shortcut - if no Ts, nothing to do */
+ return;
+ }
+
+ usage = ecalloc(op_array->T, 1);
+ defined_here = emalloc(op_array->T);
+
+ while (next_block) {
+ zend_op *opline = next_block->start_opline;
+ zend_op *end = opline + next_block->len;
+
+ if (!next_block->access) {
+ next_block = next_block->next;
+ continue;
+ }
+ memset(defined_here, 0, op_array->T);
+
+ while (opline<end) {
+ T_USAGE(opline->op1);
+ T_USAGE(opline->op2);
+
+ if (RESULT_USED(opline)) {
+ if (!defined_here[VAR_NUM(ZEND_RESULT(opline).var)] && !used_ext[VAR_NUM(ZEND_RESULT(opline).var)] &&
+ (opline->opcode == ZEND_RECV || opline->opcode == ZEND_RECV_INIT ||
+ (opline->opcode == ZEND_OP_DATA && ZEND_RESULT_TYPE(opline) == IS_TMP_VAR) ||
+ opline->opcode == ZEND_ADD_ARRAY_ELEMENT)) {
+ /* these opcodes use the result as argument */
+ used_ext[VAR_NUM(ZEND_RESULT(opline).var)] = 1;
+ }
+ defined_here[VAR_NUM(ZEND_RESULT(opline).var)] = 1;
+ }
+ opline++;
+ }
+ next_block = next_block->next;
+ }
+
+#if DEBUG_BLOCKPASS
+ {
+ int i;
+ for (i = 0; i< op_array->T; i++) {
+ fprintf(stderr, "T%d: %c\n", i, used_ext[i] + '0');
+ }
+ }
+#endif
+
+ while (block) {
+ zend_op *opline = block->start_opline + block->len - 1;
+
+ if (!block->access) {
+ block = block->next;
+ continue;
+ }
+
+ memcpy(usage, used_ext, op_array->T);
+
+ while (opline >= block->start_opline) {
+ /* usage checks */
+ if (RES_NEVER_USED(opline)) {
+ switch (opline->opcode) {
+ case ZEND_ASSIGN_ADD:
+ case ZEND_ASSIGN_SUB:
+ case ZEND_ASSIGN_MUL:
+ case ZEND_ASSIGN_DIV:
+ case ZEND_ASSIGN_MOD:
+ case ZEND_ASSIGN_SL:
+ case ZEND_ASSIGN_SR:
+ case ZEND_ASSIGN_CONCAT:
+ case ZEND_ASSIGN_BW_OR:
+ case ZEND_ASSIGN_BW_AND:
+ case ZEND_ASSIGN_BW_XOR:
+ case ZEND_PRE_INC:
+ case ZEND_PRE_DEC:
+ case ZEND_POST_INC:
+ case ZEND_POST_DEC:
+ case ZEND_ASSIGN:
+ case ZEND_ASSIGN_REF:
+ case ZEND_DO_FCALL:
+ case ZEND_DO_FCALL_BY_NAME:
+ if (ZEND_RESULT_TYPE(opline) == IS_VAR) {
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ ZEND_RESULT_TYPE(opline) |= EXT_TYPE_UNUSED;
+#else
+ ZEND_RESULT(opline).EA.type |= EXT_TYPE_UNUSED;
+#endif
+ }
+ break;
+ case ZEND_QM_ASSIGN:
+ case ZEND_BOOL:
+ case ZEND_BOOL_NOT:
+ if (ZEND_OP1_TYPE(opline) == IS_CONST) {
+ literal_dtor(&ZEND_OP1_LITERAL(opline));
+ }
+ MAKE_NOP(opline);
+ break;
+ case ZEND_PRINT:
+ opline->opcode = ZEND_ECHO;
+ ZEND_RESULT_TYPE(opline) = IS_UNUSED;
+ break;
+ case ZEND_JMPZ_EX:
+ case ZEND_JMPNZ_EX:
+ opline->opcode -= 3;
+ SET_UNUSED(opline->result);
+ break;
+ }
+ }
+
+ if (opline->opcode == ZEND_RECV ||
+ opline->opcode == ZEND_RECV_INIT ||
+ opline->opcode == ZEND_ADD_ARRAY_ELEMENT) {
+ if (ZEND_OP1_TYPE(opline) == IS_VAR || ZEND_OP1_TYPE(opline) == IS_TMP_VAR) {
+ usage[VAR_NUM(ZEND_RESULT(opline).var)] = 1;
+ }
+ } else {
+ if (RESULT_USED(opline)) {
+ usage[VAR_NUM(ZEND_RESULT(opline).var)] = 0;
+ }
+ }
+
+ if (ZEND_OP1_TYPE(opline) == IS_VAR || ZEND_OP1_TYPE(opline) == IS_TMP_VAR) {
+ usage[VAR_NUM(ZEND_OP1(opline).var)] = 1;
+ }
+ if (ZEND_OP2_TYPE(opline) == IS_VAR || ZEND_OP2_TYPE(opline) == IS_TMP_VAR) {
+ usage[VAR_NUM(ZEND_OP2(opline).var)] = 1;
+ }
+
+
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ if ((ZEND_RESULT_TYPE(opline) & IS_VAR) &&
+ (ZEND_RESULT_TYPE(opline) & EXT_TYPE_UNUSED) &&
+ usage[VAR_NUM(ZEND_RESULT(opline).var)]) {
+ ZEND_RESULT_TYPE(opline) &= ~EXT_TYPE_UNUSED;
+ }
+#else
+ if (ZEND_RESULT_TYPE(opline) == IS_VAR &&
+ usage[VAR_NUM(ZEND_RESULT(opline).var)] &&
+ (ZEND_RESULT(opline).EA.type & EXT_TYPE_UNUSED) != 0) {
+ ZEND_RESULT(opline).EA.type &= ~EXT_TYPE_UNUSED;
+ }
+#endif
+
+ opline--;
+ }
+ block = block->next;
+ } /* end blocks */
+
+ efree(defined_here);
+ efree(usage);
+}
+
+#define PASSES 3
+
+static void zend_block_optimization(zend_op_array *op_array TSRMLS_DC)
+{
+ zend_cfg cfg;
+ zend_code_block *cur_block;
+ int pass;
+ char *usage;
+
+#if DEBUG_BLOCKPASS
+ fprintf(stderr, "File %s func %s\n", op_array->filename, op_array->function_name? op_array->function_name : "main");
+ fflush(stderr);
+#endif
+
+#if ZEND_EXTENSION_API_NO > PHP_5_4_X_API_NO
+ if (op_array->has_finally_block) {
+ return;
+ }
+#endif
+
+ /* Build CFG */
+ if (!find_code_blocks(op_array, &cfg)) {
+ return;
+ }
+
+ zend_rebuild_access_path(&cfg, op_array, 0);
+ /* full rebuild here to produce correct sources! */
+ usage = emalloc(op_array->T);
+ for (pass = 0; pass < PASSES; pass++) {
+ /* Compute data dependencies */
+ memset(usage, 0, op_array->T);
+ zend_t_usage(cfg.blocks, op_array, usage);
+
+ /* optimize each basic block separately */
+ for (cur_block = cfg.blocks; cur_block; cur_block = cur_block->next) {
+ if (!cur_block->access) {
+ continue;
+ }
+ zend_optimize_block(cur_block, op_array, usage TSRMLS_CC);
+ }
+
+ /* Jump optimization for each block */
+ for (cur_block = cfg.blocks; cur_block; cur_block = cur_block->next) {
+ if (!cur_block->access) {
+ continue;
+ }
+ zend_jmp_optimization(cur_block, op_array, cfg.blocks TSRMLS_CC);
+ }
+
+ /* Eliminate unreachable basic blocks */
+ zend_rebuild_access_path(&cfg, op_array, 1);
+ }
+
+ memset(usage, 0, op_array->T);
+ zend_t_usage(cfg.blocks, op_array, usage);
+ assemble_code_blocks(&cfg, op_array);
+ efree(usage);
+
+ /* Destroy CFG */
+ for (cur_block = cfg.blocks; cur_block; cur_block = cur_block->next) {
+ zend_block_source *cs = cur_block->sources;
+ while (cs) {
+ zend_block_source *n = cs->next;
+ efree(cs);
+ cs = n;
+ }
+ }
+ efree(cfg.blocks);
+}
diff --git a/ext/opcache/Optimizer/nop_removal.c b/ext/opcache/Optimizer/nop_removal.c
new file mode 100644
index 0000000000..b2fb667ed5
--- /dev/null
+++ b/ext/opcache/Optimizer/nop_removal.c
@@ -0,0 +1,126 @@
+/* pass 10:
+ * - remove NOPs
+ */
+
+static void nop_removal(zend_op_array *op_array)
+{
+ zend_op *end, *opline;
+ zend_uint new_count, i, shift;
+ int j;
+ zend_uint *shiftlist;
+ ALLOCA_FLAG(use_heap);
+
+ shiftlist = (zend_uint *)DO_ALLOCA(sizeof(zend_uint) * op_array->last);
+ i = new_count = shift = 0;
+ end = op_array->opcodes + op_array->last;
+ for (opline = op_array->opcodes; opline < end; opline++) {
+
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+ /* GOTO target is unresolved yet. We can't optimize. */
+ if (opline->opcode == ZEND_GOTO &&
+ Z_TYPE(ZEND_OP2_LITERAL(opline)) != IS_LONG) {
+ /* TODO: in general we can avoid this restriction */
+ FREE_ALLOCA(shiftlist);
+ return;
+ }
+#endif
+
+ /* Kill JMP-over-NOP-s */
+ if (opline->opcode == ZEND_JMP && ZEND_OP1(opline).opline_num > i) {
+ /* check if there are only NOPs under the branch */
+ zend_op *target = op_array->opcodes + ZEND_OP1(opline).opline_num - 1;
+
+ while (target->opcode == ZEND_NOP) {
+ target--;
+ }
+ if (target == opline) {
+ /* only NOPs */
+ opline->opcode = ZEND_NOP;
+ }
+ }
+
+ shiftlist[i++] = shift;
+ if (opline->opcode == ZEND_NOP) {
+ shift++;
+ } else {
+ if (shift) {
+ op_array->opcodes[new_count] = *opline;
+ }
+ new_count++;
+ }
+ }
+
+ if (shift) {
+ op_array->last = new_count;
+ end = op_array->opcodes + op_array->last;
+
+ /* update JMPs */
+ for (opline = op_array->opcodes; opline<end; opline++) {
+ switch (opline->opcode) {
+ case ZEND_JMP:
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+ case ZEND_GOTO:
+#endif
+#if ZEND_EXTENSION_API_NO > PHP_5_4_X_API_NO
+ case ZEND_FAST_CALL:
+#endif
+ ZEND_OP1(opline).opline_num -= shiftlist[ZEND_OP1(opline).opline_num];
+ break;
+ case ZEND_JMPZ:
+ case ZEND_JMPNZ:
+ case ZEND_JMPZ_EX:
+ case ZEND_JMPNZ_EX:
+ case ZEND_FE_FETCH:
+ case ZEND_FE_RESET:
+ case ZEND_NEW:
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+ case ZEND_JMP_SET:
+#endif
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ case ZEND_JMP_SET_VAR:
+#endif
+ ZEND_OP2(opline).opline_num -= shiftlist[ZEND_OP2(opline).opline_num];
+ break;
+ case ZEND_JMPZNZ:
+ ZEND_OP2(opline).opline_num -= shiftlist[ZEND_OP2(opline).opline_num];
+ opline->extended_value -= shiftlist[opline->extended_value];
+ break;
+ case ZEND_CATCH:
+ opline->extended_value -= shiftlist[opline->extended_value];
+ break;
+ }
+ }
+
+ /* update brk/cont array */
+ for (j = 0; j < op_array->last_brk_cont; j++) {
+ op_array->brk_cont_array[j].brk -= shiftlist[op_array->brk_cont_array[j].brk];
+ op_array->brk_cont_array[j].cont -= shiftlist[op_array->brk_cont_array[j].cont];
+ op_array->brk_cont_array[j].start -= shiftlist[op_array->brk_cont_array[j].start];
+ }
+
+ /* update try/catch array */
+ for (j = 0; j < op_array->last_try_catch; j++) {
+ op_array->try_catch_array[j].try_op -= shiftlist[op_array->try_catch_array[j].try_op];
+ op_array->try_catch_array[j].catch_op -= shiftlist[op_array->try_catch_array[j].catch_op];
+#if ZEND_EXTENSION_API_NO > PHP_5_4_X_API_NO
+ if (op_array->try_catch_array[j].finally_op) {
+ op_array->try_catch_array[j].finally_op -= shiftlist[op_array->try_catch_array[j].finally_op];
+ op_array->try_catch_array[j].finally_end -= shiftlist[op_array->try_catch_array[j].finally_end];
+ }
+#endif
+ }
+
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+ /* update early binding list */
+ if (op_array->early_binding != (zend_uint)-1) {
+ zend_uint *opline_num = &op_array->early_binding;
+
+ do {
+ *opline_num -= shiftlist[*opline_num];
+ opline_num = &ZEND_RESULT(&op_array->opcodes[*opline_num]).opline_num;
+ } while (*opline_num != (zend_uint)-1);
+ }
+#endif
+ }
+ FREE_ALLOCA(shiftlist);
+}
diff --git a/ext/opcache/Optimizer/optimize_temp_vars_5.c b/ext/opcache/Optimizer/optimize_temp_vars_5.c
new file mode 100644
index 0000000000..dc630733fa
--- /dev/null
+++ b/ext/opcache/Optimizer/optimize_temp_vars_5.c
@@ -0,0 +1,222 @@
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+
+/* ops that use CLs:
+op1:
+ZEND_FETCH_CONSTANT:
+ZEND_INIT_CTOR_CALL:
+ZEND_INIT_STATIC_METHOD_CALL:
+ZEND_INIT_METHOD_CALL:
+ZEND_IMPORT_CLASS:
+ZEND_IMPORT_FUNCTION:
+ZEND_IMPORT_CONST:
+ZEND_ADD_INTERFACE:
+ZEND_VERIFY_ABSTRACT_CLASS:
+ZEND_NEW:
+ZEND_CATCH:
+ZEND_INIT_FCALL_BY_NAME:
+
+op2:
+ZEND_UNSET_VAR:
+ZEND_ISSET_ISEMPTY_VAR:
+ZEND_FETCH_UNSET:
+ZEND_FETCH_IS:
+ZEND_FETCH_R:
+ZEND_FETCH_W:
+ZEND_FETCH_RW:
+ZEND_FETCH_FUNC_ARG:
+ZEND_ADD_INTERFACE:
+ZEND_INSTANCEOF:
+
+extended_value:
+ZEND_DECLARE_INHERITED_CLASS:
+
+ignore result
+INIT_METHOD_CALL:
+*/
+
+#define OP1_CONST_IS_CLASS 1
+#define OP2_CONST_IS_CLASS 2
+#define EXT_CONST_IS_CLASS 4
+#define RESULT_IS_UNUSED 8
+
+static const char op_const_means_class[256] = {
+ /* 0 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 32 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
+ /* 64 */
+ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2,
+ /* 96 */
+ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 9, 1, 2, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 128 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 0, 0, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 160 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 192 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 224 */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+#endif
+
+#define GET_AVAILABLE_T() \
+ for (i = 0; i < T; i++) { \
+ if (!taken_T[i]) { \
+ break; \
+ } \
+ } \
+ taken_T[i] = 1; \
+ if (i > max) { \
+ max = i; \
+ }
+
+static void optimize_temporary_variables(zend_op_array *op_array)
+{
+ int T = op_array->T;
+ char *taken_T; /* T index in use */
+ zend_op **start_of_T; /* opline where T is first used */
+ char *valid_T; /* Is the map_T valid */
+ int *map_T; /* Map's the T to its new index */
+ zend_op *opline, *end;
+ int currT;
+ int i;
+ int max = -1;
+ int var_to_free = -1;
+
+ taken_T = (char *) emalloc(T);
+ start_of_T = (zend_op **) emalloc(T * sizeof(zend_op *));
+ valid_T = (char *) emalloc(T);
+ map_T = (int *) emalloc(T * sizeof(int));
+
+ end = op_array->opcodes;
+ opline = &op_array->opcodes[op_array->last - 1];
+
+ /* Find T definition points */
+ while (opline >= end) {
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+ if (ZEND_RESULT_TYPE(opline) & (IS_VAR | IS_TMP_VAR | IS_CONST)) {
+ if (!(op_const_means_class[opline->opcode] & RESULT_IS_UNUSED)) {
+ start_of_T[VAR_NUM(ZEND_RESULT(opline).var)] = opline;
+ }
+ }
+#else
+ if (ZEND_RESULT_TYPE(opline) & (IS_VAR | IS_TMP_VAR)) {
+ start_of_T[VAR_NUM(ZEND_RESULT(opline).var)] = opline;
+ }
+#endif
+ opline--;
+ }
+
+ memset(valid_T, 0, T);
+ memset(taken_T, 0, T);
+
+ end = op_array->opcodes;
+ opline = &op_array->opcodes[op_array->last - 1];
+
+ while (opline >= end) {
+ if ((ZEND_OP1_TYPE(opline) & (IS_VAR | IS_TMP_VAR))
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+ || ((op_const_means_class[opline->opcode] & OP1_CONST_IS_CLASS) && ZEND_OP1_TYPE(opline) == IS_CONST)
+#endif
+ ) {
+ currT = VAR_NUM(ZEND_OP1(opline).var);
+ if (!valid_T[currT]) {
+ GET_AVAILABLE_T();
+ map_T[currT] = i;
+ valid_T[currT] = 1;
+ }
+ ZEND_OP1(opline).var = NUM_VAR(map_T[currT]);
+ }
+
+ /* Skip OP_DATA */
+ if (opline->opcode == ZEND_OP_DATA &&
+ (opline-1)->opcode == ZEND_ASSIGN_DIM) {
+ opline--;
+ continue;
+ }
+
+ if ((ZEND_OP2_TYPE(opline) & (IS_VAR | IS_TMP_VAR))
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+ || ((op_const_means_class[opline->opcode] & OP2_CONST_IS_CLASS) && ZEND_OP2_TYPE(opline) == IS_CONST)
+#endif
+ ) {
+ currT = VAR_NUM(ZEND_OP2(opline).var);
+ if (!valid_T[currT]) {
+ GET_AVAILABLE_T();
+ map_T[currT] = i;
+ valid_T[currT] = 1;
+ }
+ ZEND_OP2(opline).var = NUM_VAR(map_T[currT]);
+ }
+
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+ if ((op_const_means_class[opline->opcode] & EXT_CONST_IS_CLASS)) {
+#else
+ if (opline->opcode == ZEND_DECLARE_INHERITED_CLASS ||
+ opline->opcode == ZEND_DECLARE_INHERITED_CLASS_DELAYED) {
+#endif
+ currT = VAR_NUM(opline->extended_value);
+ if (!valid_T[currT]) {
+ GET_AVAILABLE_T();
+ map_T[currT] = i;
+ valid_T[currT] = 1;
+ }
+ opline->extended_value = NUM_VAR(map_T[currT]);
+ }
+
+ /* Allocate OP_DATA->op2 after "operands", but before "result" */
+ if (opline->opcode == ZEND_ASSIGN_DIM &&
+ (opline + 1)->opcode == ZEND_OP_DATA &&
+ ZEND_OP2_TYPE(opline + 1) & (IS_VAR | IS_TMP_VAR)) {
+ currT = VAR_NUM(ZEND_OP2(opline + 1).var);
+ GET_AVAILABLE_T();
+ map_T[currT] = i;
+ valid_T[currT] = 1;
+ taken_T[i] = 0;
+ ZEND_OP2(opline + 1).var = NUM_VAR(i);
+ var_to_free = i;
+ }
+
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+ if (ZEND_RESULT_TYPE(opline) & (IS_VAR | IS_TMP_VAR | IS_CONST)) {
+ if (!(op_const_means_class[opline->opcode] & RESULT_IS_UNUSED)) {
+#else
+ if (ZEND_RESULT_TYPE(opline) & (IS_VAR | IS_TMP_VAR)) {
+#endif
+ currT = VAR_NUM(ZEND_RESULT(opline).var);
+ if (valid_T[currT]) {
+ if (start_of_T[currT] == opline) {
+ taken_T[map_T[currT]] = 0;
+ }
+ ZEND_RESULT(opline).var = NUM_VAR(map_T[currT]);
+ } else { /* Au still needs to be assigned a T which is a bit dumb. Should consider changing Zend */
+ GET_AVAILABLE_T();
+
+ if (RESULT_UNUSED(opline)) {
+ taken_T[i] = 0;
+ } else {
+ /* Code which gets here is using a wrongly built opcode such as RECV() */
+ map_T[currT] = i;
+ valid_T[currT] = 1;
+ }
+ ZEND_RESULT(opline).var = NUM_VAR(i);
+ }
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+ }
+#endif
+ }
+
+ if (var_to_free >= 0) {
+ taken_T[var_to_free] = 0;
+ var_to_free = -1;
+ }
+
+ opline--;
+ }
+
+ efree(taken_T);
+ efree(start_of_T);
+ efree(valid_T);
+ efree(map_T);
+ op_array->T = max + 1;
+}
diff --git a/ext/opcache/Optimizer/pass10.c b/ext/opcache/Optimizer/pass10.c
new file mode 100644
index 0000000000..3bfcec643a
--- /dev/null
+++ b/ext/opcache/Optimizer/pass10.c
@@ -0,0 +1,3 @@
+if (((ZEND_OPTIMIZER_PASS_10|ZEND_OPTIMIZER_PASS_5) & OPTIMIZATION_LEVEL) == ZEND_OPTIMIZER_PASS_10) {
+ nop_removal(op_array);
+}
diff --git a/ext/opcache/Optimizer/pass1_5.c b/ext/opcache/Optimizer/pass1_5.c
new file mode 100644
index 0000000000..ca5b882901
--- /dev/null
+++ b/ext/opcache/Optimizer/pass1_5.c
@@ -0,0 +1,338 @@
+/* pass 1
+ * - substitute persistent constants (true, false, null, etc)
+ * - perform compile-time evaluation of constant binary and unary operations
+ * - optimize series of ADD_STRING and/or ADD_CHAR
+ * - convert CAST(IS_BOOL,x) into BOOL(x)
+ * - convert INTI_FCALL_BY_NAME, DO_FCALL_BY_NAME into DO_FCALL
+ */
+
+if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) {
+ int i = 0;
+ zend_op *opline = op_array->opcodes;
+ zend_op *end = opline + op_array->last;
+
+ while (opline < end) {
+ switch (opline->opcode) {
+ case ZEND_ADD:
+ case ZEND_SUB:
+ case ZEND_MUL:
+ case ZEND_DIV:
+ case ZEND_MOD:
+ case ZEND_SL:
+ case ZEND_SR:
+ case ZEND_CONCAT:
+ case ZEND_IS_EQUAL:
+ case ZEND_IS_NOT_EQUAL:
+ case ZEND_IS_SMALLER:
+ case ZEND_IS_SMALLER_OR_EQUAL:
+ case ZEND_IS_IDENTICAL:
+ case ZEND_IS_NOT_IDENTICAL:
+ case ZEND_BW_OR:
+ case ZEND_BW_AND:
+ case ZEND_BW_XOR:
+ case ZEND_BOOL_XOR:
+ if (ZEND_OP1_TYPE(opline) == IS_CONST &&
+ ZEND_OP2_TYPE(opline) == IS_CONST) {
+ /* binary operation with constant operands */
+ int (*binary_op)(zval *result, zval *op1, zval *op2 TSRMLS_DC) = get_binary_op(opline->opcode);
+ zend_uint tv = ZEND_RESULT(opline).var; /* temporary variable */
+ zval result;
+ int er;
+
+ if (opline->opcode == ZEND_DIV &&
+ Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_LONG &&
+ Z_LVAL(ZEND_OP2_LITERAL(opline)) == 0) {
+ /* div by 0 */
+ break;
+ }
+ er = EG(error_reporting);
+ EG(error_reporting) = 0;
+ /* evaluate constant expression */
+ if (binary_op(&result, &ZEND_OP1_LITERAL(opline), &ZEND_OP2_LITERAL(opline) TSRMLS_CC) != SUCCESS) {
+ EG(error_reporting) = er;
+ break;
+ }
+ EG(error_reporting) = er;
+ PZ_SET_REFCOUNT_P(&result, 1);
+ PZ_UNSET_ISREF_P(&result);
+
+ literal_dtor(&ZEND_OP1_LITERAL(opline));
+ literal_dtor(&ZEND_OP2_LITERAL(opline));
+ MAKE_NOP(opline);
+
+ replace_tmp_by_const(op_array, opline + 1, tv, &result TSRMLS_CC);
+ }
+ break;
+
+ case ZEND_CAST:
+ if (ZEND_OP1_TYPE(opline) == IS_CONST &&
+ opline->extended_value != IS_ARRAY &&
+ opline->extended_value != IS_OBJECT &&
+ opline->extended_value != IS_RESOURCE) {
+ /* cast of constant operand */
+ zend_uint tv = ZEND_RESULT(opline).var; /* temporary variable */
+ zval res;
+ res = ZEND_OP1_LITERAL(opline);
+ zval_copy_ctor(&res);
+ switch (opline->extended_value) {
+ case IS_NULL:
+ convert_to_null(&res);
+ break;
+ case IS_BOOL:
+ convert_to_boolean(&res);
+ break;
+ case IS_LONG:
+ convert_to_long(&res);
+ break;
+ case IS_DOUBLE:
+ convert_to_double(&res);
+ break;
+ case IS_STRING:
+ convert_to_string(&res);
+ break;
+ }
+
+ literal_dtor(&ZEND_OP1_LITERAL(opline));
+ MAKE_NOP(opline);
+
+ replace_tmp_by_const(op_array, opline + 1, tv, &res TSRMLS_CC);
+ } else if (opline->extended_value == IS_BOOL) {
+ /* T = CAST(X, IS_BOOL) => T = BOOL(X) */
+ opline->opcode = ZEND_BOOL;
+ opline->extended_value = 0;
+ }
+ break;
+
+ case ZEND_BW_NOT:
+ case ZEND_BOOL_NOT:
+ if (ZEND_OP1_TYPE(opline) == IS_CONST) {
+ /* unary operation on constant operand */
+ unary_op_type unary_op = get_unary_op(opline->opcode);
+ zval result;
+ zend_uint tv = ZEND_RESULT(opline).var; /* temporary variable */
+ int er;
+
+ er = EG(error_reporting);
+ EG(error_reporting) = 0;
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+ if (unary_op(&result, &ZEND_OP1_LITERAL(opline)) != SUCCESS) {
+#else
+ if (unary_op(&result, &ZEND_OP1_LITERAL(opline) TSRMLS_CC) != SUCCESS) {
+#endif
+ EG(error_reporting) = er;
+ break;
+ }
+ EG(error_reporting) = er;
+ PZ_SET_REFCOUNT_P(&result, 1);
+ PZ_UNSET_ISREF_P(&result);
+
+ literal_dtor(&ZEND_OP1_LITERAL(opline));
+ MAKE_NOP(opline);
+
+ replace_tmp_by_const(op_array, opline + 1, tv, &result TSRMLS_CC);
+ }
+ break;
+
+ case ZEND_ADD_STRING:
+ case ZEND_ADD_CHAR:
+ {
+ zend_op *next_op = opline + 1;
+ int requires_conversion = (opline->opcode == ZEND_ADD_CHAR? 1 : 0);
+ size_t final_length = 0;
+ char *ptr;
+ zend_op *last_op;
+
+ /* There is always a ZEND_RETURN at the end
+ if (next_op>=end) {
+ break;
+ }
+ */
+ while (next_op->opcode == ZEND_ADD_STRING || next_op->opcode == ZEND_ADD_CHAR) {
+ if (ZEND_RESULT(opline).var != ZEND_RESULT(next_op).var) {
+ break;
+ }
+ if (next_op->opcode == ZEND_ADD_CHAR) {
+ final_length += 1;
+ } else { /* ZEND_ADD_STRING */
+ final_length += ZEND_OP2_LITERAL(next_op).value.str.len;
+ }
+ next_op++;
+ }
+ if (final_length == 0) {
+ break;
+ }
+ last_op = next_op;
+ final_length += (requires_conversion? 1 : ZEND_OP2_LITERAL(opline).value.str.len);
+ ptr = (char *)emalloc(final_length + 1);
+ ptr[final_length] = '\0';
+ if (requires_conversion) { /* ZEND_ADD_CHAR */
+ char chval = (char)ZEND_OP2_LITERAL(opline).value.lval;
+
+ ZEND_OP2_LITERAL(opline).value.str.val = ptr;
+ ptr[0] = chval;
+ ZEND_OP2_LITERAL(opline).type = IS_STRING;
+ opline->opcode = ZEND_ADD_STRING;
+ ptr++;
+ } else { /* ZEND_ADD_STRING */
+ memcpy(ptr, Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline)));
+ if (!IS_INTERNED(Z_STRVAL(ZEND_OP2_LITERAL(opline)))) {
+ efree(Z_STRVAL(ZEND_OP2_LITERAL(opline)));
+ }
+ Z_STRVAL(ZEND_OP2_LITERAL(opline)) = ptr;
+ ptr += Z_STRLEN(ZEND_OP2_LITERAL(opline));
+ }
+ ZEND_OP2_LITERAL(opline).value.str.len = final_length;
+ next_op = opline + 1;
+ while (next_op < last_op) {
+ if (next_op->opcode == ZEND_ADD_STRING) {
+ memcpy(ptr, ZEND_OP2_LITERAL(next_op).value.str.val, ZEND_OP2_LITERAL(next_op).value.str.len);
+ ptr += ZEND_OP2_LITERAL(next_op).value.str.len;
+ literal_dtor(&ZEND_OP2_LITERAL(next_op));
+ } else { /* ZEND_ADD_CHAR */
+ *ptr = (char)ZEND_OP2_LITERAL(next_op).value.lval;
+ ptr++;
+ }
+ MAKE_NOP(next_op);
+ next_op++;
+ }
+ if (!((ZEND_OPTIMIZER_PASS_5|ZEND_OPTIMIZER_PASS_10) & OPTIMIZATION_LEVEL)) {
+ /* NOP removal is disabled => insert JMP over NOPs */
+ if (last_op-opline >= 3) { /* If we have more than 2 NOPS then JMP over them */
+ (opline + 1)->opcode = ZEND_JMP;
+ ZEND_OP1(opline + 1).opline_num = last_op - op_array->opcodes; /* that's OK even for ZE2, since opline_num's are resolved in pass 2 later */
+ }
+ }
+ }
+ break;
+
+ case ZEND_FETCH_CONSTANT:
+ if (ZEND_OP1_TYPE(opline) == IS_UNUSED &&
+ ZEND_OP2_TYPE(opline) == IS_CONST &&
+ Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING &&
+ Z_STRLEN(ZEND_OP2_LITERAL(opline)) == sizeof("__COMPILER_HALT_OFFSET__") - 1 &&
+ memcmp(Z_STRVAL(ZEND_OP2_LITERAL(opline)), "__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__") - 1) == 0) {
+ /* substitute __COMPILER_HALT_OFFSET__ constant */
+ zend_bool orig_in_execution = EG(in_execution);
+ zend_op_array *orig_op_array = EG(active_op_array);
+ zval offset;
+
+ EG(in_execution) = 1;
+ EG(active_op_array) = op_array;
+ if (zend_get_constant("__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__") - 1, &offset TSRMLS_CC)) {
+ zend_uint tv = ZEND_RESULT(opline).var;
+
+ literal_dtor(&ZEND_OP2_LITERAL(opline));
+ MAKE_NOP(opline);
+ replace_tmp_by_const(op_array, opline, tv, &offset TSRMLS_CC);
+ }
+ EG(active_op_array) = orig_op_array;
+ EG(in_execution) = orig_in_execution;
+ break;
+ }
+
+ if (ZEND_OP1_TYPE(opline) == IS_UNUSED &&
+ ZEND_OP2_TYPE(opline) == IS_CONST &&
+ ZEND_OP2_LITERAL(opline).type == IS_STRING) {
+ /* substitute persistent constants */
+ zend_uint tv = ZEND_RESULT(opline).var;
+ zval c;
+
+ if (!zend_get_persistent_constant(Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline)), &c, 1 TSRMLS_CC)) {
+ break;
+ }
+ literal_dtor(&ZEND_OP2_LITERAL(opline));
+ MAKE_NOP(opline);
+ replace_tmp_by_const(op_array, opline, tv, &c TSRMLS_CC);
+ }
+ break;
+
+ case ZEND_INIT_FCALL_BY_NAME:
+ if (opline->extended_value == 0 /* not method */ &&
+ ZEND_OP1_TYPE(opline) == IS_UNUSED &&
+ ZEND_OP2_TYPE(opline) == IS_CONST) {
+ if ((opline + 1)->opcode == ZEND_DO_FCALL_BY_NAME &&
+ (opline + 1)->extended_value == 0) {
+ (opline + 1)->opcode = ZEND_DO_FCALL;
+ COPY_NODE((opline + 1)->op1, opline->op2);
+ zend_str_tolower(Z_STRVAL(ZEND_OP1_LITERAL(opline + 1)), Z_STRLEN(ZEND_OP1_LITERAL(opline + 1)));
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ Z_HASH_P(&ZEND_OP1_LITERAL(opline + 1)) = zend_hash_func(Z_STRVAL(ZEND_OP1_LITERAL(opline + 1)), Z_STRLEN(ZEND_OP1_LITERAL(opline + 1)) + 1);
+ op_array->literals[(opline + 1)->op1.constant].cache_slot = op_array->last_cache_slot++;
+#endif
+ MAKE_NOP(opline);
+ }
+ }
+ break;
+
+#if ZEND_EXTENSION_API_NO >= PHP_5_5_X_API_NO
+ case ZEND_FETCH_R:
+ case ZEND_FETCH_W:
+ case ZEND_FETCH_RW:
+ case ZEND_FETCH_FUNC_ARG:
+ case ZEND_FETCH_IS:
+ case ZEND_FETCH_UNSET:
+ if (opline != op_array->opcodes &&
+ (opline-1)->opcode == ZEND_BEGIN_SILENCE &&
+ (opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_LOCAL &&
+ opline->op1_type == IS_CONST &&
+ opline->op2_type == IS_UNUSED &&
+ Z_TYPE(ZEND_OP1_LITERAL(opline)) == IS_STRING &&
+ (Z_STRLEN(ZEND_OP1_LITERAL(opline)) != sizeof("this")-1 ||
+ memcmp(Z_STRVAL(ZEND_OP1_LITERAL(opline)), "this", sizeof("this")) != 0)) {
+
+ int var = opline->result.var;
+ int level = 0;
+ zend_op *op = opline + 1;
+ zend_op *use = NULL;
+
+ while (op < end) {
+ if (op->opcode == ZEND_BEGIN_SILENCE) {
+ level++;
+ } else if (op->opcode == ZEND_END_SILENCE) {
+ if (level == 0) {
+ break;
+ } else {
+ level--;
+ }
+ }
+ if (op->op1_type == IS_VAR && op->op1.var == var) {
+ if (use) {
+ /* used more than once */
+ use = NULL;
+ break;
+ }
+ use = op;
+ } else if (op->op2_type == IS_VAR && op->op2.var == var) {
+ if (use) {
+ /* used more than once */
+ use = NULL;
+ break;
+ }
+ use = op;
+ }
+ op++;
+ }
+ if (use) {
+ if (use->op1_type == IS_VAR && use->op1.var == var) {
+ use->op1_type = IS_CV;
+ use->op1.var = zend_optimizer_lookup_cv(op_array,
+ Z_STRVAL(ZEND_OP1_LITERAL(opline)),
+ Z_STRLEN(ZEND_OP1_LITERAL(opline)));
+ MAKE_NOP(opline);
+ } else if (use->op2_type == IS_VAR && use->op2.var == var) {
+ use->op2_type = IS_CV;
+ use->op2.var = zend_optimizer_lookup_cv(op_array,
+ Z_STRVAL(ZEND_OP1_LITERAL(opline)),
+ Z_STRLEN(ZEND_OP1_LITERAL(opline)));
+ MAKE_NOP(opline);
+ }
+ }
+ }
+ break;
+#endif
+
+ }
+ opline++;
+ i++;
+ }
+}
diff --git a/ext/opcache/Optimizer/pass2.c b/ext/opcache/Optimizer/pass2.c
new file mode 100644
index 0000000000..30708a0935
--- /dev/null
+++ b/ext/opcache/Optimizer/pass2.c
@@ -0,0 +1,211 @@
+/* pass 2:
+ * - convert non-numeric constants to numeric constants in numeric operators
+ * - optimize constant conditional JMPs
+ * - optimize static BRKs and CONTs
+ */
+
+if (ZEND_OPTIMIZER_PASS_2 & OPTIMIZATION_LEVEL) {
+ zend_op *opline;
+ zend_op *end = op_array->opcodes + op_array->last;
+
+ opline = op_array->opcodes;
+ while (opline < end) {
+ switch (opline->opcode) {
+ case ZEND_ADD:
+ case ZEND_SUB:
+ case ZEND_MUL:
+ case ZEND_DIV:
+ if (ZEND_OP1_TYPE(opline) == IS_CONST) {
+ if (ZEND_OP1_LITERAL(opline).type == IS_STRING) {
+ convert_scalar_to_number(&ZEND_OP1_LITERAL(opline) TSRMLS_CC);
+ }
+ }
+ /* break missing *intentionally* - the assign_op's may only optimize op2 */
+ case ZEND_ASSIGN_ADD:
+ case ZEND_ASSIGN_SUB:
+ case ZEND_ASSIGN_MUL:
+ case ZEND_ASSIGN_DIV:
+ if (opline->extended_value != 0) {
+ /* object tristate op - don't attempt to optimize it! */
+ break;
+ }
+ if (ZEND_OP2_TYPE(opline) == IS_CONST) {
+ if (ZEND_OP2_LITERAL(opline).type == IS_STRING) {
+ convert_scalar_to_number(&ZEND_OP2_LITERAL(opline) TSRMLS_CC);
+ }
+ }
+ break;
+
+ case ZEND_MOD:
+ case ZEND_SL:
+ case ZEND_SR:
+ if (ZEND_OP1_TYPE(opline) == IS_CONST) {
+ if (ZEND_OP1_LITERAL(opline).type != IS_LONG) {
+ convert_to_long(&ZEND_OP1_LITERAL(opline));
+ }
+ }
+ /* break missing *intentionally - the assign_op's may only optimize op2 */
+ case ZEND_ASSIGN_MOD:
+ case ZEND_ASSIGN_SL:
+ case ZEND_ASSIGN_SR:
+ if (opline->extended_value != 0) {
+ /* object tristate op - don't attempt to optimize it! */
+ break;
+ }
+ if (ZEND_OP2_TYPE(opline) == IS_CONST) {
+ if (ZEND_OP2_LITERAL(opline).type != IS_LONG) {
+ convert_to_long(&ZEND_OP2_LITERAL(opline));
+ }
+ }
+ break;
+
+ case ZEND_CONCAT:
+ if (ZEND_OP1_TYPE(opline) == IS_CONST) {
+ if (ZEND_OP1_LITERAL(opline).type != IS_STRING) {
+ convert_to_string(&ZEND_OP1_LITERAL(opline));
+ }
+ }
+ /* break missing *intentionally - the assign_op's may only optimize op2 */
+ case ZEND_ASSIGN_CONCAT:
+ if (opline->extended_value != 0) {
+ /* object tristate op - don't attempt to optimize it! */
+ break;
+ }
+ if (ZEND_OP2_TYPE(opline) == IS_CONST) {
+ if (ZEND_OP2_LITERAL(opline).type != IS_STRING) {
+ convert_to_string(&ZEND_OP2_LITERAL(opline));
+ }
+ }
+ break;
+
+ case ZEND_JMPZ_EX:
+ case ZEND_JMPNZ_EX:
+ /* convert Ti = JMPZ_EX(Ti, L) to JMPZ(Ti, L) */
+ if (0 && /* FIXME: temporary disable unsafe pattern */
+ ZEND_OP1_TYPE(opline) == IS_TMP_VAR &&
+ ZEND_RESULT_TYPE(opline) == IS_TMP_VAR &&
+ ZEND_OP1(opline).var == ZEND_RESULT(opline).var) {
+ opline->opcode -= 3;
+ /* convert Ti = JMPZ_EX(C, L) => Ti = QM_ASSIGN(C)
+ in case we know it wouldn't jump */
+ } else if (ZEND_OP1_TYPE(opline) == IS_CONST) {
+ int should_jmp = zend_is_true(&ZEND_OP1_LITERAL(opline));
+ if (opline->opcode == ZEND_JMPZ_EX) {
+ should_jmp = !should_jmp;
+ }
+ if (!should_jmp) {
+ opline->opcode = ZEND_QM_ASSIGN;
+ SET_UNUSED(opline->op2);
+ }
+ }
+ break;
+
+ case ZEND_JMPZ:
+ case ZEND_JMPNZ:
+ if (ZEND_OP1_TYPE(opline) == IS_CONST) {
+ int should_jmp = zend_is_true(&ZEND_OP1_LITERAL(opline));
+
+ if (opline->opcode == ZEND_JMPZ) {
+ should_jmp = !should_jmp;
+ }
+ literal_dtor(&ZEND_OP1_LITERAL(opline));
+ ZEND_OP1_TYPE(opline) = IS_UNUSED;
+ if (should_jmp) {
+ opline->opcode = ZEND_JMP;
+ COPY_NODE(opline->op1, opline->op2);
+ } else {
+ MAKE_NOP(opline);
+ }
+ break;
+ }
+ if ((opline + 1)->opcode == ZEND_JMP) {
+ /* JMPZ(X, L1), JMP(L2) => JMPZNZ(X, L1, L2) */
+ /* JMPNZ(X, L1), JMP(L2) => JMPZNZ(X, L2, L1) */
+ if (ZEND_OP2(opline).opline_num == ZEND_OP1(opline + 1).opline_num) {
+ /* JMPZ(X, L1), JMP(L1) => NOP, JMP(L1) */
+ MAKE_NOP(opline);
+ } else {
+ if (opline->opcode == ZEND_JMPZ) {
+ opline->extended_value = ZEND_OP1(opline + 1).opline_num;
+ } else {
+ opline->extended_value = ZEND_OP2(opline).opline_num;
+ COPY_NODE(opline->op2, (opline + 1)->op1);
+ }
+ opline->opcode = ZEND_JMPZNZ;
+ }
+ }
+ break;
+
+ case ZEND_JMPZNZ:
+ if (ZEND_OP1_TYPE(opline) == IS_CONST) {
+ int opline_num;
+
+ if (zend_is_true(&ZEND_OP1_LITERAL(opline))) {
+ opline_num = opline->extended_value; /* JMPNZ */
+ } else {
+ opline_num = ZEND_OP2(opline).opline_num; /* JMPZ */
+ }
+ literal_dtor(&ZEND_OP1_LITERAL(opline));
+ ZEND_OP1(opline).opline_num = opline_num;
+ ZEND_OP1_TYPE(opline) = IS_UNUSED;
+ opline->opcode = ZEND_JMP;
+ }
+ break;
+
+ case ZEND_BRK:
+ case ZEND_CONT:
+ {
+ zend_brk_cont_element *jmp_to;
+ int array_offset;
+ int nest_levels;
+ int dont_optimize = 0;
+
+ if (ZEND_OP2_TYPE(opline) != IS_CONST) {
+ break;
+ }
+ convert_to_long(&ZEND_OP2_LITERAL(opline));
+ nest_levels = ZEND_OP2_LITERAL(opline).value.lval;
+
+ array_offset = ZEND_OP1(opline).opline_num;
+ while (1) {
+ if (array_offset == -1) {
+ dont_optimize = 1; /* don't optimize this bogus break/continue, let the executor shout */
+ break;
+ }
+ jmp_to = &op_array->brk_cont_array[array_offset];
+ array_offset = jmp_to->parent;
+ if (--nest_levels > 0) {
+ if (opline->opcode == ZEND_BRK &&
+ (op_array->opcodes[jmp_to->brk].opcode == ZEND_FREE ||
+ op_array->opcodes[jmp_to->brk].opcode == ZEND_SWITCH_FREE)) {
+ dont_optimize = 1;
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+
+ if (dont_optimize) {
+ break;
+ }
+
+ /* optimize - convert to a JMP */
+ switch (opline->opcode) {
+ case ZEND_BRK:
+ MAKE_NOP(opline);
+ ZEND_OP1(opline).opline_num = jmp_to->brk;
+ break;
+ case ZEND_CONT:
+ MAKE_NOP(opline);
+ ZEND_OP1(opline).opline_num = jmp_to->cont;
+ break;
+ }
+ opline->opcode = ZEND_JMP;
+ /* MAKE_NOP() already set op1 and op2 to IS_UNUSED */
+ }
+ break;
+ }
+ opline++;
+ }
+}
diff --git a/ext/opcache/Optimizer/pass3.c b/ext/opcache/Optimizer/pass3.c
new file mode 100644
index 0000000000..fd2a190009
--- /dev/null
+++ b/ext/opcache/Optimizer/pass3.c
@@ -0,0 +1,442 @@
+/* pass 3:
+ * - optimize $i = $i+expr to $i+=expr
+ * - optimize series of JMPs
+ * - change $i++ to ++$i where possible
+ */
+
+/* compares opcodes with allowing oc1 be _EX of oc2 */
+#define SAME_OPCODE_EX(oc1, oc2) ((oc1 == oc2) || (oc1 == ZEND_JMPZ_EX && oc2 == ZEND_JMPZ) || (oc1 == ZEND_JMPNZ_EX && oc2 == ZEND_JMPNZ))
+
+/* we use "jmp_hitlist" to avoid infinity loops during jmp optimization */
+#define CHECK_JMP(target, label) \
+ for (i=0; i<jmp_hitlist_count; i++) { \
+ if (jmp_hitlist[i] == ZEND_OP1(&op_array->opcodes[target]).opline_num) { \
+ goto label; \
+ } \
+ } \
+ jmp_hitlist[jmp_hitlist_count++] = ZEND_OP1(&op_array->opcodes[target]).opline_num;
+
+#define CHECK_JMP2(target, label) \
+ for (i=0; i<jmp_hitlist_count; i++) { \
+ if (jmp_hitlist[i] == ZEND_OP2(&op_array->opcodes[target]).opline_num) { \
+ goto label; \
+ } \
+ } \
+ jmp_hitlist[jmp_hitlist_count++] = ZEND_OP2(&op_array->opcodes[target]).opline_num;
+
+if (ZEND_OPTIMIZER_PASS_3 & OPTIMIZATION_LEVEL) {
+ zend_op *opline;
+ zend_op *end = op_array->opcodes + op_array->last;
+ zend_uint *jmp_hitlist;
+ int jmp_hitlist_count;
+ int i;
+ zend_uint opline_num = 0;
+ ALLOCA_FLAG(use_heap);
+
+ jmp_hitlist = (zend_uint *)DO_ALLOCA(sizeof(zend_uint)*op_array->last);
+ opline = op_array->opcodes;
+
+ while (opline < end) {
+ jmp_hitlist_count = 0;
+
+ switch (opline->opcode) {
+ case ZEND_ADD:
+ case ZEND_SUB:
+ case ZEND_MUL:
+ case ZEND_DIV:
+ case ZEND_MOD:
+ case ZEND_CONCAT:
+ case ZEND_SL:
+ case ZEND_SR:
+ case ZEND_BW_OR:
+ case ZEND_BW_AND:
+ case ZEND_BW_XOR:
+ {
+ zend_op *next_opline = opline + 1;
+
+ while (next_opline < end && next_opline->opcode == ZEND_NOP) {
+ ++next_opline;
+ }
+
+ if (next_opline >= end || next_opline->opcode != ZEND_ASSIGN) {
+ break;
+ }
+
+ if ((ZEND_OP2_TYPE(opline) == IS_VAR || ZEND_OP2_TYPE(opline) == IS_CV)
+ && ZEND_OP2(opline).var == ZEND_OP1(next_opline).var &&
+ (opline->opcode == ZEND_ADD ||
+ opline->opcode == ZEND_MUL ||
+ opline->opcode == ZEND_BW_OR ||
+ opline->opcode == ZEND_BW_AND ||
+ opline->opcode == ZEND_BW_XOR)) {
+ /* change $i=expr+$i to $i=$i+expr so that the next
+ * optimization works on it
+ */
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ zend_uchar tmp_type = opline->op1_type;
+ znode_op tmp = opline->op1;
+#else
+ znode tmp = opline->op1;
+#endif
+
+ if (opline->opcode != ZEND_ADD || ZEND_OP1_TYPE(opline) == IS_CONST) {
+ /* protection from array add: $a = array + $a is not commutative! */
+ COPY_NODE(opline->op1, opline->op2);
+ COPY_NODE(opline->op2, tmp);
+ }
+ }
+ if ((ZEND_OP1_TYPE(opline) == IS_VAR || ZEND_OP1_TYPE(opline) == IS_CV)
+ && ZEND_OP1(opline).var == ZEND_OP1(next_opline).var
+ && ZEND_OP1_TYPE(opline) == ZEND_OP1_TYPE(next_opline)) {
+ switch (opline->opcode) {
+ case ZEND_ADD:
+ opline->opcode = ZEND_ASSIGN_ADD;
+ break;
+ case ZEND_SUB:
+ opline->opcode = ZEND_ASSIGN_SUB;
+ break;
+ case ZEND_MUL:
+ opline->opcode = ZEND_ASSIGN_MUL;
+ break;
+ case ZEND_DIV:
+ opline->opcode = ZEND_ASSIGN_DIV;
+ break;
+ case ZEND_MOD:
+ opline->opcode = ZEND_ASSIGN_MOD;
+ break;
+ case ZEND_CONCAT:
+ opline->opcode = ZEND_ASSIGN_CONCAT;
+ break;
+ case ZEND_SL:
+ opline->opcode = ZEND_ASSIGN_SL;
+ break;
+ case ZEND_SR:
+ opline->opcode = ZEND_ASSIGN_SR;
+ break;
+ case ZEND_BW_OR:
+ opline->opcode = ZEND_ASSIGN_BW_OR;
+ break;
+ case ZEND_BW_AND:
+ opline->opcode = ZEND_ASSIGN_BW_AND;
+ break;
+ case ZEND_BW_XOR:
+ opline->opcode = ZEND_ASSIGN_BW_XOR;
+ break;
+ }
+ COPY_NODE(opline->result, next_opline->result);
+ MAKE_NOP(next_opline);
+ opline++;
+ opline_num++;
+ }
+ }
+ break;
+
+ case ZEND_JMP:
+#if ZEND_EXTENSION_API_NO > PHP_5_4_X_API_NO
+ if (op_array->has_finally_block) {
+ break;
+ }
+#endif
+
+ /* convert L: JMP L+1 to NOP */
+ if (ZEND_OP1(opline).opline_num == opline_num + 1) {
+ MAKE_NOP(opline);
+ goto done_jmp_optimization;
+ }
+
+ /* convert JMP L1 ... L1: JMP L2 to JMP L2 .. L1: JMP L2 */
+ while (ZEND_OP1(opline).opline_num < op_array->last
+ && op_array->opcodes[ZEND_OP1(opline).opline_num].opcode == ZEND_JMP) {
+ int target = ZEND_OP1(opline).opline_num;
+ CHECK_JMP(target, done_jmp_optimization);
+ ZEND_OP1(opline).opline_num = ZEND_OP1(&op_array->opcodes[target]).opline_num;
+ }
+ break;
+
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+ case ZEND_JMP_SET:
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ case ZEND_JMP_SET_VAR:
+#endif
+
+#if ZEND_EXTENSION_API_NO > PHP_5_4_X_API_NO
+ if (op_array->has_finally_block) {
+ break;
+ }
+#endif
+
+ while (ZEND_OP2(opline).opline_num < op_array->last) {
+ int target = ZEND_OP2(opline).opline_num;
+ if (op_array->opcodes[target].opcode == ZEND_JMP) {
+ ZEND_OP2(opline).opline_num = ZEND_OP1(&op_array->opcodes[target]).opline_num;
+ } else {
+ break;
+ }
+ }
+ break;
+#endif
+
+ case ZEND_JMPZ:
+ case ZEND_JMPNZ:
+#if ZEND_EXTENSION_API_NO > PHP_5_4_X_API_NO
+ if (op_array->has_finally_block) {
+ break;
+ }
+#endif
+
+ /* convert L: JMPZ L+1 to NOP */
+ if (ZEND_OP2(opline).opline_num == opline_num + 1) {
+ MAKE_NOP(opline);
+ goto done_jmp_optimization;
+ }
+
+ while (ZEND_OP2(opline).opline_num < op_array->last) {
+ int target = ZEND_OP2(opline).opline_num;
+
+ if (op_array->opcodes[target].opcode == ZEND_JMP) {
+ /* plain JMP */
+ /* JMPZ(X,L1), L1: JMP(L2) => JMPZ(X,L2), L1: JMP(L2) */
+ CHECK_JMP(target, done_jmp_optimization);
+ ZEND_OP2(opline).opline_num = ZEND_OP1(&op_array->opcodes[target]).opline_num;
+ } else if (op_array->opcodes[target].opcode == opline->opcode &&
+ SAME_VAR(opline->op1, op_array->opcodes[target].op1)) {
+ /* same opcode and same var as this opcode */
+ /* JMPZ(X,L1), L1: JMPZ(X,L2) => JMPZ(X,L2), L1: JMPZ(X,L2) */
+ CHECK_JMP2(target, done_jmp_optimization);
+ ZEND_OP2(opline).opline_num = ZEND_OP2(&op_array->opcodes[target]).opline_num;
+ } else if (op_array->opcodes[target].opcode == opline->opcode + 3 &&
+ SAME_VAR(opline->op1, op_array->opcodes[target].op1)) {
+ /* convert JMPZ(X,L1), L1: T JMPZ_EX(X,L2) to
+ T = JMPZ_EX(X, L2) */
+ ZEND_OP2(opline).opline_num = ZEND_OP2(&op_array->opcodes[target]).opline_num;opline->opcode += 3;
+ COPY_NODE(opline->result, op_array->opcodes[target].result);
+ break;
+ } else if (op_array->opcodes[target].opcode == INV_COND(opline->opcode) &&
+ SAME_VAR(opline->op1, op_array->opcodes[target].op1)) {
+ /* convert JMPZ(X,L1), L1: JMPNZ(X,L2) to
+ JMPZ(X,L1+1) */
+ ZEND_OP2(opline).opline_num = target + 1;
+ break;
+ } else if (op_array->opcodes[target].opcode == INV_COND_EX(opline->opcode) &&
+ SAME_VAR(opline->op1, op_array->opcodes[target].op1)) {
+ /* convert JMPZ(X,L1), L1: T = JMPNZ_EX(X,L2) to
+ T = JMPZ_EX(X,L1+1) */
+ ZEND_OP2(opline).opline_num = target + 1;
+ opline->opcode += 3;
+ COPY_NODE(opline->result, op_array->opcodes[target].result);
+ break;
+ } else {
+ break;
+ }
+ }
+ break;
+
+ case ZEND_JMPZ_EX:
+ case ZEND_JMPNZ_EX: {
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ zend_uchar T_type = opline->result_type;
+ znode_op T = opline->result;
+#else
+ znode T = opline->result;
+#endif
+#if ZEND_EXTENSION_API_NO > PHP_5_4_X_API_NO
+ if (op_array->has_finally_block) {
+ break;
+ }
+#endif
+ /* convert L: T = JMPZ_EX X,L+1 to T = BOOL(X) */
+ /* convert L: T = JMPZ_EX T,L+1 to NOP */
+ if (ZEND_OP2(opline).opline_num == opline_num + 1) {
+ if (ZEND_OP1(opline).var == ZEND_RESULT(opline).var) {
+ MAKE_NOP(opline);
+ } else {
+ opline->opcode = ZEND_BOOL;
+ SET_UNUSED(opline->op2);
+ }
+ goto done_jmp_optimization;
+ }
+
+ while (ZEND_OP2(opline).opline_num < op_array->last) {
+ int target = ZEND_OP2(opline).opline_num;
+ if (SAME_OPCODE_EX(opline->opcode, op_array->opcodes[target].opcode) &&
+ SAME_VAR(op_array->opcodes[target].op1, T)) {
+ /* Check for JMPZ_EX to JMPZ[_EX] with the same condition, either with _EX or not */
+ if (op_array->opcodes[target].opcode == opline->opcode) {
+ /* change T only if we have _EX opcode there */
+ COPY_NODE(T, op_array->opcodes[target].result);
+ }
+ CHECK_JMP2(target, continue_jmp_ex_optimization);
+ ZEND_OP2(opline).opline_num = ZEND_OP2(&op_array->opcodes[target]).opline_num;
+ } else if (op_array->opcodes[target].opcode == ZEND_JMPZNZ &&
+ SAME_VAR(op_array->opcodes[target].op1, T)) {
+ /* Check for JMPZNZ with same cond variable */
+ int new_target;
+ CHECK_JMP2(target, continue_jmp_ex_optimization);
+ if (opline->opcode == ZEND_JMPZ_EX) {
+ new_target = ZEND_OP2(&op_array->opcodes[target]).opline_num;
+ } else {
+ /* JMPNZ_EX */
+ new_target = op_array->opcodes[target].extended_value;
+ }
+ ZEND_OP2(opline).opline_num = new_target;
+ } else if ((op_array->opcodes[target].opcode == INV_EX_COND_EX(opline->opcode) ||
+ op_array->opcodes[target].opcode == INV_EX_COND(opline->opcode)) &&
+ SAME_VAR(opline->op1, op_array->opcodes[target].op1)) {
+ /* convert JMPZ_EX(X,L1), L1: JMPNZ_EX(X,L2) to
+ JMPZ_EX(X,L1+1) */
+ ZEND_OP2(opline).opline_num = target + 1;
+ break;
+ } else {
+ break;
+ }
+ } /* while */
+continue_jmp_ex_optimization:
+ break;
+#if 0
+ /* If Ti = JMPZ_EX(X, L) and Ti is not used, convert to JMPZ(X, L) */
+ {
+ zend_op *op;
+ for(op = opline+1; op<end; op++) {
+ if(ZEND_RESULT_TYPE(op) == IS_TMP_VAR &&
+ ZEND_RESULT(op).var == ZEND_RESULT(opline).var) {
+ break; /* can pass to part 2 */
+ }
+
+ if(op->opcode == ZEND_JMP ||
+ op->opcode == ZEND_JMPZ ||
+ op->opcode == ZEND_JMPZ_EX ||
+ op->opcode == ZEND_JMPNZ ||
+ op->opcode == ZEND_JMPNZ_EX ||
+ op->opcode == ZEND_JMPZNZ ||
+ op->opcode == ZEND_BRK ||
+ op->opcode == ZEND_CONT ||
+ op->opcode == ZEND_CASE ||
+ op->opcode == ZEND_RETURN ||
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ op->opcode == ZEND_RETURN_BY_REF ||
+#endif
+#if ZEND_EXTENSION_API_NO > PHP_5_4_X_API_NO
+ op->opcode == ZEND_FAST_RET ||
+#endif
+ op->opcode == ZEND_FE_FETCH ||
+ op->opcode == ZEND_EXIT) {
+ break;
+ }
+
+ if(ZEND_OP1_TYPE(op) == IS_TMP_VAR &&
+ ZEND_OP1(op).var == ZEND_RESULT(opline).var) {
+ goto done_jmp_optimization;
+ }
+
+ if(ZEND_OP2_TYPE(op) == IS_TMP_VAR &&
+ ZEND_OP2(op).var == ZEND_RESULT(opline).var) {
+ goto done_jmp_optimization;
+ }
+ } /* for */
+
+ for(op = &op_array->opcodes[ZEND_OP2(opline).opline_num]; op<end; op++) {
+
+ if(ZEND_RESULT_TYPE(op) == IS_TMP_VAR &&
+ ZEND_RESULT(op).var == ZEND_RESULT(opline).var) {
+ break; /* can pass to optimization */
+ }
+
+ if(op->opcode == ZEND_JMP ||
+ op->opcode == ZEND_JMPZ ||
+ op->opcode == ZEND_JMPZ_EX ||
+ op->opcode == ZEND_JMPNZ ||
+ op->opcode == ZEND_JMPNZ_EX ||
+ op->opcode == ZEND_JMPZNZ ||
+ op->opcode == ZEND_BRK ||
+ op->opcode == ZEND_CONT ||
+ op->opcode == ZEND_CASE ||
+ op->opcode == ZEND_RETURN ||
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ op->opcode == ZEND_RETURN_BY_REF ||
+#endif
+#if ZEND_EXTENSION_API_NO > PHP_5_4_X_API_NO
+ op->opcode == ZEND_FAST_RET ||
+#endif
+ op->opcode == ZEND_FE_FETCH ||
+ op->opcode == ZEND_EXIT) {
+ break;
+ }
+
+ if(ZEND_OP1_TYPE(op) == IS_TMP_VAR &&
+ ZEND_OP1(op).var == ZEND_RESULT(opline).var) {
+ goto done_jmp_optimization;
+ }
+
+ if(ZEND_OP2_TYPE(op) == IS_TMP_VAR &&
+ ZEND_OP2(op).var == ZEND_RESULT(opline).var) {
+ goto done_jmp_optimization;
+ }
+ }
+
+ opline->opcode = opline->opcode-3; /* JMP_EX -> JMP */
+ SET_UNUSED(opline->result);
+ break;
+ }
+#endif
+ }
+ break;
+
+ case ZEND_JMPZNZ:
+#if ZEND_EXTENSION_API_NO > PHP_5_4_X_API_NO
+ if (op_array->has_finally_block) {
+ break;
+ }
+#endif
+ /* JMPZNZ(X,L1,L2), L1: JMP(L3) => JMPZNZ(X,L3,L2), L1: JMP(L3) */
+ while (ZEND_OP2(opline).opline_num < op_array->last
+ && op_array->opcodes[ZEND_OP2(opline).opline_num].opcode == ZEND_JMP) {
+ int target = ZEND_OP2(opline).opline_num;
+ CHECK_JMP(target, continue_jmpznz_optimization);
+ ZEND_OP2(opline).opline_num = ZEND_OP1(&op_array->opcodes[target]).opline_num;
+ }
+continue_jmpznz_optimization:
+ /* JMPZNZ(X,L1,L2), L2: JMP(L3) => JMPZNZ(X,L1,L3), L2: JMP(L3) */
+ while (opline->extended_value < op_array->last
+ && op_array->opcodes[opline->extended_value].opcode == ZEND_JMP) {
+ int target = opline->extended_value;
+ CHECK_JMP(target, done_jmp_optimization);
+ opline->extended_value = ZEND_OP1(&op_array->opcodes[target]).opline_num;
+ }
+ break;
+
+ case ZEND_POST_INC:
+ case ZEND_POST_DEC: {
+ /* POST_INC, FREE => PRE_INC */
+ zend_op *next_op = opline + 1;
+
+ if (next_op >= end) {
+ break;
+ }
+ if (next_op->opcode == ZEND_FREE &&
+ ZEND_OP1(next_op).var == ZEND_RESULT(opline).var) {
+ MAKE_NOP(next_op);
+ switch (opline->opcode) {
+ case ZEND_POST_INC:
+ opline->opcode = ZEND_PRE_INC;
+ break;
+ case ZEND_POST_DEC:
+ opline->opcode = ZEND_PRE_DEC;
+ break;
+ }
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ ZEND_RESULT_TYPE(opline) = IS_VAR | EXT_TYPE_UNUSED;
+#else
+ ZEND_RESULT_TYPE(opline) = IS_VAR;
+ ZEND_RESULT(opline).EA.type = 0;
+ ZEND_RESULT(opline).EA.type |= EXT_TYPE_UNUSED;
+#endif
+ }
+ }
+ break;
+ }
+done_jmp_optimization:
+ opline++;
+ opline_num++;
+ }
+ FREE_ALLOCA(jmp_hitlist);
+}
diff --git a/ext/opcache/Optimizer/pass5.c b/ext/opcache/Optimizer/pass5.c
new file mode 100644
index 0000000000..b0d651a5fc
--- /dev/null
+++ b/ext/opcache/Optimizer/pass5.c
@@ -0,0 +1,3 @@
+if (ZEND_OPTIMIZER_PASS_5 & OPTIMIZATION_LEVEL) {
+ zend_block_optimization(op_array TSRMLS_CC);
+}
diff --git a/ext/opcache/Optimizer/pass9.c b/ext/opcache/Optimizer/pass9.c
new file mode 100644
index 0000000000..586160c14d
--- /dev/null
+++ b/ext/opcache/Optimizer/pass9.c
@@ -0,0 +1,8 @@
+/* pass 9
+ *
+ * - optimize usage of temporary variables
+ */
+
+if (ZEND_OPTIMIZER_PASS_9 & OPTIMIZATION_LEVEL) {
+ optimize_temporary_variables(op_array);
+}
diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c
new file mode 100644
index 0000000000..fd0f77dbc8
--- /dev/null
+++ b/ext/opcache/Optimizer/zend_optimizer.c
@@ -0,0 +1,351 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2014 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: Andi Gutmans <andi@zend.com> |
+ | Zeev Suraski <zeev@zend.com> |
+ | Stanislav Malyshev <stas@zend.com> |
+ | Dmitry Stogov <dmitry@zend.com> |
+ +----------------------------------------------------------------------+
+*/
+
+#include "php.h"
+#include "Optimizer/zend_optimizer.h"
+#include "Optimizer/zend_optimizer_internal.h"
+#include "zend_API.h"
+#include "zend_constants.h"
+#include "zend_execute.h"
+
+#define OPTIMIZATION_LEVEL \
+ ZCG(accel_directives).optimization_level
+
+#if ZEND_EXTENSION_API_NO >= PHP_5_5_X_API_NO
+static int zend_optimizer_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);
+
+ while (i < op_array->last_var) {
+ if (op_array->vars[i].name == name ||
+ (op_array->vars[i].hash_value == hash_value &&
+ op_array->vars[i].name_len == name_len &&
+ memcmp(op_array->vars[i].name, name, name_len) == 0)) {
+ return i;
+ }
+ i++;
+ }
+ i = op_array->last_var;
+ op_array->last_var++;
+ op_array->vars = erealloc(op_array->vars, op_array->last_var * sizeof(zend_compiled_variable));
+ if (IS_INTERNED(name)) {
+ op_array->vars[i].name = name;
+ } else {
+ op_array->vars[i].name = estrndup(name, name_len);
+ }
+ op_array->vars[i].name_len = name_len;
+ op_array->vars[i].hash_value = hash_value;
+ return i;
+}
+#endif
+
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+int zend_optimizer_add_literal(zend_op_array *op_array, const zval *zv TSRMLS_DC)
+{
+ int i = op_array->last_literal;
+ op_array->last_literal++;
+ if (i >= CG(context).literals_size) {
+ CG(context).literals_size += 16; /* FIXME */
+ op_array->literals = (zend_literal*)erealloc(op_array->literals, CG(context).literals_size * sizeof(zend_literal));
+ }
+ op_array->literals[i].constant = *zv;
+ op_array->literals[i].hash_value = 0;
+ op_array->literals[i].cache_slot = -1;
+ Z_SET_REFCOUNT(op_array->literals[i].constant, 2);
+ Z_SET_ISREF(op_array->literals[i].constant);
+ return i;
+}
+
+# define LITERAL_LONG(op, val) do { \
+ zval _c; \
+ ZVAL_LONG(&_c, val); \
+ op.constant = zend_optimizer_add_literal(op_array, &_c TSRMLS_CC); \
+ } while (0)
+
+# define LITERAL_BOOL(op, val) do { \
+ zval _c; \
+ ZVAL_BOOL(&_c, val); \
+ op.constant = zend_optimizer_add_literal(op_array, &_c TSRMLS_CC); \
+ } while (0)
+
+# define literal_dtor(zv) do { \
+ zval_dtor(zv); \
+ Z_TYPE_P(zv) = IS_NULL; \
+ } while (0)
+
+#define COPY_NODE(target, src) do { \
+ target ## _type = src ## _type; \
+ target = src; \
+ } while (0)
+
+#else
+
+# define LITERAL_LONG(op, val) ZVAL_LONG(&op.u.constant, val)
+
+# define LITERAL_BOOL(op, val) ZVAL_BOOL(&op.u.constant, val)
+
+# define literal_dtor(zv) zval_dtor(zv)
+
+#define COPY_NODE(target, src) do { \
+ target = src; \
+ } while (0)
+
+#endif
+
+static void update_op1_const(zend_op_array *op_array,
+ zend_op *opline,
+ zval *val TSRMLS_DC)
+{
+ if (opline->opcode == ZEND_FREE) {
+ MAKE_NOP(opline);
+ zval_dtor(val);
+ } else {
+ ZEND_OP1_TYPE(opline) = IS_CONST;
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ if (Z_TYPE_P(val) == IS_STRING) {
+ switch (opline->opcode) {
+ case ZEND_INIT_STATIC_METHOD_CALL:
+ case ZEND_CATCH:
+ case ZEND_FETCH_CONSTANT:
+ opline->op1.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC);
+ Z_HASH_P(&ZEND_OP1_LITERAL(opline)) = zend_hash_func(Z_STRVAL(ZEND_OP1_LITERAL(opline)), Z_STRLEN(ZEND_OP1_LITERAL(opline)) + 1);
+ op_array->literals[opline->op1.constant].cache_slot = op_array->last_cache_slot++;
+ zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
+ zend_optimizer_add_literal(op_array, val TSRMLS_CC);
+ op_array->literals[opline->op1.constant+1].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[opline->op1.constant+1].constant), Z_STRLEN(op_array->literals[opline->op1.constant+1].constant) + 1);
+ break;
+ case ZEND_DO_FCALL:
+ zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
+ opline->op1.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC);
+ Z_HASH_P(&ZEND_OP1_LITERAL(opline)) = zend_hash_func(Z_STRVAL(ZEND_OP1_LITERAL(opline)), Z_STRLEN(ZEND_OP1_LITERAL(opline)) + 1);
+ op_array->literals[opline->op1.constant].cache_slot = op_array->last_cache_slot++;
+ break;
+ default:
+ opline->op1.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC);
+ Z_HASH_P(&ZEND_OP1_LITERAL(opline)) = zend_hash_func(Z_STRVAL(ZEND_OP1_LITERAL(opline)), Z_STRLEN(ZEND_OP1_LITERAL(opline)) + 1);
+ break;
+ }
+ } else {
+ opline->op1.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC);
+ }
+#else
+ ZEND_OP1_LITERAL(opline) = *val;
+#endif
+ }
+}
+
+static void update_op2_const(zend_op_array *op_array,
+ zend_op *opline,
+ zval *val TSRMLS_DC)
+{
+ ZEND_OP2_TYPE(opline) = IS_CONST;
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ opline->op2.constant = zend_optimizer_add_literal(op_array, val TSRMLS_CC);
+ if (Z_TYPE_P(val) == IS_STRING) {
+ Z_HASH_P(&ZEND_OP2_LITERAL(opline)) = zend_hash_func(Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline)) + 1);
+ switch (opline->opcode) {
+ case ZEND_FETCH_R:
+ case ZEND_FETCH_W:
+ case ZEND_FETCH_RW:
+ case ZEND_FETCH_IS:
+ case ZEND_FETCH_UNSET:
+ case ZEND_FETCH_FUNC_ARG:
+ case ZEND_FETCH_CLASS:
+ case ZEND_INIT_FCALL_BY_NAME:
+ /*case ZEND_INIT_NS_FCALL_BY_NAME:*/
+ case ZEND_UNSET_VAR:
+ case ZEND_ISSET_ISEMPTY_VAR:
+ case ZEND_ADD_INTERFACE:
+ case ZEND_ADD_TRAIT:
+ op_array->literals[opline->op2.constant].cache_slot = op_array->last_cache_slot++;
+ zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
+ zend_optimizer_add_literal(op_array, val TSRMLS_CC);
+ op_array->literals[opline->op2.constant+1].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[opline->op2.constant+1].constant), Z_STRLEN(op_array->literals[opline->op2.constant+1].constant) + 1);
+ break;
+ case ZEND_INIT_METHOD_CALL:
+ case ZEND_INIT_STATIC_METHOD_CALL:
+ zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
+ zend_optimizer_add_literal(op_array, val TSRMLS_CC);
+ op_array->literals[opline->op2.constant+1].hash_value = zend_hash_func(Z_STRVAL(op_array->literals[opline->op2.constant+1].constant), Z_STRLEN(op_array->literals[opline->op2.constant+1].constant) + 1);
+ /* break missing intentionally */
+ /*case ZEND_FETCH_CONSTANT:*/
+ case ZEND_ASSIGN_OBJ:
+ case ZEND_FETCH_OBJ_R:
+ case ZEND_FETCH_OBJ_W:
+ case ZEND_FETCH_OBJ_RW:
+ case ZEND_FETCH_OBJ_IS:
+ case ZEND_FETCH_OBJ_UNSET:
+ case ZEND_FETCH_OBJ_FUNC_ARG:
+ case ZEND_UNSET_OBJ:
+ case ZEND_PRE_INC_OBJ:
+ case ZEND_PRE_DEC_OBJ:
+ case ZEND_POST_INC_OBJ:
+ case ZEND_POST_DEC_OBJ:
+ case ZEND_ISSET_ISEMPTY_PROP_OBJ:
+ op_array->literals[opline->op2.constant].cache_slot = op_array->last_cache_slot;
+ op_array->last_cache_slot += 2;
+ break;
+ case ZEND_ASSIGN_ADD:
+ case ZEND_ASSIGN_SUB:
+ case ZEND_ASSIGN_MUL:
+ case ZEND_ASSIGN_DIV:
+ case ZEND_ASSIGN_MOD:
+ case ZEND_ASSIGN_SL:
+ case ZEND_ASSIGN_SR:
+ case ZEND_ASSIGN_CONCAT:
+ case ZEND_ASSIGN_BW_OR:
+ case ZEND_ASSIGN_BW_AND:
+ case ZEND_ASSIGN_BW_XOR:
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ op_array->literals[opline->op2.constant].cache_slot = op_array->last_cache_slot;
+ op_array->last_cache_slot += 2;
+ }
+ break;
+#if ZEND_EXTENSION_API_NO >= PHP_5_4_X_API_NO
+ case ZEND_OP_DATA:
+ if ((opline-1)->opcode == ZEND_ASSIGN_DIM ||
+ ((opline-1)->extended_value == ZEND_ASSIGN_DIM &&
+ ((opline-1)->opcode == ZEND_ASSIGN_ADD ||
+ (opline-1)->opcode == ZEND_ASSIGN_SUB ||
+ (opline-1)->opcode == ZEND_ASSIGN_MUL ||
+ (opline-1)->opcode == ZEND_ASSIGN_DIV ||
+ (opline-1)->opcode == ZEND_ASSIGN_MOD ||
+ (opline-1)->opcode == ZEND_ASSIGN_SL ||
+ (opline-1)->opcode == ZEND_ASSIGN_SR ||
+ (opline-1)->opcode == ZEND_ASSIGN_CONCAT ||
+ (opline-1)->opcode == ZEND_ASSIGN_BW_OR ||
+ (opline-1)->opcode == ZEND_ASSIGN_BW_AND ||
+ (opline-1)->opcode == ZEND_ASSIGN_BW_XOR))) {
+ goto check_numeric;
+ }
+ break;
+ case ZEND_ISSET_ISEMPTY_DIM_OBJ:
+ case ZEND_ADD_ARRAY_ELEMENT:
+ case ZEND_INIT_ARRAY:
+ case ZEND_UNSET_DIM:
+ case ZEND_FETCH_DIM_R:
+ case ZEND_FETCH_DIM_W:
+ case ZEND_FETCH_DIM_RW:
+ case ZEND_FETCH_DIM_IS:
+ case ZEND_FETCH_DIM_FUNC_ARG:
+ case ZEND_FETCH_DIM_UNSET:
+ case ZEND_FETCH_DIM_TMP_VAR:
+check_numeric:
+ {
+ ulong index;
+ int numeric = 0;
+
+ ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(val), Z_STRLEN_P(val)+1, index, numeric = 1);
+ if (numeric) {
+ zval_dtor(val);
+ ZVAL_LONG(val, index);
+ op_array->literals[opline->op2.constant].constant = *val;
+ }
+ }
+ break;
+#endif
+ default:
+ break;
+ }
+ }
+#else
+ ZEND_OP2_LITERAL(opline) = *val;
+#endif
+}
+
+static void replace_tmp_by_const(zend_op_array *op_array,
+ zend_op *opline,
+ zend_uint var,
+ zval *val
+ TSRMLS_DC)
+{
+ zend_op *end = op_array->opcodes + op_array->last;
+
+ while (opline < end) {
+ if (ZEND_OP1_TYPE(opline) == IS_TMP_VAR &&
+ ZEND_OP1(opline).var == var) {
+
+ update_op1_const(op_array, opline, val TSRMLS_CC);
+ /* TMP_VAR my be used only once */
+ break;
+ }
+
+ if (ZEND_OP2_TYPE(opline) == IS_TMP_VAR &&
+ ZEND_OP2(opline).var == var) {
+
+ update_op2_const(op_array, opline, val TSRMLS_CC);
+ /* TMP_VAR my be used only once */
+ break;
+ }
+ opline++;
+ }
+}
+
+#include "Optimizer/nop_removal.c"
+#include "Optimizer/block_pass.c"
+#include "Optimizer/optimize_temp_vars_5.c"
+
+void zend_optimizer(zend_op_array *op_array TSRMLS_DC)
+{
+ if (op_array->type == ZEND_EVAL_CODE ||
+ (op_array->fn_flags & ZEND_ACC_INTERACTIVE)) {
+ return;
+ }
+
+ /* pass 1
+ * - substitute persistent constants (true, false, null, etc)
+ * - perform compile-time evaluation of constant binary and unary operations
+ * - optimize series of ADD_STRING and/or ADD_CHAR
+ * - convert CAST(IS_BOOL,x) into BOOL(x)
+ * - convert INTI_FCALL_BY_NAME + DO_FCALL_BY_NAME into DO_FCALL
+ */
+#include "Optimizer/pass1_5.c"
+
+ /* pass 2:
+ * - convert non-numeric constants to numeric constants in numeric operators
+ * - optimize constant conditional JMPs
+ * - optimize static BRKs and CONTs
+ */
+#include "Optimizer/pass2.c"
+
+ /* pass 3:
+ * - optimize $i = $i+expr to $i+=expr
+ * - optimize series of JMPs
+ * - change $i++ to ++$i where possible
+ */
+#include "Optimizer/pass3.c"
+
+ /* pass 5:
+ * - CFG optimization
+ */
+#include "Optimizer/pass5.c"
+
+ /* pass 9:
+ * - Optimize temp variables usage
+ */
+#include "Optimizer/pass9.c"
+
+ /* pass 10:
+ * - remove NOPs
+ */
+#include "Optimizer/pass10.c"
+}
diff --git a/ext/opcache/Optimizer/zend_optimizer.h b/ext/opcache/Optimizer/zend_optimizer.h
new file mode 100644
index 0000000000..7802d6df98
--- /dev/null
+++ b/ext/opcache/Optimizer/zend_optimizer.h
@@ -0,0 +1,49 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2014 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: Andi Gutmans <andi@zend.com> |
+ | Zeev Suraski <zeev@zend.com> |
+ | Stanislav Malyshev <stas@zend.com> |
+ | Dmitry Stogov <dmitry@zend.com> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef ZEND_OPTIMIZER_H
+#define ZEND_OPTIMIZER_H
+
+#include "zend.h"
+#include "zend_compile.h"
+
+#define ZEND_OPTIMIZER_PASS_1 (1<<0) /* CSE, STRING construction */
+#define ZEND_OPTIMIZER_PASS_2 (1<<1) /* Constant conversion and jumps */
+#define ZEND_OPTIMIZER_PASS_3 (1<<2) /* ++, +=, series of jumps */
+#define ZEND_OPTIMIZER_PASS_4 (1<<3)
+#define ZEND_OPTIMIZER_PASS_5 (1<<4) /* CFG based optimization */
+#define ZEND_OPTIMIZER_PASS_6 (1<<5)
+#define ZEND_OPTIMIZER_PASS_7 (1<<6)
+#define ZEND_OPTIMIZER_PASS_8 (1<<7)
+#define ZEND_OPTIMIZER_PASS_9 (1<<8) /* TMP VAR usage */
+#define ZEND_OPTIMIZER_PASS_10 (1<<9) /* NOP removal */
+#define ZEND_OPTIMIZER_PASS_11 (1<<10)
+#define ZEND_OPTIMIZER_PASS_12 (1<<11)
+#define ZEND_OPTIMIZER_PASS_13 (1<<12)
+#define ZEND_OPTIMIZER_PASS_14 (1<<13)
+
+#define ZEND_OPTIMIZER_ALL_PASSES 0xFFFFFFFF
+
+#define DEFAULT_OPTIMIZATION_LEVEL "0xFFFFFFFF"
+
+void zend_optimizer(zend_op_array *op_array TSRMLS_DC);
+
+#endif
diff --git a/ext/opcache/Optimizer/zend_optimizer_internal.h b/ext/opcache/Optimizer/zend_optimizer_internal.h
new file mode 100644
index 0000000000..d4baf531e1
--- /dev/null
+++ b/ext/opcache/Optimizer/zend_optimizer_internal.h
@@ -0,0 +1,86 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2014 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: Andi Gutmans <andi@zend.com> |
+ | Zeev Suraski <zeev@zend.com> |
+ | Stanislav Malyshev <stas@zend.com> |
+ | Dmitry Stogov <dmitry@zend.com> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef ZEND_OPTIMIZER_INTERNAL_H
+#define ZEND_OPTIMIZER_INTERNAL_H
+
+#include "ZendAccelerator.h"
+
+#if ZEND_EXTENSION_API_NO > PHP_5_4_X_API_NO
+# define VAR_NUM(v) ((zend_uint)(EX_TMP_VAR_NUM(0, 0) - EX_TMP_VAR(0, v)))
+# define NUM_VAR(v) ((zend_uint)(zend_uintptr_t)EX_TMP_VAR_NUM(0, v))
+#elif ZEND_EXTENSION_API_NO > PHP_5_2_X_API_NO
+# define VAR_NUM(v) ((v)/ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)))
+# define NUM_VAR(v) ((v)*ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)))
+#else
+# define VAR_NUM(v) ((v)/(sizeof(temp_variable)))
+# define NUM_VAR(v) ((v)*(sizeof(temp_variable)))
+#endif
+
+#define INV_COND(op) ((op) == ZEND_JMPZ ? ZEND_JMPNZ : ZEND_JMPZ)
+#define INV_EX_COND(op) ((op) == ZEND_JMPZ_EX ? ZEND_JMPNZ : ZEND_JMPZ)
+#define INV_COND_EX(op) ((op) == ZEND_JMPZ ? ZEND_JMPNZ_EX : ZEND_JMPZ_EX)
+#define INV_EX_COND_EX(op) ((op) == ZEND_JMPZ_EX ? ZEND_JMPNZ_EX : ZEND_JMPZ_EX)
+
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+# define MAKE_NOP(opline) { opline->opcode = ZEND_NOP; memset(&opline->result,0,sizeof(opline->result)); memset(&opline->op1,0,sizeof(opline->op1)); memset(&opline->op2,0,sizeof(opline->op2)); opline->result_type=opline->op1_type=opline->op2_type=IS_UNUSED; opline->handler = zend_opcode_handlers[ZEND_NOP]; }
+# define RESULT_USED(op) (((op->result_type & IS_VAR) && !(op->result_type & EXT_TYPE_UNUSED)) || op->result_type == IS_TMP_VAR)
+# define RESULT_UNUSED(op) ((op->result_type & EXT_TYPE_UNUSED) != 0)
+# define SAME_VAR(op1, op2) ((((op1 ## _type & IS_VAR) && (op2 ## _type & IS_VAR)) || (op1 ## _type == IS_TMP_VAR && op2 ## _type == IS_TMP_VAR)) && op1.var == op2.var)
+#else
+# 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; opline->handler = zend_opcode_handlers[ZEND_NOP]; }
+# define RESULT_USED(op) ((op->result.op_type == IS_VAR && (op->result.u.EA.type & EXT_TYPE_UNUSED) == 0) || (op->result.op_type == IS_TMP_VAR))
+# define RESULT_UNUSED(op) ((op->result.op_type == IS_VAR) && (op->result.u.EA.type == EXT_TYPE_UNUSED))
+# define SAME_VAR(op1, op2) (((op1.op_type == IS_VAR && op2.op_type == IS_VAR) || (op1.op_type == IS_TMP_VAR && op2.op_type == IS_TMP_VAR)) && op1.u.var == op2.u.var)
+#endif
+
+typedef struct _zend_code_block zend_code_block;
+typedef struct _zend_block_source zend_block_source;
+
+struct _zend_code_block {
+ int access;
+ zend_op *start_opline;
+ int start_opline_no;
+ int len;
+ zend_code_block *op1_to;
+ zend_code_block *op2_to;
+ zend_code_block *ext_to;
+ zend_code_block *follow_to;
+ zend_code_block *next;
+ zend_block_source *sources;
+ zend_bool protected; /* don't merge this block with others */
+};
+
+typedef struct _zend_cfg {
+ zend_code_block *blocks;
+ zend_code_block **try;
+ zend_code_block **catch;
+ zend_code_block **loop_start;
+ zend_code_block **loop_cont;
+ zend_code_block **loop_brk;
+} zend_cfg;
+
+struct _zend_block_source {
+ zend_code_block *from;
+ zend_block_source *next;
+};
+
+#endif
diff --git a/ext/opcache/README b/ext/opcache/README
new file mode 100644
index 0000000000..693a7b4e3c
--- /dev/null
+++ b/ext/opcache/README
@@ -0,0 +1,220 @@
+The Zend OPcache
+================
+
+The Zend OPcache provides faster PHP execution through opcode caching and
+optimization. It improves PHP performance by storing precompiled script
+bytecode in the shared memory. This eliminates the stages of reading code from
+the disk and compiling it on future access. In addition, it applies a few
+bytecode optimization patterns that make code execution faster.
+
+Compatibility
+-------------
+
+This version of Zend OPcache is compatible with PHP 5.2.*, 5.3.*, 5.4.*
+and PHP-5.5 development branch. PHP 5.2 support may be removed in the future.
+
+Quick Install
+-------------
+
+- Compile
+
+ $PHP_DIR/bin/phpize
+ ./configure \
+ --with-php-config=$PHP_DIR/bin/php-config
+ make
+
+- Install
+
+ make install # this will copy opcache.so into PHP extension directory
+
+- Edit php.ini
+
+ zend_extension=/...full path.../opcache.so
+
+NOTE: In case you are going to use Zend OPcache together with Xdebug or Zend Debugger,
+be sure that the debugger is loaded after OPcache. "php -v" must show the debugger
+after OPcache.
+
+- Restart PHP
+
+Speed Tuning
+-------------
+
+We recommend the following configuration options for best performance
+in a production environment.
+
+opcache.memory_consumption=128
+opcache.interned_strings_buffer=8
+opcache.max_accelerated_files=4000
+opcache.revalidate_freq=60
+opcache.fast_shutdown=1
+opcache.enable_cli=1
+
+You also may add the following, but it may break some applications and
+frameworks. Please, read description of these directives and add them on your
+own risk.
+
+opcache.save_comments=0
+opcache.enable_file_override=1
+
+In some cases you may like to prefer enabling/disabling some features
+to avoid incompatibilities at the cost of some performance degradation.
+
+For development environment we would recommend setting opcache.revalidate_freq
+into 0.
+
+Configuration Directives
+------------------------
+
+opcache.enable (default "1")
+ OPcache On/Off switch. When set to Off, code is not optimized and cached.
+
+opcache.enable_cli (default "0")
+ Enables the OPcache for the CLI version of PHP. It's mostly for testing
+ and debugging.
+
+opcache.memory_consumption (default "64")
+ The OPcache shared memory storage size. The amount of memory for storing
+ precompiled PHP code in Mbytes.
+
+opcache.interned_strings_buffer (default "4")
+ The amount of memory for interned strings in Mbytes.
+
+opcache.max_accelerated_files (default "2000")
+ The maximum number of keys (scripts) in the OPcache hash table.
+ The number is actually the first one in the following set of prime
+ numbers that is bigger than the one supplied: { 223, 463, 983, 1979, 3907,
+ 7963, 16229, 32531, 65407, 130987, 262237, 524521, 1048793 }. Only numbers
+ between 200 and 1000000 are allowed.
+
+opcache.max_wasted_percentage (default "5")
+ The maximum percentage of "wasted" memory until a restart is scheduled.
+
+opcache.use_cwd (default "1")
+ When this directive is enabled, the OPcache appends the current working
+ directory to the script key, thus eliminating possible collisions between
+ files with the same name (basename). Disabling the directive improves
+ performance, but may break existing applications.
+
+opcache.validate_timestamps (default "1")
+ When disabled, you must reset the OPcache manually or restart the
+ webserver for changes to the filesystem to take effect.
+ The frequency of the check is controlled by the directive
+ "opcache.revalidate_freq".
+
+opcache.revalidate_freq (default "2")
+ How often (in seconds) to check file timestamps for changes to the shared
+ memory storage allocation. ("1" means validate once per second, but only
+ once per request. "0" means always validate)
+
+opcache.file_update_protection (default "2")
+ Prevents caching files that are less than this number of seconds old.
+ It protects from caching of incompletely updated files. In case all file
+ updates on your site are atomic, you may increase performance setting it
+ to "0".
+
+opcache.revalidate_path (default "0")
+ Enables or disables file search in include_path optimization
+ If the file search is disabled and a cached file is found that uses
+ the same include_path, the file is not searched again. Thus, if a file
+ with the same name appears somewhere else in include_path, it
+ won't be found. Enable this directive if this optimization has an effect on
+ your applications. The default for this directive is disabled, which means
+ that optimization is active.
+
+opcache.save_comments (default "1")
+ If disabled, all PHPDoc comments are dropped from the code to reduce the
+ size of the optimized code. Disabling "Doc Comments" may break some
+ existing applications and frameworks (e.g. Doctrine, ZF2, PHPUnit)
+
+opcache.load_comments (default "1")
+ If disabled, PHPDoc comments are not loaded from SHM, so "Doc Comments"
+ may be always stored (save_comments=1), but not loaded by applications
+ that don't need them anyway.
+
+opcache.fast_shutdown (default "0")
+ If enabled, a fast shutdown sequence is used for the accelerated code
+ The fast shutdown sequence doesn't free each allocated block, but lets
+ the Zend Engine Memory Manager do the work.
+
+opcache.enable_file_override (default "0")
+ Allow file existence override (file_exists, etc.) performance feature.
+
+opcache.optimization_level (default "0xffffffff")
+ A bitmask, where each bit enables or disables the appropriate OPcache
+ passes
+
+opcache.inherited_hack (default "1")
+ Enable this hack as a workaround for "can't redeclare class" errors.
+ The OPcache stores the places where DECLARE_CLASS opcodes use
+ inheritance (These are the only opcodes that can be executed by PHP,
+ but which may not be executed because the parent class is missing due to
+ optimization). When the file is loaded, OPcache tries to bind the
+ inherited classes by using the current environment. The problem with this
+ scenario is that, while the DECLARE_CLASS opcode may not be needed for the
+ current script, if the script requires that the opcode at least be defined,
+ it may not run. The default for this directive is disabled, which means
+ that optimization is active. In php-5.3 and above this hack is not needed
+ anymore and this setting has no effect.
+
+opcache.dups_fix (default "0")
+ Enable this hack as a workaround for "Cannot redeclare class" errors.
+
+opcache.blacklist_filename
+ The location of the OPcache blacklist file (wildcards allowed).
+ Each OPcache blacklist file is a text file that holds the names of files
+ that should not be accelerated. The file format is to add each filename
+ to a new line. The filename may be a full path or just a file prefix
+ (i.e., /var/www/x blacklists all the files and directories in /var/www
+ that start with 'x'). Line starting with a ; are ignored (comments).
+ Files are usually triggered by one of the following three reasons:
+ 1) Directories that contain auto generated code, like Smarty or ZFW cache.
+ 2) Code that does not work well when accelerated, due to some delayed
+ compile time evaluation.
+ 3) Code that triggers an OPcache bug.
+
+opcache.max_file_size (default "0")
+ Allows exclusion of large files from being cached. By default all files
+ are cached.
+
+opcache.consistency_checks (default "0")
+ Check the cache checksum each N requests.
+ The default value of "0" means that the checks are disabled.
+ Because calculating the checksum impairs performance, this directive should
+ be enabled only as part of a debugging process.
+
+opcache.force_restart_timeout (default "180")
+ How long to wait (in seconds) for a scheduled restart to begin if the cache
+ is not being accessed.
+ The OPcache uses this directive to identify a situation where there may
+ be a problem with a process. After this time period has passed, the
+ OPcache assumes that something has happened and starts killing the
+ processes that still hold the locks that are preventing a restart.
+ If the log level is 3 or above, a "killed locker" error is recorded
+ in the Apache logs when this happens.
+
+opcache.error_log
+ OPcache error_log file name. Empty string assumes "stderr".
+
+opcache.log_verbosity_level (default "1")
+ All OPcache errors go to the Web server log.
+ By default, only fatal errors (level 0) or errors (level 1) are logged.
+ You can also enable warnings (level 2), info messages (level 3) or
+ debug messages (level 4).
+
+opcache.preferred_memory_model
+ Preferred Shared Memory back-end. Leave empty and let the system decide.
+
+opcache.protect_memory (default "0")
+ Protect the shared memory from unexpected writing during script execution.
+ Useful for internal debugging only.
+
+opcache.restrict_api (default "")
+ Allows calling OPcache API functions only from PHP scripts which path is
+ started from specified string. The default "" means no restriction.
+
+opcache.mmap_base
+ Mapping base of shared memory segments (for Windows only). All the PHP
+ processes have to map shared memory into the same address space. This
+ directive allows to manually fix the "Unable to reattach to base address"
+ errors.
diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c
new file mode 100644
index 0000000000..d174f2a42f
--- /dev/null
+++ b/ext/opcache/ZendAccelerator.c
@@ -0,0 +1,2832 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2014 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: Andi Gutmans <andi@zend.com> |
+ | Zeev Suraski <zeev@zend.com> |
+ | Stanislav Malyshev <stas@zend.com> |
+ | Dmitry Stogov <dmitry@zend.com> |
+ +----------------------------------------------------------------------+
+*/
+
+#include "main/php.h"
+#include "main/php_globals.h"
+#include "zend.h"
+#include "zend_extensions.h"
+#include "zend_compile.h"
+#include "ZendAccelerator.h"
+#include "zend_persist.h"
+#include "zend_shared_alloc.h"
+#include "zend_accelerator_module.h"
+#include "zend_accelerator_blacklist.h"
+#include "zend_list.h"
+#include "zend_execute.h"
+#include "main/SAPI.h"
+#include "main/php_streams.h"
+#include "main/php_open_temporary_file.h"
+#include "zend_API.h"
+#include "zend_ini.h"
+#include "TSRM/tsrm_virtual_cwd.h"
+#include "zend_accelerator_util_funcs.h"
+#include "zend_accelerator_hash.h"
+
+#ifndef ZEND_WIN32
+#include <netdb.h>
+#endif
+
+#ifdef ZEND_WIN32
+typedef int uid_t;
+typedef int gid_t;
+#include <io.h>
+#endif
+
+#ifndef ZEND_WIN32
+# include <sys/time.h>
+#else
+# include <process.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#include <fcntl.h>
+#include <signal.h>
+#include <time.h>
+
+#ifndef ZEND_WIN32
+# include <sys/types.h>
+# include <sys/ipc.h>
+#endif
+
+#include <sys/stat.h>
+#include <errno.h>
+
+#define SHM_PROTECT() \
+ do { \
+ if (ZCG(accel_directives).protect_memory) { \
+ zend_accel_shared_protect(1 TSRMLS_CC); \
+ } \
+ } while (0)
+#define SHM_UNPROTECT() \
+ do { \
+ if (ZCG(accel_directives).protect_memory) { \
+ zend_accel_shared_protect(0 TSRMLS_CC); \
+ } \
+ } while (0)
+
+ZEND_EXTENSION();
+
+#ifndef ZTS
+zend_accel_globals accel_globals;
+#else
+int accel_globals_id;
+#endif
+
+/* Points to the structure shared across all PHP processes */
+zend_accel_shared_globals *accel_shared_globals = NULL;
+
+/* true globals, no need for thread safety */
+zend_bool accel_startup_ok = 0;
+static char *zps_failure_reason = NULL;
+char *zps_api_failure_reason = NULL;
+
+static zend_op_array *(*accelerator_orig_compile_file)(zend_file_handle *file_handle, int type TSRMLS_DC);
+static int (*accelerator_orig_zend_stream_open_function)(const char *filename, zend_file_handle *handle TSRMLS_DC);
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+static char *(*accelerator_orig_zend_resolve_path)(const char *filename, int filename_len TSRMLS_DC);
+#endif
+static void (*orig_chdir)(INTERNAL_FUNCTION_PARAMETERS) = NULL;
+static ZEND_INI_MH((*orig_include_path_on_modify)) = NULL;
+
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+static char *accel_php_resolve_path(const char *filename, int filename_length, const char *path TSRMLS_DC);
+#endif
+
+#ifdef ZEND_WIN32
+# define INCREMENT(v) InterlockedIncrement(&ZCSG(v))
+# define DECREMENT(v) InterlockedDecrement(&ZCSG(v))
+# define LOCKVAL(v) (ZCSG(v))
+#endif
+
+#ifdef ZEND_WIN32
+static time_t zend_accel_get_time(void)
+{
+ FILETIME now;
+ GetSystemTimeAsFileTime(&now);
+
+ return (time_t) ((((((__int64)now.dwHighDateTime) << 32)|now.dwLowDateTime) - 116444736000000000L)/10000000);
+}
+#else
+# define zend_accel_get_time() time(NULL)
+#endif
+
+static inline int is_stream_path(const char *filename)
+{
+ const char *p;
+
+ for (p = filename; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; p++);
+ return ((*p == ':') && (p - filename > 1) && (p[1] == '/') && (p[2] == '/'));
+}
+
+static inline int is_cacheable_stream_path(const char *filename)
+{
+ return memcmp(filename, "file://", sizeof("file://") - 1) == 0 ||
+ memcmp(filename, "phar://", sizeof("phar://") - 1) == 0;
+}
+
+/* O+ overrides PHP chdir() function and remembers the current working directory
+ * in ZCG(cwd) and ZCG(cwd_len). Later accel_getcwd() can use stored value and
+ * avoid getcwd() call.
+ */
+static ZEND_FUNCTION(accel_chdir)
+{
+ char cwd[MAXPATHLEN];
+
+ orig_chdir(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ if (VCWD_GETCWD(cwd, MAXPATHLEN)) {
+ if (ZCG(cwd)) {
+ efree(ZCG(cwd));
+ }
+ ZCG(cwd_len) = strlen(cwd);
+ ZCG(cwd) = estrndup(cwd, ZCG(cwd_len));
+ } else {
+ if (ZCG(cwd)) {
+ efree(ZCG(cwd));
+ ZCG(cwd) = NULL;
+ }
+ }
+}
+
+static inline char* accel_getcwd(int *cwd_len TSRMLS_DC)
+{
+ if (ZCG(cwd)) {
+ *cwd_len = ZCG(cwd_len);
+ return ZCG(cwd);
+ } else {
+ char cwd[MAXPATHLEN + 1];
+
+ if (!VCWD_GETCWD(cwd, MAXPATHLEN)) {
+ return NULL;
+ }
+ *cwd_len = ZCG(cwd_len) = strlen(cwd);
+ ZCG(cwd) = estrndup(cwd, ZCG(cwd_len));
+ return ZCG(cwd);
+ }
+}
+
+void zend_accel_schedule_restart_if_necessary(zend_accel_restart_reason reason TSRMLS_DC)
+{
+ if ((((double) ZSMMG(wasted_shared_memory)) / ZCG(accel_directives).memory_consumption) >= ZCG(accel_directives).max_wasted_percentage) {
+ zend_accel_schedule_restart(reason TSRMLS_CC);
+ }
+}
+
+/* O+ tracks changes of "include_path" directive. It stores all the requested
+ * values in ZCG(include_paths) shared hash table, current value in
+ * ZCG(include_path)/ZCG(include_path_len) and one letter "path key" in
+ * ZCG(include_path_key).
+ */
+static ZEND_INI_MH(accel_include_path_on_modify)
+{
+ int ret = orig_include_path_on_modify(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
+
+ ZCG(include_path_key) = NULL;
+ if (ret == SUCCESS) {
+ ZCG(include_path) = new_value;
+ if (ZCG(include_path) && *ZCG(include_path)) {
+ ZCG(include_path_len) = new_value_length;
+
+ if (ZCG(enabled) && accel_startup_ok &&
+ (ZCG(counted) || ZCSG(accelerator_enabled))) {
+
+ ZCG(include_path_key) = zend_accel_hash_find(&ZCSG(include_paths), ZCG(include_path), ZCG(include_path_len) + 1);
+ if (!ZCG(include_path_key) &&
+ !zend_accel_hash_is_full(&ZCSG(include_paths))) {
+ SHM_UNPROTECT();
+ zend_shared_alloc_lock(TSRMLS_C);
+
+ ZCG(include_path_key) = zend_accel_hash_find(&ZCSG(include_paths), ZCG(include_path), ZCG(include_path_len) + 1);
+ if (!ZCG(include_path_key) &&
+ !zend_accel_hash_is_full(&ZCSG(include_paths))) {
+ char *key;
+
+ key = zend_shared_alloc(ZCG(include_path_len) + 2);
+ if (key) {
+ memcpy(key, ZCG(include_path), ZCG(include_path_len) + 1);
+ key[ZCG(include_path_len) + 1] = 'A' + ZCSG(include_paths).num_entries;
+ ZCG(include_path_key) = key + ZCG(include_path_len) + 1;
+ zend_accel_hash_update(&ZCSG(include_paths), key, ZCG(include_path_len) + 1, 0, ZCG(include_path_key));
+ } else {
+ zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_OOM TSRMLS_CC);
+ }
+ }
+
+ zend_shared_alloc_unlock(TSRMLS_C);
+ SHM_PROTECT();
+ }
+ } else {
+ ZCG(include_path_check) = 1;
+ }
+ } else {
+ ZCG(include_path) = "";
+ ZCG(include_path_len) = 0;
+ }
+ }
+ return ret;
+}
+
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+/* Interned strings support */
+static char *orig_interned_strings_start;
+static char *orig_interned_strings_end;
+static const char *(*orig_new_interned_string)(const char *str, int len, int free_src TSRMLS_DC);
+static void (*orig_interned_strings_snapshot)(TSRMLS_D);
+static void (*orig_interned_strings_restore)(TSRMLS_D);
+
+/* O+ disables creation of interned strings by regular PHP compiler, instead,
+ * it creates interned strings in shared memory when saves a script.
+ * Such interned strings are shared across all PHP processes
+ */
+static const char *accel_new_interned_string_for_php(const char *str, int len, int free_src TSRMLS_DC)
+{
+ return str;
+}
+
+static void accel_interned_strings_snapshot_for_php(TSRMLS_D)
+{
+}
+
+static void accel_interned_strings_restore_for_php(TSRMLS_D)
+{
+}
+
+#ifndef ZTS
+static void accel_interned_strings_restore_state(TSRMLS_D)
+{
+ unsigned int i;
+
+ for (i = 0; i < ZCSG(interned_strings).nTableSize; i++) {
+ ZCSG(interned_strings).arBuckets[i] = ZCSG(interned_strings_saved_state).arBuckets[i];
+ if (ZCSG(interned_strings).arBuckets[i]) {
+ ZCSG(interned_strings).arBuckets[i]->pLast = NULL;
+ }
+ }
+ ZCSG(interned_strings).pListHead = ZCSG(interned_strings_saved_state).pListHead;
+ ZCSG(interned_strings).pListTail = ZCSG(interned_strings_saved_state).pListTail;
+ if (ZCSG(interned_strings).pListHead) {
+ ZCSG(interned_strings).pListHead->pListLast = NULL;
+ }
+ if (ZCSG(interned_strings).pListTail) {
+ ZCSG(interned_strings).pListTail->pListNext = NULL;
+ }
+ ZCSG(interned_strings_top) = ZCSG(interned_strings_saved_state).top;
+}
+
+static void accel_interned_strings_save_state(TSRMLS_D)
+{
+ ZCSG(interned_strings_saved_state).arBuckets = (Bucket**)zend_shared_alloc(ZCSG(interned_strings).nTableSize * sizeof(Bucket *));
+ if (!ZCSG(interned_strings_saved_state).arBuckets) {
+ zend_accel_error(ACCEL_LOG_FATAL, "Insufficient shared memory!");
+ }
+ memcpy(ZCSG(interned_strings_saved_state).arBuckets, ZCSG(interned_strings).arBuckets, ZCSG(interned_strings).nTableSize * sizeof(Bucket *));
+ ZCSG(interned_strings_saved_state).pListHead = ZCSG(interned_strings).pListHead;
+ ZCSG(interned_strings_saved_state).pListTail = ZCSG(interned_strings).pListTail;
+ ZCSG(interned_strings_saved_state).top = ZCSG(interned_strings_top);
+}
+#endif
+
+const char *accel_new_interned_string(const char *arKey, int nKeyLength, int free_src TSRMLS_DC)
+{
+/* for now interned strings are supported only for non-ZTS build */
+#ifndef ZTS
+ ulong h;
+ uint nIndex;
+ Bucket *p;
+
+ if (arKey >= ZCSG(interned_strings_start) && arKey < ZCSG(interned_strings_end)) {
+ /* this is already an interned string */
+ return arKey;
+ }
+
+ h = zend_inline_hash_func(arKey, nKeyLength);
+ nIndex = h & ZCSG(interned_strings).nTableMask;
+
+ /* check for existing interned string */
+ p = ZCSG(interned_strings).arBuckets[nIndex];
+ while (p != NULL) {
+ if ((p->h == h) && (p->nKeyLength == (uint)nKeyLength)) {
+ if (!memcmp(p->arKey, arKey, nKeyLength)) {
+ if (free_src) {
+ efree((char*)arKey);
+ }
+ return p->arKey;
+ }
+ }
+ p = p->pNext;
+ }
+
+ if (ZCSG(interned_strings_top) + ZEND_MM_ALIGNED_SIZE(sizeof(Bucket) + nKeyLength) >=
+ ZCSG(interned_strings_end)) {
+ /* no memory, return the same non-interned string */
+ return arKey;
+ }
+
+ /* create new interning string in shared interned strings buffer */
+ p = (Bucket *) ZCSG(interned_strings_top);
+ ZCSG(interned_strings_top) += ZEND_MM_ALIGNED_SIZE(sizeof(Bucket) + nKeyLength);
+
+ p->arKey = (char*)(p + 1);
+ memcpy((char*)p->arKey, arKey, nKeyLength);
+ p->nKeyLength = nKeyLength;
+ p->h = h;
+ p->pData = &p->pDataPtr;
+ p->pDataPtr = p;
+
+ p->pNext = ZCSG(interned_strings).arBuckets[nIndex];
+ p->pLast = NULL;
+ if (p->pNext) {
+ p->pNext->pLast = p;
+ }
+ ZCSG(interned_strings).arBuckets[nIndex] = p;
+
+ p->pListLast = ZCSG(interned_strings).pListTail;
+ ZCSG(interned_strings).pListTail = p;
+ p->pListNext = NULL;
+ if (p->pListLast != NULL) {
+ p->pListLast->pListNext = p;
+ }
+ if (!ZCSG(interned_strings).pListHead) {
+ ZCSG(interned_strings).pListHead = p;
+ }
+
+ ZCSG(interned_strings).nNumOfElements++;
+
+ if (free_src) {
+ efree((char*)arKey);
+ }
+
+ return p->arKey;
+#else
+ return arKey;
+#endif
+}
+
+#ifndef ZTS
+/* Copy PHP interned strings from PHP process memory into the shared memory */
+static void accel_use_shm_interned_strings(TSRMLS_D)
+{
+ Bucket *p, *q;
+
+ /* function table hash keys */
+ p = CG(function_table)->pListHead;
+ while (p) {
+ if (p->nKeyLength) {
+ p->arKey = accel_new_interned_string(p->arKey, p->nKeyLength, 0 TSRMLS_CC);
+ }
+ p = p->pListNext;
+ }
+
+ /* class table hash keys, class names, properties, methods, constants, etc */
+ p = CG(class_table)->pListHead;
+ while (p) {
+ zend_class_entry *ce = (zend_class_entry*)(p->pDataPtr);
+
+ if (p->nKeyLength) {
+ p->arKey = accel_new_interned_string(p->arKey, p->nKeyLength, 0 TSRMLS_CC);
+ }
+
+ if (ce->name) {
+ ce->name = accel_new_interned_string(ce->name, ce->name_length + 1, 0 TSRMLS_CC);
+ }
+
+ q = ce->properties_info.pListHead;
+ while (q) {
+ zend_property_info *info = (zend_property_info*)(q->pData);
+
+ if (q->nKeyLength) {
+ q->arKey = accel_new_interned_string(q->arKey, q->nKeyLength, 0 TSRMLS_CC);
+ }
+
+ if (info->name) {
+ info->name = accel_new_interned_string(info->name, info->name_length + 1, 0 TSRMLS_CC);
+ }
+
+ q = q->pListNext;
+ }
+
+ q = ce->function_table.pListHead;
+ while (q) {
+ if (q->nKeyLength) {
+ q->arKey = accel_new_interned_string(q->arKey, q->nKeyLength, 0 TSRMLS_CC);
+ }
+ q = q->pListNext;
+ }
+
+ q = ce->constants_table.pListHead;
+ while (q) {
+ if (q->nKeyLength) {
+ q->arKey = accel_new_interned_string(q->arKey, q->nKeyLength, 0 TSRMLS_CC);
+ }
+ q = q->pListNext;
+ }
+
+ p = p->pListNext;
+ }
+
+ /* constant hash keys */
+ p = EG(zend_constants)->pListHead;
+ while (p) {
+ if (p->nKeyLength) {
+ p->arKey = accel_new_interned_string(p->arKey, p->nKeyLength, 0 TSRMLS_CC);
+ }
+ p = p->pListNext;
+ }
+
+ /* auto globals hash keys and names */
+ p = CG(auto_globals)->pListHead;
+ while (p) {
+ zend_auto_global *auto_global = (zend_auto_global*)p->pData;
+
+ auto_global->name = accel_new_interned_string(auto_global->name, auto_global->name_len + 1, 0 TSRMLS_CC);
+ if (p->nKeyLength) {
+ p->arKey = accel_new_interned_string(p->arKey, p->nKeyLength, 0 TSRMLS_CC);
+ }
+ p = p->pListNext;
+ }
+}
+#endif
+#endif
+
+static inline void accel_restart_enter(TSRMLS_D)
+{
+#ifdef ZEND_WIN32
+ INCREMENT(restart_in);
+#else
+ static const FLOCK_STRUCTURE(restart_in_progress, F_WRLCK, SEEK_SET, 2, 1);
+
+ if (fcntl(lock_file, F_SETLK, &restart_in_progress) == -1) {
+ zend_accel_error(ACCEL_LOG_DEBUG, "RestartC(+1): %s (%d)", strerror(errno), errno);
+ }
+#endif
+ ZCSG(restart_in_progress) = 1;
+}
+
+static inline void accel_restart_leave(TSRMLS_D)
+{
+#ifdef ZEND_WIN32
+ ZCSG(restart_in_progress) = 0;
+ DECREMENT(restart_in);
+#else
+ static const FLOCK_STRUCTURE(restart_finished, F_UNLCK, SEEK_SET, 2, 1);
+
+ ZCSG(restart_in_progress) = 0;
+ if (fcntl(lock_file, F_SETLK, &restart_finished) == -1) {
+ zend_accel_error(ACCEL_LOG_DEBUG, "RestartC(-1): %s (%d)", strerror(errno), errno);
+ }
+#endif
+}
+
+static inline int accel_restart_is_active(TSRMLS_D)
+{
+ if (ZCSG(restart_in_progress)) {
+#ifndef ZEND_WIN32
+ FLOCK_STRUCTURE(restart_check, F_WRLCK, SEEK_SET, 2, 1);
+
+ if (fcntl(lock_file, F_GETLK, &restart_check) == -1) {
+ zend_accel_error(ACCEL_LOG_DEBUG, "RestartC: %s (%d)", strerror(errno), errno);
+ return FAILURE;
+ }
+ if (restart_check.l_type == F_UNLCK) {
+ ZCSG(restart_in_progress) = 0;
+ return 0;
+ } else {
+ return 1;
+ }
+#else
+ return LOCKVAL(restart_in) != 0;
+#endif
+ }
+ return 0;
+}
+
+/* Creates a read lock for SHM access */
+static inline void accel_activate_add(TSRMLS_D)
+{
+#ifdef ZEND_WIN32
+ INCREMENT(mem_usage);
+#else
+ static const FLOCK_STRUCTURE(mem_usage_lock, F_RDLCK, SEEK_SET, 1, 1);
+
+ if (fcntl(lock_file, F_SETLK, &mem_usage_lock) == -1) {
+ zend_accel_error(ACCEL_LOG_DEBUG, "UpdateC(+1): %s (%d)", strerror(errno), errno);
+ }
+#endif
+}
+
+/* Releases a lock for SHM access */
+static inline void accel_deactivate_sub(TSRMLS_D)
+{
+#ifdef ZEND_WIN32
+ if (ZCG(counted)) {
+ DECREMENT(mem_usage);
+ ZCG(counted) = 0;
+ }
+#else
+ static const FLOCK_STRUCTURE(mem_usage_unlock, F_UNLCK, SEEK_SET, 1, 1);
+
+ if (fcntl(lock_file, F_SETLK, &mem_usage_unlock) == -1) {
+ zend_accel_error(ACCEL_LOG_DEBUG, "UpdateC(-1): %s (%d)", strerror(errno), errno);
+ }
+#endif
+}
+
+static inline void accel_unlock_all(TSRMLS_D)
+{
+#ifdef ZEND_WIN32
+ accel_deactivate_sub(TSRMLS_C);
+#else
+ static const FLOCK_STRUCTURE(mem_usage_unlock_all, F_UNLCK, SEEK_SET, 0, 0);
+
+ if (fcntl(lock_file, F_SETLK, &mem_usage_unlock_all) == -1) {
+ zend_accel_error(ACCEL_LOG_DEBUG, "UnlockAll: %s (%d)", strerror(errno), errno);
+ }
+#endif
+}
+
+#ifndef ZEND_WIN32
+static inline void kill_all_lockers(struct flock *mem_usage_check)
+{
+ int tries = 10;
+
+ /* so that other process won't try to force while we are busy cleaning up */
+ ZCSG(force_restart_time) = 0;
+ while (mem_usage_check->l_pid > 0) {
+ while (tries--) {
+ zend_accel_error(ACCEL_LOG_INFO, "Killed locker %d", mem_usage_check->l_pid);
+ if (kill(mem_usage_check->l_pid, SIGKILL)) {
+ break;
+ }
+ /* give it a chance to die */
+ usleep(20000);
+ if (kill(mem_usage_check->l_pid, 0)) {
+ /* can't kill it */
+ break;
+ }
+ usleep(10000);
+ }
+ if (!tries) {
+ zend_accel_error(ACCEL_LOG_INFO, "Can't kill %d after 20 tries!", mem_usage_check->l_pid);
+ ZCSG(force_restart_time) = time(NULL); /* restore forced restart request */
+ }
+
+ mem_usage_check->l_type = F_WRLCK;
+ mem_usage_check->l_whence = SEEK_SET;
+ mem_usage_check->l_start = 1;
+ mem_usage_check->l_len = 1;
+ mem_usage_check->l_pid = -1;
+ if (fcntl(lock_file, F_GETLK, mem_usage_check) == -1) {
+ zend_accel_error(ACCEL_LOG_DEBUG, "KLockers: %s (%d)", strerror(errno), errno);
+ break;
+ }
+
+ if (mem_usage_check->l_type == F_UNLCK || mem_usage_check->l_pid <= 0) {
+ break;
+ }
+ }
+}
+#endif
+
+static inline int accel_is_inactive(TSRMLS_D)
+{
+#ifdef ZEND_WIN32
+ if (LOCKVAL(mem_usage) == 0) {
+ return SUCCESS;
+ }
+#else
+ FLOCK_STRUCTURE(mem_usage_check, F_WRLCK, SEEK_SET, 1, 1);
+
+ mem_usage_check.l_pid = -1;
+ if (fcntl(lock_file, F_GETLK, &mem_usage_check) == -1) {
+ zend_accel_error(ACCEL_LOG_DEBUG, "UpdateC: %s (%d)", strerror(errno), errno);
+ return FAILURE;
+ }
+ if (mem_usage_check.l_type == F_UNLCK) {
+ return SUCCESS;
+ }
+
+ if (ZCG(accel_directives).force_restart_timeout
+ && ZCSG(force_restart_time)
+ && time(NULL) >= ZCSG(force_restart_time)) {
+ zend_accel_error(ACCEL_LOG_WARNING, "Forced restart at %d (after %d seconds), locked by %d", time(NULL), ZCG(accel_directives).force_restart_timeout, mem_usage_check.l_pid);
+ kill_all_lockers(&mem_usage_check);
+
+ return FAILURE; /* next request should be able to restart it */
+ }
+#endif
+
+ return FAILURE;
+}
+
+static int zend_get_stream_timestamp(const char *filename, struct stat *statbuf TSRMLS_DC)
+{
+ php_stream_wrapper *wrapper;
+ php_stream_statbuf stream_statbuf;
+ int ret, er;
+
+ if (!filename) {
+ return FAILURE;
+ }
+
+ wrapper = php_stream_locate_url_wrapper(filename, NULL, STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC);
+ if (!wrapper) {
+ return FAILURE;
+ }
+ if (!wrapper->wops || !wrapper->wops->url_stat) {
+ statbuf->st_mtime = 1;
+ return SUCCESS; /* anything other than 0 is considered to be a valid timestamp */
+ }
+
+ er = EG(error_reporting);
+ EG(error_reporting) = 0;
+ zend_try {
+ ret = wrapper->wops->url_stat(wrapper, (char*)filename, PHP_STREAM_URL_STAT_QUIET, &stream_statbuf, NULL TSRMLS_CC);
+ } zend_catch {
+ ret = -1;
+ } zend_end_try();
+ EG(error_reporting) = er;
+
+ if (ret != 0) {
+ return FAILURE;
+ }
+
+ *statbuf = stream_statbuf.sb;
+ return SUCCESS;
+}
+
+#if ZEND_WIN32
+static accel_time_t zend_get_file_handle_timestamp_win(zend_file_handle *file_handle, size_t *size)
+{
+ static unsigned __int64 utc_base = 0;
+ static FILETIME utc_base_ft;
+ WIN32_FILE_ATTRIBUTE_DATA fdata;
+
+ if (!file_handle->opened_path) {
+ return 0;
+ }
+
+ if (!utc_base) {
+ SYSTEMTIME st;
+
+ st.wYear = 1970;
+ st.wMonth = 1;
+ st.wDay = 1;
+ st.wHour = 0;
+ st.wMinute = 0;
+ st.wSecond = 0;
+ st.wMilliseconds = 0;
+
+ SystemTimeToFileTime (&st, &utc_base_ft);
+ utc_base = (((unsigned __int64)utc_base_ft.dwHighDateTime) << 32) + utc_base_ft.dwLowDateTime;
+ }
+
+ if (GetFileAttributesEx(file_handle->opened_path, GetFileExInfoStandard, &fdata) != 0) {
+ unsigned __int64 ftime;
+
+ if (CompareFileTime (&fdata.ftLastWriteTime, &utc_base_ft) < 0) {
+ return 0;
+ }
+
+ ftime = (((unsigned __int64)fdata.ftLastWriteTime.dwHighDateTime) << 32) + fdata.ftLastWriteTime.dwLowDateTime - utc_base;
+ ftime /= 10000000L;
+
+ if (size) {
+ *size = (size_t)(((unsigned __int64)fdata.nFileSizeHigh) << 32 + (unsigned __int64)fdata.nFileSizeLow);
+ }
+ return (accel_time_t)ftime;
+ }
+ return 0;
+}
+#endif
+
+static accel_time_t zend_get_file_handle_timestamp(zend_file_handle *file_handle, size_t *size TSRMLS_DC)
+{
+ struct stat statbuf;
+#ifdef ZEND_WIN32
+ accel_time_t res;
+#endif
+
+ if (sapi_module.get_stat &&
+ !EG(opline_ptr) &&
+ file_handle->filename == SG(request_info).path_translated) {
+
+ struct stat *tmpbuf = sapi_module.get_stat(TSRMLS_C);
+
+ if (tmpbuf) {
+ if (size) {
+ *size = tmpbuf->st_size;
+ }
+ return tmpbuf->st_mtime;
+ }
+ }
+
+#ifdef ZEND_WIN32
+ res = zend_get_file_handle_timestamp_win(file_handle, size);
+ if (res) {
+ return res;
+ }
+#endif
+
+ switch (file_handle->type) {
+ case ZEND_HANDLE_FD:
+ if (fstat(file_handle->handle.fd, &statbuf) == -1) {
+ return 0;
+ }
+ break;
+ case ZEND_HANDLE_FP:
+ if (fstat(fileno(file_handle->handle.fp), &statbuf) == -1) {
+ if (zend_get_stream_timestamp(file_handle->filename, &statbuf TSRMLS_CC) != SUCCESS) {
+ return 0;
+ }
+ }
+ break;
+ case ZEND_HANDLE_FILENAME:
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+ case ZEND_HANDLE_MAPPED:
+#endif
+ {
+ char *file_path = file_handle->opened_path;
+
+ if (file_path) {
+ if (is_stream_path(file_path)) {
+ if (zend_get_stream_timestamp(file_path, &statbuf TSRMLS_CC) == SUCCESS) {
+ break;
+ }
+ }
+ if (VCWD_STAT(file_path, &statbuf) != -1) {
+ break;
+ }
+ }
+
+ if (zend_get_stream_timestamp(file_handle->filename, &statbuf TSRMLS_CC) != SUCCESS) {
+ return 0;
+ }
+ break;
+ }
+ case ZEND_HANDLE_STREAM:
+ {
+ php_stream *stream = (php_stream *)file_handle->handle.stream.handle;
+ php_stream_statbuf sb;
+ int ret, er;
+
+ if (!stream ||
+ !stream->ops ||
+ !stream->ops->stat) {
+ return 0;
+ }
+
+ er = EG(error_reporting);
+ EG(error_reporting) = 0;
+ zend_try {
+ ret = stream->ops->stat(stream, &sb TSRMLS_CC);
+ } zend_catch {
+ ret = -1;
+ } zend_end_try();
+ EG(error_reporting) = er;
+ if (ret != 0) {
+ return 0;
+ }
+
+ statbuf = sb.sb;
+ }
+ break;
+
+ default:
+ return 0;
+ }
+
+ if (size) {
+ *size = statbuf.st_size;
+ }
+ return statbuf.st_mtime;
+}
+
+static inline int do_validate_timestamps(zend_persistent_script *persistent_script, zend_file_handle *file_handle TSRMLS_DC)
+{
+ zend_file_handle ps_handle;
+ char *full_path_ptr = NULL;
+
+ /** check that the persistant script is indeed the same file we cached
+ * (if part of the path is a symlink than it possible that the user will change it)
+ * See bug #15140
+ */
+ if (file_handle->opened_path) {
+ if (strcmp(persistent_script->full_path, file_handle->opened_path) != 0) {
+ return FAILURE;
+ }
+ } else {
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+ full_path_ptr = accel_php_resolve_path(file_handle->filename, strlen(file_handle->filename), ZCG(include_path) TSRMLS_CC);
+#else
+ full_path_ptr = accelerator_orig_zend_resolve_path(file_handle->filename, strlen(file_handle->filename) TSRMLS_CC);
+#endif
+ if (full_path_ptr && strcmp(persistent_script->full_path, full_path_ptr) != 0) {
+ efree(full_path_ptr);
+ return FAILURE;
+ }
+ file_handle->opened_path = full_path_ptr;
+ }
+
+ if (persistent_script->timestamp == 0) {
+ if (full_path_ptr) {
+ efree(full_path_ptr);
+ file_handle->opened_path = NULL;
+ }
+ return FAILURE;
+ }
+
+ if (zend_get_file_handle_timestamp(file_handle, NULL TSRMLS_CC) == persistent_script->timestamp) {
+ if (full_path_ptr) {
+ efree(full_path_ptr);
+ file_handle->opened_path = NULL;
+ }
+ return SUCCESS;
+ }
+ if (full_path_ptr) {
+ efree(full_path_ptr);
+ file_handle->opened_path = NULL;
+ }
+
+ ps_handle.type = ZEND_HANDLE_FILENAME;
+ ps_handle.filename = persistent_script->full_path;
+ ps_handle.opened_path = persistent_script->full_path;
+
+ if (zend_get_file_handle_timestamp(&ps_handle, NULL TSRMLS_CC) == persistent_script->timestamp) {
+ return SUCCESS;
+ }
+
+ return FAILURE;
+}
+
+int validate_timestamp_and_record(zend_persistent_script *persistent_script, zend_file_handle *file_handle TSRMLS_DC)
+{
+ if (ZCG(accel_directives).revalidate_freq &&
+ (persistent_script->dynamic_members.revalidate >= ZCSG(revalidate_at))) {
+ return SUCCESS;
+ } else if (do_validate_timestamps(persistent_script, file_handle TSRMLS_CC) == FAILURE) {
+ return FAILURE;
+ } else {
+ persistent_script->dynamic_members.revalidate = ZCSG(revalidate_at);
+ return SUCCESS;
+ }
+}
+
+static unsigned int zend_accel_script_checksum(zend_persistent_script *persistent_script)
+{
+ signed char *mem = (signed char*)persistent_script->mem;
+ size_t size = persistent_script->size;
+ size_t persistent_script_check_block_size = ((char *)&(persistent_script->dynamic_members)) - (char *)persistent_script;
+ unsigned int checksum = ADLER32_INIT;
+
+ if (mem < (signed char*)persistent_script) {
+ checksum = zend_adler32(checksum, mem, (signed char*)persistent_script - mem);
+ size -= (signed char*)persistent_script - mem;
+ mem += (signed char*)persistent_script - mem;
+ }
+
+ zend_adler32(checksum, mem, persistent_script_check_block_size);
+ mem += sizeof(*persistent_script);
+ size -= sizeof(*persistent_script);
+
+ if (size > 0) {
+ checksum = zend_adler32(checksum, mem, size);
+ }
+ return checksum;
+}
+
+/* Instead of resolving full real path name each time we need to identify file,
+ * we create a key that consist from requested file name, current working
+ * directory, current include_path, etc */
+char *accel_make_persistent_key_ex(zend_file_handle *file_handle, int path_length, int *key_len TSRMLS_DC)
+{
+ int key_length;
+
+ /* CWD and include_path don't matter for absolute file names and streams */
+ if (ZCG(accel_directives).use_cwd &&
+ !IS_ABSOLUTE_PATH(file_handle->filename, path_length) &&
+ !is_stream_path(file_handle->filename)) {
+ char *include_path = NULL;
+ int include_path_len = 0;
+ const char *parent_script = NULL;
+ int parent_script_len = 0;
+ int cur_len = 0;
+ int cwd_len;
+ char *cwd;
+
+ if ((cwd = accel_getcwd(&cwd_len TSRMLS_CC)) == NULL) {
+ /* we don't handle this well for now. */
+ zend_accel_error(ACCEL_LOG_INFO, "getcwd() failed for '%s' (%d), please try to set opcache.use_cwd to 0 in ini file", file_handle->filename, errno);
+ if (file_handle->opened_path) {
+ cwd = file_handle->opened_path;
+ cwd_len = strlen(cwd);
+ } else {
+ ZCG(key_len) = 0;
+ return NULL;
+ }
+ }
+
+ if (ZCG(include_path_key)) {
+ include_path = ZCG(include_path_key);
+ include_path_len = 1;
+ } else {
+ include_path = ZCG(include_path);
+ include_path_len = ZCG(include_path_len);
+ if (ZCG(include_path_check) &&
+ ZCG(enabled) && accel_startup_ok &&
+ (ZCG(counted) || ZCSG(accelerator_enabled)) &&
+ !zend_accel_hash_find(&ZCSG(include_paths), ZCG(include_path), ZCG(include_path_len) + 1) &&
+ !zend_accel_hash_is_full(&ZCSG(include_paths))) {
+
+ SHM_UNPROTECT();
+ zend_shared_alloc_lock(TSRMLS_C);
+
+ ZCG(include_path_key) = zend_accel_hash_find(&ZCSG(include_paths), ZCG(include_path), ZCG(include_path_len) + 1);
+ if (ZCG(include_path_key)) {
+ include_path = ZCG(include_path_key);
+ include_path_len = 1;
+ } else if (!zend_accel_hash_is_full(&ZCSG(include_paths))) {
+ char *key;
+
+ key = zend_shared_alloc(ZCG(include_path_len) + 2);
+ if (key) {
+ memcpy(key, ZCG(include_path), ZCG(include_path_len) + 1);
+ key[ZCG(include_path_len) + 1] = 'A' + ZCSG(include_paths).num_entries;
+ ZCG(include_path_key) = key + ZCG(include_path_len) + 1;
+ zend_accel_hash_update(&ZCSG(include_paths), key, ZCG(include_path_len) + 1, 0, ZCG(include_path_key));
+ include_path = ZCG(include_path_key);
+ include_path_len = 1;
+ } else {
+ zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_OOM TSRMLS_CC);
+ }
+ }
+
+ zend_shared_alloc_unlock(TSRMLS_C);
+ SHM_PROTECT();
+ }
+ }
+
+ /* Here we add to the key the parent script directory,
+ since fopen_wrappers from version 4.0.7 use current script's path
+ in include path too.
+ */
+ if (EG(in_execution) &&
+ (parent_script = zend_get_executed_filename(TSRMLS_C)) != NULL &&
+ parent_script[0] != '[') {
+
+ parent_script_len = strlen(parent_script);
+ while ((--parent_script_len > 0) && !IS_SLASH(parent_script[parent_script_len]));
+ }
+
+ /* Calculate key length */
+ key_length = cwd_len + path_length + include_path_len + 2;
+ if (parent_script_len) {
+ key_length += parent_script_len + 1;
+ }
+
+ /* Generate key
+ * Note - the include_path must be the last element in the key,
+ * since in itself, it may include colons (which we use to separate
+ * different components of the key)
+ */
+ if ((size_t)key_length >= sizeof(ZCG(key))) {
+ ZCG(key_len) = 0;
+ return NULL;
+ }
+ memcpy(ZCG(key), cwd, cwd_len);
+ ZCG(key)[cwd_len] = ':';
+
+ memcpy(ZCG(key) + cwd_len + 1, file_handle->filename, path_length);
+
+ ZCG(key)[cwd_len + 1 + path_length] = ':';
+
+ cur_len = cwd_len + 1 + path_length + 1;
+
+ if (parent_script_len) {
+ memcpy(ZCG(key) + cur_len, parent_script, parent_script_len);
+ cur_len += parent_script_len;
+ ZCG(key)[cur_len] = ':';
+ cur_len++;
+ }
+ memcpy(ZCG(key) + cur_len, include_path, include_path_len);
+ ZCG(key)[key_length] = '\0';
+ } else {
+ /* not use_cwd */
+ key_length = path_length;
+ if ((size_t)key_length >= sizeof(ZCG(key))) {
+ ZCG(key_len) = 0;
+ return NULL;
+ }
+ memcpy(ZCG(key), file_handle->filename, key_length + 1);
+ }
+
+ *key_len = ZCG(key_len) = key_length;
+ return ZCG(key);
+}
+
+static inline char *accel_make_persistent_key(zend_file_handle *file_handle, int *key_len TSRMLS_DC)
+{
+ return accel_make_persistent_key_ex(file_handle, strlen(file_handle->filename), key_len TSRMLS_CC);
+}
+
+int zend_accel_invalidate(const char *filename, int filename_len, zend_bool force TSRMLS_DC)
+{
+ char *realpath;
+ zend_persistent_script *persistent_script;
+
+ if (!ZCG(enabled) || !accel_startup_ok || !ZCSG(accelerator_enabled) || accelerator_shm_read_lock(TSRMLS_C) != SUCCESS) {
+ return FAILURE;
+ }
+
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+ realpath = accel_php_resolve_path(filename, filename_len, ZCG(include_path) TSRMLS_CC);
+#else
+ realpath = accelerator_orig_zend_resolve_path(filename, filename_len TSRMLS_CC);
+#endif
+
+ if (!realpath) {
+ return FAILURE;
+ }
+
+ persistent_script = zend_accel_hash_find(&ZCSG(hash), realpath, strlen(realpath) + 1);
+ if (persistent_script && !persistent_script->corrupted) {
+ zend_file_handle file_handle;
+
+ file_handle.type = ZEND_HANDLE_FILENAME;
+ file_handle.filename = realpath;
+ file_handle.opened_path = realpath;
+
+ if (force ||
+ !ZCG(accel_directives).validate_timestamps ||
+ do_validate_timestamps(persistent_script, &file_handle TSRMLS_CC) == FAILURE) {
+ SHM_UNPROTECT();
+ zend_shared_alloc_lock(TSRMLS_C);
+ if (!persistent_script->corrupted) {
+ persistent_script->corrupted = 1;
+ persistent_script->timestamp = 0;
+ ZSMMG(wasted_shared_memory) += persistent_script->dynamic_members.memory_consumption;
+ if (ZSMMG(memory_exhausted)) {
+ zend_accel_restart_reason reason =
+ zend_accel_hash_is_full(&ZCSG(hash)) ? ACCEL_RESTART_HASH : ACCEL_RESTART_OOM;
+ zend_accel_schedule_restart_if_necessary(reason TSRMLS_CC);
+ }
+ }
+ zend_shared_alloc_unlock(TSRMLS_C);
+ SHM_PROTECT();
+ }
+ }
+
+ accelerator_shm_read_unlock(TSRMLS_C);
+ efree(realpath);
+
+ return SUCCESS;
+}
+
+/* Adds another key for existing cached script */
+static void zend_accel_add_key(char *key, unsigned int key_length, zend_accel_hash_entry *bucket TSRMLS_DC)
+{
+ if (!zend_accel_hash_find(&ZCSG(hash), key, key_length + 1)) {
+ if (zend_accel_hash_is_full(&ZCSG(hash))) {
+ zend_accel_error(ACCEL_LOG_DEBUG, "No more entries in hash table!");
+ ZSMMG(memory_exhausted) = 1;
+ zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_HASH TSRMLS_CC);
+ } else {
+ char *new_key = zend_shared_alloc(key_length + 1);
+ if (new_key) {
+ memcpy(new_key, key, key_length + 1);
+ if (zend_accel_hash_update(&ZCSG(hash), new_key, key_length + 1, 1, bucket)) {
+ zend_accel_error(ACCEL_LOG_INFO, "Added key '%s'", new_key);
+ }
+ } else {
+ zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_OOM TSRMLS_CC);
+ }
+ }
+ }
+}
+
+static zend_persistent_script *cache_script_in_shared_memory(zend_persistent_script *new_persistent_script, char *key, unsigned int key_length, int *from_shared_memory TSRMLS_DC)
+{
+ zend_accel_hash_entry *bucket;
+ uint memory_used;
+
+ /* Check if script may be stored in shared memory */
+ if (!zend_accel_script_persistable(new_persistent_script)) {
+ return new_persistent_script;
+ }
+
+ if (!compact_persistent_script(new_persistent_script)) {
+ return new_persistent_script;
+ }
+
+ /* exclusive lock */
+ zend_shared_alloc_lock(TSRMLS_C);
+
+ if (zend_accel_hash_is_full(&ZCSG(hash))) {
+ zend_accel_error(ACCEL_LOG_DEBUG, "No more entries in hash table!");
+ ZSMMG(memory_exhausted) = 1;
+ zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_HASH TSRMLS_CC);
+ zend_shared_alloc_unlock(TSRMLS_C);
+ return new_persistent_script;
+ }
+
+ /* Check if we still need to put the file into the cache (may be it was
+ * already stored by another process. This final check is done under
+ * exclusive lock) */
+ bucket = zend_accel_hash_find_entry(&ZCSG(hash), new_persistent_script->full_path, new_persistent_script->full_path_len + 1);
+ if (bucket) {
+ zend_persistent_script *existing_persistent_script = (zend_persistent_script *)bucket->data;
+
+ if (!existing_persistent_script->corrupted) {
+ if (!ZCG(accel_directives).revalidate_path &&
+ (!ZCG(accel_directives).validate_timestamps ||
+ (new_persistent_script->timestamp == existing_persistent_script->timestamp))) {
+ zend_accel_add_key(key, key_length, bucket TSRMLS_CC);
+ }
+ zend_shared_alloc_unlock(TSRMLS_C);
+ return new_persistent_script;
+ }
+ }
+
+ /* Calculate the required memory size */
+ memory_used = zend_accel_script_persist_calc(new_persistent_script, key, key_length TSRMLS_CC);
+
+ /* Allocate shared memory */
+ ZCG(mem) = zend_shared_alloc(memory_used);
+ if (!ZCG(mem)) {
+ zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_OOM TSRMLS_CC);
+ zend_shared_alloc_unlock(TSRMLS_C);
+ return new_persistent_script;
+ }
+
+ /* cleanup after calculation */
+ new_persistent_script->mem = ZCG(mem);
+ new_persistent_script->size = memory_used;
+
+ /* Copy into shared memory */
+ new_persistent_script = zend_accel_script_persist(new_persistent_script, &key, key_length TSRMLS_CC);
+
+ /* Consistency check */
+ if ((char*)new_persistent_script->mem + new_persistent_script->size != (char*)ZCG(mem)) {
+ zend_accel_error(
+ ((char*)new_persistent_script->mem + new_persistent_script->size < (char*)ZCG(mem)) ? ACCEL_LOG_ERROR : ACCEL_LOG_WARNING,
+ "Internal error: wrong size calculation: %s start=0x%08x, end=0x%08x, real=0x%08x\n",
+ new_persistent_script->full_path,
+ new_persistent_script->mem,
+ (char *)new_persistent_script->mem + new_persistent_script->size,
+ ZCG(mem));
+ }
+
+ new_persistent_script->dynamic_members.checksum = zend_accel_script_checksum(new_persistent_script);
+
+ /* store script structure in the hash table */
+ bucket = zend_accel_hash_update(&ZCSG(hash), new_persistent_script->full_path, new_persistent_script->full_path_len + 1, 0, new_persistent_script);
+ if (bucket) {
+ zend_accel_error(ACCEL_LOG_INFO, "Cached script '%s'", new_persistent_script->full_path);
+ if (!ZCG(accel_directives).revalidate_path &&
+ /* key may contain non-persistent PHAR aliases (see issues #115 and #149) */
+ memcmp(key, "phar://", sizeof("phar://") - 1) != 0 &&
+ (new_persistent_script->full_path_len != key_length ||
+ memcmp(new_persistent_script->full_path, key, key_length) != 0)) {
+ /* link key to the same persistent script in hash table */
+ if (zend_accel_hash_update(&ZCSG(hash), key, key_length + 1, 1, bucket)) {
+ zend_accel_error(ACCEL_LOG_INFO, "Added key '%s'", key);
+ } else {
+ zend_accel_error(ACCEL_LOG_DEBUG, "No more entries in hash table!");
+ ZSMMG(memory_exhausted) = 1;
+ zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_HASH TSRMLS_CC);
+ }
+ }
+ }
+
+ new_persistent_script->dynamic_members.memory_consumption = ZEND_ALIGNED_SIZE(new_persistent_script->size);
+
+ zend_shared_alloc_unlock(TSRMLS_C);
+
+ *from_shared_memory = 1;
+ return new_persistent_script;
+}
+
+static const struct jit_auto_global_info
+{
+ const char *name;
+ size_t len;
+} jit_auto_globals_info[] = {
+ { "_SERVER", sizeof("_SERVER")},
+ { "_ENV", sizeof("_ENV")},
+ { "_REQUEST", sizeof("_REQUEST")},
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ { "GLOBALS", sizeof("GLOBALS")},
+#endif
+};
+
+static int zend_accel_get_auto_globals(TSRMLS_D)
+{
+ int i, ag_size = (sizeof(jit_auto_globals_info) / sizeof(jit_auto_globals_info[0]));
+ int n = 1;
+ int mask = 0;
+
+ for (i = 0; i < ag_size ; i++) {
+ if (zend_hash_exists(&EG(symbol_table), jit_auto_globals_info[i].name, jit_auto_globals_info[i].len)) {
+ mask |= n;
+ }
+ n += n;
+ }
+ return mask;
+}
+
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+static int zend_accel_get_auto_globals_no_jit(TSRMLS_D)
+{
+ if (zend_hash_exists(&EG(symbol_table), jit_auto_globals_info[3].name, jit_auto_globals_info[3].len)) {
+ return 8;
+ }
+ return 0;
+}
+#endif
+
+static void zend_accel_set_auto_globals(int mask TSRMLS_DC)
+{
+ int i, ag_size = (sizeof(jit_auto_globals_info) / sizeof(jit_auto_globals_info[0]));
+ int n = 1;
+
+ for (i = 0; i < ag_size ; i++) {
+ if (mask & n) {
+ zend_is_auto_global(jit_auto_globals_info[i].name, jit_auto_globals_info[i].len - 1 TSRMLS_CC);
+ }
+ n += n;
+ }
+}
+
+static zend_persistent_script *compile_and_cache_file(zend_file_handle *file_handle, int type, char *key, unsigned int key_length, zend_op_array **op_array_p, int *from_shared_memory TSRMLS_DC)
+{
+ zend_persistent_script *new_persistent_script;
+ zend_op_array *orig_active_op_array;
+ HashTable *orig_function_table, *orig_class_table;
+ zval *orig_user_error_handler;
+ zend_op_array *op_array;
+ int do_bailout = 0;
+ accel_time_t timestamp = 0;
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+ zend_uint orig_compiler_options = 0;
+#endif
+
+ /* Try to open file */
+ if (file_handle->type == ZEND_HANDLE_FILENAME) {
+ if (accelerator_orig_zend_stream_open_function(file_handle->filename, file_handle TSRMLS_CC) == SUCCESS) {
+ /* key may be changed by zend_stream_open_function() */
+ if (key == ZCG(key)) {
+ key_length = ZCG(key_len);
+ }
+ } else {
+ *op_array_p = NULL;
+ if (type == ZEND_REQUIRE) {
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+ zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, file_handle->filename);
+#else
+ zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, file_handle->filename TSRMLS_CC);
+#endif
+ zend_bailout();
+ } else {
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+ zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, file_handle->filename);
+#else
+ zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, file_handle->filename TSRMLS_CC);
+#endif
+ }
+ return NULL;
+ }
+ }
+
+ /* check blacklist right after ensuring that file was opened */
+ if (file_handle->opened_path && zend_accel_blacklist_is_blacklisted(&accel_blacklist, file_handle->opened_path)) {
+ ZCSG(blacklist_misses)++;
+ *op_array_p = accelerator_orig_compile_file(file_handle, type TSRMLS_CC);
+ return NULL;
+ }
+
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+ if (file_handle->type == ZEND_HANDLE_STREAM &&
+ (!strstr(file_handle->filename, ".phar") ||
+ strstr(file_handle->filename, "://"))) {
+ char *buf;
+ size_t size;
+
+ /* Stream callbacks needs to be called in context of original
+ * function and class tables (see: https://bugs.php.net/bug.php?id=64353)
+ */
+ if (zend_stream_fixup(file_handle, &buf, &size TSRMLS_CC) == FAILURE) {
+ *op_array_p = NULL;
+ return NULL;
+ }
+ }
+#endif
+
+ if (ZCG(accel_directives).validate_timestamps ||
+ ZCG(accel_directives).file_update_protection ||
+ ZCG(accel_directives).max_file_size > 0) {
+ size_t size = 0;
+
+ /* Obtain the file timestamps, *before* actually compiling them,
+ * otherwise we have a race-condition.
+ */
+ timestamp = zend_get_file_handle_timestamp(file_handle, ZCG(accel_directives).max_file_size > 0 ? &size : NULL TSRMLS_CC);
+
+ /* If we can't obtain a timestamp (that means file is possibly socket)
+ * we won't cache it
+ */
+ if (timestamp == 0) {
+ *op_array_p = accelerator_orig_compile_file(file_handle, type TSRMLS_CC);
+ return NULL;
+ }
+
+ /* check if file is too new (may be it's not written completely yet) */
+ if (ZCG(accel_directives).file_update_protection &&
+ (ZCG(request_time) - ZCG(accel_directives).file_update_protection < timestamp)) {
+ *op_array_p = accelerator_orig_compile_file(file_handle, type TSRMLS_CC);
+ return NULL;
+ }
+
+ if (ZCG(accel_directives).max_file_size > 0 && size > (size_t)ZCG(accel_directives).max_file_size) {
+ ZCSG(blacklist_misses)++;
+ *op_array_p = accelerator_orig_compile_file(file_handle, type TSRMLS_CC);
+ return NULL;
+ }
+ }
+
+ new_persistent_script = create_persistent_script();
+
+ /* Save the original values for the op_array, function table and class table */
+ orig_active_op_array = CG(active_op_array);
+ orig_function_table = CG(function_table);
+ orig_class_table = CG(class_table);
+ orig_user_error_handler = EG(user_error_handler);
+
+ /* Override them with ours */
+ CG(function_table) = &ZCG(function_table);
+ EG(class_table) = CG(class_table) = &new_persistent_script->class_table;
+ EG(user_error_handler) = NULL;
+
+ zend_try {
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+ orig_compiler_options = CG(compiler_options);
+ CG(compiler_options) |= ZEND_COMPILE_HANDLE_OP_ARRAY;
+ CG(compiler_options) |= ZEND_COMPILE_IGNORE_INTERNAL_CLASSES;
+ CG(compiler_options) |= ZEND_COMPILE_DELAYED_BINDING;
+ CG(compiler_options) |= ZEND_COMPILE_NO_CONSTANT_SUBSTITUTION;
+#endif
+ op_array = *op_array_p = accelerator_orig_compile_file(file_handle, type TSRMLS_CC);
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+ CG(compiler_options) = orig_compiler_options;
+#endif
+ } zend_catch {
+ op_array = NULL;
+ do_bailout = 1;
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+ CG(compiler_options) = orig_compiler_options;
+#endif
+ } zend_end_try();
+
+ /* Restore originals */
+ CG(active_op_array) = orig_active_op_array;
+ CG(function_table) = orig_function_table;
+ EG(class_table) = CG(class_table) = orig_class_table;
+ EG(user_error_handler) = orig_user_error_handler;
+
+ if (!op_array) {
+ /* compilation failed */
+ free_persistent_script(new_persistent_script, 1);
+ zend_accel_free_user_functions(&ZCG(function_table) TSRMLS_CC);
+ if (do_bailout) {
+ zend_bailout();
+ }
+ return NULL;
+ }
+
+ /* Build the persistent_script structure.
+ Here we aren't sure we would store it, but we will need it
+ further anyway.
+ */
+ zend_accel_move_user_functions(&ZCG(function_table), &new_persistent_script->function_table TSRMLS_CC);
+ new_persistent_script->main_op_array = *op_array;
+
+ efree(op_array); /* we have valid persistent_script, so it's safe to free op_array */
+
+ /* Fill in the ping_auto_globals_mask for the new script. If jit for auto globals is enabled we
+ will have to ping the used auto global variables before execution */
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ if (PG(auto_globals_jit)) {
+ new_persistent_script->ping_auto_globals_mask = zend_accel_get_auto_globals(TSRMLS_C);
+ } else {
+ new_persistent_script->ping_auto_globals_mask = zend_accel_get_auto_globals_no_jit(TSRMLS_C);
+ }
+#else
+ if ((PG(auto_globals_jit) && !PG(register_globals) && !PG(register_long_arrays))) {
+ new_persistent_script->ping_auto_globals_mask = zend_accel_get_auto_globals(TSRMLS_C);
+ }
+#endif
+
+ if (ZCG(accel_directives).validate_timestamps) {
+ /* Obtain the file timestamps, *before* actually compiling them,
+ * otherwise we have a race-condition.
+ */
+ new_persistent_script->timestamp = timestamp;
+ new_persistent_script->dynamic_members.revalidate = ZCSG(revalidate_at);
+ }
+
+ if (file_handle->opened_path) {
+ new_persistent_script->full_path_len = strlen(file_handle->opened_path);
+ new_persistent_script->full_path = estrndup(file_handle->opened_path, new_persistent_script->full_path_len);
+ } else {
+ new_persistent_script->full_path_len = strlen(file_handle->filename);
+ new_persistent_script->full_path = estrndup(file_handle->filename, new_persistent_script->full_path_len);
+ }
+ new_persistent_script->hash_value = zend_hash_func(new_persistent_script->full_path, new_persistent_script->full_path_len + 1);
+
+ /* Now persistent_script structure is ready in process memory */
+ return cache_script_in_shared_memory(new_persistent_script, key, key_length, from_shared_memory TSRMLS_CC);
+}
+
+/* zend_compile() replacement */
+zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC)
+{
+ zend_persistent_script *persistent_script = NULL;
+ char *key = NULL;
+ int key_length;
+ int from_shared_memory; /* if the script we've got is stored in SHM */
+
+ if (!file_handle->filename ||
+ !ZCG(enabled) || !accel_startup_ok ||
+ (!ZCG(counted) && !ZCSG(accelerator_enabled)) ||
+ CG(interactive) ||
+ (ZCSG(restart_in_progress) && accel_restart_is_active(TSRMLS_C)) ||
+ (is_stream_path(file_handle->filename) &&
+ !is_cacheable_stream_path(file_handle->filename))) {
+ /* The Accelerator is disabled, act as if without the Accelerator */
+ return accelerator_orig_compile_file(file_handle, type TSRMLS_CC);
+ }
+
+ /* Make sure we only increase the currently running processes semaphore
+ * once each execution (this function can be called more than once on
+ * each execution)
+ */
+ if (!ZCG(counted)) {
+ ZCG(counted) = 1;
+ accel_activate_add(TSRMLS_C);
+ }
+
+ /* In case this callback is called from include_once, require_once or it's
+ * a main FastCGI request, the key must be already calculated, and cached
+ * persistent script already found */
+ if ((EG(opline_ptr) == NULL &&
+ ZCG(cache_opline) == NULL &&
+ file_handle->filename == SG(request_info).path_translated &&
+ ZCG(cache_persistent_script)) ||
+ (EG(opline_ptr) && *EG(opline_ptr) &&
+ *EG(opline_ptr) == ZCG(cache_opline) &&
+ (*EG(opline_ptr))->opcode == ZEND_INCLUDE_OR_EVAL &&
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ ((*EG(opline_ptr))->extended_value == ZEND_INCLUDE_ONCE ||
+ (*EG(opline_ptr))->extended_value == ZEND_REQUIRE_ONCE))) {
+#else
+ ((*EG(opline_ptr))->op2.u.constant.value.lval == ZEND_INCLUDE_ONCE ||
+ (*EG(opline_ptr))->op2.u.constant.value.lval == ZEND_REQUIRE_ONCE))) {
+#endif
+ if (!ZCG(key_len)) {
+ return accelerator_orig_compile_file(file_handle, type TSRMLS_CC);
+ }
+ /* persistent script was already found by overridden open() or
+ * resolve_path() callbacks */
+ persistent_script = ZCG(cache_persistent_script);
+ key = ZCG(key);
+ key_length = ZCG(key_len);
+ } else {
+ /* try to find cached script by key */
+ if ((key = accel_make_persistent_key(file_handle, &key_length TSRMLS_CC)) == NULL) {
+ return accelerator_orig_compile_file(file_handle, type TSRMLS_CC);
+ }
+ persistent_script = zend_accel_hash_find(&ZCSG(hash), key, key_length + 1);
+ if (!persistent_script) {
+ /* try to find cached script by full real path */
+ zend_accel_hash_entry *bucket;
+
+ /* open file to resolve the path */
+ if (file_handle->type == ZEND_HANDLE_FILENAME &&
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+ accelerator_orig_zend_stream_open_function(file_handle->filename, file_handle TSRMLS_CC) == FAILURE) {
+#else
+ zend_stream_open(file_handle->filename, file_handle TSRMLS_CC) == FAILURE) {
+#endif
+ if (type == ZEND_REQUIRE) {
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+ zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, file_handle->filename);
+#else
+ zend_message_dispatcher(ZMSG_FAILED_REQUIRE_FOPEN, file_handle->filename TSRMLS_CC);
+#endif
+ zend_bailout();
+ } else {
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+ zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, file_handle->filename);
+#else
+ zend_message_dispatcher(ZMSG_FAILED_INCLUDE_FOPEN, file_handle->filename TSRMLS_CC);
+#endif
+ }
+ return NULL;
+ }
+
+ if (file_handle->opened_path &&
+ (bucket = zend_accel_hash_find_entry(&ZCSG(hash), file_handle->opened_path, strlen(file_handle->opened_path) + 1)) != NULL) {
+
+ persistent_script = (zend_persistent_script *)bucket->data;
+ if (!ZCG(accel_directives).revalidate_path &&
+ !persistent_script->corrupted) {
+ SHM_UNPROTECT();
+ zend_shared_alloc_lock(TSRMLS_C);
+ zend_accel_add_key(key, key_length, bucket TSRMLS_CC);
+ zend_shared_alloc_unlock(TSRMLS_C);
+ SHM_PROTECT();
+ }
+ }
+ }
+ }
+
+ /* clear cache */
+ ZCG(cache_opline) = NULL;
+ ZCG(cache_persistent_script) = NULL;
+
+ if (persistent_script && persistent_script->corrupted) {
+ persistent_script = NULL;
+ }
+
+ SHM_UNPROTECT();
+
+ /* If script is found then validate_timestamps if option is enabled */
+ if (persistent_script && ZCG(accel_directives).validate_timestamps) {
+ if (validate_timestamp_and_record(persistent_script, file_handle TSRMLS_CC) == FAILURE) {
+ zend_shared_alloc_lock(TSRMLS_C);
+ if (!persistent_script->corrupted) {
+ persistent_script->corrupted = 1;
+ persistent_script->timestamp = 0;
+ ZSMMG(wasted_shared_memory) += persistent_script->dynamic_members.memory_consumption;
+ if (ZSMMG(memory_exhausted)) {
+ zend_accel_restart_reason reason =
+ zend_accel_hash_is_full(&ZCSG(hash)) ? ACCEL_RESTART_HASH : ACCEL_RESTART_OOM;
+ zend_accel_schedule_restart_if_necessary(reason TSRMLS_CC);
+ }
+ }
+ zend_shared_alloc_unlock(TSRMLS_C);
+ persistent_script = NULL;
+ }
+ }
+
+ /* if turned on - check the compiled script ADLER32 checksum */
+ if (persistent_script && ZCG(accel_directives).consistency_checks
+ && persistent_script->dynamic_members.hits % ZCG(accel_directives).consistency_checks == 0) {
+
+ unsigned int checksum = zend_accel_script_checksum(persistent_script);
+ if (checksum != persistent_script->dynamic_members.checksum ) {
+ /* The checksum is wrong */
+ zend_accel_error(ACCEL_LOG_INFO, "Checksum failed for '%s': expected=0x%0.8X, found=0x%0.8X",
+ persistent_script->full_path, persistent_script->dynamic_members.checksum, checksum);
+ zend_shared_alloc_lock(TSRMLS_C);
+ if (!persistent_script->corrupted) {
+ persistent_script->corrupted = 1;
+ persistent_script->timestamp = 0;
+ ZSMMG(wasted_shared_memory) += persistent_script->dynamic_members.memory_consumption;
+ if (ZSMMG(memory_exhausted)) {
+ zend_accel_restart_reason reason =
+ zend_accel_hash_is_full(&ZCSG(hash)) ? ACCEL_RESTART_HASH : ACCEL_RESTART_OOM;
+ zend_accel_schedule_restart_if_necessary(reason TSRMLS_CC);
+ }
+ }
+ zend_shared_alloc_unlock(TSRMLS_C);
+ persistent_script = NULL;
+ }
+ }
+
+ /* If script was not found or invalidated by validate_timestamps */
+ if (!persistent_script) {
+ zend_op_array *op_array;
+
+ /* Cache miss.. */
+ ZCSG(misses)++;
+
+ /* No memory left. Behave like without the Accelerator */
+ if (ZSMMG(memory_exhausted) || ZCSG(restart_pending)) {
+ SHM_PROTECT();
+ return accelerator_orig_compile_file(file_handle, type TSRMLS_CC);
+ }
+
+ /* Try and cache the script and assume that it is returned from_shared_memory.
+ * If it isn't compile_and_cache_file() changes the flag to 0
+ */
+ from_shared_memory = 0;
+ persistent_script = compile_and_cache_file(file_handle, type, key, key_length, &op_array, &from_shared_memory TSRMLS_CC);
+
+ /* Caching is disabled, returning op_array;
+ * or something went wrong during compilation, returning NULL
+ */
+ if (!persistent_script) {
+ SHM_PROTECT();
+ return op_array;
+ }
+ } else {
+
+#if !ZEND_WIN32
+ ZCSG(hits)++; /* TBFixed: may lose one hit */
+ persistent_script->dynamic_members.hits++; /* see above */
+#else
+ InterlockedIncrement(&ZCSG(hits));
+ InterlockedIncrement(&persistent_script->dynamic_members.hits);
+#endif
+
+ /* see bug #15471 (old BTS) */
+ if (persistent_script->full_path) {
+ if (!EG(opline_ptr) || !*EG(opline_ptr) ||
+ (*EG(opline_ptr))->opcode != ZEND_INCLUDE_OR_EVAL ||
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ ((*EG(opline_ptr))->extended_value != ZEND_INCLUDE_ONCE &&
+ (*EG(opline_ptr))->extended_value != ZEND_REQUIRE_ONCE)) {
+#else
+ ((*EG(opline_ptr))->op2.u.constant.value.lval != ZEND_INCLUDE_ONCE &&
+ (*EG(opline_ptr))->op2.u.constant.value.lval != ZEND_REQUIRE_ONCE)) {
+#endif
+ void *dummy = (void *) 1;
+
+ if (zend_hash_quick_add(&EG(included_files), persistent_script->full_path, persistent_script->full_path_len + 1, persistent_script->hash_value, &dummy, sizeof(void *), NULL) == SUCCESS) {
+ /* ext/phar has to load phar's metadata into memory */
+ if (strstr(persistent_script->full_path, ".phar") && !strstr(persistent_script->full_path, "://")) {
+ php_stream_statbuf ssb;
+ char *fname = emalloc(sizeof("phar://") + persistent_script->full_path_len);
+
+ memcpy(fname, "phar://", sizeof("phar://") - 1);
+ memcpy(fname + sizeof("phar://") - 1, persistent_script->full_path, persistent_script->full_path_len + 1);
+ php_stream_stat_path(fname, &ssb);
+ efree(fname);
+ }
+ }
+ }
+ }
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+ zend_file_handle_dtor(file_handle);
+#else
+ zend_file_handle_dtor(file_handle TSRMLS_CC);
+#endif
+ from_shared_memory = 1;
+ }
+
+ persistent_script->dynamic_members.last_used = ZCG(request_time);
+
+ SHM_PROTECT();
+
+ /* Fetch jit auto globals used in the script before execution */
+ if (persistent_script->ping_auto_globals_mask) {
+ zend_accel_set_auto_globals(persistent_script->ping_auto_globals_mask TSRMLS_CC);
+ }
+
+ return zend_accel_load_script(persistent_script, from_shared_memory TSRMLS_CC);
+}
+
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+
+/* Taken from php-5.2.5 because early versions don't have correct version */
+static char *accel_tsrm_realpath(const char *path, int path_len TSRMLS_DC)
+{
+ cwd_state new_state;
+ char *real_path;
+ char *cwd;
+ int cwd_len;
+
+ /* realpath("") returns CWD */
+ if (!*path) {
+ new_state.cwd = (char*)malloc(1);
+ if (!new_state.cwd) {
+ zend_accel_error(ACCEL_LOG_ERROR, "malloc() failed");
+ return NULL;
+ }
+ new_state.cwd[0] = '\0';
+ new_state.cwd_length = 0;
+ if ((cwd = accel_getcwd(&cwd_len TSRMLS_CC)) != NULL) {
+ path = cwd;
+ }
+ } else if (!IS_ABSOLUTE_PATH(path, path_len) &&
+ (cwd = accel_getcwd(&cwd_len TSRMLS_CC)) != NULL) {
+ new_state.cwd = zend_strndup(cwd, cwd_len);
+ if (!new_state.cwd) {
+ zend_accel_error(ACCEL_LOG_ERROR, "malloc() failed");
+ return NULL;
+ }
+ new_state.cwd_length = cwd_len;
+ } else {
+ new_state.cwd = (char*)malloc(1);
+ if (!new_state.cwd) {
+ zend_accel_error(ACCEL_LOG_ERROR, "malloc() failed");
+ return NULL;
+ }
+ new_state.cwd[0] = '\0';
+ new_state.cwd_length = 0;
+ }
+
+#ifndef CWD_REALPATH
+# define CWD_REALPATH 2
+#endif
+ if (virtual_file_ex(&new_state, path, NULL, CWD_REALPATH)) {
+ free(new_state.cwd);
+ return NULL;
+ }
+
+ real_path = emalloc(new_state.cwd_length + 1);
+ memcpy(real_path, new_state.cwd, new_state.cwd_length + 1);
+ free(new_state.cwd);
+ return real_path;
+}
+
+static char *accel_php_resolve_path(const char *filename, int filename_length, const char *path TSRMLS_DC)
+{
+ char *resolved_path;
+ char trypath[MAXPATHLEN];
+ const char *ptr, *end;
+ int len;
+
+ if (!filename) {
+ return NULL;
+ }
+
+ if (*filename == '.' ||
+ IS_ABSOLUTE_PATH(filename, filename_length) ||
+ !path ||
+ !*path) {
+ return accel_tsrm_realpath(filename, filename_length TSRMLS_CC);
+ }
+
+ ptr = path;
+ while (*ptr) {
+ for (end = ptr; *end && *end != DEFAULT_DIR_SEPARATOR; end++);
+ len = end - ptr;
+ if (*end) end++;
+ if (len + 1 + filename_length + 1 >= MAXPATHLEN) {
+ ptr = end;
+ continue;
+ }
+ memcpy(trypath, ptr, len);
+ trypath[len] = '/';
+ memcpy(trypath + len + 1, filename, filename_length + 1);
+ ptr = end;
+ if ((resolved_path = accel_tsrm_realpath(trypath, len + 1 + filename_length TSRMLS_CC)) != NULL) {
+ return resolved_path;
+ }
+ } /* end provided path */
+
+ /* check in calling scripts' current working directory as a fall back case
+ */
+ if (EG(in_execution)) {
+ char *exec_fname = zend_get_executed_filename(TSRMLS_C);
+ int exec_fname_length = strlen(exec_fname);
+
+ while ((--exec_fname_length >= 0) && !IS_SLASH(exec_fname[exec_fname_length]));
+ if (exec_fname && exec_fname[0] != '[' &&
+ exec_fname_length > 0 &&
+ exec_fname_length + 1 + filename_length + 1 < MAXPATHLEN) {
+ memcpy(trypath, exec_fname, exec_fname_length + 1);
+ memcpy(trypath + exec_fname_length + 1, filename, filename_length + 1);
+ return accel_tsrm_realpath(trypath, exec_fname_length + 1 + filename_length TSRMLS_CC);
+ }
+ }
+
+ return NULL;
+}
+
+/* zend_stream_open_function() replacement for PHP 5.2 */
+static int persistent_stream_open_function(const char *filename, zend_file_handle *handle TSRMLS_DC)
+{
+ if (ZCG(enabled) && accel_startup_ok &&
+ (ZCG(counted) || ZCSG(accelerator_enabled)) &&
+ !CG(interactive) &&
+ !ZCSG(restart_in_progress)) {
+
+ if (EG(opline_ptr) && *EG(opline_ptr)) {
+ zend_op *opline = *EG(opline_ptr);
+
+ if (opline->opcode == ZEND_INCLUDE_OR_EVAL &&
+ (opline->op2.u.constant.value.lval == ZEND_INCLUDE_ONCE ||
+ opline->op2.u.constant.value.lval == ZEND_REQUIRE_ONCE)) {
+ /* we are in include_once */
+ char *key = NULL;
+ int key_length;
+ char *resolved_path;
+ zend_accel_hash_entry *bucket;
+ zend_persistent_script *persistent_script;
+ int filename_len;
+
+ if (opline->op1.op_type == IS_CONST) {
+ filename_len = Z_STRLEN(opline->op1.u.constant);
+ } else {
+ filename_len = strlen(filename);
+ }
+ handle->filename = (char*)filename;
+ handle->free_filename = 0;
+ handle->opened_path = NULL;
+
+ /* Check if requested file already cached (by full name) */
+ if (IS_ABSOLUTE_PATH(filename, filename_len) &&
+ (persistent_script = zend_accel_hash_find(&ZCSG(hash), (char*)filename, filename_len + 1)) != NULL &&
+ !persistent_script->corrupted) {
+
+ handle->opened_path = estrndup(persistent_script->full_path, persistent_script->full_path_len);
+ handle->type = ZEND_HANDLE_FILENAME;
+ memcpy(ZCG(key), persistent_script->full_path, persistent_script->full_path_len + 1);
+ ZCG(key_len) = persistent_script->full_path_len;
+ ZCG(cache_opline) = opline;
+ ZCG(cache_persistent_script) = persistent_script;
+ return SUCCESS;
+ }
+
+ /* Check if requested file already cached (by key) */
+ key = accel_make_persistent_key_ex(handle, filename_len, &key_length TSRMLS_CC);
+ if (!ZCG(accel_directives).revalidate_path &&
+ key &&
+ (persistent_script = zend_accel_hash_find(&ZCSG(hash), key, key_length + 1)) != NULL &&
+ !persistent_script->corrupted) {
+
+ handle->opened_path = estrndup(persistent_script->full_path, persistent_script->full_path_len);
+ handle->type = ZEND_HANDLE_FILENAME;
+ ZCG(cache_opline) = opline;
+ ZCG(cache_persistent_script) = persistent_script;
+ return SUCCESS;
+ }
+
+ /* find the full real path */
+ resolved_path = accel_php_resolve_path(filename, filename_len, ZCG(include_path) TSRMLS_CC);
+
+ /* Check if requested file already cached (by real name) */
+ if (resolved_path &&
+ (bucket = zend_accel_hash_find_entry(&ZCSG(hash), resolved_path, strlen(resolved_path) + 1)) != NULL) {
+
+ persistent_script = (zend_persistent_script *)bucket->data;
+ if (persistent_script && !persistent_script->corrupted) {
+ handle->opened_path = resolved_path;
+ handle->type = ZEND_HANDLE_FILENAME;
+ if (key && !ZCG(accel_directives).revalidate_path) {
+ /* add another "key" for the same bucket */
+ SHM_UNPROTECT();
+ zend_shared_alloc_lock(TSRMLS_C);
+ zend_accel_add_key(key, key_length, bucket TSRMLS_CC);
+ zend_shared_alloc_unlock(TSRMLS_C);
+ SHM_PROTECT();
+ }
+ ZCG(cache_opline) = opline;
+ ZCG(cache_persistent_script) = persistent_script;
+ return SUCCESS;
+ }
+ }
+ if (resolved_path) {
+ efree(resolved_path);
+ }
+ }
+ }
+ }
+ ZCG(cache_opline) = NULL;
+ ZCG(cache_persistent_script) = NULL;
+ return accelerator_orig_zend_stream_open_function(filename, handle TSRMLS_CC);
+}
+
+#else
+
+/* zend_stream_open_function() replacement for PHP 5.3 and above */
+static int persistent_stream_open_function(const char *filename, zend_file_handle *handle TSRMLS_DC)
+{
+ if (ZCG(enabled) && accel_startup_ok &&
+ (ZCG(counted) || ZCSG(accelerator_enabled)) &&
+ !CG(interactive) &&
+ !ZCSG(restart_in_progress)) {
+
+ /* check if callback is called from include_once or it's a main request */
+ if ((!EG(opline_ptr) &&
+ filename == SG(request_info).path_translated) ||
+ (EG(opline_ptr) &&
+ *EG(opline_ptr) &&
+ (*EG(opline_ptr))->opcode == ZEND_INCLUDE_OR_EVAL &&
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ ((*EG(opline_ptr))->extended_value == ZEND_INCLUDE_ONCE ||
+ (*EG(opline_ptr))->extended_value == ZEND_REQUIRE_ONCE))) {
+#else
+ ((*EG(opline_ptr))->op2.u.constant.value.lval == ZEND_INCLUDE_ONCE ||
+ (*EG(opline_ptr))->op2.u.constant.value.lval == ZEND_REQUIRE_ONCE))) {
+#endif
+
+ /* we are in include_once or FastCGI request */
+ zend_persistent_script *persistent_script;
+
+ handle->filename = (char*)filename;
+ handle->free_filename = 0;
+
+ /* check if cached script was already found by resolve_path() */
+ if ((EG(opline_ptr) == NULL &&
+ ZCG(cache_opline) == NULL &&
+ ZCG(cache_persistent_script) != NULL) ||
+ (EG(opline_ptr) &&
+ (ZCG(cache_opline) == *EG(opline_ptr)))) {
+ persistent_script = ZCG(cache_persistent_script);
+ handle->opened_path = estrndup(persistent_script->full_path, persistent_script->full_path_len);
+ handle->type = ZEND_HANDLE_FILENAME;
+ return SUCCESS;
+#if 0
+ } else {
+ /* FIXME: It looks like this part is not needed any more */
+ int filename_len = strlen(filename);
+
+ if ((IS_ABSOLUTE_PATH(filename, filename_len) ||
+ is_stream_path(filename)) &&
+ (persistent_script = zend_accel_hash_find(&ZCSG(hash), (char*)filename, filename_len + 1)) != NULL &&
+ !persistent_script->corrupted) {
+
+ handle->opened_path = estrndup(persistent_script->full_path, persistent_script->full_path_len);
+ handle->type = ZEND_HANDLE_FILENAME;
+ memcpy(ZCG(key), persistent_script->full_path, persistent_script->full_path_len + 1);
+ ZCG(key_len) = persistent_script->full_path_len;
+ ZCG(cache_opline) = EG(opline_ptr) ? *EG(opline_ptr) : NULL;
+ ZCG(cache_persistent_script) = EG(opline_ptr) ? persistent_script : NULL;
+ return SUCCESS;
+ }
+#endif
+ }
+ }
+ }
+ ZCG(cache_opline) = NULL;
+ ZCG(cache_persistent_script) = NULL;
+ return accelerator_orig_zend_stream_open_function(filename, handle TSRMLS_CC);
+}
+
+/* zend_resolve_path() replacement for PHP 5.3 and above */
+static char* persistent_zend_resolve_path(const char *filename, int filename_len TSRMLS_DC)
+{
+ if (ZCG(enabled) && accel_startup_ok &&
+ (ZCG(counted) || ZCSG(accelerator_enabled)) &&
+ !CG(interactive) &&
+ !ZCSG(restart_in_progress)) {
+
+ /* check if callback is called from include_once or it's a main request */
+ if ((!EG(opline_ptr) &&
+ filename == SG(request_info).path_translated) ||
+ (EG(opline_ptr) &&
+ *EG(opline_ptr) &&
+ (*EG(opline_ptr))->opcode == ZEND_INCLUDE_OR_EVAL &&
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ ((*EG(opline_ptr))->extended_value == ZEND_INCLUDE_ONCE ||
+ (*EG(opline_ptr))->extended_value == ZEND_REQUIRE_ONCE))) {
+#else
+ ((*EG(opline_ptr))->op2.u.constant.value.lval == ZEND_INCLUDE_ONCE ||
+ (*EG(opline_ptr))->op2.u.constant.value.lval == ZEND_REQUIRE_ONCE))) {
+#endif
+
+ /* we are in include_once or FastCGI request */
+ zend_file_handle handle;
+ char *key = NULL;
+ int key_length;
+ char *resolved_path;
+ zend_accel_hash_entry *bucket;
+ zend_persistent_script *persistent_script;
+
+ /* Check if requested file already cached (by full name) */
+ if ((IS_ABSOLUTE_PATH(filename, filename_len) ||
+ is_stream_path(filename)) &&
+ (bucket = zend_accel_hash_find_entry(&ZCSG(hash), (char*)filename, filename_len + 1)) != NULL) {
+ persistent_script = (zend_persistent_script *)bucket->data;
+ if (persistent_script && !persistent_script->corrupted) {
+ memcpy(ZCG(key), persistent_script->full_path, persistent_script->full_path_len + 1);
+ ZCG(key_len) = persistent_script->full_path_len;
+ ZCG(cache_opline) = EG(opline_ptr) ? *EG(opline_ptr) : NULL;
+ ZCG(cache_persistent_script) = persistent_script;
+ return estrndup(persistent_script->full_path, persistent_script->full_path_len);
+ }
+ }
+
+ /* Check if requested file already cached (by key) */
+ handle.filename = (char*)filename;
+ handle.free_filename = 0;
+ handle.opened_path = NULL;
+ key = accel_make_persistent_key_ex(&handle, filename_len, &key_length TSRMLS_CC);
+ if (!ZCG(accel_directives).revalidate_path &&
+ key &&
+ (persistent_script = zend_accel_hash_find(&ZCSG(hash), key, key_length + 1)) != NULL &&
+ !persistent_script->corrupted) {
+
+ /* we have persistent script */
+ ZCG(cache_opline) = EG(opline_ptr) ? *EG(opline_ptr) : NULL;
+ ZCG(cache_persistent_script) = persistent_script;
+ return estrndup(persistent_script->full_path, persistent_script->full_path_len);
+ }
+
+ /* find the full real path */
+ resolved_path = accelerator_orig_zend_resolve_path(filename, filename_len TSRMLS_CC);
+
+ /* Check if requested file already cached (by real path) */
+ if (resolved_path &&
+ (bucket = zend_accel_hash_find_entry(&ZCSG(hash), resolved_path, strlen(resolved_path) + 1)) != NULL) {
+ persistent_script = (zend_persistent_script *)bucket->data;
+
+ if (persistent_script && !persistent_script->corrupted) {
+ if (key && !ZCG(accel_directives).revalidate_path) {
+ /* add another "key" for the same bucket */
+ SHM_UNPROTECT();
+ zend_shared_alloc_lock(TSRMLS_C);
+ zend_accel_add_key(key, key_length, bucket TSRMLS_CC);
+ zend_shared_alloc_unlock(TSRMLS_C);
+ SHM_PROTECT();
+ }
+ ZCG(cache_opline) = (EG(opline_ptr) && key) ? *EG(opline_ptr): NULL;
+ ZCG(cache_persistent_script) = key ? persistent_script : NULL;
+ return resolved_path;
+ }
+ }
+ ZCG(cache_opline) = NULL;
+ ZCG(cache_persistent_script) = NULL;
+ return resolved_path;
+ }
+ }
+ ZCG(cache_opline) = NULL;
+ ZCG(cache_persistent_script) = NULL;
+ return accelerator_orig_zend_resolve_path(filename, filename_len TSRMLS_CC);
+}
+
+#endif
+
+static void zend_reset_cache_vars(TSRMLS_D)
+{
+ ZSMMG(memory_exhausted) = 0;
+ ZCSG(hits) = 0;
+ ZCSG(misses) = 0;
+ ZCSG(blacklist_misses) = 0;
+ ZSMMG(wasted_shared_memory) = 0;
+ ZCSG(restart_pending) = 0;
+ ZCSG(force_restart_time) = 0;
+}
+
+static void accel_activate(void)
+{
+ TSRMLS_FETCH();
+
+ if (!ZCG(enabled) || !accel_startup_ok) {
+ return;
+ }
+
+ SHM_UNPROTECT();
+ /* PHP-5.4 and above return "double", but we use 1 sec precision */
+ ZCG(request_time) = (time_t)sapi_get_request_time(TSRMLS_C);
+ ZCG(cache_opline) = NULL;
+ ZCG(cache_persistent_script) = NULL;
+ ZCG(include_path_check) = !ZCG(include_path_key);
+
+ if (ZCG(counted)) {
+#ifdef ZTS
+ zend_accel_error(ACCEL_LOG_WARNING, "Stuck count for thread id %d", tsrm_thread_id());
+#else
+ zend_accel_error(ACCEL_LOG_WARNING, "Stuck count for pid %d", getpid());
+#endif
+ accel_unlock_all(TSRMLS_C);
+ ZCG(counted) = 0;
+ }
+
+ if (ZCSG(restart_pending)) {
+ zend_shared_alloc_lock(TSRMLS_C);
+ if (ZCSG(restart_pending) != 0) { /* check again, to ensure that the cache wasn't already cleaned by another process */
+ if (accel_is_inactive(TSRMLS_C) == SUCCESS) {
+ zend_accel_error(ACCEL_LOG_DEBUG, "Restarting!");
+ ZCSG(restart_pending) = 0;
+ switch ZCSG(restart_reason) {
+ case ACCEL_RESTART_OOM:
+ ZCSG(oom_restarts)++;
+ break;
+ case ACCEL_RESTART_HASH:
+ ZCSG(hash_restarts)++;
+ break;
+ case ACCEL_RESTART_USER:
+ ZCSG(manual_restarts)++;
+ break;
+ }
+ accel_restart_enter(TSRMLS_C);
+
+ zend_reset_cache_vars(TSRMLS_C);
+ zend_accel_hash_clean(&ZCSG(hash));
+
+ /* include_paths keeps only the first path */
+ if (ZCSG(include_paths).num_entries > 1) {
+ ZCSG(include_paths).num_entries = 1;
+ ZCSG(include_paths).num_direct_entries = 1;
+ memset(ZCSG(include_paths).hash_table, 0, sizeof(zend_accel_hash_entry*) * ZCSG(include_paths).max_num_entries);
+ ZCSG(include_paths).hash_table[zend_inline_hash_func(ZCSG(include_paths).hash_entries[0].key, ZCSG(include_paths).hash_entries[0].key_length) % ZCSG(include_paths).max_num_entries] = &ZCSG(include_paths).hash_entries[0];
+ }
+
+#if (ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO) && !defined(ZTS)
+ if (ZCG(accel_directives).interned_strings_buffer) {
+ accel_interned_strings_restore_state(TSRMLS_C);
+ }
+#endif
+
+ zend_shared_alloc_restore_state();
+ ZCSG(accelerator_enabled) = ZCSG(cache_status_before_restart);
+ ZCSG(last_restart_time) = ZCG(request_time);
+ accel_restart_leave(TSRMLS_C);
+ }
+ }
+ zend_shared_alloc_unlock(TSRMLS_C);
+ }
+
+ /* check if ZCG(function_table) wasn't somehow polluted on the way */
+ if (ZCG(internal_functions_count) != zend_hash_num_elements(&ZCG(function_table))) {
+ zend_accel_error(ACCEL_LOG_WARNING, "Internal functions count changed - was %d, now %d", ZCG(internal_functions_count), zend_hash_num_elements(&ZCG(function_table)));
+ }
+
+ if (ZCG(accel_directives).validate_timestamps) {
+ time_t now = ZCG(request_time);
+ if (now > ZCSG(revalidate_at) + (time_t)ZCG(accel_directives).revalidate_freq) {
+ ZCSG(revalidate_at) = now;
+ }
+ }
+
+ ZCG(cwd) = NULL;
+
+ SHM_PROTECT();
+}
+
+#if !ZEND_DEBUG
+
+/* Fast Request Shutdown
+ * =====================
+ * Zend Memory Manager frees memory by its own. We don't have to free each
+ * allocated block separately, but we like to call all the destructors and
+ * callbacks in exactly the same order.
+ */
+
+static void accel_fast_hash_destroy(HashTable *ht)
+{
+ Bucket *p = ht->pListHead;
+
+ while (p != NULL) {
+ ht->pDestructor(p->pData);
+ p = p->pListNext;
+ }
+}
+
+static void accel_fast_zval_ptr_dtor(zval **zval_ptr)
+{
+ zval *zvalue = *zval_ptr;
+
+ if (Z_DELREF_P(zvalue) == 0) {
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+ switch (Z_TYPE_P(zvalue) & IS_CONSTANT_TYPE_MASK) {
+#else
+ switch (Z_TYPE_P(zvalue) & ~IS_CONSTANT_INDEX) {
+#endif
+ case IS_ARRAY:
+ case IS_CONSTANT_ARRAY: {
+ TSRMLS_FETCH();
+
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+ GC_REMOVE_ZVAL_FROM_BUFFER(zvalue);
+#endif
+ if (zvalue->value.ht && (zvalue->value.ht != &EG(symbol_table))) {
+ /* break possible cycles */
+ Z_TYPE_P(zvalue) = IS_NULL;
+ zvalue->value.ht->pDestructor = (dtor_func_t)accel_fast_zval_ptr_dtor;
+ accel_fast_hash_destroy(zvalue->value.ht);
+ }
+ }
+ break;
+ case IS_OBJECT:
+ {
+ TSRMLS_FETCH();
+
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+ GC_REMOVE_ZVAL_FROM_BUFFER(zvalue);
+#endif
+ Z_OBJ_HT_P(zvalue)->del_ref(zvalue TSRMLS_CC);
+ }
+ break;
+ case IS_RESOURCE:
+ {
+ TSRMLS_FETCH();
+
+ /* destroy resource */
+ zend_list_delete(zvalue->value.lval);
+ }
+ break;
+ case IS_LONG:
+ case IS_DOUBLE:
+ case IS_BOOL:
+ case IS_NULL:
+ case IS_STRING:
+ case IS_CONSTANT:
+ default:
+ return;
+ break;
+ }
+ }
+}
+
+static int accel_clean_non_persistent_function(zend_function *function TSRMLS_DC)
+{
+ if (function->type == ZEND_INTERNAL_FUNCTION) {
+ return ZEND_HASH_APPLY_STOP;
+ } else {
+ if (function->op_array.static_variables) {
+ function->op_array.static_variables->pDestructor = (dtor_func_t)accel_fast_zval_ptr_dtor;
+ accel_fast_hash_destroy(function->op_array.static_variables);
+ function->op_array.static_variables = NULL;
+ }
+ return (--(*function->op_array.refcount) <= 0) ?
+ ZEND_HASH_APPLY_REMOVE :
+ ZEND_HASH_APPLY_KEEP;
+ }
+}
+
+static int accel_cleanup_function_data(zend_function *function TSRMLS_DC)
+{
+ if (function->type == ZEND_USER_FUNCTION) {
+ if (function->op_array.static_variables) {
+ function->op_array.static_variables->pDestructor = (dtor_func_t)accel_fast_zval_ptr_dtor;
+ accel_fast_hash_destroy(function->op_array.static_variables);
+ function->op_array.static_variables = NULL;
+ }
+ }
+ return 0;
+}
+
+static int accel_clean_non_persistent_class(zend_class_entry **pce TSRMLS_DC)
+{
+ zend_class_entry *ce = *pce;
+
+ if (ce->type == ZEND_INTERNAL_CLASS) {
+ return ZEND_HASH_APPLY_STOP;
+ } else {
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ if (ce->ce_flags & ZEND_HAS_STATIC_IN_METHODS) {
+ zend_hash_apply(&ce->function_table, (apply_func_t) accel_cleanup_function_data TSRMLS_CC);
+ }
+ if (ce->static_members_table) {
+ int i;
+
+ for (i = 0; i < ce->default_static_members_count; i++) {
+ if (ce->static_members_table[i]) {
+ accel_fast_zval_ptr_dtor(&ce->static_members_table[i]);
+ ce->static_members_table[i] = NULL;
+ }
+ }
+ ce->static_members_table = NULL;
+ }
+#else
+ zend_hash_apply(&ce->function_table, (apply_func_t) accel_cleanup_function_data TSRMLS_CC);
+ if (ce->static_members) {
+ ce->static_members->pDestructor = (dtor_func_t)accel_fast_zval_ptr_dtor;
+ accel_fast_hash_destroy(ce->static_members);
+ ce->static_members = NULL;
+ }
+#endif
+ return ZEND_HASH_APPLY_REMOVE;
+ }
+}
+
+static int accel_clean_non_persistent_constant(zend_constant *c TSRMLS_DC)
+{
+ if (c->flags & CONST_PERSISTENT) {
+ return ZEND_HASH_APPLY_STOP;
+ } else {
+ interned_free(c->name);
+ return ZEND_HASH_APPLY_REMOVE;
+ }
+}
+
+static void zend_accel_fast_shutdown(TSRMLS_D)
+{
+ if (EG(full_tables_cleanup)) {
+ EG(symbol_table).pDestructor = (dtor_func_t)accel_fast_zval_ptr_dtor;
+ } else {
+ dtor_func_t old_destructor;
+
+ if (EG(objects_store).top > 1 || zend_hash_num_elements(&EG(regular_list)) > 0) {
+ /* We don't have to destroy all zvals if they cannot call any destructors */
+
+ old_destructor = EG(symbol_table).pDestructor;
+ EG(symbol_table).pDestructor = (dtor_func_t)accel_fast_zval_ptr_dtor;
+ zend_try {
+ zend_hash_graceful_reverse_destroy(&EG(symbol_table));
+ } zend_end_try();
+ EG(symbol_table).pDestructor = old_destructor;
+ }
+ zend_hash_init(&EG(symbol_table), 0, NULL, NULL, 0);
+ old_destructor = EG(function_table)->pDestructor;
+ EG(function_table)->pDestructor = NULL;
+ zend_hash_reverse_apply(EG(function_table), (apply_func_t) accel_clean_non_persistent_function TSRMLS_CC);
+ EG(function_table)->pDestructor = old_destructor;
+ old_destructor = EG(class_table)->pDestructor;
+ EG(class_table)->pDestructor = NULL;
+ zend_hash_reverse_apply(EG(class_table), (apply_func_t) accel_clean_non_persistent_class TSRMLS_CC);
+ EG(class_table)->pDestructor = old_destructor;
+ old_destructor = EG(zend_constants)->pDestructor;
+ EG(zend_constants)->pDestructor = NULL;
+ zend_hash_reverse_apply(EG(zend_constants), (apply_func_t) accel_clean_non_persistent_constant TSRMLS_CC);
+ EG(zend_constants)->pDestructor = old_destructor;
+ }
+ CG(unclean_shutdown) = 1;
+}
+#endif
+
+static void accel_deactivate(void)
+{
+ /* ensure that we restore function_table and class_table
+ * In general, they're restored by persistent_compile_file(), but in case
+ * the script is aborted abnormally, they may become messed up.
+ */
+ TSRMLS_FETCH();
+
+ if (!ZCG(enabled) || !accel_startup_ok) {
+ return;
+ }
+
+ zend_shared_alloc_safe_unlock(TSRMLS_C); /* be sure we didn't leave cache locked */
+ accel_unlock_all(TSRMLS_C);
+ ZCG(counted) = 0;
+
+#if !ZEND_DEBUG
+ if (ZCG(accel_directives).fast_shutdown) {
+ zend_accel_fast_shutdown(TSRMLS_C);
+ }
+#endif
+
+ if (ZCG(cwd)) {
+ efree(ZCG(cwd));
+ ZCG(cwd) = NULL;
+ }
+
+}
+
+static int accelerator_remove_cb(zend_extension *element1, zend_extension *element2)
+{
+ (void)element2; /* keep the compiler happy */
+
+ if (!strcmp(element1->name, ACCELERATOR_PRODUCT_NAME )) {
+ element1->startup = NULL;
+#if 0
+ /* We have to call shutdown callback it to free TS resources */
+ element1->shutdown = NULL;
+#endif
+ element1->activate = NULL;
+ element1->deactivate = NULL;
+ element1->op_array_handler = NULL;
+
+#ifdef __DEBUG_MESSAGES__
+ fprintf(stderr, ACCELERATOR_PRODUCT_NAME " is disabled: %s\n", (zps_failure_reason ? zps_failure_reason : "unknown error"));
+ fflush(stderr);
+#endif
+ }
+
+ return 0;
+}
+
+static void zps_startup_failure(char *reason, char *api_reason, int (*cb)(zend_extension *, zend_extension *) TSRMLS_DC)
+{
+ accel_startup_ok = 0;
+ zps_failure_reason = reason;
+ zps_api_failure_reason = api_reason?api_reason:reason;
+ zend_llist_del_element(&zend_extensions, NULL, (int (*)(void *, void *))cb);
+}
+
+static inline int accel_find_sapi(TSRMLS_D)
+{
+ static const char *supported_sapis[] = {
+ "apache",
+ "fastcgi",
+ "cli-server",
+ "cgi-fcgi",
+ "fpm-fcgi",
+ "isapi",
+ "apache2filter",
+ "apache2handler",
+ "litespeed",
+ NULL
+ };
+ const char **sapi_name;
+
+ if (sapi_module.name) {
+ for (sapi_name = supported_sapis; *sapi_name; sapi_name++) {
+ if (strcmp(sapi_module.name, *sapi_name) == 0) {
+ return SUCCESS;
+ }
+ }
+ if (ZCG(accel_directives).enable_cli &&
+ strcmp(sapi_module.name, "cli") == 0) {
+ return SUCCESS;
+ }
+ }
+
+ return FAILURE;
+}
+
+static int zend_accel_init_shm(TSRMLS_D)
+{
+ zend_shared_alloc_lock(TSRMLS_C);
+
+ accel_shared_globals = zend_shared_alloc(sizeof(zend_accel_shared_globals));
+ if (!accel_shared_globals) {
+ zend_accel_error(ACCEL_LOG_FATAL, "Insufficient shared memory!");
+ return FAILURE;
+ }
+ ZSMMG(app_shared_globals) = accel_shared_globals;
+
+ zend_accel_hash_init(&ZCSG(hash), ZCG(accel_directives).max_accelerated_files);
+ zend_accel_hash_init(&ZCSG(include_paths), 32);
+
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+
+ ZCSG(interned_strings_start) = ZCSG(interned_strings_end) = NULL;
+# ifndef ZTS
+ zend_hash_init(&ZCSG(interned_strings), (ZCG(accel_directives).interned_strings_buffer * 1024 * 1024) / (sizeof(Bucket) + sizeof(Bucket*) + 8 /* average string length */), NULL, NULL, 1);
+ if (ZCG(accel_directives).interned_strings_buffer) {
+ ZCSG(interned_strings).nTableMask = ZCSG(interned_strings).nTableSize - 1;
+ ZCSG(interned_strings).arBuckets = zend_shared_alloc(ZCSG(interned_strings).nTableSize * sizeof(Bucket *));
+ ZCSG(interned_strings_start) = zend_shared_alloc((ZCG(accel_directives).interned_strings_buffer * 1024 * 1024));
+ if (!ZCSG(interned_strings).arBuckets || !ZCSG(interned_strings_start)) {
+ zend_accel_error(ACCEL_LOG_FATAL, ACCELERATOR_PRODUCT_NAME " cannot allocate buffer for interned strings");
+ return FAILURE;
+ }
+ ZCSG(interned_strings_end) = ZCSG(interned_strings_start) + (ZCG(accel_directives).interned_strings_buffer * 1024 * 1024);
+ ZCSG(interned_strings_top) = ZCSG(interned_strings_start);
+
+ orig_interned_strings_start = CG(interned_strings_start);
+ orig_interned_strings_end = CG(interned_strings_end);
+ CG(interned_strings_start) = ZCSG(interned_strings_start);
+ CG(interned_strings_end) = ZCSG(interned_strings_end);
+ }
+# endif
+
+ orig_new_interned_string = zend_new_interned_string;
+ orig_interned_strings_snapshot = zend_interned_strings_snapshot;
+ orig_interned_strings_restore = zend_interned_strings_restore;
+ zend_new_interned_string = accel_new_interned_string_for_php;
+ zend_interned_strings_snapshot = accel_interned_strings_snapshot_for_php;
+ zend_interned_strings_restore = accel_interned_strings_restore_for_php;
+
+# ifndef ZTS
+ if (ZCG(accel_directives).interned_strings_buffer) {
+ accel_use_shm_interned_strings(TSRMLS_C);
+ accel_interned_strings_save_state(TSRMLS_C);
+ }
+# endif
+
+#endif
+
+ zend_reset_cache_vars(TSRMLS_C);
+
+ ZCSG(oom_restarts) = 0;
+ ZCSG(hash_restarts) = 0;
+ ZCSG(manual_restarts) = 0;
+
+ ZCSG(accelerator_enabled) = 1;
+ ZCSG(start_time) = zend_accel_get_time();
+ ZCSG(last_restart_time) = 0;
+ ZCSG(restart_in_progress) = 0;
+
+ zend_shared_alloc_unlock(TSRMLS_C);
+
+ return SUCCESS;
+}
+
+static void accel_globals_ctor(zend_accel_globals *accel_globals TSRMLS_DC)
+{
+ memset(accel_globals, 0, sizeof(zend_accel_globals));
+ zend_hash_init(&accel_globals->function_table, zend_hash_num_elements(CG(function_table)), NULL, ZEND_FUNCTION_DTOR, 1);
+ zend_accel_copy_internal_functions(TSRMLS_C);
+}
+
+static void accel_globals_dtor(zend_accel_globals *accel_globals TSRMLS_DC)
+{
+ accel_globals->function_table.pDestructor = NULL;
+ zend_hash_destroy(&accel_globals->function_table);
+}
+
+static int accel_startup(zend_extension *extension)
+{
+ zend_function *func;
+ zend_ini_entry *ini_entry;
+ TSRMLS_FETCH();
+
+#ifdef ZTS
+ accel_globals_id = ts_allocate_id(&accel_globals_id, sizeof(zend_accel_globals), (ts_allocate_ctor) accel_globals_ctor, (ts_allocate_dtor) accel_globals_dtor);
+#else
+ accel_globals_ctor(&accel_globals);
+#endif
+
+#ifdef ZEND_WIN32
+ _setmaxstdio(2048); /* The default configuration is limited to 512 stdio files */
+#endif
+
+ if (start_accel_module() == FAILURE) {
+ accel_startup_ok = 0;
+ zend_error(E_WARNING, ACCELERATOR_PRODUCT_NAME ": module registration failed!");
+ return FAILURE;
+ }
+
+ /* no supported SAPI found - disable acceleration and stop initialization */
+ if (accel_find_sapi(TSRMLS_C) == FAILURE) {
+ accel_startup_ok = 0;
+ if (!ZCG(accel_directives).enable_cli &&
+ strcmp(sapi_module.name, "cli") == 0) {
+ zps_startup_failure("Opcode Caching is disabled for CLI", NULL, accelerator_remove_cb TSRMLS_CC);
+ } else {
+ zps_startup_failure("Opcode Caching is only supported in Apache, ISAPI, FPM, FastCGI and LiteSpeed SAPIs", NULL, accelerator_remove_cb TSRMLS_CC);
+ }
+ return SUCCESS;
+ }
+
+ if (ZCG(enabled) == 0) {
+ return SUCCESS ;
+ }
+/********************************************/
+/* End of non-SHM dependent initializations */
+/********************************************/
+ switch (zend_shared_alloc_startup(ZCG(accel_directives).memory_consumption)) {
+ case ALLOC_SUCCESS:
+ if (zend_accel_init_shm(TSRMLS_C) == FAILURE) {
+ accel_startup_ok = 0;
+ return FAILURE;
+ }
+ break;
+ case ALLOC_FAILURE:
+ accel_startup_ok = 0;
+ zend_accel_error(ACCEL_LOG_FATAL, "Failure to initialize shared memory structures - probably not enough shared memory.");
+ return SUCCESS;
+ case SUCCESSFULLY_REATTACHED:
+ accel_shared_globals = (zend_accel_shared_globals *) ZSMMG(app_shared_globals);
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ zend_shared_alloc_lock(TSRMLS_C);
+ orig_interned_strings_start = CG(interned_strings_start);
+ orig_interned_strings_end = CG(interned_strings_end);
+ orig_new_interned_string = zend_new_interned_string;
+ orig_interned_strings_snapshot = zend_interned_strings_snapshot;
+ orig_interned_strings_restore = zend_interned_strings_restore;
+
+ CG(interned_strings_start) = ZCSG(interned_strings_start);
+ CG(interned_strings_end) = ZCSG(interned_strings_end);
+ zend_new_interned_string = accel_new_interned_string_for_php;
+ zend_interned_strings_snapshot = accel_interned_strings_snapshot_for_php;
+ zend_interned_strings_restore = accel_interned_strings_restore_for_php;
+
+# ifndef ZTS
+ accel_use_shm_interned_strings(TSRMLS_C);
+# endif
+
+ zend_shared_alloc_unlock(TSRMLS_C);
+#endif
+
+ break;
+ case FAILED_REATTACHED:
+ accel_startup_ok = 0;
+ zend_accel_error(ACCEL_LOG_FATAL, "Failure to initialize shared memory structures - can not reattach to exiting shared memory.");
+ return SUCCESS;
+ break;
+ }
+
+ /* from this point further, shared memory is supposed to be OK */
+
+ /* Override compiler */
+ accelerator_orig_compile_file = zend_compile_file;
+ zend_compile_file = persistent_compile_file;
+
+ /* Override stream opener function (to eliminate open() call caused by
+ * include/require statements ) */
+ accelerator_orig_zend_stream_open_function = zend_stream_open_function;
+ zend_stream_open_function = persistent_stream_open_function;
+
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+ /* Override path resolver function (to eliminate stat() calls caused by
+ * include_once/require_once statements */
+ accelerator_orig_zend_resolve_path = zend_resolve_path;
+ zend_resolve_path = persistent_zend_resolve_path;
+#endif
+
+ if (ZCG(accel_directives).validate_timestamps) {
+ ZCSG(revalidate_at) = zend_accel_get_time() + ZCG(accel_directives).revalidate_freq;
+ }
+
+ /* Override chdir() function */
+ if (zend_hash_find(CG(function_table), "chdir", sizeof("chdir"), (void**)&func) == SUCCESS &&
+ func->type == ZEND_INTERNAL_FUNCTION) {
+ orig_chdir = func->internal_function.handler;
+ func->internal_function.handler = ZEND_FN(accel_chdir);
+ }
+ ZCG(cwd) = NULL;
+
+ /* Override "include_path" modifier callback */
+ if (zend_hash_find(EG(ini_directives), "include_path", sizeof("include_path"), (void **) &ini_entry) == SUCCESS) {
+ ZCG(include_path) = INI_STR("include_path");
+ ZCG(include_path_key) = NULL;
+ if (ZCG(include_path) && *ZCG(include_path)) {
+ ZCG(include_path_len) = strlen(ZCG(include_path));
+ ZCG(include_path_key) = zend_accel_hash_find(&ZCSG(include_paths), ZCG(include_path), ZCG(include_path_len) + 1);
+ if (!ZCG(include_path_key) &&
+ !zend_accel_hash_is_full(&ZCSG(include_paths))) {
+ char *key;
+
+ zend_shared_alloc_lock(TSRMLS_C);
+ key = zend_shared_alloc(ZCG(include_path_len) + 2);
+ if (key) {
+ memcpy(key, ZCG(include_path), ZCG(include_path_len) + 1);
+ key[ZCG(include_path_len) + 1] = 'A' + ZCSG(include_paths).num_entries;
+ ZCG(include_path_key) = key + ZCG(include_path_len) + 1;
+ zend_accel_hash_update(&ZCSG(include_paths), key, ZCG(include_path_len) + 1, 0, ZCG(include_path_key));
+ } else {
+ zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_OOM TSRMLS_CC);
+ }
+ zend_shared_alloc_unlock(TSRMLS_C);
+ }
+ } else {
+ ZCG(include_path) = "";
+ ZCG(include_path_len) = 0;
+ }
+ orig_include_path_on_modify = ini_entry->on_modify;
+ ini_entry->on_modify = accel_include_path_on_modify;
+ }
+
+ zend_shared_alloc_lock(TSRMLS_C);
+ zend_shared_alloc_save_state();
+ zend_shared_alloc_unlock(TSRMLS_C);
+
+ SHM_PROTECT();
+
+ accel_startup_ok = 1;
+
+ /* Override file_exists(), is_file() and is_readable() */
+ zend_accel_override_file_functions(TSRMLS_C);
+
+ /* Load black list */
+ accel_blacklist.entries = NULL;
+ if (ZCG(enabled) && accel_startup_ok &&
+ ZCG(accel_directives).user_blacklist_filename &&
+ *ZCG(accel_directives.user_blacklist_filename)) {
+ zend_accel_blacklist_init(&accel_blacklist);
+ zend_accel_blacklist_load(&accel_blacklist, ZCG(accel_directives.user_blacklist_filename));
+ }
+
+#if 0
+ /* FIXME: We probably don't need it here */
+ zend_accel_copy_internal_functions(TSRMLS_C);
+#endif
+
+ return SUCCESS;
+}
+
+static void accel_free_ts_resources()
+{
+#ifndef ZTS
+ accel_globals_dtor(&accel_globals);
+#else
+ ts_free_id(accel_globals_id);
+#endif
+}
+
+void accel_shutdown(TSRMLS_D)
+{
+ zend_ini_entry *ini_entry;
+
+ zend_accel_blacklist_shutdown(&accel_blacklist);
+
+ if (!ZCG(enabled) || !accel_startup_ok) {
+ accel_free_ts_resources();
+ return;
+ }
+
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ if (ZCG(accel_directives).interned_strings_buffer) {
+# ifndef ZTS
+ zend_hash_clean(CG(function_table));
+ zend_hash_clean(CG(class_table));
+ zend_hash_clean(EG(zend_constants));
+# endif
+ CG(interned_strings_start) = orig_interned_strings_start;
+ CG(interned_strings_end) = orig_interned_strings_end;
+ }
+ zend_new_interned_string = orig_new_interned_string;
+ zend_interned_strings_snapshot = orig_interned_strings_snapshot;
+ zend_interned_strings_restore = orig_interned_strings_restore;
+#endif
+
+ accel_free_ts_resources();
+ zend_shared_alloc_shutdown();
+ zend_compile_file = accelerator_orig_compile_file;
+
+ if (zend_hash_find(EG(ini_directives), "include_path", sizeof("include_path"), (void **) &ini_entry) == SUCCESS) {
+ ini_entry->on_modify = orig_include_path_on_modify;
+ }
+}
+
+void zend_accel_schedule_restart(zend_accel_restart_reason reason TSRMLS_DC)
+{
+ if (ZCSG(restart_pending)) {
+ /* don't schedule twice */
+ return;
+ }
+ zend_accel_error(ACCEL_LOG_DEBUG, "Restart Scheduled!");
+
+ SHM_UNPROTECT();
+ ZCSG(restart_pending) = 1;
+ ZCSG(restart_reason) = reason;
+ ZCSG(cache_status_before_restart) = ZCSG(accelerator_enabled);
+ ZCSG(accelerator_enabled) = 0;
+
+ if (ZCG(accel_directives).force_restart_timeout) {
+ ZCSG(force_restart_time) = zend_accel_get_time() + ZCG(accel_directives).force_restart_timeout;
+ } else {
+ ZCSG(force_restart_time) = 0;
+ }
+ SHM_PROTECT();
+}
+
+/* this is needed because on WIN32 lock is not decreased unless ZCG(counted) is set */
+#ifdef ZEND_WIN32
+#define accel_deactivate_now() ZCG(counted) = 1; accel_deactivate_sub(TSRMLS_C)
+#else
+#define accel_deactivate_now() accel_deactivate_sub(TSRMLS_C)
+#endif
+
+/* ensures it is OK to read SHM
+ if it's not OK (restart in progress) returns FAILURE
+ if OK returns SUCCESS
+ MUST call accelerator_shm_read_unlock after done lock operations
+*/
+int accelerator_shm_read_lock(TSRMLS_D)
+{
+ if (ZCG(counted)) {
+ /* counted means we are holding read lock for SHM, so that nothing bad can happen */
+ return SUCCESS;
+ } else {
+ /* here accelerator is active but we do not hold SHM lock. This means restart was scheduled
+ or is in progress now */
+ accel_activate_add(TSRMLS_C); /* acquire usage lock */
+ /* Now if we weren't inside restart, restart would not begin until we remove usage lock */
+ if (ZCSG(restart_in_progress)) {
+ /* we already were inside restart this means it's not safe to touch shm */
+ accel_deactivate_now(); /* drop usage lock */
+ return FAILURE;
+ }
+ }
+ return SUCCESS;
+}
+
+/* must be called ONLY after SUCCESSFUL accelerator_shm_read_lock */
+void accelerator_shm_read_unlock(TSRMLS_D)
+{
+ if (!ZCG(counted)) {
+ /* counted is 0 - meaning we had to readlock manually, release readlock now */
+ accel_deactivate_now();
+ }
+}
+
+static void accel_op_array_handler(zend_op_array *op_array)
+{
+ TSRMLS_FETCH();
+
+ if (ZCG(enabled) &&
+ accel_startup_ok &&
+ ZCSG(accelerator_enabled) &&
+ !ZSMMG(memory_exhausted) &&
+ !ZCSG(restart_pending)) {
+ zend_optimizer(op_array TSRMLS_CC);
+ }
+}
+
+ZEND_EXT_API zend_extension zend_extension_entry = {
+ ACCELERATOR_PRODUCT_NAME, /* name */
+ ACCELERATOR_VERSION, /* version */
+ "Zend Technologies", /* author */
+ "http://www.zend.com/", /* URL */
+ "Copyright (c) 1999-2014", /* copyright */
+ accel_startup, /* startup */
+ NULL, /* shutdown */
+ accel_activate, /* per-script activation */
+ accel_deactivate, /* per-script deactivation */
+ NULL, /* message handler */
+ accel_op_array_handler, /* op_array handler */
+ NULL, /* extended statement handler */
+ NULL, /* extended fcall begin handler */
+ NULL, /* extended fcall end handler */
+ NULL, /* op_array ctor */
+ NULL, /* op_array dtor */
+ STANDARD_ZEND_EXTENSION_PROPERTIES
+};
diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h
new file mode 100644
index 0000000000..cfe376cf52
--- /dev/null
+++ b/ext/opcache/ZendAccelerator.h
@@ -0,0 +1,398 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2014 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: Andi Gutmans <andi@zend.com> |
+ | Zeev Suraski <zeev@zend.com> |
+ | Stanislav Malyshev <stas@zend.com> |
+ | Dmitry Stogov <dmitry@zend.com> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef ZEND_ACCELERATOR_H
+#define ZEND_ACCELERATOR_H
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define ACCELERATOR_PRODUCT_NAME "Zend OPcache"
+#define ACCELERATOR_VERSION "7.0.3-dev"
+/* 2 - added Profiler support, on 20010712 */
+/* 3 - added support for Optimizer's encoded-only-files mode */
+/* 4 - works with the new Optimizer, that supports the file format with licenses */
+/* 5 - API 4 didn't really work with the license-enabled file format. v5 does. */
+/* 6 - Monitor was removed from ZendPlatform.so, to a module of its own */
+/* 7 - Optimizer was embedded into Accelerator */
+/* 8 - Standalone Open Source Zend OPcache */
+#define ACCELERATOR_API_NO 8
+
+#if ZEND_WIN32
+# include "zend_config.w32.h"
+#else
+#include "zend_config.h"
+# include <sys/time.h>
+# include <sys/resource.h>
+#endif
+
+#if HAVE_UNISTD_H
+# include "unistd.h"
+#endif
+
+#include "zend_extensions.h"
+#include "zend_compile.h"
+
+#include "Optimizer/zend_optimizer.h"
+#include "zend_accelerator_hash.h"
+#include "zend_accelerator_debug.h"
+
+#ifndef PHPAPI
+# ifdef ZEND_WIN32
+# define PHPAPI __declspec(dllimport)
+# else
+# define PHPAPI
+# endif
+#endif
+
+#ifndef ZEND_EXT_API
+# if WIN32|WINNT
+# define ZEND_EXT_API __declspec(dllexport)
+# elif defined(__GNUC__) && __GNUC__ >= 4
+# define ZEND_EXT_API __attribute__ ((visibility("default")))
+# else
+# define ZEND_EXT_API
+# endif
+#endif
+
+#ifdef ZEND_WIN32
+# ifndef MAXPATHLEN
+# define MAXPATHLEN _MAX_PATH
+# endif
+# include <direct.h>
+#else
+# ifndef MAXPATHLEN
+# define MAXPATHLEN 4096
+# endif
+# include <sys/param.h>
+#endif
+
+#define PHP_5_0_X_API_NO 220040412
+#define PHP_5_1_X_API_NO 220051025
+#define PHP_5_2_X_API_NO 220060519
+#define PHP_5_3_X_API_NO 220090626
+#define PHP_5_4_X_API_NO 220100525
+#define PHP_5_5_X_API_NO 220121212
+
+/*** file locking ***/
+#ifndef ZEND_WIN32
+extern int lock_file;
+
+# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || (defined(__APPLE__) && defined(__MACH__)/* Darwin */) || defined(__OpenBSD__) || defined(__NetBSD__)
+# define FLOCK_STRUCTURE(name, type, whence, start, len) \
+ struct flock name = {start, len, -1, type, whence}
+# elif defined(__svr4__)
+# define FLOCK_STRUCTURE(name, type, whence, start, len) \
+ struct flock name = {type, whence, start, len}
+# elif defined(__linux__) || defined(__hpux) || defined(__GNU__)
+# define FLOCK_STRUCTURE(name, type, whence, start, len) \
+ struct flock name = {type, whence, start, len, 0}
+# elif defined(_AIX)
+# if defined(_LARGE_FILES) || defined(__64BIT__)
+# define FLOCK_STRUCTURE(name, type, whence, start, len) \
+ struct flock name = {type, whence, 0, 0, 0, start, len }
+# else
+# define FLOCK_STRUCTURE(name, type, whence, start, len) \
+ struct flock name = {type, whence, start, len}
+# endif
+# elif defined(HAVE_FLOCK_BSD)
+# define FLOCK_STRUCTURE(name, type, whence, start, len) \
+ struct flock name = {start, len, -1, type, whence}
+# elif defined(HAVE_FLOCK_LINUX)
+# define FLOCK_STRUCTURE(name, type, whence, start, len) \
+ struct flock name = {type, whence, start, len}
+# else
+# error "Don't know how to define struct flock"
+# endif
+#endif
+
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+ #define Z_REFCOUNT_P(pz) (pz)->refcount
+ #define Z_SET_REFCOUNT_P(pz, v) (pz)->refcount = (v)
+ #define Z_ADDREF_P(pz) ++((pz)->refcount)
+ #define Z_DELREF_P(pz) --((pz)->refcount)
+ #define Z_ISREF_P(pz) (pz)->is_ref
+ #define Z_SET_ISREF_P(pz) Z_SET_ISREF_TO_P(pz, 1)
+ #define Z_UNSET_ISREF_P(pz) Z_SET_ISREF_TO_P(pz, 0)
+ #define Z_SET_ISREF_TO_P(pz, isref) (pz)->is_ref = (isref)
+ #define PZ_REFCOUNT_P(pz) (pz)->refcount
+ #define PZ_SET_REFCOUNT_P(pz, v) (pz)->refcount = (v)
+ #define PZ_ADDREF_P(pz) ++((pz)->refcount)
+ #define PZ_DELREF_P(pz) --((pz)->refcount)
+ #define PZ_ISREF_P(pz) (pz)->is_ref
+ #define PZ_SET_ISREF_P(pz) Z_SET_ISREF_TO_P(pz, 1)
+ #define PZ_UNSET_ISREF_P(pz) Z_SET_ISREF_TO_P(pz, 0)
+ #define PZ_SET_ISREF_TO_P(pz, isref) (pz)->is_ref = (isref)
+#else
+ #define PZ_REFCOUNT_P(pz) (pz)->refcount__gc
+ #define PZ_SET_REFCOUNT_P(pz, v) (pz)->refcount__gc = (v)
+ #define PZ_ADDREF_P(pz) ++((pz)->refcount__gc)
+ #define PZ_DELREF_P(pz) --((pz)->refcount__gc)
+ #define PZ_ISREF_P(pz) (pz)->is_ref__gc
+ #define PZ_SET_ISREF_P(pz) Z_SET_ISREF_TO_P(pz, 1)
+ #define PZ_UNSET_ISREF_P(pz) Z_SET_ISREF_TO_P(pz, 0)
+ #define PZ_SET_ISREF_TO_P(pz, isref) (pz)->is_ref__gc = (isref)
+#endif
+
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+# ifdef ALLOCA_FLAG
+ #define DO_ALLOCA(x) do_alloca_with_limit(x, use_heap)
+ #define FREE_ALLOCA(x) free_alloca_with_limit(x, use_heap)
+# else
+ #define ALLOCA_FLAG(x)
+ #define DO_ALLOCA(x) do_alloca(x)
+ #define FREE_ALLOCA(x) free_alloca(x)
+# endif
+#else
+ #define DO_ALLOCA(x) do_alloca(x, use_heap)
+ #define FREE_ALLOCA(x) free_alloca(x, use_heap)
+#endif
+
+
+#if ZEND_WIN32
+typedef unsigned __int64 accel_time_t;
+#else
+typedef time_t accel_time_t;
+#endif
+
+typedef enum _zend_accel_restart_reason {
+ ACCEL_RESTART_OOM, /* restart because of out of memory */
+ ACCEL_RESTART_HASH, /* restart because of hash overflow */
+ ACCEL_RESTART_USER /* restart scheduled by opcache_reset() */
+} zend_accel_restart_reason;
+
+typedef struct _zend_persistent_script {
+ ulong hash_value;
+ char *full_path; /* full real path with resolved symlinks */
+ unsigned int full_path_len;
+ zend_op_array main_op_array;
+ HashTable function_table;
+ HashTable class_table;
+ long compiler_halt_offset; /* position of __HALT_COMPILER or -1 */
+ int ping_auto_globals_mask; /* which autoglobals are used by the script */
+ accel_time_t timestamp; /* the script modification time */
+ zend_bool corrupted;
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+ zend_uint early_binding; /* the linked list of delayed declarations */
+#endif
+
+ void *mem; /* shared memory area used by script structures */
+ size_t size; /* size of used shared memory */
+
+ /* All entries that shouldn't be counted in the ADLER32
+ * checksum must be declared in this struct
+ */
+ struct zend_persistent_script_dynamic_members {
+ time_t last_used;
+ ulong hits;
+ unsigned int memory_consumption;
+ unsigned int checksum;
+ time_t revalidate;
+ } dynamic_members;
+} zend_persistent_script;
+
+typedef struct _zend_accel_directives {
+ long memory_consumption;
+ long max_accelerated_files;
+ double max_wasted_percentage;
+ char *user_blacklist_filename;
+ long consistency_checks;
+ long force_restart_timeout;
+ zend_bool use_cwd;
+ zend_bool ignore_dups;
+ zend_bool validate_timestamps;
+ zend_bool revalidate_path;
+ zend_bool save_comments;
+ zend_bool load_comments;
+ zend_bool fast_shutdown;
+ zend_bool protect_memory;
+ zend_bool file_override_enabled;
+ zend_bool inherited_hack;
+ zend_bool enable_cli;
+ unsigned long revalidate_freq;
+ unsigned long file_update_protection;
+ char *error_log;
+#ifdef ZEND_WIN32
+ char *mmap_base;
+#endif
+ char *memory_model;
+ long log_verbosity_level;
+
+ long optimization_level;
+ long max_file_size;
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ long interned_strings_buffer;
+#endif
+ char *restrict_api;
+} zend_accel_directives;
+
+typedef struct _zend_accel_globals {
+ /* copy of CG(function_table) used for compilation scripts into cache */
+ /* initially it contains only internal functions */
+ HashTable function_table;
+ int internal_functions_count;
+ int counted; /* the process uses shared memory */
+ zend_bool enabled;
+ zend_bool locked; /* thread obtained exclusive lock */
+ HashTable bind_hash; /* prototype and zval lookup table */
+ zend_accel_directives accel_directives;
+ char *cwd; /* current working directory or NULL */
+ int cwd_len; /* "cwd" string length */
+ char *include_path_key; /* one letter key of current "include_path" */
+ char *include_path; /* current section of "include_path" directive */
+ int include_path_len; /* "include_path" string length */
+ int include_path_check;
+ time_t request_time;
+ /* preallocated shared-memory block to save current script */
+ void *mem;
+ /* cache to save hash lookup on the same INCLUDE opcode */
+ zend_op *cache_opline;
+ zend_persistent_script *cache_persistent_script;
+ /* preallocated buffer for keys */
+ int key_len;
+ char key[MAXPATHLEN * 8];
+} zend_accel_globals;
+
+typedef struct _zend_accel_shared_globals {
+ /* Cache Data Structures */
+ unsigned long hits;
+ unsigned long misses;
+ unsigned long blacklist_misses;
+ unsigned long oom_restarts; /* number of restarts because of out of memory */
+ unsigned long hash_restarts; /* number of restarts because of hash overflow */
+ unsigned long manual_restarts; /* number of restarts scheduled by opcache_reset() */
+ zend_accel_hash hash; /* hash table for cached scripts */
+ zend_accel_hash include_paths; /* used "include_path" values */
+
+ /* Directives & Maintenance */
+ time_t start_time;
+ time_t last_restart_time;
+ time_t force_restart_time;
+ zend_bool accelerator_enabled;
+ zend_bool restart_pending;
+ zend_accel_restart_reason restart_reason;
+ zend_bool cache_status_before_restart;
+#ifdef ZEND_WIN32
+ unsigned long mem_usage;
+ unsigned long restart_in;
+#endif
+ zend_bool restart_in_progress;
+ time_t revalidate_at;
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ /* Interned Strings Support */
+ char *interned_strings_start;
+ char *interned_strings_top;
+ char *interned_strings_end;
+ HashTable interned_strings;
+ struct {
+ Bucket **arBuckets;
+ Bucket *pListHead;
+ Bucket *pListTail;
+ char *top;
+ } interned_strings_saved_state;
+#endif
+} zend_accel_shared_globals;
+
+extern zend_bool accel_startup_ok;
+
+extern zend_accel_shared_globals *accel_shared_globals;
+#define ZCSG(element) (accel_shared_globals->element)
+
+#ifdef ZTS
+# define ZCG(v) TSRMG(accel_globals_id, zend_accel_globals *, v)
+extern int accel_globals_id;
+#else
+# define ZCG(v) (accel_globals.v)
+extern zend_accel_globals accel_globals;
+#endif
+
+extern char *zps_api_failure_reason;
+
+void accel_shutdown(TSRMLS_D);
+void zend_accel_schedule_restart(zend_accel_restart_reason reason TSRMLS_DC);
+void zend_accel_schedule_restart_if_necessary(zend_accel_restart_reason reason TSRMLS_DC);
+int validate_timestamp_and_record(zend_persistent_script *persistent_script, zend_file_handle *file_handle TSRMLS_DC);
+int zend_accel_invalidate(const char *filename, int filename_len, zend_bool force TSRMLS_DC);
+int accelerator_shm_read_lock(TSRMLS_D);
+void accelerator_shm_read_unlock(TSRMLS_D);
+
+char *accel_make_persistent_key_ex(zend_file_handle *file_handle, int path_length, int *key_len TSRMLS_DC);
+zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC);
+
+#if !defined(ZEND_DECLARE_INHERITED_CLASS_DELAYED)
+# define ZEND_DECLARE_INHERITED_CLASS_DELAYED 145
+#endif
+
+#define ZEND_DECLARE_INHERITED_CLASS_DELAYED_FLAG 0x80
+
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+
+const char *accel_new_interned_string(const char *arKey, int nKeyLength, int free_src TSRMLS_DC);
+
+# define interned_free(s) do { \
+ if (!IS_INTERNED(s)) { \
+ free(s); \
+ } \
+ } while (0)
+# define interned_efree(s) do { \
+ if (!IS_INTERNED(s)) { \
+ efree(s); \
+ } \
+ } while (0)
+# define interned_estrndup(s, n) \
+ (IS_INTERNED(s) ? (s) : estrndup(s, n))
+# define ZEND_RESULT_TYPE(opline) (opline)->result_type
+# define ZEND_RESULT(opline) (opline)->result
+# define ZEND_OP1_TYPE(opline) (opline)->op1_type
+# define ZEND_OP1(opline) (opline)->op1
+# define ZEND_OP1_CONST(opline) (*(opline)->op1.zv)
+# define ZEND_OP1_LITERAL(opline) (op_array)->literals[(opline)->op1.constant].constant
+# define ZEND_OP2_TYPE(opline) (opline)->op2_type
+# define ZEND_OP2(opline) (opline)->op2
+# define ZEND_OP2_CONST(opline) (*(opline)->op2.zv)
+# define ZEND_OP2_LITERAL(opline) (op_array)->literals[(opline)->op2.constant].constant
+# define ZEND_DONE_PASS_TWO(op_array) (((op_array)->fn_flags & ZEND_ACC_DONE_PASS_TWO) != 0)
+# define ZEND_CE_FILENAME(ce) (ce)->info.user.filename
+# define ZEND_CE_DOC_COMMENT(ce) (ce)->info.user.doc_comment
+# define ZEND_CE_DOC_COMMENT_LEN(ce) (ce)->info.user.doc_comment_len
+#else
+# define IS_INTERNED(s) 0
+# define interned_free(s) free(s)
+# define interned_efree(s) efree(s)
+# define interned_estrndup(s, n) estrndup(s, n)
+# define ZEND_RESULT_TYPE(opline) (opline)->result.op_type
+# define ZEND_RESULT(opline) (opline)->result.u
+# define ZEND_OP1_TYPE(opline) (opline)->op1.op_type
+# define ZEND_OP1(opline) (opline)->op1.u
+# define ZEND_OP1_CONST(opline) (opline)->op1.u.constant
+# define ZEND_OP1_LITERAL(opline) (opline)->op1.u.constant
+# define ZEND_OP2_TYPE(opline) (opline)->op2.op_type
+# define ZEND_OP2(opline) (opline)->op2.u
+# define ZEND_OP2_CONST(opline) (opline)->op2.u.constant
+# define ZEND_OP2_LITERAL(opline) (opline)->op2.u.constant
+# define ZEND_DONE_PASS_TWO(op_array) ((op_array)->done_pass_two != 0)
+# define ZEND_CE_FILENAME(ce) (ce)->filename
+# define ZEND_CE_DOC_COMMENT(ce) (ce)->doc_comment
+# define ZEND_CE_DOC_COMMENT_LEN(ce) (ce)->doc_comment_len
+#endif
+
+#endif /* ZEND_ACCELERATOR_H */
diff --git a/ext/opcache/config.m4 b/ext/opcache/config.m4
new file mode 100644
index 0000000000..60edeed966
--- /dev/null
+++ b/ext/opcache/config.m4
@@ -0,0 +1,383 @@
+dnl
+dnl $Id$
+dnl
+
+PHP_ARG_ENABLE(opcache, whether to enable Zend OPcache support,
+[ --enable-opcache Enable Zend OPcache support], yes)
+
+if test "$PHP_OPCACHE" != "no"; then
+
+ AC_CHECK_FUNC(mprotect,[
+ AC_DEFINE(HAVE_MPROTECT, 1, [Define if you have mprotect() function])
+ ])
+
+ AC_MSG_CHECKING(for sysvipc shared memory support)
+ AC_TRY_RUN([
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <unistd.h>
+#include <string.h>
+
+int main() {
+ pid_t pid;
+ int status;
+ int ipc_id;
+ char *shm;
+ struct shmid_ds shmbuf;
+
+ ipc_id = shmget(IPC_PRIVATE, 4096, (IPC_CREAT | SHM_R | SHM_W));
+ if (ipc_id == -1) {
+ return 1;
+ }
+
+ shm = shmat(ipc_id, NULL, 0);
+ if (shm == (void *)-1) {
+ shmctl(ipc_id, IPC_RMID, NULL);
+ return 2;
+ }
+
+ if (shmctl(ipc_id, IPC_STAT, &shmbuf) != 0) {
+ shmdt(shm);
+ shmctl(ipc_id, IPC_RMID, NULL);
+ return 3;
+ }
+
+ shmbuf.shm_perm.uid = getuid();
+ shmbuf.shm_perm.gid = getgid();
+ shmbuf.shm_perm.mode = 0600;
+
+ if (shmctl(ipc_id, IPC_SET, &shmbuf) != 0) {
+ shmdt(shm);
+ shmctl(ipc_id, IPC_RMID, NULL);
+ return 4;
+ }
+
+ shmctl(ipc_id, IPC_RMID, NULL);
+
+ strcpy(shm, "hello");
+
+ pid = fork();
+ if (pid < 0) {
+ return 5;
+ } else if (pid == 0) {
+ strcpy(shm, "bye");
+ return 6;
+ }
+ if (wait(&status) != pid) {
+ return 7;
+ }
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 6) {
+ return 8;
+ }
+ if (strcmp(shm, "bye") != 0) {
+ return 9;
+ }
+ return 0;
+}
+],dnl
+ AC_DEFINE(HAVE_SHM_IPC, 1, [Define if you have SysV IPC SHM support])
+ msg=yes,msg=no,msg=no)
+ AC_MSG_RESULT([$msg])
+
+ AC_MSG_CHECKING(for mmap() using MAP_ANON shared memory support)
+ AC_TRY_RUN([
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <string.h>
+
+#ifndef MAP_ANON
+# ifdef MAP_ANONYMOUS
+# define MAP_ANON MAP_ANONYMOUS
+# endif
+#endif
+#ifndef MAP_FAILED
+# define MAP_FAILED ((void*)-1)
+#endif
+
+int main() {
+ pid_t pid;
+ int status;
+ char *shm;
+
+ shm = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
+ if (shm == MAP_FAILED) {
+ return 1;
+ }
+
+ strcpy(shm, "hello");
+
+ pid = fork();
+ if (pid < 0) {
+ return 5;
+ } else if (pid == 0) {
+ strcpy(shm, "bye");
+ return 6;
+ }
+ if (wait(&status) != pid) {
+ return 7;
+ }
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 6) {
+ return 8;
+ }
+ if (strcmp(shm, "bye") != 0) {
+ return 9;
+ }
+ return 0;
+}
+],dnl
+ AC_DEFINE(HAVE_SHM_MMAP_ANON, 1, [Define if you have mmap(MAP_ANON) SHM support])
+ msg=yes,msg=no,msg=no)
+ AC_MSG_RESULT([$msg])
+
+ AC_MSG_CHECKING(for mmap() using /dev/zero shared memory support)
+ AC_TRY_RUN([
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
+#ifndef MAP_FAILED
+# define MAP_FAILED ((void*)-1)
+#endif
+
+int main() {
+ pid_t pid;
+ int status;
+ int fd;
+ char *shm;
+
+ fd = open("/dev/zero", O_RDWR, S_IRUSR | S_IWUSR);
+ if (fd == -1) {
+ return 1;
+ }
+
+ shm = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (shm == MAP_FAILED) {
+ return 2;
+ }
+
+ strcpy(shm, "hello");
+
+ pid = fork();
+ if (pid < 0) {
+ return 5;
+ } else if (pid == 0) {
+ strcpy(shm, "bye");
+ return 6;
+ }
+ if (wait(&status) != pid) {
+ return 7;
+ }
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 6) {
+ return 8;
+ }
+ if (strcmp(shm, "bye") != 0) {
+ return 9;
+ }
+ return 0;
+}
+],dnl
+ AC_DEFINE(HAVE_SHM_MMAP_ZERO, 1, [Define if you have mmap("/dev/zero") SHM support])
+ msg=yes,msg=no,msg=no)
+ AC_MSG_RESULT([$msg])
+
+ AC_MSG_CHECKING(for mmap() using shm_open() shared memory support)
+ AC_TRY_RUN([
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifndef MAP_FAILED
+# define MAP_FAILED ((void*)-1)
+#endif
+
+int main() {
+ pid_t pid;
+ int status;
+ int fd;
+ char *shm;
+ char tmpname[4096];
+
+ sprintf(tmpname,"test.shm.%dXXXXXX", getpid());
+ if (mktemp(tmpname) == NULL) {
+ return 1;
+ }
+ fd = shm_open(tmpname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
+ if (fd == -1) {
+ return 2;
+ }
+ if (ftruncate(fd, 4096) < 0) {
+ close(fd);
+ shm_unlink(tmpname);
+ return 3;
+ }
+
+ shm = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (shm == MAP_FAILED) {
+ return 4;
+ }
+ shm_unlink(tmpname);
+ close(fd);
+
+ strcpy(shm, "hello");
+
+ pid = fork();
+ if (pid < 0) {
+ return 5;
+ } else if (pid == 0) {
+ strcpy(shm, "bye");
+ return 6;
+ }
+ if (wait(&status) != pid) {
+ return 7;
+ }
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 6) {
+ return 8;
+ }
+ if (strcmp(shm, "bye") != 0) {
+ return 9;
+ }
+ return 0;
+}
+],dnl
+ AC_DEFINE(HAVE_SHM_MMAP_POSIX, 1, [Define if you have POSIX mmap() SHM support])
+ msg=yes,msg=no,msg=no)
+ AC_MSG_RESULT([$msg])
+
+ AC_MSG_CHECKING(for mmap() using regular file shared memory support)
+ AC_TRY_RUN([
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifndef MAP_FAILED
+# define MAP_FAILED ((void*)-1)
+#endif
+
+int main() {
+ pid_t pid;
+ int status;
+ int fd;
+ char *shm;
+ char tmpname[4096];
+
+ sprintf(tmpname,"test.shm.%dXXXXXX", getpid());
+ if (mktemp(tmpname) == NULL) {
+ return 1;
+ }
+ fd = open(tmpname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
+ if (fd == -1) {
+ return 2;
+ }
+ if (ftruncate(fd, 4096) < 0) {
+ close(fd);
+ unlink(tmpname);
+ return 3;
+ }
+
+ shm = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (shm == MAP_FAILED) {
+ return 4;
+ }
+ unlink(tmpname);
+ close(fd);
+
+ strcpy(shm, "hello");
+
+ pid = fork();
+ if (pid < 0) {
+ return 5;
+ } else if (pid == 0) {
+ strcpy(shm, "bye");
+ return 6;
+ }
+ if (wait(&status) != pid) {
+ return 7;
+ }
+ if (!WIFEXITED(status) || WEXITSTATUS(status) != 6) {
+ return 8;
+ }
+ if (strcmp(shm, "bye") != 0) {
+ return 9;
+ }
+ return 0;
+}
+],dnl
+ AC_DEFINE(HAVE_SHM_MMAP_FILE, 1, [Define if you have mmap() SHM support])
+ msg=yes,msg=no,msg=no)
+ AC_MSG_RESULT([$msg])
+
+flock_type=unknown
+AC_MSG_CHECKING("whether flock struct is linux ordered")
+AC_TRY_RUN([
+ #include <fcntl.h>
+ struct flock lock = { 1, 2, 3, 4, 5 };
+ int main() {
+ if(lock.l_type == 1 && lock.l_whence == 2 && lock.l_start == 3 && lock.l_len == 4) {
+ return 0;
+ }
+ return 1;
+ }
+], [
+ flock_type=linux
+ AC_DEFINE([HAVE_FLOCK_LINUX], [], [Struct flock is Linux-type])
+ AC_MSG_RESULT("yes")
+], AC_MSG_RESULT("no") )
+
+AC_MSG_CHECKING("whether flock struct is BSD ordered")
+AC_TRY_RUN([
+ #include <fcntl.h>
+ struct flock lock = { 1, 2, 3, 4, 5 };
+ int main() {
+ if(lock.l_start == 1 && lock.l_len == 2 && lock.l_type == 4 && lock.l_whence == 5) {
+ return 0;
+ }
+ return 1;
+ }
+], [
+ flock_type=bsd
+ AC_DEFINE([HAVE_FLOCK_BSD], [], [Struct flock is BSD-type])
+ AC_MSG_RESULT("yes")
+], AC_MSG_RESULT("no") )
+
+if test "$flock_type" == "unknown"; then
+ AC_MSG_ERROR([Don't know how to define struct flock on this system[,] set --enable-opcache=no])
+fi
+
+ PHP_NEW_EXTENSION(opcache,
+ ZendAccelerator.c \
+ zend_accelerator_blacklist.c \
+ zend_accelerator_debug.c \
+ zend_accelerator_hash.c \
+ zend_accelerator_module.c \
+ zend_persist.c \
+ zend_persist_calc.c \
+ zend_shared_alloc.c \
+ zend_accelerator_util_funcs.c \
+ shared_alloc_shm.c \
+ shared_alloc_mmap.c \
+ shared_alloc_posix.c \
+ Optimizer/zend_optimizer.c,
+ shared,,,,yes)
+
+ PHP_ADD_BUILD_DIR([$ext_builddir/Optimizer], 1)
+fi
diff --git a/ext/opcache/config.w32 b/ext/opcache/config.w32
new file mode 100644
index 0000000000..280ce228c6
--- /dev/null
+++ b/ext/opcache/config.w32
@@ -0,0 +1,27 @@
+ARG_ENABLE("opcache", "whether to enable Zend OPcache support", "yes");
+
+if (PHP_OPCACHE != "no") {
+
+ PHP_PGI = "no"; // workaround
+ PHP_PGO = "no"; // workaround
+
+ EXTENSION('opcache', "\
+ ZendAccelerator.c \
+ zend_accelerator_blacklist.c \
+ zend_accelerator_debug.c \
+ zend_accelerator_hash.c \
+ zend_accelerator_module.c \
+ zend_accelerator_util_funcs.c \
+ zend_persist.c \
+ zend_persist_calc.c \
+ zend_shared_alloc.c \
+ shared_alloc_win32.c", true);
+
+ ADD_SOURCES(configure_module_dirname + "/Optimizer", "zend_optimizer.c", "opcache", "OptimizerObj");
+
+
+ ADD_FLAG('CFLAGS_OPCACHE', "/I " + configure_module_dirname);
+
+ ADD_FLAG('CFLAGS_OPCACHE', "/Dregexec=php_regexec /Dregerror=php_regerror /Dregfree=php_regfree /Dregcomp=php_regcomp /Iext/ereg/regex");
+
+}
diff --git a/ext/opcache/shared_alloc_mmap.c b/ext/opcache/shared_alloc_mmap.c
new file mode 100644
index 0000000000..d995e20f12
--- /dev/null
+++ b/ext/opcache/shared_alloc_mmap.c
@@ -0,0 +1,78 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2014 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: Andi Gutmans <andi@zend.com> |
+ | Zeev Suraski <zeev@zend.com> |
+ | Stanislav Malyshev <stas@zend.com> |
+ | Dmitry Stogov <dmitry@zend.com> |
+ +----------------------------------------------------------------------+
+*/
+
+#include "zend_shared_alloc.h"
+
+#ifdef USE_MMAP
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+
+#if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
+# define MAP_ANONYMOUS MAP_ANON
+#endif
+
+static int create_segments(size_t requested_size, zend_shared_segment ***shared_segments_p, int *shared_segments_count, char **error_in)
+{
+ zend_shared_segment *shared_segment;
+
+ *shared_segments_count = 1;
+ *shared_segments_p = (zend_shared_segment **) calloc(1, sizeof(zend_shared_segment) + sizeof(void *));
+ if (!*shared_segments_p) {
+ *error_in = "calloc";
+ return ALLOC_FAILURE;
+ }
+ shared_segment = (zend_shared_segment *)((char *)(*shared_segments_p) + sizeof(void *));
+ (*shared_segments_p)[0] = shared_segment;
+
+ shared_segment->p = mmap(0, requested_size, PROT_READ | PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
+ if (shared_segment->p == MAP_FAILED) {
+ *error_in = "mmap";
+ return ALLOC_FAILURE;
+ }
+
+ shared_segment->pos = 0;
+ shared_segment->size = requested_size;
+
+ return ALLOC_SUCCESS;
+}
+
+static int detach_segment(zend_shared_segment *shared_segment)
+{
+ munmap(shared_segment->p, shared_segment->size);
+ return 0;
+}
+
+static size_t segment_type_size(void)
+{
+ return sizeof(zend_shared_segment);
+}
+
+zend_shared_memory_handlers zend_alloc_mmap_handlers = {
+ create_segments,
+ detach_segment,
+ segment_type_size
+};
+
+#endif /* USE_MMAP */
diff --git a/ext/opcache/shared_alloc_posix.c b/ext/opcache/shared_alloc_posix.c
new file mode 100644
index 0000000000..e4a34bd795
--- /dev/null
+++ b/ext/opcache/shared_alloc_posix.c
@@ -0,0 +1,98 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2014 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: Andi Gutmans <andi@zend.com> |
+ | Zeev Suraski <zeev@zend.com> |
+ | Stanislav Malyshev <stas@zend.com> |
+ | Dmitry Stogov <dmitry@zend.com> |
+ +----------------------------------------------------------------------+
+*/
+
+#include "zend_shared_alloc.h"
+
+#ifdef USE_SHM_OPEN
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+typedef struct {
+ zend_shared_segment common;
+ int shm_fd;
+} zend_shared_segment_posix;
+
+static int create_segments(size_t requested_size, zend_shared_segment_posix ***shared_segments_p, int *shared_segments_count, char **error_in)
+{
+ zend_shared_segment_posix *shared_segment;
+ char shared_segment_name[sizeof("/ZendAccelerator.") + 20];
+
+ *shared_segments_count = 1;
+ *shared_segments_p = (zend_shared_segment_posix **) calloc(1, sizeof(zend_shared_segment_posix) + sizeof(void *));
+ if (!*shared_segments_p) {
+ *error_in = "calloc";
+ return ALLOC_FAILURE;
+ }
+ shared_segment = (zend_shared_segment_posix *)((char *)(*shared_segments_p) + sizeof(void *));
+ (*shared_segments_p)[0] = shared_segment;
+
+ sprintf(shared_segment_name, "/ZendAccelerator.%d", getpid());
+ shared_segment->shm_fd = shm_open(shared_segment_name, O_RDWR|O_CREAT|O_TRUNC, 0600);
+ if (shared_segment->shm_fd == -1) {
+ *error_in = "shm_open";
+ return ALLOC_FAILURE;
+ }
+
+ if (ftruncate(shared_segment->shm_fd, requested_size) != 0) {
+ *error_in = "ftruncate";
+ shm_unlink(shared_segment_name);
+ return ALLOC_FAILURE;
+ }
+
+ shared_segment->common.p = mmap(0, requested_size, PROT_READ | PROT_WRITE, MAP_SHARED, shared_segment->shm_fd, 0);
+ if (shared_segment->common.p == MAP_FAILED) {
+ *error_in = "mmap";
+ shm_unlink(shared_segment_name);
+ return ALLOC_FAILURE;
+ }
+ shm_unlink(shared_segment_name);
+
+ shared_segment->common.pos = 0;
+ shared_segment->common.size = requested_size;
+
+ return ALLOC_SUCCESS;
+}
+
+static int detach_segment(zend_shared_segment_posix *shared_segment)
+{
+ munmap(shared_segment->common.p, shared_segment->common.size);
+ close(shared_segment->shm_fd);
+ return 0;
+}
+
+static size_t segment_type_size(void)
+{
+ return sizeof(zend_shared_segment_posix);
+}
+
+zend_shared_memory_handlers zend_alloc_posix_handlers = {
+ (create_segments_t)create_segments,
+ (detach_segment_t)detach_segment,
+ segment_type_size
+};
+
+#endif /* USE_SHM_OPEN */
diff --git a/ext/opcache/shared_alloc_shm.c b/ext/opcache/shared_alloc_shm.c
new file mode 100644
index 0000000000..4d9e10fc6f
--- /dev/null
+++ b/ext/opcache/shared_alloc_shm.c
@@ -0,0 +1,145 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2014 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: Andi Gutmans <andi@zend.com> |
+ | Zeev Suraski <zeev@zend.com> |
+ | Stanislav Malyshev <stas@zend.com> |
+ | Dmitry Stogov <dmitry@zend.com> |
+ +----------------------------------------------------------------------+
+*/
+
+#include "zend_shared_alloc.h"
+
+#ifdef USE_SHM
+
+#if defined(__FreeBSD__)
+# include <machine/param.h>
+#endif
+#include <sys/types.h>
+#include <sys/shm.h>
+#include <sys/ipc.h>
+#include <dirent.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#ifndef MIN
+# define MIN(x, y) ((x) > (y)? (y) : (x))
+#endif
+
+#define SEG_ALLOC_SIZE_MAX 32*1024*1024
+#define SEG_ALLOC_SIZE_MIN 2*1024*1024
+
+typedef struct {
+ zend_shared_segment common;
+ int shm_id;
+} zend_shared_segment_shm;
+
+static int create_segments(size_t requested_size, zend_shared_segment_shm ***shared_segments_p, int *shared_segments_count, char **error_in)
+{
+ int i;
+ size_t allocate_size = 0, remaining_bytes = requested_size, seg_allocate_size;
+ int first_segment_id = -1;
+ key_t first_segment_key = -1;
+ struct shmid_ds sds;
+ int shmget_flags;
+ zend_shared_segment_shm *shared_segments;
+
+ seg_allocate_size = SEG_ALLOC_SIZE_MAX;
+ /* determine segment size we _really_ need:
+ * no more than to include requested_size
+ */
+ while (requested_size * 2 <= seg_allocate_size && seg_allocate_size > SEG_ALLOC_SIZE_MIN) {
+ seg_allocate_size >>= 1;
+ }
+
+ shmget_flags = IPC_CREAT|SHM_R|SHM_W|IPC_EXCL;
+
+ /* try allocating this much, if not - try shrinking */
+ while (seg_allocate_size >= SEG_ALLOC_SIZE_MIN) {
+ allocate_size = MIN(requested_size, seg_allocate_size);
+ first_segment_id = shmget(first_segment_key, allocate_size, shmget_flags);
+ if (first_segment_id != -1) {
+ break;
+ }
+ seg_allocate_size >>= 1; /* shrink the allocated block */
+ }
+
+ if (first_segment_id == -1) {
+ *error_in = "shmget";
+ return ALLOC_FAILURE;
+ }
+
+ *shared_segments_count = ((requested_size - 1) / seg_allocate_size) + 1;
+ *shared_segments_p = (zend_shared_segment_shm **) calloc(1, (*shared_segments_count) * sizeof(zend_shared_segment_shm) + sizeof(void *) * (*shared_segments_count));
+ if (!*shared_segments_p) {
+ *error_in = "calloc";
+ return ALLOC_FAILURE;
+ }
+ shared_segments = (zend_shared_segment_shm *)((char *)(*shared_segments_p) + sizeof(void *) * (*shared_segments_count));
+ for (i = 0; i < *shared_segments_count; i++) {
+ (*shared_segments_p)[i] = shared_segments + i;
+ }
+
+ remaining_bytes = requested_size;
+ for (i = 0; i < *shared_segments_count; i++) {
+ allocate_size = MIN(remaining_bytes, seg_allocate_size);
+ if (i != 0) {
+ shared_segments[i].shm_id = shmget(IPC_PRIVATE, allocate_size, shmget_flags);
+ } else {
+ shared_segments[i].shm_id = first_segment_id;
+ }
+
+ if (shared_segments[i].shm_id == -1) {
+ return ALLOC_FAILURE;
+ }
+
+ shared_segments[i].common.p = shmat(shared_segments[i].shm_id, NULL, 0);
+ if (shared_segments[i].common.p == (void *)-1) {
+ *error_in = "shmat";
+ shmctl(shared_segments[i].shm_id, IPC_RMID, &sds);
+ return ALLOC_FAILURE;
+ }
+ shmctl(shared_segments[i].shm_id, IPC_RMID, &sds);
+
+ shared_segments[i].common.pos = 0;
+ shared_segments[i].common.size = allocate_size;
+ remaining_bytes -= allocate_size;
+ }
+ return ALLOC_SUCCESS;
+}
+
+static int detach_segment(zend_shared_segment_shm *shared_segment)
+{
+ shmdt(shared_segment->common.p);
+ return 0;
+}
+
+static size_t segment_type_size(void)
+{
+ return sizeof(zend_shared_segment_shm);
+}
+
+zend_shared_memory_handlers zend_alloc_shm_handlers = {
+ (create_segments_t)create_segments,
+ (detach_segment_t)detach_segment,
+ segment_type_size
+};
+
+#endif /* USE_SHM */
diff --git a/ext/opcache/shared_alloc_win32.c b/ext/opcache/shared_alloc_win32.c
new file mode 100644
index 0000000000..37431fb18a
--- /dev/null
+++ b/ext/opcache/shared_alloc_win32.c
@@ -0,0 +1,344 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2014 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: Andi Gutmans <andi@zend.com> |
+ | Zeev Suraski <zeev@zend.com> |
+ | Stanislav Malyshev <stas@zend.com> |
+ | Dmitry Stogov <dmitry@zend.com> |
+ +----------------------------------------------------------------------+
+*/
+
+#include "ZendAccelerator.h"
+#include "zend_shared_alloc.h"
+#include "zend_accelerator_util_funcs.h"
+#include <winbase.h>
+#include <process.h>
+#include <LMCONS.H>
+
+#define ACCEL_FILEMAP_NAME "ZendOPcache.SharedMemoryArea"
+#define ACCEL_MUTEX_NAME "ZendOPcache.SharedMemoryMutex"
+#define ACCEL_FILEMAP_BASE_DEFAULT 0x01000000
+#define ACCEL_FILEMAP_BASE "ZendOPcache.MemoryBase"
+#define ACCEL_EVENT_SOURCE "Zend OPcache"
+
+static HANDLE memfile = NULL, memory_mutex = NULL;
+static void *mapping_base;
+
+#define MAX_MAP_RETRIES 25
+
+static void zend_win_error_message(int type, char *msg, int err)
+{
+ LPVOID lpMsgBuf;
+ HANDLE h;
+ char *ev_msgs[2];
+
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ err,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
+ (LPTSTR) &lpMsgBuf,
+ 0,
+ NULL
+ );
+
+ h = RegisterEventSource(NULL, TEXT(ACCEL_EVENT_SOURCE));
+ ev_msgs[0] = msg;
+ ev_msgs[1] = lpMsgBuf;
+ ReportEvent(h, // event log handle
+ EVENTLOG_ERROR_TYPE, // event type
+ 0, // category zero
+ err, // event identifier
+ NULL, // no user security identifier
+ 2, // one substitution string
+ 0, // no data
+ ev_msgs, // pointer to string array
+ NULL); // pointer to data
+ DeregisterEventSource(h);
+
+ LocalFree( lpMsgBuf );
+
+ zend_accel_error(type, msg);
+}
+
+static char *create_name_with_username(char *name)
+{
+ static char newname[MAXPATHLEN + UNLEN + 4];
+ char uname[UNLEN + 1];
+ DWORD unsize = UNLEN;
+
+ GetUserName(uname, &unsize);
+ snprintf(newname, sizeof(newname) - 1, "%s@%s", name, uname);
+ return newname;
+}
+
+static char *get_mmap_base_file(void)
+{
+ static char windir[MAXPATHLEN+UNLEN + 3 + sizeof("\\\\@")];
+ char uname[UNLEN + 1];
+ DWORD unsize = UNLEN;
+ int l;
+
+ GetTempPath(MAXPATHLEN, windir);
+ GetUserName(uname, &unsize);
+ l = strlen(windir);
+ snprintf(windir + l, sizeof(windir) - l - 1, "\\%s@%s", ACCEL_FILEMAP_BASE, uname);
+ return windir;
+}
+
+void zend_shared_alloc_create_lock(void)
+{
+ memory_mutex = CreateMutex(NULL, FALSE, create_name_with_username(ACCEL_MUTEX_NAME));
+ if (!memory_mutex) {
+ zend_accel_error(ACCEL_LOG_FATAL, "Cannot create mutex");
+ return;
+ }
+ ReleaseMutex(memory_mutex);
+}
+
+void zend_shared_alloc_lock_win32(void)
+{
+ DWORD waitRes = WaitForSingleObject(memory_mutex, INFINITE);
+
+ if (waitRes == WAIT_FAILED) {
+ zend_accel_error(ACCEL_LOG_ERROR, "Cannot lock mutex");
+ }
+}
+
+void zend_shared_alloc_unlock_win32(void)
+{
+ ReleaseMutex(memory_mutex);
+}
+
+static int zend_shared_alloc_reattach(size_t requested_size, char **error_in)
+{
+ int err;
+ void *wanted_mapping_base;
+ char *mmap_base_file = get_mmap_base_file();
+ FILE *fp = fopen(mmap_base_file, "r");
+ MEMORY_BASIC_INFORMATION info;
+
+ err = GetLastError();
+ if (!fp) {
+ zend_win_error_message(ACCEL_LOG_WARNING, mmap_base_file, err);
+ zend_win_error_message(ACCEL_LOG_FATAL, "Unable to open base address file", err);
+ *error_in="fopen";
+ return ALLOC_FAILURE;
+ }
+ if (!fscanf(fp, "%p", &wanted_mapping_base)) {
+ err = GetLastError();
+ zend_win_error_message(ACCEL_LOG_FATAL, "Unable to read base address", err);
+ *error_in="read mapping base";
+ fclose(fp);
+ return ALLOC_FAILURE;
+ }
+ fclose(fp);
+
+ /* Check if the requested address space is free */
+ if (VirtualQuery(wanted_mapping_base, &info, sizeof(info)) == 0 ||
+ info.State != MEM_FREE ||
+ info.RegionSize < requested_size) {
+ err = ERROR_INVALID_ADDRESS;
+ zend_win_error_message(ACCEL_LOG_FATAL, "Unable to reattach to base address", err);
+ return ALLOC_FAILURE;
+ }
+
+ mapping_base = MapViewOfFileEx(memfile, FILE_MAP_ALL_ACCESS, 0, 0, 0, wanted_mapping_base);
+ err = GetLastError();
+
+ if (mapping_base == NULL) {
+ if (err == ERROR_INVALID_ADDRESS) {
+ zend_win_error_message(ACCEL_LOG_FATAL, "Unable to reattach to base address", err);
+ return ALLOC_FAILURE;
+ }
+ return ALLOC_FAIL_MAPPING;
+ }
+ smm_shared_globals = (zend_smm_shared_globals *) mapping_base;
+
+ return SUCCESSFULLY_REATTACHED;
+}
+
+static int create_segments(size_t requested_size, zend_shared_segment ***shared_segments_p, int *shared_segments_count, char **error_in)
+{
+ int err, ret;
+ zend_shared_segment *shared_segment;
+ int map_retries = 0;
+ void *default_mapping_base_set[] = { 0, 0 };
+ /* TODO:
+ improve fixed addresses on x64. It still makes no sense to do it as Windows addresses are virtual per se and can or should be randomized anyway
+ through Address Space Layout Radomization (ASLR). We can still let the OS do its job and be sure that each process gets the same address if
+ desired. Not done yet, @zend refused but did not remember the exact reason, pls add info here if one of you know why :)
+ */
+#if defined(_WIN64)
+ void *vista_mapping_base_set[] = { (void *) 0x0000100000000000, (void *) 0x0000200000000000, (void *) 0x0000300000000000, (void *) 0x0000700000000000, 0 };
+#else
+ void *vista_mapping_base_set[] = { (void *) 0x20000000, (void *) 0x21000000, (void *) 0x30000000, (void *) 0x31000000, (void *) 0x50000000, 0 };
+#endif
+ void **wanted_mapping_base = default_mapping_base_set;
+ TSRMLS_FETCH();
+
+ zend_shared_alloc_lock_win32();
+ /* Mapping retries: When Apache2 restarts, the parent process startup routine
+ can be called before the child process is killed. In this case, the map will fail
+ and we have to sleep some time (until the child releases the mapping object) and retry.*/
+ do {
+ memfile = OpenFileMapping(FILE_MAP_WRITE, 0, create_name_with_username(ACCEL_FILEMAP_NAME));
+ err = GetLastError();
+ if (memfile == NULL) {
+ break;
+ }
+
+ ret = zend_shared_alloc_reattach(requested_size, error_in);
+ err = GetLastError();
+ if (ret == ALLOC_FAIL_MAPPING) {
+ /* Mapping failed, wait for mapping object to get freed and retry */
+ CloseHandle(memfile);
+ memfile = NULL;
+ Sleep(1000 * (map_retries + 1));
+ } else {
+ zend_shared_alloc_unlock_win32();
+ return ret;
+ }
+ } while (++map_retries < MAX_MAP_RETRIES);
+
+ if (map_retries == MAX_MAP_RETRIES) {
+ zend_shared_alloc_unlock_win32();
+ zend_win_error_message(ACCEL_LOG_FATAL, "Unable to open file mapping", err);
+ *error_in = "OpenFileMapping";
+ return ALLOC_FAILURE;
+ }
+
+ /* creating segment here */
+ *shared_segments_count = 1;
+ *shared_segments_p = (zend_shared_segment **) calloc(1, sizeof(zend_shared_segment)+sizeof(void *));
+ if (!*shared_segments_p) {
+ zend_shared_alloc_unlock_win32();
+ zend_win_error_message(ACCEL_LOG_FATAL, "calloc() failed", GetLastError());
+ *error_in = "calloc";
+ return ALLOC_FAILURE;
+ }
+ shared_segment = (zend_shared_segment *)((char *)(*shared_segments_p) + sizeof(void *));
+ (*shared_segments_p)[0] = shared_segment;
+
+ memfile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, requested_size,
+ create_name_with_username(ACCEL_FILEMAP_NAME));
+ err = GetLastError();
+ if (memfile == NULL) {
+ zend_shared_alloc_unlock_win32();
+ zend_win_error_message(ACCEL_LOG_FATAL, "Unable to create file mapping", err);
+ *error_in = "CreateFileMapping";
+ return ALLOC_FAILURE;
+ }
+
+ /* Starting from windows Vista, heap randomization occurs which might cause our mapping base to
+ be taken (fail to map). So under Vista, we try to map into a hard coded predefined addresses
+ in high memory. */
+ if (!ZCG(accel_directives).mmap_base || !*ZCG(accel_directives).mmap_base) {
+ do {
+ OSVERSIONINFOEX osvi;
+ SYSTEM_INFO si;
+
+ ZeroMemory(&si, sizeof(SYSTEM_INFO));
+ ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
+
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+
+ if (! GetVersionEx ((OSVERSIONINFO *) &osvi)) {
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ if (!GetVersionEx((OSVERSIONINFO *)&osvi)) {
+ break;
+ }
+ }
+
+ GetSystemInfo(&si);
+
+ /* Are we running Vista ? */
+ if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT && osvi.dwMajorVersion == 6) {
+ wanted_mapping_base = vista_mapping_base_set;
+ }
+ } while (0);
+ } else {
+ char *s = ZCG(accel_directives).mmap_base;
+
+ /* skip leading 0x, %p assumes hexdeciaml format anyway */
+ if (*s == '0' && *(s + 1) == 'x') {
+ s += 2;
+ }
+ if (sscanf(s, "%p", &default_mapping_base_set[0]) != 1) {
+ zend_shared_alloc_unlock_win32();
+ zend_win_error_message(ACCEL_LOG_FATAL, "Bad mapping address specified in opcache.mmap_base", err);
+ return ALLOC_FAILURE;
+ }
+ }
+
+ do {
+ shared_segment->p = mapping_base = MapViewOfFileEx(memfile, FILE_MAP_ALL_ACCESS, 0, 0, 0, *wanted_mapping_base);
+ if (*wanted_mapping_base == NULL) { /* Auto address (NULL) is the last option on the array */
+ break;
+ }
+ wanted_mapping_base++;
+ } while (!mapping_base);
+
+ err = GetLastError();
+ if (mapping_base == NULL) {
+ zend_shared_alloc_unlock_win32();
+ zend_win_error_message(ACCEL_LOG_FATAL, "Unable to create view for file mapping", err);
+ *error_in = "MapViewOfFile";
+ return ALLOC_FAILURE;
+ } else {
+ char *mmap_base_file = get_mmap_base_file();
+ FILE *fp = fopen(mmap_base_file, "w");
+ err = GetLastError();
+ if (!fp) {
+ zend_shared_alloc_unlock_win32();
+ zend_win_error_message(ACCEL_LOG_WARNING, mmap_base_file, err);
+ zend_win_error_message(ACCEL_LOG_FATAL, "Unable to write base address", err);
+ return ALLOC_FAILURE;
+ }
+ fprintf(fp, "%p\n", mapping_base);
+ fclose(fp);
+ }
+
+ shared_segment->pos = 0;
+ shared_segment->size = requested_size;
+
+ zend_shared_alloc_unlock_win32();
+
+ return ALLOC_SUCCESS;
+}
+
+static int detach_segment(zend_shared_segment *shared_segment)
+{
+ zend_shared_alloc_lock_win32();
+ if (mapping_base) {
+ UnmapViewOfFile(mapping_base);
+ }
+ CloseHandle(memfile);
+ zend_shared_alloc_unlock_win32();
+ CloseHandle(memory_mutex);
+ return 0;
+}
+
+static size_t segment_type_size(void)
+{
+ return sizeof(zend_shared_segment);
+}
+
+zend_shared_memory_handlers zend_alloc_win32_handlers = {
+ create_segments,
+ detach_segment,
+ segment_type_size
+};
diff --git a/ext/opcache/tests/001_cli.phpt b/ext/opcache/tests/001_cli.phpt
new file mode 100644
index 0000000000..c51db23f56
--- /dev/null
+++ b/ext/opcache/tests/001_cli.phpt
@@ -0,0 +1,19 @@
+--TEST--
+001: O+ works in CLI
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$config = opcache_get_configuration();
+$status = opcache_get_status();
+var_dump($config["directives"]["opcache.enable"]);
+var_dump($config["directives"]["opcache.enable_cli"]);
+var_dump($status["opcache_enabled"]);
+?>
+--EXPECT--
+bool(true)
+bool(true)
+bool(true)
diff --git a/ext/opcache/tests/blacklist-win32.phpt b/ext/opcache/tests/blacklist-win32.phpt
new file mode 100644
index 0000000000..909c695fcd
--- /dev/null
+++ b/ext/opcache/tests/blacklist-win32.phpt
@@ -0,0 +1,34 @@
+--TEST--
+Blacklist (with glob, quote and comments)
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.blacklist_filename={PWD}/opcache-*.blacklist
+opcache.file_update_protection=0
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+<?php if (substr(PHP_OS, 0, 3) != 'WIN') { die('skip only for Windows'); } ?>
+--FILE--
+<?php
+$conf = opcache_get_configuration();
+$conf = $conf['blacklist'];
+$conf[3] = preg_replace("!^\\Q".dirname(__FILE__)."\\E!", "__DIR__", $conf[3]);
+$conf[4] = preg_replace("!^\\Q".dirname(__FILE__)."\\E!", "__DIR__", $conf[4]);
+print_r($conf);
+include("blacklist.inc");
+$status = opcache_get_status();
+print_r(count($status['scripts']));
+?>
+--EXPECTF--
+Array
+(
+ [0] => C:\path\to\foo
+ [1] => C:\path\to\foo2
+ [2] => C:\path\to\bar
+ [3] => __DIR__\blacklist.inc
+ [4] => __DIR__\current.php
+ [5] => %scurrent.php
+ [6] => %scurrent.php
+)
+ok
+1
diff --git a/ext/opcache/tests/blacklist.inc b/ext/opcache/tests/blacklist.inc
new file mode 100644
index 0000000000..a9db751419
--- /dev/null
+++ b/ext/opcache/tests/blacklist.inc
@@ -0,0 +1,3 @@
+<?php
+ echo "ok\n";
+?>
diff --git a/ext/opcache/tests/blacklist.phpt b/ext/opcache/tests/blacklist.phpt
new file mode 100644
index 0000000000..0c60425dac
--- /dev/null
+++ b/ext/opcache/tests/blacklist.phpt
@@ -0,0 +1,34 @@
+--TEST--
+Blacklist (with glob, quote and comments)
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.blacklist_filename={PWD}/opcache-*.blacklist
+opcache.file_update_protection=0
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+<?php if (substr(PHP_OS, 0, 3) == 'WIN') { die('skip not for Windows'); } ?>
+--FILE--
+<?php
+$conf = opcache_get_configuration();
+$conf = $conf['blacklist'];
+$conf[3] = preg_replace("!^\\Q".dirname(__FILE__)."\\E!", "__DIR__", $conf[3]);
+$conf[4] = preg_replace("!^\\Q".dirname(__FILE__)."\\E!", "__DIR__", $conf[4]);
+print_r($conf);
+include("blacklist.inc");
+$status = opcache_get_status();
+print_r(count($status['scripts']));
+?>
+--EXPECT--
+Array
+(
+ [0] => /path/to/foo
+ [1] => /path/to/foo2
+ [2] => /path/to/bar
+ [3] => __DIR__/blacklist.inc
+ [4] => __DIR__/current.php
+ [5] => /tmp/path/?nocache.inc
+ [6] => /tmp/path/*/somedir
+)
+ok
+1
diff --git a/ext/opcache/tests/bug64353.phpt b/ext/opcache/tests/bug64353.phpt
new file mode 100644
index 0000000000..b1f0c6e713
--- /dev/null
+++ b/ext/opcache/tests/bug64353.phpt
@@ -0,0 +1,29 @@
+--TEST--
+Bug #64353 (Built-in classes can be unavailable with dynamic includes and OPcache)
+--INI--
+allow_url_include=1
+opcache.enable=1
+opcache.enable_cli=1
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+class BugLoader extends php_user_filter {
+ public function filter($in, $out, &$consumed, $closing) {
+ if (!class_exists("Test")) {
+ eval("class Test extends ArrayObject {}");
+ }
+ while ($bucket = stream_bucket_make_writeable($in)) {
+ $consumed += $bucket->datalen;
+ stream_bucket_append($out, $bucket);
+ }
+ return PSFS_PASS_ON;
+ }
+}
+
+stream_filter_register('bug.test', 'BugLoader');
+include "php://filter/read=bug.test/resource=data://text/plain,<?php\n";
+echo "OK\n";
+?>
+--EXPECT--
+OK
diff --git a/ext/opcache/tests/bug64482.inc b/ext/opcache/tests/bug64482.inc
new file mode 100644
index 0000000000..e3d2b210c5
--- /dev/null
+++ b/ext/opcache/tests/bug64482.inc
@@ -0,0 +1,2 @@
+<?php
+echo "Dynamic include";
diff --git a/ext/opcache/tests/bug64482.phpt b/ext/opcache/tests/bug64482.phpt
new file mode 100644
index 0000000000..fa722f6d45
--- /dev/null
+++ b/ext/opcache/tests/bug64482.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Bug #64482 (Opcodes for dynamic includes should not be cached)
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+include 'bug64482.inc';
+echo "\n";
+include 'php://filter/read=string.toupper/resource=bug64482.inc';
+echo "\n";
+?>
+--EXPECT--
+Dynamic include
+DYNAMIC INCLUDE
diff --git a/ext/opcache/tests/bug65510.phpt b/ext/opcache/tests/bug65510.phpt
new file mode 100644
index 0000000000..ba19d27d6f
--- /dev/null
+++ b/ext/opcache/tests/bug65510.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Bug #65510 (5.5.2 crashes in _get_zval_ptr_ptr_var)
+--INI--
+allow_url_include=1
+opcache.enable=1
+opcache.enable_cli=1
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+function parseQuery() {
+ $m = array("l", "a", "r", "u", "e", "n", "c", "e");
+ foreach($m as $n) {
+ @list($a, $b) = $n;
+ }
+}
+parseQuery();
+echo "ok\n";
+--EXPECT--
+ok
diff --git a/ext/opcache/tests/bug65559.phpt b/ext/opcache/tests/bug65559.phpt
new file mode 100644
index 0000000000..0d40cf10f8
--- /dev/null
+++ b/ext/opcache/tests/bug65559.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Bug #65559 (cache not cleared if changes occur while running)
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.file_update_protection=2
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$file = __DIR__ . "/bug6559.inc.php";
+file_put_contents($file, '<?php return 1;');
+$var = include $file;
+var_dump($var);
+file_put_contents($file, '<?php return 2;');
+$var = include $file;
+var_dump($var);
+@unlink($file);
+?>
+--EXPECT--
+int(1)
+int(2)
diff --git a/ext/opcache/tests/bug65665.phpt b/ext/opcache/tests/bug65665.phpt
new file mode 100644
index 0000000000..ac5c18dd83
--- /dev/null
+++ b/ext/opcache/tests/bug65665.phpt
@@ -0,0 +1,118 @@
+--TEST--
+Bug #65665 (Exception not properly caught when opcache enabled)
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+function foo() {
+ try
+ {
+ switch (1)
+ {
+ case 0:
+ try
+ {
+
+ }
+ catch (Exception $e)
+ {
+
+ }
+
+ break;
+
+ case 1:
+ try
+ {
+ throw new Exception('aaa');
+ }
+ catch (Exception $e)
+ {
+ echo "correct\n";
+ }
+
+ break;
+ }
+ }
+ catch (Exception $e)
+ {
+ echo "wrong\n";
+ }
+ return;
+}
+
+function foo1() {
+ try
+ {
+ switch (1)
+ {
+ case 0:
+ try
+ {
+
+ }
+ catch (Exception $e)
+ {
+dummy:
+ echo "ect\n";
+ }
+
+ break;
+
+ case 1:
+ try
+ {
+ throw new Exception('aaa');
+ }
+ catch (Exception $e)
+ {
+ echo "corr";
+ goto dummy;
+ }
+ break;
+ }
+ }
+ catch (Exception $e)
+ {
+ echo "wrong\n";
+ }
+ return;
+}
+
+function foo2() {
+ try
+ {
+ switch (1)
+ {
+ case 0:
+ try
+ {
+dummy:
+ throw new Exception('aaa');
+ }
+ catch (Exception $e)
+ {
+ echo "correct\n";
+ }
+
+ break;
+
+ case 1:
+ goto dummy;
+ break;
+ }
+ }
+ catch (Exception $e)
+ {
+ echo "wrong\n";
+ }
+ return;
+}
+foo();foo1();foo2();
+--EXPECT--
+correct
+correct
+correct
diff --git a/ext/opcache/tests/bug65845.phpt b/ext/opcache/tests/bug65845.phpt
new file mode 100644
index 0000000000..2ae5f3974a
--- /dev/null
+++ b/ext/opcache/tests/bug65845.phpt
@@ -0,0 +1,14 @@
+--TEST--
+Bug #65845 (Error when Zend Opcache Optimizer is fully enabled)
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$Pile['vars'][(string)'toto'] = 'tutu';
+var_dump($Pile['vars']['toto']);
+?>
+--EXPECT--
+string(4) "tutu"
diff --git a/ext/opcache/tests/bug65915.phpt b/ext/opcache/tests/bug65915.phpt
new file mode 100644
index 0000000000..6496ee3253
--- /dev/null
+++ b/ext/opcache/tests/bug65915.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Bug #65915 (Inconsistent results with require return value)
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+$tmp = __DIR__ . "/bug65915.inc.php";
+
+file_put_contents($tmp, '<?php return function(){ return "a";};');
+$f = require $tmp;
+var_dump($f());
+
+opcache_invalidate($tmp, true);
+
+file_put_contents($tmp, '<?php return function(){ return "b";};');
+$f = require $tmp;
+var_dump($f());
+
+@unlink($tmp);
+?>
+--EXPECT--
+string(1) "a"
+string(1) "b"
diff --git a/ext/opcache/tests/bug66176.phpt b/ext/opcache/tests/bug66176.phpt
new file mode 100644
index 0000000000..a91024a616
--- /dev/null
+++ b/ext/opcache/tests/bug66176.phpt
@@ -0,0 +1,19 @@
+--TEST--
+Bug #66176 (Invalid constant substitution)
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.optimization_level=-1
+opcache.file_update_protection=0
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+function foo($v) {
+ global $a;
+ return $a[$v];
+}
+$a = array(PHP_VERSION => 1);
+var_dump(foo(PHP_VERSION));
+--EXPECT--
+int(1)
diff --git a/ext/opcache/tests/bug66461.phpt b/ext/opcache/tests/bug66461.phpt
new file mode 100644
index 0000000000..33132abeed
--- /dev/null
+++ b/ext/opcache/tests/bug66461.phpt
@@ -0,0 +1,15 @@
+--TEST--
+Bug #66461 (PHP crashes if opcache.interned_strings_buffer=0)
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.optimization_level=-1
+opcache.file_update_protection=0
+opcache.interned_strings_buffer=0
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+echo "ok\n";
+--EXPECT--
+ok
diff --git a/ext/opcache/tests/bug66474.phpt b/ext/opcache/tests/bug66474.phpt
new file mode 100644
index 0000000000..3bd038c0de
--- /dev/null
+++ b/ext/opcache/tests/bug66474.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Bug #66474 (Optimizer bug in constant string to boolean conversion)
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.optimization_level=-1
+opcache.file_update_protection=0
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+function foo() {
+ $speed = 'slow' || 'fast';
+}
+foo();
+echo "ok\n";
+--EXPECT--
+ok
diff --git a/ext/opcache/tests/issue0057.phpt b/ext/opcache/tests/issue0057.phpt
new file mode 100644
index 0000000000..49e9156f15
--- /dev/null
+++ b/ext/opcache/tests/issue0057.phpt
@@ -0,0 +1,38 @@
+--TEST--
+ISSUE #57 (segfaults in drupal7)
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.optimization_level=-1
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+
+class ZException extends Exception {
+}
+
+function dummy($query) {
+ try {
+ switch ($query) {
+ case 1;
+ break;
+ case 2;
+ break;
+ default:
+ throw new Exception('exception');
+ }
+ } catch (ZException $e) {
+ return NULL;
+ }
+}
+
+try {
+ dummy(0);
+} catch (Exception $e) {
+ echo $e->getMessage();
+}
+
+?>
+--EXPECT--
+exception
diff --git a/ext/opcache/tests/issue0079.phpt b/ext/opcache/tests/issue0079.phpt
new file mode 100644
index 0000000000..4458fce5bc
--- /dev/null
+++ b/ext/opcache/tests/issue0079.phpt
@@ -0,0 +1,34 @@
+--TEST--
+ISSUE #79 (Optimization Problem/Bug)
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.optimization_level=-1
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+class Test {
+ public function run() {
+ $r = $this->my_parse_m();
+ var_dump ($r);
+ return $r;
+ }
+
+ public function my_parse_m() {
+ $test = true;
+ if ($test === true) {
+ $a = 'b';
+ } else {
+ return false;
+ }
+// flush();
+ return true;
+ }
+}
+
+$t = new Test();
+var_dump ($t->run());
+--EXPECT--
+bool(true)
+bool(true)
diff --git a/ext/opcache/tests/issue0115.phpt b/ext/opcache/tests/issue0115.phpt
new file mode 100644
index 0000000000..0dfdd9f0eb
--- /dev/null
+++ b/ext/opcache/tests/issue0115.phpt
@@ -0,0 +1,48 @@
+--TEST--
+ISSUE #115 (path issue when using phar)
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+phar.readonly=0
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+<?php if (!extension_loaded("phar")) die("skip"); ?>
+<?php if (php_sapi_name() != "cli") die("skip CLI only"); ?>
+--FILE--
+<?php
+$stub = '<?php
+Phar::interceptFileFuncs();
+require "phar://this/index.php";
+__HALT_COMPILER(); ?>';
+$p = new Phar(__DIR__ . '/issue0115_1.phar.php', 0, 'this');
+$p['index.php'] = '<?php
+echo "Hello from Index 1.\n";
+require_once "phar://this/hello.php";
+';
+$p['hello.php'] = "Hello World 1!\n";
+$p->setStub($stub);
+unset($p);
+$p = new Phar(__DIR__ . '/issue0115_2.phar.php', 0, 'this');
+$p['index.php'] = '<?php
+echo "Hello from Index 2.\n";
+require_once "phar://this/hello.php";
+';
+$p['hello.php'] = "Hello World 2!\n";
+$p->setStub($stub);
+unset($p);
+
+include "php_cli_server.inc";
+php_cli_server_start('-d opcache.enable=1 -d opcache.enable_cli=1');
+echo file_get_contents('http://' . PHP_CLI_SERVER_ADDRESS . '/issue0115_1.phar.php');
+echo file_get_contents('http://' . PHP_CLI_SERVER_ADDRESS . '/issue0115_2.phar.php');
+?>
+--CLEAN--
+<?php
+@unlink(__DIR__ . '/issue0115_1.phar.php');
+@unlink(__DIR__ . '/issue0115_2.phar.php');
+?>
+--EXPECT--
+Hello from Index 1.
+Hello World 1!
+Hello from Index 2.
+Hello World 2!
diff --git a/ext/opcache/tests/issue0128.phpt b/ext/opcache/tests/issue0128.phpt
new file mode 100644
index 0000000000..637f675ac2
--- /dev/null
+++ b/ext/opcache/tests/issue0128.phpt
@@ -0,0 +1,16 @@
+--TEST--
+ISSUE #128 (opcache_invalidate segmentation fault)
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.optimization_level=-1
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+var_dump(opcache_invalidate('1'));
+var_dump("okey");
+?>
+--EXPECT--
+bool(false)
+string(4) "okey"
diff --git a/ext/opcache/tests/issue0140.phpt b/ext/opcache/tests/issue0140.phpt
new file mode 100644
index 0000000000..98e0e45cc2
--- /dev/null
+++ b/ext/opcache/tests/issue0140.phpt
@@ -0,0 +1,43 @@
+--TEST--
+Issue #140: "opcache.enable_file_override" doesn't respect "opcache.revalidate_freq"
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.revalidate_freq=0
+opcache.file_update_protection=0
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+<?php if (php_sapi_name() != "cli") die("skip CLI only"); ?>
+--FILE--
+<?php
+define("FILENAME", dirname(__FILE__) . "/issuer0140.inc.php");
+file_put_contents(FILENAME, "1\n");
+
+var_dump(is_readable(FILENAME));
+include(FILENAME);
+var_dump(filemtime(FILENAME));
+
+sleep(2);
+file_put_contents(FILENAME, "2\n");
+
+var_dump(is_readable(FILENAME));
+include(FILENAME);
+var_dump(filemtime(FILENAME));
+
+sleep(2);
+unlink(FILENAME);
+
+var_dump(is_readable(FILENAME));
+var_dump(@include(FILENAME));
+var_dump(@filemtime(FILENAME));
+?>
+--EXPECTF--
+bool(true)
+1
+int(%d)
+bool(true)
+2
+int(%d)
+bool(false)
+bool(false)
+bool(false)
diff --git a/ext/opcache/tests/issue0149.phpt b/ext/opcache/tests/issue0149.phpt
new file mode 100644
index 0000000000..8c7f1bb7e0
--- /dev/null
+++ b/ext/opcache/tests/issue0149.phpt
@@ -0,0 +1,35 @@
+--TEST--
+ISSUE #149 (Phar mount points not working this OPcache enabled)
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+phar.readonly=0
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+<?php if (!extension_loaded("phar")) die("skip"); ?>
+<?php if (php_sapi_name() != "cli") die("skip CLI only"); ?>
+--FILE--
+<?php
+$stub = "<?php header('Content-Type: text/plain;');
+Phar::mount('this.file', '". __FILE__ . "');
+echo 'OK\n';
+__HALT_COMPILER(); ?>";
+$p = new Phar(__DIR__ . '/issue0149.phar.php', 0, 'this');
+$p['index.php'] = ""; # A Phar must have at least one file, hence this dummy
+$p->setStub($stub);
+unset($p);
+
+include "php_cli_server.inc";
+php_cli_server_start('-d opcache.enable=1 -d opcache.enable_cli=1');
+echo file_get_contents('http://' . PHP_CLI_SERVER_ADDRESS . '/issue0149.phar.php');
+echo file_get_contents('http://' . PHP_CLI_SERVER_ADDRESS . '/issue0149.phar.php');
+echo file_get_contents('http://' . PHP_CLI_SERVER_ADDRESS . '/issue0149.phar.php');
+?>
+--CLEAN--
+<?php
+@unlink(__DIR__ . '/issue0149.phar.php');
+?>
+--EXPECT--
+OK
+OK
+OK
diff --git a/ext/opcache/tests/opcache-1.blacklist b/ext/opcache/tests/opcache-1.blacklist
new file mode 100644
index 0000000000..5f498d637c
--- /dev/null
+++ b/ext/opcache/tests/opcache-1.blacklist
@@ -0,0 +1,5 @@
+; comments are allowed in blacklist file
+; and empty line are ignored
+
+/path/to/foo
+"/path/to/foo2" \ No newline at end of file
diff --git a/ext/opcache/tests/opcache-2.blacklist b/ext/opcache/tests/opcache-2.blacklist
new file mode 100644
index 0000000000..575d9fab30
--- /dev/null
+++ b/ext/opcache/tests/opcache-2.blacklist
@@ -0,0 +1,6 @@
+/path/to/bar
+; wildcard and relative entires
+blacklist.inc
+./current.php
+/tmp/path/?nocache.inc
+/tmp/path/*/somedir
diff --git a/ext/opcache/tests/php_cli_server.inc b/ext/opcache/tests/php_cli_server.inc
new file mode 100644
index 0000000000..0878bfafc0
--- /dev/null
+++ b/ext/opcache/tests/php_cli_server.inc
@@ -0,0 +1,47 @@
+<?php
+define ("PHP_CLI_SERVER_HOSTNAME", "localhost");
+define ("PHP_CLI_SERVER_PORT", 8964);
+define ("PHP_CLI_SERVER_ADDRESS", PHP_CLI_SERVER_HOSTNAME.":".PHP_CLI_SERVER_PORT);
+
+function php_cli_server_start($ini = "") {
+ $php_executable = getenv('TEST_PHP_EXECUTABLE');
+ $doc_root = __DIR__;
+
+ $descriptorspec = array(
+ 0 => STDIN,
+ 1 => STDOUT,
+ 2 => STDERR,
+ );
+
+ if (substr(PHP_OS, 0, 3) == 'WIN') {
+ $cmd = "{$php_executable} -t {$doc_root} $ini -S " . PHP_CLI_SERVER_ADDRESS;
+ $handle = proc_open(addslashes($cmd), $descriptorspec, $pipes, $doc_root, NULL, array("bypass_shell" => true, "suppress_errors" => true));
+ } else {
+ $cmd = "exec {$php_executable} -t {$doc_root} $ini -S " . PHP_CLI_SERVER_ADDRESS . " 2>/dev/null";
+ $handle = proc_open($cmd, $descriptorspec, $pipes, $doc_root);
+ }
+
+ // note: even when server prints 'Listening on localhost:8964...Press Ctrl-C to quit.'
+ // it might not be listening yet...need to wait until fsockopen() call returns
+ $i = 0;
+ while (($i++ < 30) && !($fp = @fsockopen(PHP_CLI_SERVER_HOSTNAME, PHP_CLI_SERVER_PORT))) {
+ usleep(10000);
+ }
+
+ if ($fp) {
+ fclose($fp);
+ }
+
+ register_shutdown_function(
+ function($handle) {
+ proc_terminate($handle);
+ },
+ $handle
+ );
+ // don't bother sleeping, server is already up
+ // server can take a variable amount of time to be up, so just sleeping a guessed amount of time
+ // does not work. this is why tests sometimes pass and sometimes fail. to get a reliable pass
+ // sleeping doesn't work.
+}
+?>
+
diff --git a/ext/opcache/tests/revalidate_path_01.phpt b/ext/opcache/tests/revalidate_path_01.phpt
new file mode 100644
index 0000000000..cf2ac0d829
--- /dev/null
+++ b/ext/opcache/tests/revalidate_path_01.phpt
@@ -0,0 +1,61 @@
+--TEST--
+revalidate_path 01: OPCache must cache only resolved real paths when revalidate_path is set
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.revalidate_path=1
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+<?php if (php_sapi_name() != "cli") die("skip CLI only"); ?>
+--FILE--
+<?php
+$dir = dirname(__FILE__);
+$dir1 = "$dir/test1";
+$dir2 = "$dir/test2";
+$link = "$dir/test";
+$file1 = "$dir1/index.php";
+$file2 = "$dir2/index.php";
+$main = "$dir/main.php";
+@mkdir($dir1);
+@mkdir($dir2);
+@file_put_contents($main, '<?php include(\'' . $link .'/index.php\');');
+@file_put_contents($file1, "TEST 1\n");
+@file_put_contents($file2, "TEST 2\n");
+while (filemtime($file1) != filemtime($file2)) {
+ touch($file1);
+ touch($file2);
+}
+@unlink($link);
+@symlink($dir1, $link);
+
+include "php_cli_server.inc";
+//php_cli_server_start('-d opcache.enable=1 -d opcache.enable_cli=1 -d opcache.revalidate_path=1');
+php_cli_server_start('-d opcache.enable=1 -d opcache.enable_cli=1 -d opcache.revalidate_path=1 -d opcache.file_update_protection=0 -d realpath_cache_size=0');
+echo file_get_contents('http://' . PHP_CLI_SERVER_ADDRESS . '/main.php');
+echo file_get_contents('http://' . PHP_CLI_SERVER_ADDRESS . '/main.php');
+@unlink($link);
+@symlink($dir2, $link);
+echo file_get_contents('http://' . PHP_CLI_SERVER_ADDRESS . '/main.php');
+echo file_get_contents('http://' . PHP_CLI_SERVER_ADDRESS . '/main.php');
+?>
+--CLEAN--
+<?php
+$dir = dirname(__FILE__);
+$dir1 = "$dir/test1";
+$dir2 = "$dir/test2";
+$link = "$dir/test";
+$file1 = "$dir1/index.php";
+$file2 = "$dir2/index.php";
+$main = "$dir/main.php";
+@unlink($main);
+@unlink($link);
+@unlink($file1);
+@unlink($file2);
+@rmdir($dir1);
+@rmdir($dir2);
+?>
+--EXPECT--
+TEST 1
+TEST 1
+TEST 2
+TEST 2
diff --git a/ext/opcache/tests/skipif.inc b/ext/opcache/tests/skipif.inc
new file mode 100644
index 0000000000..c5a8181039
--- /dev/null
+++ b/ext/opcache/tests/skipif.inc
@@ -0,0 +1,3 @@
+<?php
+ if (!extension_loaded('Zend OPcache')) die('skip Zend OPcache extension not available');
+?>
diff --git a/ext/opcache/zend_accelerator_blacklist.c b/ext/opcache/zend_accelerator_blacklist.c
new file mode 100644
index 0000000000..0ca37dfa42
--- /dev/null
+++ b/ext/opcache/zend_accelerator_blacklist.c
@@ -0,0 +1,381 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2014 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: Andi Gutmans <andi@zend.com> |
+ | Zeev Suraski <zeev@zend.com> |
+ | Stanislav Malyshev <stas@zend.com> |
+ | Dmitry Stogov <dmitry@zend.com> |
+ +----------------------------------------------------------------------+
+*/
+
+#include "main/php.h"
+#include "main/fopen_wrappers.h"
+#include "ZendAccelerator.h"
+#include "zend_accelerator_blacklist.h"
+
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+# include "ext/ereg/php_regex.h"
+#else
+# include "main/php_regex.h"
+#endif
+
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+# include "ext/standard/php_string.h"
+#endif
+
+#ifdef ZEND_WIN32
+# define REGEX_MODE (REG_EXTENDED|REG_NOSUB|REG_ICASE)
+#else
+# define REGEX_MODE (REG_EXTENDED|REG_NOSUB)
+#endif
+
+#ifdef HAVE_GLOB
+#ifdef PHP_WIN32
+#include "win32/glob.h"
+#else
+#include <glob.h>
+#endif
+#endif
+
+#define ZEND_BLACKLIST_BLOCK_SIZE 32
+
+struct _zend_regexp_list {
+ regex_t comp_regex;
+ zend_regexp_list *next;
+};
+
+zend_blacklist accel_blacklist;
+
+void zend_accel_blacklist_init(zend_blacklist *blacklist)
+{
+ blacklist->pos = 0;
+ blacklist->size = ZEND_BLACKLIST_BLOCK_SIZE;
+
+ if (blacklist->entries != NULL) {
+ zend_accel_blacklist_shutdown(blacklist);
+ }
+
+ blacklist->entries = (zend_blacklist_entry *) calloc(sizeof(zend_blacklist_entry), blacklist->size);
+ if (!blacklist->entries) {
+ zend_accel_error(ACCEL_LOG_FATAL, "Blacklist initialization: no memory\n");
+ return;
+ }
+ blacklist->regexp_list = NULL;
+}
+
+static void blacklist_report_regexp_error(regex_t *comp_regex, int reg_err)
+{
+ char *errbuf;
+ int errsize = regerror(reg_err, comp_regex, NULL, 0);
+ errbuf = malloc(errsize);
+ if (!errbuf) {
+ zend_accel_error(ACCEL_LOG_ERROR, "Blacklist compilation: no memory\n");
+ return;
+ }
+ regerror(reg_err, comp_regex, errbuf, errsize);
+ zend_accel_error(ACCEL_LOG_ERROR, "Blacklist compilation: %s\n", errbuf);
+ free(errbuf);
+}
+
+static void zend_accel_blacklist_update_regexp(zend_blacklist *blacklist)
+{
+ int i, reg_err;
+ zend_regexp_list **regexp_list_it, *it;
+ char regexp[12*1024], *p, *end, *c, *backtrack = NULL;
+
+ if (blacklist->pos == 0) {
+ /* we have no blacklist to talk about */
+ return;
+ }
+
+ regexp_list_it = &(blacklist->regexp_list);
+
+ regexp[0] = '^';
+ regexp[1] = '(';
+ p = regexp + 2;
+ end = regexp + sizeof(regexp) - sizeof("[^\\\\]*)\0");
+
+ for (i = 0; i < blacklist->pos; ) {
+ c = blacklist->entries[i].path;
+ if (p + blacklist->entries[i].path_length < end) {
+ while (*c && p < end) {
+ switch (*c) {
+ case '?':
+ c++;
+#ifdef ZEND_WIN32
+ p[0] = '['; /* * => [^\\] on Win32 */
+ p[1] = '^';
+ p[2] = '\\';
+ p[3] = '\\';
+ p[4] = ']';
+ p += 5;
+#else
+ p[0] = '['; /* * => [^/] on *nix */
+ p[1] = '^';
+ p[2] = '/';
+ p[3] = ']';
+ p += 4;
+#endif
+ break;
+ case '*':
+ c++;
+ if (*c == '*') {
+ c++;
+ p[0] = '.'; /* ** => .* */
+ p[1] = '*';
+ p += 2;
+ } else {
+#ifdef ZEND_WIN32
+ p[0] = '['; /* * => [^\\]* on Win32 */
+ p[1] = '^';
+ p[2] = '\\';
+ p[3] = '\\';
+ p[4] = ']';
+ p[5] = '*';
+ p += 6;
+#else
+ p[0] = '['; /* * => [^/]* on *nix */
+ p[1] = '^';
+ p[2] = '/';
+ p[3] = ']';
+ p[4] = '*';
+ p += 5;
+#endif
+ }
+ break;
+ case '^':
+ case '.':
+ case '[':
+ case ']':
+ case '$':
+ case '(':
+ case ')':
+ case '|':
+ case '+':
+ case '{':
+ case '}':
+ case '\\':
+ *p++ = '\\';
+ /* break missing intentionally */
+ default:
+ *p++ = *c++;
+ }
+ }
+ }
+
+ if (*c || i == blacklist->pos - 1) {
+ if (*c) {
+ if (!backtrack) {
+ zend_accel_error(ACCEL_LOG_ERROR, "Too long blacklist entry\n");
+ }
+ p = backtrack;
+ } else {
+ i++;
+ }
+ *p++ = ')';
+ *p++ = '\0';
+
+ it = (zend_regexp_list*)malloc(sizeof(zend_regexp_list));
+ if (!it) {
+ zend_accel_error(ACCEL_LOG_ERROR, "malloc() failed\n");
+ return;
+ }
+ it->next = NULL;
+
+ if ((reg_err = regcomp(&it->comp_regex, regexp, REGEX_MODE)) != 0) {
+ blacklist_report_regexp_error(&it->comp_regex, reg_err);
+ }
+ /* prepare for the next iteration */
+ p = regexp + 2;
+ *regexp_list_it = it;
+ regexp_list_it = &it->next;
+ } else {
+ backtrack = p;
+ *p++ = '|';
+ i++;
+ }
+ }
+}
+
+void zend_accel_blacklist_shutdown(zend_blacklist *blacklist)
+{
+ zend_blacklist_entry *p = blacklist->entries, *end = blacklist->entries + blacklist->pos;
+
+ while (p<end) {
+ free(p->path);
+ p++;
+ }
+ free(blacklist->entries);
+ blacklist->entries = NULL;
+ if (blacklist->regexp_list) {
+ zend_regexp_list *temp, *it = blacklist->regexp_list;
+ while (it) {
+ regfree(&it->comp_regex);
+ temp = it;
+ it = it->next;
+ free(temp);
+ }
+ }
+}
+
+static inline void zend_accel_blacklist_allocate(zend_blacklist *blacklist)
+{
+ if (blacklist->pos == blacklist->size) {
+ blacklist->size += ZEND_BLACKLIST_BLOCK_SIZE;
+ blacklist->entries = (zend_blacklist_entry *) realloc(blacklist->entries, sizeof(zend_blacklist_entry)*blacklist->size);
+ }
+}
+
+#ifdef HAVE_GLOB
+static void zend_accel_blacklist_loadone(zend_blacklist *blacklist, char *filename)
+#else
+void zend_accel_blacklist_load(zend_blacklist *blacklist, char *filename)
+#endif
+{
+ char buf[MAXPATHLEN + 1], real_path[MAXPATHLEN + 1], *blacklist_path = NULL;
+ FILE *fp;
+ int path_length, blacklist_path_length;
+ TSRMLS_FETCH();
+
+ if ((fp = fopen(filename, "r")) == NULL) {
+ zend_accel_error(ACCEL_LOG_WARNING, "Cannot load blacklist file: %s\n", filename);
+ return;
+ }
+
+ zend_accel_error(ACCEL_LOG_DEBUG,"Loading blacklist file: '%s'", filename);
+
+ if (VCWD_REALPATH(filename, buf)) {
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+ blacklist_path_length = php_dirname(buf, strlen(buf));
+#else
+ blacklist_path_length = zend_dirname(buf, strlen(buf));
+#endif
+ blacklist_path = zend_strndup(buf, blacklist_path_length);
+ }
+
+ memset(buf, 0, sizeof(buf));
+ memset(real_path, 0, sizeof(real_path));
+
+ while (fgets(buf, MAXPATHLEN, fp) != NULL) {
+ char *path_dup, *pbuf;
+ path_length = strlen(buf);
+ if (path_length > 0 && buf[path_length - 1] == '\n') {
+ buf[--path_length] = 0;
+ if (path_length > 0 && buf[path_length - 1] == '\r') {
+ buf[--path_length] = 0;
+ }
+ }
+
+ /* Strip ctrl-m prefix */
+ pbuf = &buf[0];
+ while (*pbuf == '\r') {
+ *pbuf++ = 0;
+ path_length--;
+ }
+
+ /* strip \" */
+ if (pbuf[0] == '\"' && pbuf[path_length - 1]== '\"') {
+ *pbuf++ = 0;
+ path_length -= 2;
+ }
+
+ if (path_length == 0) {
+ continue;
+ }
+
+ /* skip comments */
+ if (pbuf[0]==';') {
+ continue;
+ }
+
+ path_dup = zend_strndup(pbuf, path_length);
+ if (blacklist_path) {
+ expand_filepath_ex(path_dup, real_path, blacklist_path, blacklist_path_length TSRMLS_CC);
+ } else {
+ expand_filepath(path_dup, real_path TSRMLS_CC);
+ }
+ path_length = strlen(real_path);
+
+ free(path_dup);
+
+ zend_accel_blacklist_allocate(blacklist);
+ blacklist->entries[blacklist->pos].path_length = path_length;
+ blacklist->entries[blacklist->pos].path = (char *)malloc(path_length + 1);
+ if (!blacklist->entries[blacklist->pos].path) {
+ zend_accel_error(ACCEL_LOG_ERROR, "malloc() failed\n");
+ fclose(fp);
+ return;
+ }
+ blacklist->entries[blacklist->pos].id = blacklist->pos;
+ memcpy(blacklist->entries[blacklist->pos].path, real_path, path_length + 1);
+ blacklist->pos++;
+ }
+ fclose(fp);
+ if (blacklist_path) {
+ free(blacklist_path);
+ }
+ zend_accel_blacklist_update_regexp(blacklist);
+}
+
+#ifdef HAVE_GLOB
+void zend_accel_blacklist_load(zend_blacklist *blacklist, char *filename)
+{
+ glob_t globbuf;
+ int ret;
+ unsigned int i;
+
+ memset(&globbuf, 0, sizeof(glob_t));
+
+ ret = glob(filename, 0, NULL, &globbuf);
+#ifdef GLOB_NOMATCH
+ if (ret == GLOB_NOMATCH || !globbuf.gl_pathc) {
+#else
+ if (!globbuf.gl_pathc) {
+#endif
+ zend_accel_error(ACCEL_LOG_WARNING, "No blacklist file found matching: %s\n", filename);
+ } else {
+ for(i=0 ; i<globbuf.gl_pathc; i++) {
+ zend_accel_blacklist_loadone(blacklist, globbuf.gl_pathv[i]);
+ }
+ globfree(&globbuf);
+ }
+}
+#endif
+
+zend_bool zend_accel_blacklist_is_blacklisted(zend_blacklist *blacklist, char *verify_path)
+{
+ int ret = 0;
+ zend_regexp_list *regexp_list_it = blacklist->regexp_list;
+
+ if (regexp_list_it == NULL) {
+ return 0;
+ }
+ while (regexp_list_it != NULL) {
+ if (regexec(&(regexp_list_it->comp_regex), verify_path, 0, NULL, 0) == 0) {
+ ret = 1;
+ break;
+ }
+ regexp_list_it = regexp_list_it->next;
+ }
+ return ret;
+}
+
+void zend_accel_blacklist_apply(zend_blacklist *blacklist, apply_func_arg_t func, void *argument TSRMLS_DC)
+{
+ int i;
+
+ for (i = 0; i < blacklist->pos; i++) {
+ func(&blacklist->entries[i], argument TSRMLS_CC);
+ }
+}
diff --git a/ext/opcache/zend_accelerator_blacklist.h b/ext/opcache/zend_accelerator_blacklist.h
new file mode 100644
index 0000000000..869068410f
--- /dev/null
+++ b/ext/opcache/zend_accelerator_blacklist.h
@@ -0,0 +1,49 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2014 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: Andi Gutmans <andi@zend.com> |
+ | Zeev Suraski <zeev@zend.com> |
+ | Stanislav Malyshev <stas@zend.com> |
+ | Dmitry Stogov <dmitry@zend.com> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef ZEND_ACCELERATOR_BLACKLIST_H
+#define ZEND_ACCELERATOR_BLACKLIST_H
+
+typedef struct _zend_regexp_list zend_regexp_list;
+
+typedef struct _zend_blacklist_entry {
+ char *path;
+ int path_length;
+ int id;
+} zend_blacklist_entry;
+
+typedef struct _zend_blacklist {
+ zend_blacklist_entry *entries;
+ int size;
+ int pos;
+ zend_regexp_list *regexp_list;
+} zend_blacklist;
+
+extern zend_blacklist accel_blacklist;
+
+void zend_accel_blacklist_init(zend_blacklist *blacklist);
+void zend_accel_blacklist_shutdown(zend_blacklist *blacklist);
+
+void zend_accel_blacklist_load(zend_blacklist *blacklist, char *filename);
+zend_bool zend_accel_blacklist_is_blacklisted(zend_blacklist *blacklist, char *verify_path);
+void zend_accel_blacklist_apply(zend_blacklist *blacklist, apply_func_arg_t func, void *argument TSRMLS_DC);
+
+#endif /* ZEND_ACCELERATOR_BLACKLIST_H */
diff --git a/ext/opcache/zend_accelerator_debug.c b/ext/opcache/zend_accelerator_debug.c
new file mode 100644
index 0000000000..d0198dccb3
--- /dev/null
+++ b/ext/opcache/zend_accelerator_debug.c
@@ -0,0 +1,99 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2014 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: Andi Gutmans <andi@zend.com> |
+ | Zeev Suraski <zeev@zend.com> |
+ | Stanislav Malyshev <stas@zend.com> |
+ | Dmitry Stogov <dmitry@zend.com> |
+ +----------------------------------------------------------------------+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <time.h>
+#ifdef ZEND_WIN32
+# include <process.h>
+#endif
+#include "ZendAccelerator.h"
+
+void zend_accel_error(int type, const char *format, ...)
+{
+ va_list args;
+ time_t timestamp;
+ char *time_string;
+ FILE * fLog = NULL;
+ TSRMLS_FETCH();
+
+ if (type > ZCG(accel_directives).log_verbosity_level) {
+ return;
+ }
+
+ timestamp = time(NULL);
+ time_string = asctime(localtime(&timestamp));
+ time_string[24] = 0;
+
+ if (!ZCG(accel_directives).error_log ||
+ !*ZCG(accel_directives).error_log ||
+ strcmp(ZCG(accel_directives).error_log, "stderr") == 0) {
+
+ fLog = stderr;
+ } else {
+ fLog = fopen(ZCG(accel_directives).error_log, "a+");
+ if (!fLog) {
+ fLog = stderr;
+ }
+ }
+
+#ifdef ZTS
+ fprintf(fLog, "%s (%lu): ", time_string, (unsigned long)tsrm_thread_id());
+#else
+ fprintf(fLog, "%s (%d): ", time_string, getpid());
+#endif
+
+ switch (type) {
+ case ACCEL_LOG_FATAL:
+ fprintf(fLog, "Fatal Error ");
+ break;
+ case ACCEL_LOG_ERROR:
+ fprintf(fLog, "Error ");
+ break;
+ case ACCEL_LOG_WARNING:
+ fprintf(fLog, "Warning ");
+ break;
+ case ACCEL_LOG_INFO:
+ fprintf(fLog, "Message ");
+ break;
+ case ACCEL_LOG_DEBUG:
+ fprintf(fLog, "Debug ");
+ break;
+ }
+
+ va_start(args, format);
+ vfprintf(fLog, format, args);
+ va_end(args);
+ fprintf(fLog, "\n");
+ switch (type) {
+ case ACCEL_LOG_ERROR:
+ zend_bailout();
+ break;
+ case ACCEL_LOG_FATAL:
+ exit(-2);
+ break;
+ }
+ fflush(fLog);
+ if (fLog != stderr) {
+ fclose(fLog);
+ }
+}
diff --git a/ext/opcache/zend_accelerator_debug.h b/ext/opcache/zend_accelerator_debug.h
new file mode 100644
index 0000000000..f773f6220a
--- /dev/null
+++ b/ext/opcache/zend_accelerator_debug.h
@@ -0,0 +1,33 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2014 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: Andi Gutmans <andi@zend.com> |
+ | Zeev Suraski <zeev@zend.com> |
+ | Stanislav Malyshev <stas@zend.com> |
+ | Dmitry Stogov <dmitry@zend.com> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef ZEND_ACCELERATOR_DEBUG_H
+#define ZEND_ACCELERATOR_DEBUG_H
+
+#define ACCEL_LOG_FATAL 0
+#define ACCEL_LOG_ERROR 1
+#define ACCEL_LOG_WARNING 2
+#define ACCEL_LOG_INFO 3
+#define ACCEL_LOG_DEBUG 4
+
+void zend_accel_error(int type, const char *format, ...);
+
+#endif /* _ZEND_ACCELERATOR_DEBUG_H */
diff --git a/ext/opcache/zend_accelerator_hash.c b/ext/opcache/zend_accelerator_hash.c
new file mode 100644
index 0000000000..b75377d61b
--- /dev/null
+++ b/ext/opcache/zend_accelerator_hash.c
@@ -0,0 +1,224 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2014 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: Andi Gutmans <andi@zend.com> |
+ | Zeev Suraski <zeev@zend.com> |
+ | Stanislav Malyshev <stas@zend.com> |
+ | Dmitry Stogov <dmitry@zend.com> |
+ +----------------------------------------------------------------------+
+*/
+
+#include "ZendAccelerator.h"
+#include "zend_accelerator_hash.h"
+#include "zend_hash.h"
+#include "zend_shared_alloc.h"
+
+/* Generated on an Octa-ALPHA 300MHz CPU & 2.5GB RAM monster */
+static uint prime_numbers[] =
+ {5, 11, 19, 53, 107, 223, 463, 983, 1979, 3907, 7963, 16229, 32531, 65407, 130987, 262237, 524521, 1048793 };
+static uint num_prime_numbers = sizeof(prime_numbers) / sizeof(uint);
+
+void zend_accel_hash_clean(zend_accel_hash *accel_hash)
+{
+ accel_hash->num_entries = 0;
+ accel_hash->num_direct_entries = 0;
+ memset(accel_hash->hash_table, 0, sizeof(zend_accel_hash_entry *)*accel_hash->max_num_entries);
+}
+
+void zend_accel_hash_init(zend_accel_hash *accel_hash, zend_uint hash_size)
+{
+ uint i;
+
+ for (i=0; i<num_prime_numbers; i++) {
+ if (hash_size <= prime_numbers[i]) {
+ hash_size = prime_numbers[i];
+ break;
+ }
+ }
+
+ accel_hash->num_entries = 0;
+ accel_hash->num_direct_entries = 0;
+ accel_hash->max_num_entries = hash_size;
+
+ /* set up hash pointers table */
+ accel_hash->hash_table = zend_shared_alloc(sizeof(zend_accel_hash_entry *)*accel_hash->max_num_entries);
+ if (!accel_hash->hash_table) {
+ zend_accel_error(ACCEL_LOG_FATAL, "Insufficient shared memory!");
+ return;
+ }
+
+ /* set up hash values table */
+ accel_hash->hash_entries = zend_shared_alloc(sizeof(zend_accel_hash_entry)*accel_hash->max_num_entries);
+ if (!accel_hash->hash_entries) {
+ zend_accel_error(ACCEL_LOG_FATAL, "Insufficient shared memory!");
+ return;
+ }
+ memset(accel_hash->hash_table, 0, sizeof(zend_accel_hash_entry *)*accel_hash->max_num_entries);
+}
+
+/* Returns NULL if hash is full
+ * Returns pointer the actual hash entry on success
+ * key needs to be already allocated as it is not copied
+ */
+zend_accel_hash_entry* zend_accel_hash_update(zend_accel_hash *accel_hash, char *key, zend_uint key_length, zend_bool indirect, void *data)
+{
+ zend_ulong hash_value;
+ zend_ulong index;
+ zend_accel_hash_entry *entry;
+ zend_accel_hash_entry *indirect_bucket = NULL;
+
+ if (indirect) {
+ indirect_bucket = (zend_accel_hash_entry*)data;
+ while (indirect_bucket->indirect) {
+ indirect_bucket = (zend_accel_hash_entry*)indirect_bucket->data;
+ }
+ }
+
+ hash_value = zend_inline_hash_func(key, key_length);
+ index = hash_value % accel_hash->max_num_entries;
+
+ /* try to see if the element already exists in the hash */
+ entry = accel_hash->hash_table[index];
+ while (entry) {
+ if (entry->hash_value == hash_value
+ && entry->key_length == key_length
+ && !memcmp(entry->key, key, key_length)) {
+
+ if (entry->indirect) {
+ if (indirect_bucket) {
+ entry->data = indirect_bucket;
+ } else {
+ ((zend_accel_hash_entry*)entry->data)->data = data;
+ }
+ } else {
+ if (indirect_bucket) {
+ accel_hash->num_direct_entries--;
+ entry->data = indirect_bucket;
+ entry->indirect = 1;
+ } else {
+ entry->data = data;
+ }
+ }
+ return entry;
+ }
+ entry = entry->next;
+ }
+
+ /* Does not exist, add a new entry */
+ if (accel_hash->num_entries == accel_hash->max_num_entries) {
+ return NULL;
+ }
+
+ entry = &accel_hash->hash_entries[accel_hash->num_entries++];
+ if (indirect) {
+ entry->data = indirect_bucket;
+ entry->indirect = 1;
+ } else {
+ accel_hash->num_direct_entries++;
+ entry->data = data;
+ entry->indirect = 0;
+ }
+ entry->hash_value = hash_value;
+ entry->key = key;
+ entry->key_length = key_length;
+ entry->next = accel_hash->hash_table[index];
+ accel_hash->hash_table[index] = entry;
+ return entry;
+}
+
+/* Returns the data associated with key on success
+ * Returns NULL if data doesn't exist
+ */
+void* zend_accel_hash_find(zend_accel_hash *accel_hash, char *key, zend_uint key_length)
+{
+ zend_ulong hash_value;
+ zend_ulong index;
+ zend_accel_hash_entry *entry;
+
+ hash_value = zend_inline_hash_func(key, key_length);
+ index = hash_value % accel_hash->max_num_entries;
+
+ entry = accel_hash->hash_table[index];
+ while (entry) {
+ if (entry->hash_value == hash_value
+ && entry->key_length == key_length
+ && !memcmp(entry->key, key, key_length)) {
+ if (entry->indirect) {
+ return ((zend_accel_hash_entry *) entry->data)->data;
+ } else {
+ return entry->data;
+ }
+ }
+ entry = entry->next;
+ }
+ return NULL;
+}
+
+/* Returns the hash entry associated with key on success
+ * Returns NULL if it doesn't exist
+ */
+zend_accel_hash_entry* zend_accel_hash_find_entry(zend_accel_hash *accel_hash, char *key, zend_uint key_length)
+{
+ zend_ulong hash_value;
+ zend_ulong index;
+ zend_accel_hash_entry *entry;
+
+ hash_value = zend_inline_hash_func(key, key_length);
+ index = hash_value % accel_hash->max_num_entries;
+
+ entry = accel_hash->hash_table[index];
+ while (entry) {
+ if (entry->hash_value == hash_value
+ && entry->key_length == key_length
+ && !memcmp(entry->key, key, key_length)) {
+ if (entry->indirect) {
+ return (zend_accel_hash_entry *) entry->data;
+ } else {
+ return entry;
+ }
+ }
+ entry = entry->next;
+ }
+ return NULL;
+}
+
+int zend_accel_hash_unlink(zend_accel_hash *accel_hash, char *key, zend_uint key_length)
+{
+ zend_ulong hash_value;
+ zend_ulong index;
+ zend_accel_hash_entry *entry, *last_entry=NULL;
+
+ hash_value = zend_inline_hash_func(key, key_length);
+ index = hash_value % accel_hash->max_num_entries;
+
+ entry = accel_hash->hash_table[index];
+ while (entry) {
+ if (entry->hash_value == hash_value
+ && entry->key_length == key_length
+ && !memcmp(entry->key, key, key_length)) {
+ if (!entry->indirect) {
+ accel_hash->num_direct_entries--;
+ }
+ if (last_entry) {
+ last_entry->next = entry->next;
+ } else {
+ accel_hash->hash_table[index] = entry->next;
+ }
+ return SUCCESS;
+ }
+ last_entry = entry;
+ entry = entry->next;
+ }
+ return FAILURE;
+}
diff --git a/ext/opcache/zend_accelerator_hash.h b/ext/opcache/zend_accelerator_hash.h
new file mode 100644
index 0000000000..2de28bffa7
--- /dev/null
+++ b/ext/opcache/zend_accelerator_hash.h
@@ -0,0 +1,98 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2014 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: Andi Gutmans <andi@zend.com> |
+ | Zeev Suraski <zeev@zend.com> |
+ | Stanislav Malyshev <stas@zend.com> |
+ | Dmitry Stogov <dmitry@zend.com> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef ZEND_ACCELERATOR_HASH_H
+#define ZEND_ACCELERATOR_HASH_H
+
+#include "zend.h"
+
+/*
+ zend_accel_hash - is a hash table allocated in shared memory and
+ distributed across simultaneously running processes. The hash tables have
+ fixed sizen selected during construction by zend_accel_hash_init(). All the
+ hash entries are preallocated in the 'hash_entries' array. 'num_entries' is
+ initialized by zero and grows when new data is added.
+ zend_accel_hash_update() just takes the next entry from 'hash_entries'
+ array and puts it into appropriate place of 'hash_table'.
+ Hash collisions are resolved by separate chaining with linked lists,
+ however, entries are still taken from the same 'hash_entries' array.
+ 'key' and 'data' passed to zend_accel_hash_update() must be already
+ allocated in shared memory. Few keys may be resolved to the same data.
+ using 'indirect' entries, that point to other entries ('data' is actually
+ a pointer to another zend_accel_hash_entry).
+ zend_accel_hash_update() requires exclusive lock, however,
+ zend_accel_hash_find() does not.
+*/
+
+typedef struct _zend_accel_hash_entry zend_accel_hash_entry;
+
+struct _zend_accel_hash_entry {
+ zend_ulong hash_value;
+ char *key;
+ zend_uint key_length;
+ zend_accel_hash_entry *next;
+ void *data;
+ zend_bool indirect;
+};
+
+typedef struct _zend_accel_hash {
+ zend_accel_hash_entry **hash_table;
+ zend_accel_hash_entry *hash_entries;
+ zend_uint num_entries;
+ zend_uint max_num_entries;
+ zend_uint num_direct_entries;
+} zend_accel_hash;
+
+void zend_accel_hash_init(zend_accel_hash *accel_hash, zend_uint hash_size);
+void zend_accel_hash_clean(zend_accel_hash *accel_hash);
+
+zend_accel_hash_entry* zend_accel_hash_update(
+ zend_accel_hash *accel_hash,
+ char *key,
+ zend_uint key_length,
+ zend_bool indirect,
+ void *data);
+
+void* zend_accel_hash_find(
+ zend_accel_hash *accel_hash,
+ char *key,
+ zend_uint key_length);
+
+zend_accel_hash_entry* zend_accel_hash_find_entry(
+ zend_accel_hash *accel_hash,
+ char *key,
+ zend_uint key_length);
+
+int zend_accel_hash_unlink(
+ zend_accel_hash *accel_hash,
+ char *key,
+ zend_uint key_length);
+
+static inline zend_bool zend_accel_hash_is_full(zend_accel_hash *accel_hash)
+{
+ if (accel_hash->num_entries == accel_hash->max_num_entries) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+#endif /* ZEND_ACCELERATOR_HASH_H */
diff --git a/ext/opcache/zend_accelerator_module.c b/ext/opcache/zend_accelerator_module.c
new file mode 100644
index 0000000000..4de4ab378e
--- /dev/null
+++ b/ext/opcache/zend_accelerator_module.c
@@ -0,0 +1,761 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2014 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: Andi Gutmans <andi@zend.com> |
+ | Zeev Suraski <zeev@zend.com> |
+ | Stanislav Malyshev <stas@zend.com> |
+ | Dmitry Stogov <dmitry@zend.com> |
+ +----------------------------------------------------------------------+
+*/
+
+#include <time.h>
+
+#include "php.h"
+#include "ZendAccelerator.h"
+#include "zend_API.h"
+#include "zend_shared_alloc.h"
+#include "zend_accelerator_blacklist.h"
+#include "php_ini.h"
+#include "SAPI.h"
+#include "TSRM/tsrm_virtual_cwd.h"
+#include "ext/standard/info.h"
+#include "ext/standard/php_filestat.h"
+
+#define STRING_NOT_NULL(s) (NULL == (s)?"":s)
+#define MIN_ACCEL_FILES 200
+#define MAX_ACCEL_FILES 1000000
+#define TOKENTOSTR(X) #X
+
+static void (*orig_file_exists)(INTERNAL_FUNCTION_PARAMETERS) = NULL;
+static void (*orig_is_file)(INTERNAL_FUNCTION_PARAMETERS) = NULL;
+static void (*orig_is_readable)(INTERNAL_FUNCTION_PARAMETERS) = NULL;
+
+ZEND_BEGIN_ARG_INFO(arginfo_opcache_none, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_opcache_get_status, 0, 0, 0)
+ ZEND_ARG_INFO(0, fetch_scripts)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_opcache_compile_file, 0, 0, 1)
+ ZEND_ARG_INFO(0, file)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_opcache_invalidate, 0, 0, 1)
+ ZEND_ARG_INFO(0, script)
+ ZEND_ARG_INFO(0, force)
+ZEND_END_ARG_INFO()
+
+/* User functions */
+static ZEND_FUNCTION(opcache_reset);
+static ZEND_FUNCTION(opcache_invalidate);
+
+/* Private functions */
+static ZEND_FUNCTION(opcache_get_status);
+static ZEND_FUNCTION(opcache_compile_file);
+static ZEND_FUNCTION(opcache_get_configuration);
+
+static zend_function_entry accel_functions[] = {
+ /* User functions */
+ ZEND_FE(opcache_reset, arginfo_opcache_none)
+ ZEND_FE(opcache_invalidate, arginfo_opcache_invalidate)
+ ZEND_FE(opcache_compile_file, arginfo_opcache_compile_file)
+ /* Private functions */
+ ZEND_FE(opcache_get_configuration, arginfo_opcache_none)
+ ZEND_FE(opcache_get_status, arginfo_opcache_get_status)
+ { NULL, NULL, NULL, 0, 0 }
+};
+
+static int validate_api_restriction(TSRMLS_D)
+{
+ if (ZCG(accel_directives).restrict_api && *ZCG(accel_directives).restrict_api) {
+ int len = strlen(ZCG(accel_directives).restrict_api);
+
+ if (!SG(request_info).path_translated ||
+ strlen(SG(request_info).path_translated) < len ||
+ memcmp(SG(request_info).path_translated, ZCG(accel_directives).restrict_api, len) != 0) {
+ zend_error(E_WARNING, ACCELERATOR_PRODUCT_NAME " API is restricted by \"restrict_api\" configuration directive");
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static ZEND_INI_MH(OnUpdateMemoryConsumption)
+{
+ long *p;
+ long memsize;
+#ifndef ZTS
+ char *base = (char *) mh_arg2;
+#else
+ char *base = (char *) ts_resource(*((int *) mh_arg2));
+#endif
+
+ /* keep the compiler happy */
+ (void)entry; (void)new_value_length; (void)mh_arg2; (void)mh_arg3; (void)stage;
+
+ p = (long *) (base + (size_t)mh_arg1);
+ memsize = atoi(new_value);
+ /* sanity check we must use at least 8 MB */
+ if (memsize < 8) {
+ const char *new_new_value = "8";
+ zend_ini_entry *ini_entry;
+
+ memsize = 8;
+ zend_accel_error(ACCEL_LOG_WARNING, "opcache.memory_consumption is set below the required 8MB.\n");
+ zend_accel_error(ACCEL_LOG_WARNING, ACCELERATOR_PRODUCT_NAME " will use the minimal 8MB configuration.\n");
+
+ if (zend_hash_find(EG(ini_directives),
+ "opcache.memory_consumption",
+ sizeof("opcache.memory_consumption"),
+ (void *) &ini_entry) == FAILURE) {
+ return FAILURE;
+ }
+
+ ini_entry->value = strdup(new_new_value);
+ ini_entry->value_length = strlen(new_new_value);
+ }
+ *p = memsize * (1024 * 1024);
+ return SUCCESS;
+}
+
+static ZEND_INI_MH(OnUpdateMaxAcceleratedFiles)
+{
+ long *p;
+ long size;
+#ifndef ZTS
+ char *base = (char *) mh_arg2;
+#else
+ char *base = (char *) ts_resource(*((int *) mh_arg2));
+#endif
+
+ /* keep the compiler happy */
+ (void)entry; (void)new_value_length; (void)mh_arg2; (void)mh_arg3; (void)stage;
+
+ p = (long *) (base + (size_t)mh_arg1);
+ size = atoi(new_value);
+ /* sanity check we must use a value between MIN_ACCEL_FILES and MAX_ACCEL_FILES */
+
+ if (size < MIN_ACCEL_FILES || size > MAX_ACCEL_FILES) {
+ const char *new_new_value;
+ zend_ini_entry *ini_entry;
+
+ if (size < MIN_ACCEL_FILES) {
+ size = MIN_ACCEL_FILES;
+ new_new_value = TOKENTOSTR(MIN_ACCEL_FILES);
+ zend_accel_error(ACCEL_LOG_WARNING, "opcache.max_accelerated_files is set below the required minimum (%d).\n", MIN_ACCEL_FILES);
+ zend_accel_error(ACCEL_LOG_WARNING, ACCELERATOR_PRODUCT_NAME " will use the minimal configuration.\n");
+ }
+ if (size > MAX_ACCEL_FILES) {
+ size = MAX_ACCEL_FILES;
+ new_new_value = TOKENTOSTR(MAX_ACCEL_FILES);
+ zend_accel_error(ACCEL_LOG_WARNING, "opcache.max_accelerated_files is set above the limit (%d).\n", MAX_ACCEL_FILES);
+ zend_accel_error(ACCEL_LOG_WARNING, ACCELERATOR_PRODUCT_NAME " will use the maximal configuration.\n");
+ }
+ if (zend_hash_find(EG(ini_directives),
+ "opcache.max_accelerated_files",
+ sizeof("opcache.max_accelerated_files"),
+ (void *) &ini_entry) == FAILURE) {
+ return FAILURE;
+ }
+ ini_entry->value = strdup(new_new_value);
+ ini_entry->value_length = strlen(new_new_value);
+ }
+ *p = size;
+ return SUCCESS;
+}
+
+static ZEND_INI_MH(OnUpdateMaxWastedPercentage)
+{
+ double *p;
+ long percentage;
+#ifndef ZTS
+ char *base = (char *) mh_arg2;
+#else
+ char *base = (char *) ts_resource(*((int *) mh_arg2));
+#endif
+
+ /* keep the compiler happy */
+ (void)entry; (void)new_value_length; (void)mh_arg2; (void)mh_arg3; (void)stage;
+
+ p = (double *) (base + (size_t)mh_arg1);
+ percentage = atoi(new_value);
+
+ if (percentage <= 0 || percentage > 50) {
+ const char *new_new_value = "5";
+ zend_ini_entry *ini_entry;
+
+ percentage = 5;
+ zend_accel_error(ACCEL_LOG_WARNING, "opcache.max_wasted_percentage must be set between 1 and 50.\n");
+ zend_accel_error(ACCEL_LOG_WARNING, ACCELERATOR_PRODUCT_NAME " will use 5%.\n");
+ if (zend_hash_find(EG(ini_directives),
+ "opcache.max_wasted_percentage",
+ sizeof("opcache.max_wasted_percentage"),
+ (void *) &ini_entry) == FAILURE) {
+ return FAILURE;
+ }
+ ini_entry->value = strdup(new_new_value);
+ ini_entry->value_length = strlen(new_new_value);
+ }
+ *p = (double)percentage / 100.0;
+ return SUCCESS;
+}
+
+static ZEND_INI_MH(OnEnable)
+{
+ if (stage == ZEND_INI_STAGE_STARTUP ||
+ stage == ZEND_INI_STAGE_SHUTDOWN ||
+ stage == ZEND_INI_STAGE_DEACTIVATE) {
+ return OnUpdateBool(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
+ } else {
+ /* It may be only temporary disabled */
+ zend_bool *p;
+#ifndef ZTS
+ char *base = (char *) mh_arg2;
+#else
+ char *base = (char *) ts_resource(*((int *) mh_arg2));
+#endif
+
+ p = (zend_bool *) (base+(size_t) mh_arg1);
+ if ((new_value_length == 2 && strcasecmp("on", new_value) == 0) ||
+ (new_value_length == 3 && strcasecmp("yes", new_value) == 0) ||
+ (new_value_length == 4 && strcasecmp("true", new_value) == 0) ||
+ atoi(new_value) != 0) {
+ zend_error(E_WARNING, ACCELERATOR_PRODUCT_NAME " can't be temporary enabled (it may be only disabled till the end of request)");
+ return FAILURE;
+ } else {
+ *p = 0;
+ return SUCCESS;
+ }
+ }
+}
+
+ZEND_INI_BEGIN()
+ STD_PHP_INI_BOOLEAN("opcache.enable" , "1", PHP_INI_ALL, OnEnable, enabled , zend_accel_globals, accel_globals)
+ STD_PHP_INI_BOOLEAN("opcache.use_cwd" , "1", PHP_INI_SYSTEM, OnUpdateBool, accel_directives.use_cwd , zend_accel_globals, accel_globals)
+ STD_PHP_INI_BOOLEAN("opcache.validate_timestamps", "1", PHP_INI_ALL , OnUpdateBool, accel_directives.validate_timestamps, zend_accel_globals, accel_globals)
+ STD_PHP_INI_BOOLEAN("opcache.inherited_hack" , "1", PHP_INI_SYSTEM, OnUpdateBool, accel_directives.inherited_hack , zend_accel_globals, accel_globals)
+ STD_PHP_INI_BOOLEAN("opcache.dups_fix" , "0", PHP_INI_ALL , OnUpdateBool, accel_directives.ignore_dups , zend_accel_globals, accel_globals)
+ STD_PHP_INI_BOOLEAN("opcache.revalidate_path" , "0", PHP_INI_ALL , OnUpdateBool, accel_directives.revalidate_path , zend_accel_globals, accel_globals)
+
+ STD_PHP_INI_ENTRY("opcache.log_verbosity_level" , "1" , PHP_INI_SYSTEM, OnUpdateLong, accel_directives.log_verbosity_level, zend_accel_globals, accel_globals)
+ STD_PHP_INI_ENTRY("opcache.memory_consumption" , "64" , PHP_INI_SYSTEM, OnUpdateMemoryConsumption, accel_directives.memory_consumption, zend_accel_globals, accel_globals)
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ STD_PHP_INI_ENTRY("opcache.interned_strings_buffer", "4" , PHP_INI_SYSTEM, OnUpdateLong, accel_directives.interned_strings_buffer, zend_accel_globals, accel_globals)
+#endif
+ STD_PHP_INI_ENTRY("opcache.max_accelerated_files" , "2000", PHP_INI_SYSTEM, OnUpdateMaxAcceleratedFiles, accel_directives.max_accelerated_files, zend_accel_globals, accel_globals)
+ STD_PHP_INI_ENTRY("opcache.max_wasted_percentage" , "5" , PHP_INI_SYSTEM, OnUpdateMaxWastedPercentage, accel_directives.max_wasted_percentage, zend_accel_globals, accel_globals)
+ STD_PHP_INI_ENTRY("opcache.consistency_checks" , "0" , PHP_INI_ALL , OnUpdateLong, accel_directives.consistency_checks, zend_accel_globals, accel_globals)
+ STD_PHP_INI_ENTRY("opcache.force_restart_timeout" , "180" , PHP_INI_SYSTEM, OnUpdateLong, accel_directives.force_restart_timeout, zend_accel_globals, accel_globals)
+ STD_PHP_INI_ENTRY("opcache.revalidate_freq" , "2" , PHP_INI_ALL , OnUpdateLong, accel_directives.revalidate_freq, zend_accel_globals, accel_globals)
+ STD_PHP_INI_ENTRY("opcache.file_update_protection", "2" , PHP_INI_ALL , OnUpdateLong, accel_directives.file_update_protection, zend_accel_globals, accel_globals)
+ STD_PHP_INI_ENTRY("opcache.preferred_memory_model", "" , PHP_INI_SYSTEM, OnUpdateStringUnempty, accel_directives.memory_model, zend_accel_globals, accel_globals)
+ STD_PHP_INI_ENTRY("opcache.blacklist_filename" , "" , PHP_INI_SYSTEM, OnUpdateString, accel_directives.user_blacklist_filename, zend_accel_globals, accel_globals)
+ STD_PHP_INI_ENTRY("opcache.max_file_size" , "0" , PHP_INI_SYSTEM, OnUpdateLong, accel_directives.max_file_size, zend_accel_globals, accel_globals)
+
+ STD_PHP_INI_ENTRY("opcache.protect_memory" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.protect_memory, zend_accel_globals, accel_globals)
+ STD_PHP_INI_ENTRY("opcache.save_comments" , "1" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.save_comments, zend_accel_globals, accel_globals)
+ STD_PHP_INI_ENTRY("opcache.load_comments" , "1" , PHP_INI_ALL, OnUpdateBool, accel_directives.load_comments, zend_accel_globals, accel_globals)
+ STD_PHP_INI_ENTRY("opcache.fast_shutdown" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.fast_shutdown, zend_accel_globals, accel_globals)
+
+ STD_PHP_INI_ENTRY("opcache.optimization_level" , DEFAULT_OPTIMIZATION_LEVEL , PHP_INI_SYSTEM, OnUpdateLong, accel_directives.optimization_level, zend_accel_globals, accel_globals)
+ STD_PHP_INI_BOOLEAN("opcache.enable_file_override" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.file_override_enabled, zend_accel_globals, accel_globals)
+ STD_PHP_INI_BOOLEAN("opcache.enable_cli" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.enable_cli, zend_accel_globals, accel_globals)
+ STD_PHP_INI_ENTRY("opcache.error_log" , "" , PHP_INI_SYSTEM, OnUpdateString, accel_directives.error_log, zend_accel_globals, accel_globals)
+ STD_PHP_INI_ENTRY("opcache.restrict_api" , "" , PHP_INI_SYSTEM, OnUpdateString, accel_directives.restrict_api, zend_accel_globals, accel_globals)
+
+#ifdef ZEND_WIN32
+ STD_PHP_INI_ENTRY("opcache.mmap_base", NULL, PHP_INI_SYSTEM, OnUpdateString, accel_directives.mmap_base, zend_accel_globals, accel_globals)
+#endif
+ZEND_INI_END()
+
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+
+#undef EX
+#define EX(element) execute_data->element
+#define EX_T(offset) (*(temp_variable *)((char *) EX(Ts) + offset))
+
+static int ZEND_DECLARE_INHERITED_CLASS_DELAYED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+ zend_class_entry **pce, **pce_orig;
+
+ if (zend_hash_find(EG(class_table), Z_STRVAL(EX(opline)->op2.u.constant), Z_STRLEN(EX(opline)->op2.u.constant) + 1, (void **)&pce) == FAILURE ||
+ (zend_hash_find(EG(class_table), Z_STRVAL(EX(opline)->op1.u.constant), Z_STRLEN(EX(opline)->op1.u.constant), (void**)&pce_orig) == SUCCESS &&
+ *pce != *pce_orig)) {
+ do_bind_inherited_class(EX(opline), EG(class_table), EX_T(EX(opline)->extended_value).class_entry, 0 TSRMLS_CC);
+ }
+ EX(opline)++;
+ return ZEND_USER_OPCODE_CONTINUE;
+}
+#endif
+
+static int filename_is_in_cache(char *filename, int filename_len TSRMLS_DC)
+{
+ char *key;
+ int key_length;
+ zend_file_handle handle = {0};
+ zend_persistent_script *persistent_script;
+
+ handle.filename = filename;
+ handle.type = ZEND_HANDLE_FILENAME;
+
+ if (IS_ABSOLUTE_PATH(filename, filename_len)) {
+ persistent_script = zend_accel_hash_find(&ZCSG(hash), filename, filename_len + 1);
+ if (persistent_script) {
+ return !persistent_script->corrupted &&
+ validate_timestamp_and_record(persistent_script, &handle TSRMLS_CC) == SUCCESS;
+ }
+ }
+
+ if ((key = accel_make_persistent_key_ex(&handle, filename_len, &key_length TSRMLS_CC)) != NULL) {
+ persistent_script = zend_accel_hash_find(&ZCSG(hash), key, key_length + 1);
+ return persistent_script && !persistent_script->corrupted &&
+ validate_timestamp_and_record(persistent_script, &handle TSRMLS_CC) == SUCCESS;
+ }
+
+ return 0;
+}
+
+static int accel_file_in_cache(INTERNAL_FUNCTION_PARAMETERS)
+{
+ zval **zfilename;
+
+ if (ZEND_NUM_ARGS() != 1 ||
+ zend_get_parameters_array_ex(1, &zfilename) == FAILURE ||
+ Z_TYPE_PP(zfilename) != IS_STRING ||
+ Z_STRLEN_PP(zfilename) == 0) {
+ return 0;
+ }
+ return filename_is_in_cache(Z_STRVAL_PP(zfilename), Z_STRLEN_PP(zfilename) TSRMLS_CC);
+}
+
+static void accel_file_exists(INTERNAL_FUNCTION_PARAMETERS)
+{
+ if (accel_file_in_cache(INTERNAL_FUNCTION_PARAM_PASSTHRU)) {
+ RETURN_TRUE;
+ } else {
+ orig_file_exists(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ }
+}
+
+static void accel_is_file(INTERNAL_FUNCTION_PARAMETERS)
+{
+ if (accel_file_in_cache(INTERNAL_FUNCTION_PARAM_PASSTHRU)) {
+ RETURN_TRUE;
+ } else {
+ orig_is_file(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ }
+}
+
+static void accel_is_readable(INTERNAL_FUNCTION_PARAMETERS)
+{
+ if (accel_file_in_cache(INTERNAL_FUNCTION_PARAM_PASSTHRU)) {
+ RETURN_TRUE;
+ } else {
+ orig_is_readable(INTERNAL_FUNCTION_PARAM_PASSTHRU);
+ }
+}
+
+static ZEND_MINIT_FUNCTION(zend_accelerator)
+{
+ (void)type; /* keep the compiler happy */
+
+ REGISTER_INI_ENTRIES();
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+ zend_set_user_opcode_handler(ZEND_DECLARE_INHERITED_CLASS_DELAYED, ZEND_DECLARE_INHERITED_CLASS_DELAYED_HANDLER);
+#endif
+ return SUCCESS;
+}
+
+void zend_accel_override_file_functions(TSRMLS_D)
+{
+ zend_function *old_function;
+ if (ZCG(enabled) && accel_startup_ok && ZCG(accel_directives).file_override_enabled) {
+ /* override file_exists */
+ if (zend_hash_find(CG(function_table), "file_exists", sizeof("file_exists"), (void **)&old_function) == SUCCESS) {
+ orig_file_exists = old_function->internal_function.handler;
+ old_function->internal_function.handler = accel_file_exists;
+ }
+ if (zend_hash_find(CG(function_table), "is_file", sizeof("is_file"), (void **)&old_function) == SUCCESS) {
+ orig_is_file = old_function->internal_function.handler;
+ old_function->internal_function.handler = accel_is_file;
+ }
+ if (zend_hash_find(CG(function_table), "is_readable", sizeof("is_readable"), (void **)&old_function) == SUCCESS) {
+ orig_is_readable = old_function->internal_function.handler;
+ old_function->internal_function.handler = accel_is_readable;
+ }
+ }
+}
+
+static ZEND_MSHUTDOWN_FUNCTION(zend_accelerator)
+{
+ (void)type; /* keep the compiler happy */
+
+ UNREGISTER_INI_ENTRIES();
+ accel_shutdown(TSRMLS_C);
+ return SUCCESS;
+}
+
+void zend_accel_info(ZEND_MODULE_INFO_FUNC_ARGS)
+{
+ php_info_print_table_start();
+
+ if (ZCG(enabled) && accel_startup_ok && (ZCG(counted) || ZCSG(accelerator_enabled))) {
+ php_info_print_table_row(2, "Opcode Caching", "Up and Running");
+ } else {
+ php_info_print_table_row(2, "Opcode Caching", "Disabled");
+ }
+ if (ZCG(enabled) && accel_startup_ok && ZCSG(accelerator_enabled) && ZCG(accel_directives).optimization_level) {
+ php_info_print_table_row(2, "Optimization", "Enabled");
+ } else {
+ php_info_print_table_row(2, "Optimization", "Disabled");
+ }
+ if (ZCG(enabled)) {
+ if (!accel_startup_ok || zps_api_failure_reason) {
+ php_info_print_table_row(2, "Startup Failed", zps_api_failure_reason);
+ } else {
+ char buf[32];
+ php_info_print_table_row(2, "Startup", "OK");
+ php_info_print_table_row(2, "Shared memory model", zend_accel_get_shared_model());
+ snprintf(buf, sizeof(buf), "%ld", ZCSG(hits));
+ php_info_print_table_row(2, "Cache hits", buf);
+ snprintf(buf, sizeof(buf), "%ld", ZSMMG(memory_exhausted)?ZCSG(misses):ZCSG(misses)-ZCSG(blacklist_misses));
+ php_info_print_table_row(2, "Cache misses", buf);
+ snprintf(buf, sizeof(buf), "%ld", ZCG(accel_directives).memory_consumption-zend_shared_alloc_get_free_memory()-ZSMMG(wasted_shared_memory));
+ php_info_print_table_row(2, "Used memory", buf);
+ snprintf(buf, sizeof(buf), "%ld", zend_shared_alloc_get_free_memory());
+ php_info_print_table_row(2, "Free memory", buf);
+ snprintf(buf, sizeof(buf), "%ld", ZSMMG(wasted_shared_memory));
+ php_info_print_table_row(2, "Wasted memory", buf);
+ snprintf(buf, sizeof(buf), "%ld", ZCSG(hash).num_direct_entries);
+ php_info_print_table_row(2, "Cached scripts", buf);
+ snprintf(buf, sizeof(buf), "%ld", ZCSG(hash).num_entries);
+ php_info_print_table_row(2, "Cached keys", buf);
+ snprintf(buf, sizeof(buf), "%ld", ZCSG(hash).max_num_entries);
+ php_info_print_table_row(2, "Max keys", buf);
+ snprintf(buf, sizeof(buf), "%ld", ZCSG(oom_restarts));
+ php_info_print_table_row(2, "OOM restarts", buf);
+ snprintf(buf, sizeof(buf), "%ld", ZCSG(hash_restarts));
+ php_info_print_table_row(2, "Hash keys restarts", buf);
+ snprintf(buf, sizeof(buf), "%ld", ZCSG(manual_restarts));
+ php_info_print_table_row(2, "Manual restarts", buf);
+ }
+ }
+
+ php_info_print_table_end();
+ DISPLAY_INI_ENTRIES();
+}
+
+static zend_module_entry accel_module_entry = {
+ STANDARD_MODULE_HEADER,
+ ACCELERATOR_PRODUCT_NAME,
+ accel_functions,
+ ZEND_MINIT(zend_accelerator),
+ ZEND_MSHUTDOWN(zend_accelerator),
+ NULL,
+ NULL,
+ zend_accel_info,
+ ACCELERATOR_VERSION "FE",
+ STANDARD_MODULE_PROPERTIES
+};
+
+int start_accel_module(void)
+{
+ return zend_startup_module(&accel_module_entry);
+}
+
+/* {{{ proto array accelerator_get_scripts()
+ Get the scripts which are accelerated by ZendAccelerator */
+static zval* accelerator_get_scripts(TSRMLS_D)
+{
+ uint i;
+ zval *return_value,*persistent_script_report;
+ zend_accel_hash_entry *cache_entry;
+ struct tm *ta;
+ struct timeval exec_time;
+ struct timeval fetch_time;
+
+ if (!ZCG(enabled) || !accel_startup_ok || !ZCSG(accelerator_enabled) || accelerator_shm_read_lock(TSRMLS_C) != SUCCESS) {
+ return 0;
+ }
+
+ MAKE_STD_ZVAL(return_value);
+ array_init(return_value);
+ for (i = 0; i<ZCSG(hash).max_num_entries; i++) {
+ for (cache_entry = ZCSG(hash).hash_table[i]; cache_entry; cache_entry = cache_entry->next) {
+ zend_persistent_script *script;
+ char *str;
+ size_t len;
+
+ if (cache_entry->indirect) continue;
+
+ script = (zend_persistent_script *)cache_entry->data;
+
+ MAKE_STD_ZVAL(persistent_script_report);
+ array_init(persistent_script_report);
+ add_assoc_stringl(persistent_script_report, "full_path", script->full_path, script->full_path_len, 1);
+ add_assoc_long(persistent_script_report, "hits", script->dynamic_members.hits);
+ add_assoc_long(persistent_script_report, "memory_consumption", script->dynamic_members.memory_consumption);
+ ta = localtime(&script->dynamic_members.last_used);
+ str = asctime(ta);
+ len = strlen(str);
+ if (len > 0 && str[len - 1] == '\n') len--;
+ add_assoc_stringl(persistent_script_report, "last_used", str, len, 1);
+ add_assoc_long(persistent_script_report, "last_used_timestamp", script->dynamic_members.last_used);
+ if (ZCG(accel_directives).validate_timestamps) {
+ add_assoc_long(persistent_script_report, "timestamp", (long)script->timestamp);
+ }
+ timerclear(&exec_time);
+ timerclear(&fetch_time);
+
+ zend_hash_update(return_value->value.ht, cache_entry->key, cache_entry->key_length, &persistent_script_report, sizeof(zval *), NULL);
+ }
+ }
+ accelerator_shm_read_unlock(TSRMLS_C);
+
+ return return_value;
+}
+
+/* {{{ proto array accelerator_get_status([bool fetch_scripts])
+ Obtain statistics information regarding code acceleration */
+static ZEND_FUNCTION(opcache_get_status)
+{
+ long reqs;
+ zval *memory_usage,*statistics,*scripts;
+ zend_bool fetch_scripts = 1;
+
+ /* keep the compiler happy */
+ (void)ht; (void)return_value_ptr; (void)this_ptr; (void)return_value_used;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &fetch_scripts) == FAILURE) {
+ return;
+ }
+
+ if (!validate_api_restriction(TSRMLS_C)) {
+ RETURN_FALSE;
+ }
+
+ if (!accel_startup_ok) {
+ RETURN_FALSE;
+ }
+
+ array_init(return_value);
+
+ /* Trivia */
+ add_assoc_bool(return_value, "opcache_enabled", ZCG(enabled) && (ZCG(counted) || ZCSG(accelerator_enabled)));
+ add_assoc_bool(return_value, "cache_full", ZSMMG(memory_exhausted));
+ add_assoc_bool(return_value, "restart_pending", ZCSG(restart_pending));
+ add_assoc_bool(return_value, "restart_in_progress", ZCSG(restart_in_progress));
+
+ /* Memory usage statistics */
+ MAKE_STD_ZVAL(memory_usage);
+ array_init(memory_usage);
+ add_assoc_long(memory_usage, "used_memory", ZCG(accel_directives).memory_consumption-zend_shared_alloc_get_free_memory()-ZSMMG(wasted_shared_memory));
+ add_assoc_long(memory_usage, "free_memory", zend_shared_alloc_get_free_memory());
+ add_assoc_long(memory_usage, "wasted_memory", ZSMMG(wasted_shared_memory));
+ add_assoc_double(memory_usage, "current_wasted_percentage", (((double) ZSMMG(wasted_shared_memory))/ZCG(accel_directives).memory_consumption)*100.0);
+ add_assoc_zval(return_value, "memory_usage", memory_usage);
+
+ /* Accelerator statistics */
+ MAKE_STD_ZVAL(statistics);
+ array_init(statistics);
+ add_assoc_long(statistics, "num_cached_scripts", ZCSG(hash).num_direct_entries);
+ add_assoc_long(statistics, "num_cached_keys", ZCSG(hash).num_entries);
+ add_assoc_long(statistics, "max_cached_keys", ZCSG(hash).max_num_entries);
+ add_assoc_long(statistics, "hits", ZCSG(hits));
+ add_assoc_long(statistics, "start_time", ZCSG(start_time));
+ add_assoc_long(statistics, "last_restart_time", ZCSG(last_restart_time));
+ add_assoc_long(statistics, "oom_restarts", ZCSG(oom_restarts));
+ add_assoc_long(statistics, "hash_restarts", ZCSG(hash_restarts));
+ add_assoc_long(statistics, "manual_restarts", ZCSG(manual_restarts));
+ add_assoc_long(statistics, "misses", ZSMMG(memory_exhausted)?ZCSG(misses):ZCSG(misses)-ZCSG(blacklist_misses));
+ add_assoc_long(statistics, "blacklist_misses", ZCSG(blacklist_misses));
+ reqs = ZCSG(hits)+ZCSG(misses);
+ add_assoc_double(statistics, "blacklist_miss_ratio", reqs?(((double) ZCSG(blacklist_misses))/reqs)*100.0:0);
+ add_assoc_double(statistics, "opcache_hit_rate", reqs?(((double) ZCSG(hits))/reqs)*100.0:0);
+ add_assoc_zval(return_value, "opcache_statistics", statistics);
+
+ if (fetch_scripts) {
+ /* accelerated scripts */
+ scripts = accelerator_get_scripts(TSRMLS_C);
+ if (scripts) {
+ add_assoc_zval(return_value, "scripts", scripts);
+ }
+ }
+}
+
+static int add_blacklist_path(zend_blacklist_entry *p, zval *return_value TSRMLS_DC)
+{
+ add_next_index_stringl(return_value, p->path, p->path_length, 1);
+ return 0;
+}
+
+/* {{{ proto array accelerator_get_configuration()
+ Obtain configuration information */
+static ZEND_FUNCTION(opcache_get_configuration)
+{
+ zval *directives,*version,*blacklist;
+
+ /* keep the compiler happy */
+ (void)ht; (void)return_value_ptr; (void)this_ptr; (void)return_value_used;
+
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+ if (zend_parse_parameters_none() == FAILURE) {
+ RETURN_FALSE;
+ }
+#endif
+
+ if (!validate_api_restriction(TSRMLS_C)) {
+ RETURN_FALSE;
+ }
+
+ array_init(return_value);
+
+ /* directives */
+ MAKE_STD_ZVAL(directives);
+ array_init(directives);
+ add_assoc_bool(directives, "opcache.enable", ZCG(enabled));
+ add_assoc_bool(directives, "opcache.enable_cli", ZCG(accel_directives).enable_cli);
+ add_assoc_bool(directives, "opcache.use_cwd", ZCG(accel_directives).use_cwd);
+ add_assoc_bool(directives, "opcache.validate_timestamps", ZCG(accel_directives).validate_timestamps);
+ add_assoc_bool(directives, "opcache.inherited_hack", ZCG(accel_directives).inherited_hack);
+ add_assoc_bool(directives, "opcache.dups_fix", ZCG(accel_directives).ignore_dups);
+ add_assoc_bool(directives, "opcache.revalidate_path", ZCG(accel_directives).revalidate_path);
+
+ add_assoc_long(directives, "opcache.log_verbosity_level", ZCG(accel_directives).log_verbosity_level);
+ add_assoc_long(directives, "opcache.memory_consumption", ZCG(accel_directives).memory_consumption);
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ add_assoc_long(directives, "opcache.interned_strings_buffer",ZCG(accel_directives).interned_strings_buffer);
+#endif
+ add_assoc_long(directives, "opcache.max_accelerated_files", ZCG(accel_directives).max_accelerated_files);
+ add_assoc_double(directives, "opcache.max_wasted_percentage", ZCG(accel_directives).max_wasted_percentage);
+ add_assoc_long(directives, "opcache.consistency_checks", ZCG(accel_directives).consistency_checks);
+ add_assoc_long(directives, "opcache.force_restart_timeout", ZCG(accel_directives).force_restart_timeout);
+ add_assoc_long(directives, "opcache.revalidate_freq", ZCG(accel_directives).revalidate_freq);
+ add_assoc_string(directives, "opcache.preferred_memory_model", STRING_NOT_NULL(ZCG(accel_directives).memory_model), 1);
+ add_assoc_string(directives, "opcache.blacklist_filename", STRING_NOT_NULL(ZCG(accel_directives).user_blacklist_filename), 1);
+ add_assoc_long(directives, "opcache.max_file_size", ZCG(accel_directives).max_file_size);
+ add_assoc_string(directives, "opcache.error_log", STRING_NOT_NULL(ZCG(accel_directives).error_log), 1);
+
+ add_assoc_bool(directives, "opcache.protect_memory", ZCG(accel_directives).protect_memory);
+ add_assoc_bool(directives, "opcache.save_comments", ZCG(accel_directives).save_comments);
+ add_assoc_bool(directives, "opcache.load_comments", ZCG(accel_directives).load_comments);
+ add_assoc_bool(directives, "opcache.fast_shutdown", ZCG(accel_directives).fast_shutdown);
+ add_assoc_bool(directives, "opcache.enable_file_override", ZCG(accel_directives).file_override_enabled);
+ add_assoc_long(directives, "opcache.optimization_level", ZCG(accel_directives).optimization_level);
+
+ add_assoc_zval(return_value, "directives", directives);
+
+ /*version */
+ MAKE_STD_ZVAL(version);
+ array_init(version);
+ add_assoc_string(version, "version", ACCELERATOR_VERSION, 1);
+ add_assoc_string(version, "opcache_product_name", ACCELERATOR_PRODUCT_NAME, 1);
+ add_assoc_zval(return_value, "version", version);
+
+ /* blacklist */
+ MAKE_STD_ZVAL(blacklist);
+ array_init(blacklist);
+ zend_accel_blacklist_apply(&accel_blacklist, (apply_func_arg_t) add_blacklist_path, blacklist TSRMLS_CC);
+ add_assoc_zval(return_value, "blacklist", blacklist);
+}
+
+/* {{{ proto void accelerator_reset()
+ Request that the contents of the opcode cache to be reset */
+static ZEND_FUNCTION(opcache_reset)
+{
+ /* keep the compiler happy */
+ (void)ht; (void)return_value_ptr; (void)this_ptr; (void)return_value_used;
+
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+ if (zend_parse_parameters_none() == FAILURE) {
+ RETURN_FALSE;
+ }
+#endif
+
+ if (!validate_api_restriction(TSRMLS_C)) {
+ RETURN_FALSE;
+ }
+
+ if (!ZCG(enabled) || !accel_startup_ok || !ZCSG(accelerator_enabled)) {
+ RETURN_FALSE;
+ }
+
+ zend_accel_schedule_restart(ACCEL_RESTART_USER TSRMLS_CC);
+ RETURN_TRUE;
+}
+
+/* {{{ proto void opcache_invalidate(string $script [, bool $force = false])
+ Invalidates cached script (in necessary or forced) */
+static ZEND_FUNCTION(opcache_invalidate)
+{
+ char *script_name;
+ int script_name_len;
+ zend_bool force = 0;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|b", &script_name, &script_name_len, &force) == FAILURE) {
+ return;
+ }
+
+ if (!validate_api_restriction(TSRMLS_C)) {
+ RETURN_FALSE;
+ }
+
+ if (zend_accel_invalidate(script_name, script_name_len, force TSRMLS_CC) == SUCCESS) {
+ RETURN_TRUE;
+ } else {
+ RETURN_FALSE;
+ }
+}
+
+static ZEND_FUNCTION(opcache_compile_file)
+{
+ char *script_name;
+ int script_name_len;
+ zend_file_handle handle;
+ zend_op_array *op_array = NULL;
+ zend_execute_data *orig_execute_data = NULL;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &script_name, &script_name_len) == FAILURE) {
+ return;
+ }
+
+ if (!ZCG(enabled) || !accel_startup_ok || !ZCSG(accelerator_enabled)) {
+ zend_error(E_NOTICE, ACCELERATOR_PRODUCT_NAME " seems to be disabled, can't compile file");
+ RETURN_FALSE;
+ }
+
+ handle.filename = script_name;
+ handle.free_filename = 0;
+ handle.opened_path = NULL;
+ handle.type = ZEND_HANDLE_FILENAME;
+
+ orig_execute_data = EG(current_execute_data);
+
+ zend_try {
+ op_array = persistent_compile_file(&handle, ZEND_INCLUDE TSRMLS_CC);
+ } zend_catch {
+ EG(current_execute_data) = orig_execute_data;
+ zend_error(E_WARNING, ACCELERATOR_PRODUCT_NAME " could not compile file %s" TSRMLS_CC, handle.filename);
+ } zend_end_try();
+
+ if(op_array != NULL) {
+ destroy_op_array(op_array TSRMLS_CC);
+ efree(op_array);
+ RETVAL_TRUE;
+ } else {
+ RETVAL_FALSE;
+ }
+ zend_destroy_file_handle(&handle TSRMLS_CC);
+}
diff --git a/ext/opcache/zend_accelerator_module.h b/ext/opcache/zend_accelerator_module.h
new file mode 100644
index 0000000000..ece4a7d6b5
--- /dev/null
+++ b/ext/opcache/zend_accelerator_module.h
@@ -0,0 +1,28 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2014 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: Andi Gutmans <andi@zend.com> |
+ | Zeev Suraski <zeev@zend.com> |
+ | Stanislav Malyshev <stas@zend.com> |
+ | Dmitry Stogov <dmitry@zend.com> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef ZEND_ACCELERATOR_MODULE_H
+#define ZEND_ACCELERATOR_MODULE_H
+
+int start_accel_module(void);
+void zend_accel_override_file_functions(TSRMLS_D);
+
+#endif /* _ZEND_ACCELERATOR_MODULE_H */
diff --git a/ext/opcache/zend_accelerator_util_funcs.c b/ext/opcache/zend_accelerator_util_funcs.c
new file mode 100644
index 0000000000..14c6f7490f
--- /dev/null
+++ b/ext/opcache/zend_accelerator_util_funcs.c
@@ -0,0 +1,1077 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2014 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: Andi Gutmans <andi@zend.com> |
+ | Zeev Suraski <zeev@zend.com> |
+ | Stanislav Malyshev <stas@zend.com> |
+ | Dmitry Stogov <dmitry@zend.com> |
+ +----------------------------------------------------------------------+
+*/
+
+#include "zend_API.h"
+#include "zend_constants.h"
+#include "zend_accelerator_util_funcs.h"
+#include "zend_persist.h"
+#include "zend_shared_alloc.h"
+
+#define ZEND_PROTECTED_REFCOUNT (1<<30)
+
+static zend_uint zend_accel_refcount = ZEND_PROTECTED_REFCOUNT;
+
+#if SIZEOF_SIZE_T <= SIZEOF_LONG
+/* If sizeof(void*) == sizeof(ulong) we can use zend_hash index functions */
+# define accel_xlat_set(old, new) zend_hash_index_update(&ZCG(bind_hash), (ulong)(zend_uintptr_t)(old), &(new), sizeof(void*), NULL)
+# define accel_xlat_get(old, new) zend_hash_index_find(&ZCG(bind_hash), (ulong)(zend_uintptr_t)(old), (void**)&(new))
+#else
+# define accel_xlat_set(old, new) zend_hash_quick_add(&ZCG(bind_hash), (char*)&(old), sizeof(void*), (ulong)(zend_uintptr_t)(old), (void**)&(new), sizeof(void*), NULL)
+# define accel_xlat_get(old, new) zend_hash_quick_find(&ZCG(bind_hash), (char*)&(old), sizeof(void*), (ulong)(zend_uintptr_t)(old), (void**)&(new))
+#endif
+
+typedef int (*id_function_t)(void *, void *);
+typedef void (*unique_copy_ctor_func_t)(void *pElement);
+
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+static const Bucket *uninitialized_bucket = NULL;
+#endif
+
+static int zend_prepare_function_for_execution(zend_op_array *op_array);
+static void zend_hash_clone_zval(HashTable *ht, HashTable *source, int bind);
+
+static void zend_accel_destroy_zend_function(zend_function *function)
+{
+ TSRMLS_FETCH();
+
+ if (function->type == ZEND_USER_FUNCTION) {
+ if (function->op_array.static_variables) {
+
+ efree(function->op_array.static_variables);
+ function->op_array.static_variables = NULL;
+ }
+ }
+
+ destroy_zend_function(function TSRMLS_CC);
+}
+
+static void zend_accel_destroy_zend_class(zend_class_entry **pce)
+{
+ zend_class_entry *ce = *pce;
+
+ ce->function_table.pDestructor = (dtor_func_t) zend_accel_destroy_zend_function;
+ destroy_zend_class(pce);
+}
+
+zend_persistent_script* create_persistent_script(void)
+{
+ zend_persistent_script *persistent_script = (zend_persistent_script *) emalloc(sizeof(zend_persistent_script));
+ memset(persistent_script, 0, sizeof(zend_persistent_script));
+
+ zend_hash_init(&persistent_script->function_table, 100, NULL, (dtor_func_t) zend_accel_destroy_zend_function, 0);
+ /* class_table is usually destroyed by free_persistent_script() that
+ * overrides destructor. ZEND_CLASS_DTOR may be used by standard
+ * PHP compiler
+ */
+ zend_hash_init(&persistent_script->class_table, 10, NULL, ZEND_CLASS_DTOR, 0);
+
+ return persistent_script;
+}
+
+static int compact_hash_table(HashTable *ht)
+{
+ uint i = 3;
+ uint nSize;
+ Bucket **t;
+
+ if (!ht->nNumOfElements) {
+ /* Empty tables don't allocate space for Buckets */
+ return 1;
+ }
+
+ if (ht->nNumOfElements >= 0x80000000) {
+ /* prevent overflow */
+ nSize = 0x80000000;
+ } else {
+ while ((1U << i) < ht->nNumOfElements) {
+ i++;
+ }
+ nSize = 1 << i;
+ }
+
+ if (nSize >= ht->nTableSize) {
+ /* Keep the size */
+ return 1;
+ }
+
+ t = (Bucket **)pemalloc(nSize * sizeof(Bucket *), ht->persistent);
+ if (!t) {
+ return 0;
+ }
+
+ pefree(ht->arBuckets, ht->persistent);
+
+ ht->arBuckets = t;
+ ht->nTableSize = nSize;
+ ht->nTableMask = ht->nTableSize - 1;
+ zend_hash_rehash(ht);
+
+ return 1;
+}
+
+int compact_persistent_script(zend_persistent_script *persistent_script)
+{
+ return compact_hash_table(&persistent_script->function_table) &&
+ compact_hash_table(&persistent_script->class_table);
+}
+
+void free_persistent_script(zend_persistent_script *persistent_script, int destroy_elements)
+{
+ if (destroy_elements) {
+ persistent_script->function_table.pDestructor = (dtor_func_t)zend_accel_destroy_zend_function;
+ persistent_script->class_table.pDestructor = (dtor_func_t)zend_accel_destroy_zend_class;
+ } else {
+ persistent_script->function_table.pDestructor = NULL;
+ persistent_script->class_table.pDestructor = NULL;
+ }
+
+ zend_hash_destroy(&persistent_script->function_table);
+ zend_hash_destroy(&persistent_script->class_table);
+
+ if (persistent_script->full_path) {
+ efree(persistent_script->full_path);
+ }
+
+ efree(persistent_script);
+}
+
+static int is_not_internal_function(zend_function *function)
+{
+ return(function->type != ZEND_INTERNAL_FUNCTION);
+}
+
+void zend_accel_free_user_functions(HashTable *ht TSRMLS_DC)
+{
+ dtor_func_t orig_dtor = ht->pDestructor;
+
+ ht->pDestructor = NULL;
+ zend_hash_apply(ht, (apply_func_t) is_not_internal_function TSRMLS_CC);
+ ht->pDestructor = orig_dtor;
+}
+
+static int move_user_function(zend_function *function
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+ TSRMLS_DC
+#endif
+ , int num_args, va_list args, zend_hash_key *hash_key)
+{
+ HashTable *function_table = va_arg(args, HashTable *);
+ (void)num_args; /* keep the compiler happy */
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+ TSRMLS_FETCH();
+#endif
+
+ if (function->type == ZEND_USER_FUNCTION) {
+ zend_hash_quick_update(function_table, hash_key->arKey, hash_key->nKeyLength, hash_key->h, function, sizeof(zend_function), NULL);
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+void zend_accel_move_user_functions(HashTable *src, HashTable *dst TSRMLS_DC)
+{
+ dtor_func_t orig_dtor = src->pDestructor;
+
+ src->pDestructor = NULL;
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+ zend_hash_apply_with_arguments(src, (apply_func_args_t)move_user_function, 1, dst);
+#else
+ zend_hash_apply_with_arguments(src TSRMLS_CC, (apply_func_args_t)move_user_function, 1, dst);
+#endif
+ src->pDestructor = orig_dtor;
+}
+
+static int copy_internal_function(zend_function *function, HashTable *function_table TSRMLS_DC)
+{
+ if (function->type == ZEND_INTERNAL_FUNCTION) {
+ zend_hash_update(function_table, function->common.function_name, strlen(function->common.function_name) + 1, function, sizeof(zend_function), NULL);
+ }
+ return 0;
+}
+
+void zend_accel_copy_internal_functions(TSRMLS_D)
+{
+ zend_hash_apply_with_argument(CG(function_table), (apply_func_arg_t)copy_internal_function, &ZCG(function_table) TSRMLS_CC);
+ ZCG(internal_functions_count) = zend_hash_num_elements(&ZCG(function_table));
+}
+
+static void zend_destroy_property_info(zend_property_info *property_info)
+{
+ interned_efree((char*)property_info->name);
+ if (property_info->doc_comment) {
+ efree((char*)property_info->doc_comment);
+ }
+}
+
+static inline zval* zend_clone_zval(zval *src, int bind TSRMLS_DC)
+{
+ zval *ret, **ret_ptr = NULL;
+
+ if (!bind) {
+ ALLOC_ZVAL(ret);
+ *ret = *src;
+ INIT_PZVAL(ret);
+ } else if (Z_REFCOUNT_P(src) == 1) {
+ ALLOC_ZVAL(ret);
+ *ret = *src;
+ } else if (accel_xlat_get(src, ret_ptr) != SUCCESS) {
+ ALLOC_ZVAL(ret);
+ *ret = *src;
+ accel_xlat_set(src, ret);
+ } else {
+ return *ret_ptr;
+ }
+
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+ if ((Z_TYPE_P(ret) & IS_CONSTANT_TYPE_MASK) >= IS_ARRAY) {
+ switch ((Z_TYPE_P(ret) & IS_CONSTANT_TYPE_MASK)) {
+#else
+ if ((Z_TYPE_P(ret) & ~IS_CONSTANT_INDEX) >= IS_ARRAY) {
+ switch ((Z_TYPE_P(ret) & ~IS_CONSTANT_INDEX)) {
+#endif
+ case IS_STRING:
+ case IS_CONSTANT:
+ Z_STRVAL_P(ret) = (char *) interned_estrndup(Z_STRVAL_P(ret), Z_STRLEN_P(ret));
+ break;
+ case IS_ARRAY:
+ case IS_CONSTANT_ARRAY:
+ if (ret->value.ht && ret->value.ht != &EG(symbol_table)) {
+ ALLOC_HASHTABLE(ret->value.ht);
+ zend_hash_clone_zval(ret->value.ht, src->value.ht, 0);
+ }
+ break;
+ }
+ }
+ return ret;
+}
+
+static void zend_hash_clone_zval(HashTable *ht, HashTable *source, int bind)
+{
+ Bucket *p, *q, **prev;
+ ulong nIndex;
+ zval *ppz;
+ TSRMLS_FETCH();
+
+ ht->nTableSize = source->nTableSize;
+ ht->nTableMask = source->nTableMask;
+ ht->nNumOfElements = source->nNumOfElements;
+ ht->nNextFreeElement = source->nNextFreeElement;
+ ht->pDestructor = ZVAL_PTR_DTOR;
+#if ZEND_DEBUG
+ ht->inconsistent = 0;
+#endif
+ ht->persistent = 0;
+ ht->arBuckets = NULL;
+ ht->pListHead = NULL;
+ ht->pListTail = NULL;
+ ht->pInternalPointer = NULL;
+ ht->nApplyCount = 0;
+ ht->bApplyProtection = 1;
+
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ if (!ht->nTableMask) {
+ ht->arBuckets = (Bucket**)&uninitialized_bucket;
+ return;
+ }
+#endif
+
+ ht->arBuckets = (Bucket **) ecalloc(ht->nTableSize, sizeof(Bucket *));
+
+ prev = &ht->pListHead;
+ p = source->pListHead;
+ while (p) {
+ nIndex = p->h & ht->nTableMask;
+
+ /* Create bucket and initialize key */
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ if (!p->nKeyLength) {
+ q = (Bucket *) emalloc(sizeof(Bucket));
+ q->arKey = NULL;
+ } else if (IS_INTERNED(p->arKey)) {
+ q = (Bucket *) emalloc(sizeof(Bucket));
+ q->arKey = p->arKey;
+ } else {
+ q = (Bucket *) emalloc(sizeof(Bucket) + p->nKeyLength);
+ q->arKey = ((char*)q) + sizeof(Bucket);
+ memcpy((char*)q->arKey, p->arKey, p->nKeyLength);
+ }
+#else
+ q = (Bucket *) emalloc(sizeof(Bucket) - 1 + p->nKeyLength);
+ if (p->nKeyLength) {
+ memcpy(q->arKey, p->arKey, p->nKeyLength);
+ }
+#endif
+ q->h = p->h;
+ q->nKeyLength = p->nKeyLength;
+
+ /* Insert into hash collision list */
+ q->pNext = ht->arBuckets[nIndex];
+ q->pLast = NULL;
+ if (q->pNext) {
+ q->pNext->pLast = q;
+ }
+ ht->arBuckets[nIndex] = q;
+
+ /* Insert into global list */
+ q->pListLast = ht->pListTail;
+ ht->pListTail = q;
+ q->pListNext = NULL;
+ *prev = q;
+ prev = &q->pListNext;
+
+ /* Copy data */
+ q->pData = &q->pDataPtr;
+ if (!bind) {
+ ALLOC_ZVAL(ppz);
+ *ppz = *((zval*)p->pDataPtr);
+ INIT_PZVAL(ppz);
+ } else if (Z_REFCOUNT_P((zval*)p->pDataPtr) == 1) {
+ ALLOC_ZVAL(ppz);
+ *ppz = *((zval*)p->pDataPtr);
+ } else if (accel_xlat_get(p->pDataPtr, ppz) != SUCCESS) {
+ ALLOC_ZVAL(ppz);
+ *ppz = *((zval*)p->pDataPtr);
+ accel_xlat_set(p->pDataPtr, ppz);
+ } else {
+ q->pDataPtr = *(void**)ppz;
+ p = p->pListNext;
+ continue;
+ }
+ q->pDataPtr = (void*)ppz;
+
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+ if ((Z_TYPE_P((zval*)p->pDataPtr) & IS_CONSTANT_TYPE_MASK) >= IS_ARRAY) {
+ switch ((Z_TYPE_P((zval*)p->pDataPtr) & IS_CONSTANT_TYPE_MASK)) {
+#else
+ if ((Z_TYPE_P((zval*)p->pDataPtr) & ~IS_CONSTANT_INDEX) >= IS_ARRAY) {
+ switch ((Z_TYPE_P((zval*)p->pDataPtr) & ~IS_CONSTANT_INDEX)) {
+#endif
+ case IS_STRING:
+ case IS_CONSTANT:
+ Z_STRVAL_P(ppz) = (char *) interned_estrndup(Z_STRVAL_P((zval*)p->pDataPtr), Z_STRLEN_P((zval*)p->pDataPtr));
+ break;
+ case IS_ARRAY:
+ case IS_CONSTANT_ARRAY:
+ if (((zval*)p->pDataPtr)->value.ht && ((zval*)p->pDataPtr)->value.ht != &EG(symbol_table)) {
+ ALLOC_HASHTABLE(ppz->value.ht);
+ zend_hash_clone_zval(ppz->value.ht, ((zval*)p->pDataPtr)->value.ht, 0);
+ }
+ break;
+ }
+ }
+
+ p = p->pListNext;
+ }
+ ht->pInternalPointer = ht->pListHead;
+}
+
+static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class_entry *old_ce, zend_class_entry *ce TSRMLS_DC)
+{
+ Bucket *p, *q, **prev;
+ ulong nIndex;
+ zend_class_entry **new_ce;
+ zend_function** new_prototype;
+ zend_op_array *new_entry;
+
+ ht->nTableSize = source->nTableSize;
+ ht->nTableMask = source->nTableMask;
+ ht->nNumOfElements = source->nNumOfElements;
+ ht->nNextFreeElement = source->nNextFreeElement;
+ ht->pDestructor = ZEND_FUNCTION_DTOR;
+#if ZEND_DEBUG
+ ht->inconsistent = 0;
+#endif
+ ht->persistent = 0;
+ ht->pListHead = NULL;
+ ht->pListTail = NULL;
+ ht->pInternalPointer = NULL;
+ ht->nApplyCount = 0;
+ ht->bApplyProtection = 1;
+
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ if (!ht->nTableMask) {
+ ht->arBuckets = (Bucket**)&uninitialized_bucket;
+ return;
+ }
+#endif
+
+ ht->arBuckets = (Bucket **) ecalloc(ht->nTableSize, sizeof(Bucket *));
+
+ prev = &ht->pListHead;
+ p = source->pListHead;
+ while (p) {
+ nIndex = p->h & ht->nTableMask;
+
+ /* Create bucket and initialize key */
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ if (!p->nKeyLength) {
+ q = (Bucket *) emalloc(sizeof(Bucket));
+ q->arKey = NULL;
+ } else if (IS_INTERNED(p->arKey)) {
+ q = (Bucket *) emalloc(sizeof(Bucket));
+ q->arKey = p->arKey;
+ } else {
+ q = (Bucket *) emalloc(sizeof(Bucket) + p->nKeyLength);
+ q->arKey = ((char*)q) + sizeof(Bucket);
+ memcpy((char*)q->arKey, p->arKey, p->nKeyLength);
+ }
+#else
+ q = (Bucket *) emalloc(sizeof(Bucket) - 1 + p->nKeyLength);
+ if (p->nKeyLength) {
+ memcpy(q->arKey, p->arKey, p->nKeyLength);
+ }
+#endif
+ q->h = p->h;
+ q->nKeyLength = p->nKeyLength;
+
+ /* Insert into hash collision list */
+ q->pNext = ht->arBuckets[nIndex];
+ q->pLast = NULL;
+ if (q->pNext) {
+ q->pNext->pLast = q;
+ }
+ ht->arBuckets[nIndex] = q;
+
+ /* Insert into global list */
+ q->pListLast = ht->pListTail;
+ ht->pListTail = q;
+ q->pListNext = NULL;
+ *prev = q;
+ prev = &q->pListNext;
+
+ /* Copy data */
+ q->pData = (void *) emalloc(sizeof(zend_function));
+ new_entry = (zend_op_array*)q->pData;
+ *new_entry = *(zend_op_array*)p->pData;
+ q->pDataPtr = NULL;
+
+ /* Copy constructor */
+ /* we use refcount to show that op_array is referenced from several places */
+ if (new_entry->refcount != NULL) {
+ accel_xlat_set(p->pData, new_entry);
+ }
+
+ zend_prepare_function_for_execution(new_entry);
+
+ if (old_ce == new_entry->scope) {
+ new_entry->scope = ce;
+ } else {
+ if (accel_xlat_get(new_entry->scope, new_ce) == SUCCESS) {
+ new_entry->scope = *new_ce;
+ } else {
+ zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s, function %s", ce->name, new_entry->function_name);
+ }
+ }
+
+ /* update prototype */
+ if (new_entry->prototype) {
+ if (accel_xlat_get(new_entry->prototype, new_prototype) == SUCCESS) {
+ new_entry->prototype = *new_prototype;
+ } else {
+ zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s, function %s", ce->name, new_entry->function_name);
+ }
+ }
+
+ p = p->pListNext;
+ }
+ ht->pInternalPointer = ht->pListHead;
+}
+
+static void zend_hash_clone_prop_info(HashTable *ht, HashTable *source, zend_class_entry *old_ce, zend_class_entry *ce TSRMLS_DC)
+{
+ Bucket *p, *q, **prev;
+ ulong nIndex;
+ zend_class_entry **new_ce;
+ zend_property_info *prop_info;
+
+ ht->nTableSize = source->nTableSize;
+ ht->nTableMask = source->nTableMask;
+ ht->nNumOfElements = source->nNumOfElements;
+ ht->nNextFreeElement = source->nNextFreeElement;
+ ht->pDestructor = (dtor_func_t) zend_destroy_property_info;
+#if ZEND_DEBUG
+ ht->inconsistent = 0;
+#endif
+ ht->persistent = 0;
+ ht->pListHead = NULL;
+ ht->pListTail = NULL;
+ ht->pInternalPointer = NULL;
+ ht->nApplyCount = 0;
+ ht->bApplyProtection = 1;
+
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ if (!ht->nTableMask) {
+ ht->arBuckets = (Bucket**)&uninitialized_bucket;
+ return;
+ }
+#endif
+
+ ht->arBuckets = (Bucket **) ecalloc(ht->nTableSize, sizeof(Bucket *));
+
+ prev = &ht->pListHead;
+ p = source->pListHead;
+ while (p) {
+ nIndex = p->h & ht->nTableMask;
+
+ /* Create bucket and initialize key */
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ if (!p->nKeyLength) {
+ q = (Bucket *) emalloc(sizeof(Bucket));
+ q->arKey = NULL;
+ } else if (IS_INTERNED(p->arKey)) {
+ q = (Bucket *) emalloc(sizeof(Bucket));
+ q->arKey = p->arKey;
+ } else {
+ q = (Bucket *) emalloc(sizeof(Bucket) + p->nKeyLength);
+ q->arKey = ((char*)q) + sizeof(Bucket);
+ memcpy((char*)q->arKey, p->arKey, p->nKeyLength);
+ }
+#else
+ q = (Bucket *) emalloc(sizeof(Bucket) - 1 + p->nKeyLength);
+ if (p->nKeyLength) {
+ memcpy(q->arKey, p->arKey, p->nKeyLength);
+ }
+#endif
+ q->h = p->h;
+ q->nKeyLength = p->nKeyLength;
+
+ /* Insert into hash collision list */
+ q->pNext = ht->arBuckets[nIndex];
+ q->pLast = NULL;
+ if (q->pNext) {
+ q->pNext->pLast = q;
+ }
+ ht->arBuckets[nIndex] = q;
+
+ /* Insert into global list */
+ q->pListLast = ht->pListTail;
+ ht->pListTail = q;
+ q->pListNext = NULL;
+ *prev = q;
+ prev = &q->pListNext;
+
+ /* Copy data */
+ q->pData = (void *) emalloc(sizeof(zend_property_info));
+ prop_info = q->pData;
+ *prop_info = *(zend_property_info*)p->pData;
+ q->pDataPtr = NULL;
+
+ /* Copy constructor */
+ prop_info->name = interned_estrndup(prop_info->name, prop_info->name_length);
+ if (prop_info->doc_comment) {
+ if (ZCG(accel_directives).load_comments) {
+ prop_info->doc_comment = estrndup(prop_info->doc_comment, prop_info->doc_comment_len);
+ } else {
+ prop_info->doc_comment = NULL;
+ }
+ }
+ if (prop_info->ce == old_ce) {
+ prop_info->ce = ce;
+ } else if (accel_xlat_get(prop_info->ce, new_ce) == SUCCESS) {
+ prop_info->ce = *new_ce;
+ } else {
+ zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME" class loading error, class %s, property %s", ce->name, prop_info->name);
+ }
+
+ p = p->pListNext;
+ }
+ ht->pInternalPointer = ht->pListHead;
+}
+
+/* protects reference count, creates copy of statics */
+static int zend_prepare_function_for_execution(zend_op_array *op_array)
+{
+ HashTable *shared_statics = op_array->static_variables;
+
+ /* protect reference count */
+ op_array->refcount = &zend_accel_refcount;
+ (*op_array->refcount) = ZEND_PROTECTED_REFCOUNT;
+
+ /* copy statics */
+ if (shared_statics) {
+ ALLOC_HASHTABLE(op_array->static_variables);
+ zend_hash_clone_zval(op_array->static_variables, shared_statics, 0);
+ }
+
+ return 0;
+}
+
+#define zend_update_inherited_handler(handler) \
+{ \
+ if (ce->handler != NULL) { \
+ if (accel_xlat_get(ce->handler, new_func) == SUCCESS) { \
+ ce->handler = *new_func; \
+ } else { \
+ zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s", ce->name); \
+ } \
+ } \
+}
+
+/* Protects class' refcount, copies default properties, functions and class name */
+static void zend_class_copy_ctor(zend_class_entry **pce)
+{
+ zend_class_entry *ce = *pce;
+ zend_class_entry *old_ce = ce;
+ zend_class_entry **new_ce;
+ zend_function **new_func;
+ TSRMLS_FETCH();
+
+ *pce = ce = emalloc(sizeof(zend_class_entry));
+ *ce = *old_ce;
+ ce->refcount = 1;
+
+ if (old_ce->refcount != 1) {
+ /* this class is not used as a parent for any other classes */
+ accel_xlat_set(old_ce, ce);
+ }
+
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ if (old_ce->default_properties_table) {
+ int i;
+
+ ce->default_properties_table = emalloc(sizeof(zval*) * old_ce->default_properties_count);
+ for (i = 0; i < old_ce->default_properties_count; i++) {
+ if (old_ce->default_properties_table[i]) {
+ ce->default_properties_table[i] = zend_clone_zval(old_ce->default_properties_table[i], 0 TSRMLS_CC);
+ } else {
+ ce->default_properties_table[i] = NULL;
+ }
+ }
+ }
+#else
+ zend_hash_clone_zval(&ce->default_properties, &old_ce->default_properties, 0);
+#endif
+
+ zend_hash_clone_methods(&ce->function_table, &old_ce->function_table, old_ce, ce TSRMLS_CC);
+
+ /* static members */
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ if (old_ce->default_static_members_table) {
+ int i;
+
+ ce->default_static_members_table = emalloc(sizeof(zval*) * old_ce->default_static_members_count);
+ for (i = 0; i < old_ce->default_static_members_count; i++) {
+ if (old_ce->default_static_members_table[i]) {
+ ce->default_static_members_table[i] = zend_clone_zval(old_ce->default_static_members_table[i], 1 TSRMLS_CC);
+ } else {
+ ce->default_static_members_table[i] = NULL;
+ }
+ }
+ }
+ ce->static_members_table = ce->default_static_members_table;
+#else
+ zend_hash_clone_zval(&ce->default_static_members, &old_ce->default_static_members, 1);
+ ce->static_members = &ce->default_static_members;
+#endif
+
+ /* properties_info */
+ zend_hash_clone_prop_info(&ce->properties_info, &old_ce->properties_info, old_ce, ce TSRMLS_CC);
+
+ /* constants table */
+ zend_hash_clone_zval(&ce->constants_table, &old_ce->constants_table, 0);
+
+ ce->name = interned_estrndup(ce->name, ce->name_length);
+
+ /* interfaces aren't really implemented, so we create a new table */
+ if (ce->num_interfaces) {
+ ce->interfaces = emalloc(sizeof(zend_class_entry *) * ce->num_interfaces);
+ memset(ce->interfaces, 0, sizeof(zend_class_entry *) * ce->num_interfaces);
+ } else {
+ ce->interfaces = NULL;
+ }
+ if (ZEND_CE_DOC_COMMENT(ce)) {
+ if (ZCG(accel_directives).load_comments) {
+ ZEND_CE_DOC_COMMENT(ce) = estrndup(ZEND_CE_DOC_COMMENT(ce), ZEND_CE_DOC_COMMENT_LEN(ce));
+ } else {
+ ZEND_CE_DOC_COMMENT(ce) = NULL;
+ }
+ }
+
+ if (ce->parent) {
+ if (accel_xlat_get(ce->parent, new_ce) == SUCCESS) {
+ ce->parent = *new_ce;
+ } else {
+ zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME" class loading error, class %s", ce->name);
+ }
+ }
+
+ zend_update_inherited_handler(constructor);
+ zend_update_inherited_handler(destructor);
+ zend_update_inherited_handler(clone);
+ zend_update_inherited_handler(__get);
+ zend_update_inherited_handler(__set);
+ zend_update_inherited_handler(__call);
+/* 5.1 stuff */
+ zend_update_inherited_handler(serialize_func);
+ zend_update_inherited_handler(unserialize_func);
+ zend_update_inherited_handler(__isset);
+ zend_update_inherited_handler(__unset);
+/* 5.2 stuff */
+ zend_update_inherited_handler(__tostring);
+
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+/* 5.3 stuff */
+ zend_update_inherited_handler(__callstatic);
+#endif
+
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+/* 5.4 traits */
+ if (ce->trait_aliases) {
+ zend_trait_alias **trait_aliases;
+ int i = 0;
+
+ while (ce->trait_aliases[i]) {
+ i++;
+ }
+ trait_aliases = emalloc(sizeof(zend_trait_alias*) * (i + 1));
+ i = 0;
+ while (ce->trait_aliases[i]) {
+ trait_aliases[i] = emalloc(sizeof(zend_trait_alias));
+ memcpy(trait_aliases[i], ce->trait_aliases[i], sizeof(zend_trait_alias));
+ trait_aliases[i]->trait_method = emalloc(sizeof(zend_trait_method_reference));
+ memcpy(trait_aliases[i]->trait_method, ce->trait_aliases[i]->trait_method, sizeof(zend_trait_method_reference));
+ if (trait_aliases[i]->trait_method) {
+ if (trait_aliases[i]->trait_method->method_name) {
+ trait_aliases[i]->trait_method->method_name =
+ estrndup(trait_aliases[i]->trait_method->method_name,
+ trait_aliases[i]->trait_method->mname_len);
+ }
+ if (trait_aliases[i]->trait_method->class_name) {
+ trait_aliases[i]->trait_method->class_name =
+ estrndup(trait_aliases[i]->trait_method->class_name,
+ trait_aliases[i]->trait_method->cname_len);
+ }
+ }
+
+ if (trait_aliases[i]->alias) {
+ trait_aliases[i]->alias =
+ estrndup(trait_aliases[i]->alias,
+ trait_aliases[i]->alias_len);
+ }
+ i++;
+ }
+ trait_aliases[i] = NULL;
+ ce->trait_aliases = trait_aliases;
+ }
+
+ if (ce->trait_precedences) {
+ zend_trait_precedence **trait_precedences;
+ int i = 0;
+
+ while (ce->trait_precedences[i]) {
+ i++;
+ }
+ trait_precedences = emalloc(sizeof(zend_trait_precedence*) * (i + 1));
+ i = 0;
+ while (ce->trait_precedences[i]) {
+ trait_precedences[i] = emalloc(sizeof(zend_trait_precedence));
+ memcpy(trait_precedences[i], ce->trait_precedences[i], sizeof(zend_trait_precedence));
+ trait_precedences[i]->trait_method = emalloc(sizeof(zend_trait_method_reference));
+ memcpy(trait_precedences[i]->trait_method, ce->trait_precedences[i]->trait_method, sizeof(zend_trait_method_reference));
+
+ trait_precedences[i]->trait_method->method_name =
+ estrndup(trait_precedences[i]->trait_method->method_name,
+ trait_precedences[i]->trait_method->mname_len);
+ trait_precedences[i]->trait_method->class_name =
+ estrndup(trait_precedences[i]->trait_method->class_name,
+ trait_precedences[i]->trait_method->cname_len);
+
+ if (trait_precedences[i]->exclude_from_classes) {
+ zend_class_entry **exclude_from_classes;
+ int j = 0;
+
+ while (trait_precedences[i]->exclude_from_classes[j]) {
+ j++;
+ }
+ exclude_from_classes = emalloc(sizeof(zend_class_entry*) * (j + 1));
+ j = 0;
+ while (trait_precedences[i]->exclude_from_classes[j]) {
+ exclude_from_classes[j] = (zend_class_entry*)estrndup(
+ (char*)trait_precedences[i]->exclude_from_classes[j],
+ strlen((char*)trait_precedences[i]->exclude_from_classes[j]));
+ j++;
+ }
+ exclude_from_classes[j] = NULL;
+ trait_precedences[i]->exclude_from_classes = exclude_from_classes;
+ }
+ i++;
+ }
+ trait_precedences[i] = NULL;
+ ce->trait_precedences = trait_precedences;
+ }
+#endif
+}
+
+static int zend_hash_unique_copy(HashTable *target, HashTable *source, unique_copy_ctor_func_t pCopyConstructor, uint size, int ignore_dups, void **fail_data, void **conflict_data)
+{
+ Bucket *p;
+ void *t;
+
+ p = source->pListHead;
+ while (p) {
+ if (p->nKeyLength > 0) {
+ if (zend_hash_quick_add(target, p->arKey, p->nKeyLength, p->h, p->pData, size, &t) == SUCCESS) {
+ if (pCopyConstructor) {
+ pCopyConstructor(t);
+ }
+ } else {
+ if (p->nKeyLength > 0 && p->arKey[0] == 0) {
+ /* Mangled key */
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+ if (((zend_function*)p->pData)->common.fn_flags & ZEND_ACC_CLOSURE) {
+ /* update closure */
+ if (zend_hash_quick_update(target, p->arKey, p->nKeyLength, p->h, p->pData, size, &t) == SUCCESS) {
+ if (pCopyConstructor) {
+ pCopyConstructor(t);
+ }
+ }
+ } else {
+ /* ignore and wait for runtime */
+ }
+#endif
+ } else if (!ignore_dups && zend_hash_quick_find(target, p->arKey, p->nKeyLength, p->h, &t) == SUCCESS) {
+ *fail_data = p->pData;
+ *conflict_data = t;
+ return FAILURE;
+ }
+ }
+ } else {
+ if (!zend_hash_index_exists(target, p->h) && zend_hash_index_update(target, p->h, p->pData, size, &t) == SUCCESS) {
+ if (pCopyConstructor) {
+ pCopyConstructor(t);
+ }
+ } else if (!ignore_dups && zend_hash_index_find(target,p->h, &t) == SUCCESS) {
+ *fail_data = p->pData;
+ *conflict_data = t;
+ return FAILURE;
+ }
+ }
+ p = p->pListNext;
+ }
+ target->pInternalPointer = target->pListHead;
+
+ return SUCCESS;
+}
+
+static void zend_accel_function_hash_copy(HashTable *target, HashTable *source, unique_copy_ctor_func_t pCopyConstructor)
+{
+ zend_function *function1, *function2;
+ TSRMLS_FETCH();
+
+ if (zend_hash_unique_copy(target, source, pCopyConstructor, sizeof(zend_function), 0, (void**)&function1, (void**)&function2) != SUCCESS) {
+ CG(in_compilation) = 1;
+ zend_set_compiled_filename(function1->op_array.filename TSRMLS_CC);
+ CG(zend_lineno) = function1->op_array.opcodes[0].lineno;
+ if (function2->type == ZEND_USER_FUNCTION
+ && function2->op_array.last > 0) {
+ zend_error(E_ERROR, "Cannot redeclare %s() (previously declared in %s:%d)",
+ function1->common.function_name,
+ function2->op_array.filename,
+ (int)function2->op_array.opcodes[0].lineno);
+ } else {
+ zend_error(E_ERROR, "Cannot redeclare %s()", function1->common.function_name);
+ }
+ }
+}
+
+static void zend_accel_class_hash_copy(HashTable *target, HashTable *source, unique_copy_ctor_func_t pCopyConstructor TSRMLS_DC)
+{
+ zend_class_entry **pce1, **pce2;
+
+ if (zend_hash_unique_copy(target, source, pCopyConstructor, sizeof(zend_class_entry*), ZCG(accel_directives).ignore_dups, (void**)&pce1, (void**)&pce2) != SUCCESS) {
+ CG(in_compilation) = 1;
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ zend_set_compiled_filename((*pce1)->info.user.filename TSRMLS_CC);
+ CG(zend_lineno) = (*pce1)->info.user.line_start;
+#else
+ zend_set_compiled_filename((*pce1)->filename TSRMLS_CC);
+ CG(zend_lineno) = (*pce1)->line_start;
+#endif
+ zend_error(E_ERROR, "Cannot redeclare class %s", (*pce1)->name);
+ }
+}
+
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+static void zend_do_delayed_early_binding(zend_op_array *op_array, zend_uint early_binding TSRMLS_DC)
+{
+ zend_uint opline_num = early_binding;
+
+ if ((int)opline_num != -1) {
+ zend_bool orig_in_compilation = CG(in_compilation);
+ char *orig_compiled_filename = zend_set_compiled_filename(op_array->filename TSRMLS_CC);
+ zend_class_entry **pce;
+
+ CG(in_compilation) = 1;
+ while ((int)opline_num != -1) {
+ if (zend_lookup_class(Z_STRVAL(op_array->opcodes[opline_num - 1].op2.u.constant), Z_STRLEN(op_array->opcodes[opline_num - 1].op2.u.constant), &pce TSRMLS_CC) == SUCCESS) {
+ do_bind_inherited_class(&op_array->opcodes[opline_num], EG(class_table), *pce, 1 TSRMLS_CC);
+ }
+ opline_num = op_array->opcodes[opline_num].result.u.opline_num;
+ }
+ zend_restore_compiled_filename(orig_compiled_filename TSRMLS_CC);
+ CG(in_compilation) = orig_in_compilation;
+ }
+}
+#endif
+
+zend_op_array* zend_accel_load_script(zend_persistent_script *persistent_script, int from_shared_memory TSRMLS_DC)
+{
+ zend_op_array *op_array;
+
+ op_array = (zend_op_array *) emalloc(sizeof(zend_op_array));
+ *op_array = persistent_script->main_op_array;
+
+ if (from_shared_memory) {
+ /* Copy all the necessary stuff from shared memory to regular memory, and protect the shared script */
+ if (zend_hash_num_elements(&persistent_script->class_table) > 0) {
+ zend_hash_init(&ZCG(bind_hash), 10, NULL, NULL, 0);
+ zend_accel_class_hash_copy(CG(class_table), &persistent_script->class_table, (unique_copy_ctor_func_t) zend_class_copy_ctor TSRMLS_CC);
+ zend_hash_destroy(&ZCG(bind_hash));
+ }
+ /* we must first to copy all classes and then prepare functions, since functions may try to bind
+ classes - which depend on pre-bind class entries existent in the class table */
+ if (zend_hash_num_elements(&persistent_script->function_table) > 0) {
+ zend_accel_function_hash_copy(CG(function_table), &persistent_script->function_table, (unique_copy_ctor_func_t)zend_prepare_function_for_execution);
+ }
+
+ zend_prepare_function_for_execution(op_array);
+
+ /* Register __COMPILER_HALT_OFFSET__ constant */
+ if (persistent_script->compiler_halt_offset != 0 &&
+ persistent_script->full_path) {
+ char *name, *cfilename;
+ char haltoff[] = "__COMPILER_HALT_OFFSET__";
+ int len, clen;
+
+ cfilename = persistent_script->full_path;
+ clen = strlen(cfilename);
+ zend_mangle_property_name(&name, &len, haltoff, sizeof(haltoff) - 1, cfilename, clen, 0);
+ if (!zend_hash_exists(EG(zend_constants), name, len + 1)) {
+ zend_register_long_constant(name, len + 1, persistent_script->compiler_halt_offset, CONST_CS, 0 TSRMLS_CC);
+ }
+ efree(name);
+ }
+
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+ if ((int)persistent_script->early_binding != -1) {
+ zend_do_delayed_early_binding(op_array, persistent_script->early_binding TSRMLS_CC);
+ }
+#endif
+
+ } else /* if (!from_shared_memory) */ {
+ if (zend_hash_num_elements(&persistent_script->function_table) > 0) {
+ zend_accel_function_hash_copy(CG(function_table), &persistent_script->function_table, NULL);
+ }
+ if (zend_hash_num_elements(&persistent_script->class_table) > 0) {
+ zend_accel_class_hash_copy(CG(class_table), &persistent_script->class_table, NULL TSRMLS_CC);
+ }
+ free_persistent_script(persistent_script, 0); /* free only hashes */
+ }
+
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+ if (op_array->early_binding != (zend_uint)-1) {
+ char *orig_compiled_filename = CG(compiled_filename);
+ CG(compiled_filename) = persistent_script->full_path;
+ zend_do_delayed_early_binding(op_array TSRMLS_CC);
+ CG(compiled_filename) = orig_compiled_filename;
+ }
+#endif
+
+ return op_array;
+}
+
+/*
+ * zend_adler32() is based on zlib implementation
+ * Computes the Adler-32 checksum of a data stream
+ *
+ * Copyright (C) 1995-2005 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ *
+ */
+
+#define ADLER32_BASE 65521 /* largest prime smaller than 65536 */
+#define ADLER32_NMAX 5552
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+
+#define ADLER32_DO1(buf) {s1 += *(buf); s2 += s1;}
+#define ADLER32_DO2(buf, i) ADLER32_DO1(buf + i); ADLER32_DO1(buf + i + 1);
+#define ADLER32_DO4(buf, i) ADLER32_DO2(buf, i); ADLER32_DO2(buf, i + 2);
+#define ADLER32_DO8(buf, i) ADLER32_DO4(buf, i); ADLER32_DO4(buf, i + 4);
+#define ADLER32_DO16(buf) ADLER32_DO8(buf, 0); ADLER32_DO8(buf, 8);
+
+unsigned int zend_adler32(unsigned int checksum, signed char *buf, uint len)
+{
+ unsigned int s1 = checksum & 0xffff;
+ unsigned int s2 = (checksum >> 16) & 0xffff;
+ signed char *end;
+
+ while (len >= ADLER32_NMAX) {
+ len -= ADLER32_NMAX;
+ end = buf + ADLER32_NMAX;
+ do {
+ ADLER32_DO16(buf);
+ buf += 16;
+ } while (buf != end);
+ s1 %= ADLER32_BASE;
+ s2 %= ADLER32_BASE;
+ }
+
+ if (len) {
+ if (len >= 16) {
+ end = buf + (len & 0xfff0);
+ len &= 0xf;
+ do {
+ ADLER32_DO16(buf);
+ buf += 16;
+ } while (buf != end);
+ }
+ if (len) {
+ end = buf + len;
+ do {
+ ADLER32_DO1(buf);
+ buf++;
+ } while (buf != end);
+ }
+ s1 %= ADLER32_BASE;
+ s2 %= ADLER32_BASE;
+ }
+
+ return (s2 << 16) | s1;
+}
diff --git a/ext/opcache/zend_accelerator_util_funcs.h b/ext/opcache/zend_accelerator_util_funcs.h
new file mode 100644
index 0000000000..2f515d85cc
--- /dev/null
+++ b/ext/opcache/zend_accelerator_util_funcs.h
@@ -0,0 +1,50 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2014 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: Andi Gutmans <andi@zend.com> |
+ | Zeev Suraski <zeev@zend.com> |
+ | Stanislav Malyshev <stas@zend.com> |
+ | Dmitry Stogov <dmitry@zend.com> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef ZEND_ACCELERATOR_UTIL_FUNCS_H
+#define ZEND_ACCELERATOR_UTIL_FUNCS_H
+
+#include "zend.h"
+#include "ZendAccelerator.h"
+
+void zend_accel_copy_internal_functions(TSRMLS_D);
+
+zend_persistent_script* create_persistent_script(void);
+int compact_persistent_script(zend_persistent_script *script);
+void free_persistent_script(zend_persistent_script *persistent_script, int destroy_elements);
+
+void zend_accel_free_user_functions(HashTable *ht TSRMLS_DC);
+void zend_accel_move_user_functions(HashTable *str, HashTable *dst TSRMLS_DC);
+
+zend_op_array* zend_accel_load_script(zend_persistent_script *persistent_script, int from_shared_memory TSRMLS_DC);
+
+#define ADLER32_INIT 1 /* initial Adler-32 value */
+
+unsigned int zend_adler32(unsigned int checksum, signed char *buf, uint len);
+
+#endif /* ZEND_ACCELERATOR_UTIL_FUNCS_H */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c
new file mode 100644
index 0000000000..6e06cac436
--- /dev/null
+++ b/ext/opcache/zend_persist.c
@@ -0,0 +1,684 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2014 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: Andi Gutmans <andi@zend.com> |
+ | Zeev Suraski <zeev@zend.com> |
+ | Stanislav Malyshev <stas@zend.com> |
+ | Dmitry Stogov <dmitry@zend.com> |
+ +----------------------------------------------------------------------+
+*/
+
+#include "zend.h"
+#include "ZendAccelerator.h"
+#include "zend_persist.h"
+#include "zend_extensions.h"
+#include "zend_shared_alloc.h"
+#include "zend_vm.h"
+#include "zend_constants.h"
+#include "zend_operators.h"
+
+#define zend_accel_store(p, size) \
+ (p = _zend_shared_memdup((void*)p, size, 1 TSRMLS_CC))
+#define zend_accel_memdup(p, size) \
+ _zend_shared_memdup((void*)p, size, 0 TSRMLS_CC)
+
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+# define zend_accel_memdup_interned_string(str, len) \
+ IS_INTERNED(str) ? str : zend_accel_memdup(str, len)
+
+# define zend_accel_store_interned_string(str, len) do { \
+ if (!IS_INTERNED(str)) { zend_accel_store(str, len); } \
+ } while (0)
+#else
+# define zend_accel_memdup_interned_string(str, len) \
+ zend_accel_memdup(str, len)
+
+# define zend_accel_store_interned_string(str, len) \
+ zend_accel_store(str, len)
+#endif
+
+typedef void (*zend_persist_func_t)(void * TSRMLS_DC);
+
+static void zend_persist_zval_ptr(zval **zp TSRMLS_DC);
+
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+static const Bucket *uninitialized_bucket = NULL;
+#endif
+
+static void zend_hash_persist(HashTable *ht, void (*pPersistElement)(void *pElement TSRMLS_DC), size_t el_size TSRMLS_DC)
+{
+ Bucket *p = ht->pListHead;
+ uint i;
+
+ while (p) {
+ Bucket *q = p;
+
+ /* persist bucket and key */
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ p = zend_accel_memdup(p, sizeof(Bucket));
+ if (p->nKeyLength) {
+ p->arKey = zend_accel_memdup_interned_string(p->arKey, p->nKeyLength);
+ }
+#else
+ p = zend_accel_memdup(p, sizeof(Bucket) - 1 + p->nKeyLength);
+#endif
+
+ /* persist data pointer in bucket */
+ if (!p->pDataPtr) {
+ zend_accel_store(p->pData, el_size);
+ } else {
+ /* Update p->pData to point to the new p->pDataPtr address, after the bucket relocation */
+ p->pData = &p->pDataPtr;
+ }
+
+ /* persist the data itself */
+ if (pPersistElement) {
+ pPersistElement(p->pData TSRMLS_CC);
+ }
+
+ /* update linked lists */
+ if (p->pLast) {
+ p->pLast->pNext = p;
+ }
+ if (p->pNext) {
+ p->pNext->pLast = p;
+ }
+ if (p->pListLast) {
+ p->pListLast->pListNext = p;
+ }
+ if (p->pListNext) {
+ p->pListNext->pListLast = p;
+ }
+
+ p = p->pListNext;
+
+ /* delete the old non-persistent bucket */
+ efree(q);
+ }
+
+ /* update linked lists */
+ if (ht->pListHead) {
+ ht->pListHead = zend_shared_alloc_get_xlat_entry(ht->pListHead);
+ }
+ if (ht->pListTail) {
+ ht->pListTail = zend_shared_alloc_get_xlat_entry(ht->pListTail);
+ }
+ if (ht->pInternalPointer) {
+ ht->pInternalPointer = zend_shared_alloc_get_xlat_entry(ht->pInternalPointer);
+ }
+
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ /* Check if HastTable is initialized */
+ if (ht->nTableMask) {
+#endif
+ if (ht->nNumOfElements) {
+ /* update hash table */
+ for (i = 0; i < ht->nTableSize; i++) {
+ if (ht->arBuckets[i]) {
+ ht->arBuckets[i] = zend_shared_alloc_get_xlat_entry(ht->arBuckets[i]);
+ }
+ }
+ }
+ zend_accel_store(ht->arBuckets, sizeof(Bucket*) * ht->nTableSize);
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ } else {
+ ht->arBuckets = (Bucket**)&uninitialized_bucket;
+ }
+#endif
+}
+
+static void zend_persist_zval(zval *z TSRMLS_DC)
+{
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+ switch (z->type & IS_CONSTANT_TYPE_MASK) {
+#else
+ switch (z->type & ~IS_CONSTANT_INDEX) {
+#endif
+ case IS_STRING:
+ case IS_CONSTANT:
+ zend_accel_store_interned_string(z->value.str.val, z->value.str.len + 1);
+ break;
+ case IS_ARRAY:
+ case IS_CONSTANT_ARRAY:
+ zend_accel_store(z->value.ht, sizeof(HashTable));
+ zend_hash_persist(z->value.ht, (zend_persist_func_t) zend_persist_zval_ptr, sizeof(zval**) TSRMLS_CC);
+ break;
+ }
+}
+
+static void zend_persist_zval_ptr(zval **zp TSRMLS_DC)
+{
+ zval *new_ptr = zend_shared_alloc_get_xlat_entry(*zp);
+
+ if (new_ptr) {
+ *zp = new_ptr;
+ } else {
+ /* Attempt to store only if we didn't store this zval_ptr yet */
+ zend_accel_store(*zp, sizeof(zval));
+ zend_persist_zval(*zp TSRMLS_CC);
+ }
+}
+
+static void zend_protect_zval(zval *z TSRMLS_DC)
+{
+ PZ_SET_ISREF_P(z);
+ PZ_SET_REFCOUNT_P(z, 2);
+}
+
+static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_script* main_persistent_script TSRMLS_DC)
+{
+ zend_op *persist_ptr;
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+ int has_jmp = 0;
+#endif
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ zend_literal *orig_literals = NULL;
+#endif
+
+ if (op_array->type != ZEND_USER_FUNCTION) {
+ return;
+ }
+
+#if ZEND_EXTENSION_API_NO <= PHP_5_3_X_API_NO
+ op_array->size = op_array->last;
+#endif
+
+ if (--(*op_array->refcount) == 0) {
+ efree(op_array->refcount);
+ }
+ op_array->refcount = NULL;
+
+ if (op_array->filename) {
+ /* do not free! PHP has centralized filename storage, compiler will free it */
+ op_array->filename = zend_accel_memdup(op_array->filename, strlen(op_array->filename) + 1);
+ }
+
+ if (main_persistent_script) {
+ zend_bool orig_in_execution = EG(in_execution);
+ zend_op_array *orig_op_array = EG(active_op_array);
+ zval offset;
+
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+ main_persistent_script->early_binding = -1;
+#endif
+ EG(in_execution) = 1;
+ EG(active_op_array) = op_array;
+ if (zend_get_constant("__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__") - 1, &offset TSRMLS_CC)) {
+ main_persistent_script->compiler_halt_offset = Z_LVAL(offset);
+ }
+ EG(active_op_array) = orig_op_array;
+ EG(in_execution) = orig_in_execution;
+ }
+
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ if (op_array->literals) {
+ orig_literals = zend_shared_alloc_get_xlat_entry(op_array->literals);
+ if (orig_literals) {
+ op_array->literals = orig_literals;
+ } else {
+ zend_literal *p = zend_accel_memdup(op_array->literals, sizeof(zend_literal) * op_array->last_literal);
+ zend_literal *end = p + op_array->last_literal;
+ orig_literals = op_array->literals;
+ op_array->literals = p;
+ while (p < end) {
+ zend_persist_zval(&p->constant TSRMLS_CC);
+ zend_protect_zval(&p->constant TSRMLS_CC);
+ p++;
+ }
+ efree(orig_literals);
+ }
+ }
+#endif
+
+ if ((persist_ptr = zend_shared_alloc_get_xlat_entry(op_array->opcodes))) {
+ op_array->opcodes = persist_ptr;
+ } else {
+ zend_op *new_opcodes = zend_accel_memdup(op_array->opcodes, sizeof(zend_op) * op_array->last);
+ zend_op *opline = new_opcodes;
+ zend_op *end = new_opcodes + op_array->last;
+ int offset = 0;
+
+ for (; opline < end ; opline++, offset++) {
+ if (ZEND_OP1_TYPE(opline) == IS_CONST) {
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ opline->op1.zv = (zval*)((char*)opline->op1.zv + ((char*)op_array->literals - (char*)orig_literals));
+#else
+ zend_persist_zval(&opline->op1.u.constant TSRMLS_CC);
+ zend_protect_zval(&opline->op1.u.constant TSRMLS_CC);
+#endif
+ }
+ if (ZEND_OP2_TYPE(opline) == IS_CONST) {
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ opline->op2.zv = (zval*)((char*)opline->op2.zv + ((char*)op_array->literals - (char*)orig_literals));
+#else
+ zend_persist_zval(&opline->op2.u.constant TSRMLS_CC);
+ zend_protect_zval(&opline->op2.u.constant TSRMLS_CC);
+#endif
+ }
+
+#if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
+ switch (opline->opcode) {
+ case ZEND_JMP:
+ has_jmp = 1;
+ if (ZEND_DONE_PASS_TWO(op_array)) {
+ ZEND_OP1(opline).jmp_addr = &new_opcodes[ZEND_OP1(opline).jmp_addr - op_array->opcodes];
+ }
+ break;
+ case ZEND_JMPZ:
+ case ZEND_JMPNZ:
+ case ZEND_JMPZ_EX:
+ case ZEND_JMPNZ_EX:
+ has_jmp = 1;
+ if (ZEND_DONE_PASS_TWO(op_array)) {
+ ZEND_OP2(opline).jmp_addr = &new_opcodes[ZEND_OP2(opline).jmp_addr - op_array->opcodes];
+ }
+ break;
+ case ZEND_JMPZNZ:
+ case ZEND_BRK:
+ case ZEND_CONT:
+ has_jmp = 1;
+ break;
+ case ZEND_DECLARE_INHERITED_CLASS:
+ if (main_persistent_script && ZCG(accel_directives).inherited_hack) {
+ if (!has_jmp &&
+ ((opline + 2) >= end ||
+ (opline + 1)->opcode != ZEND_FETCH_CLASS ||
+ (opline + 2)->opcode != ZEND_ADD_INTERFACE)) {
+
+ zend_uint *opline_num = &main_persistent_script->early_binding;
+
+ while ((int)*opline_num != -1) {
+ opline_num = &new_opcodes[*opline_num].result.u.opline_num;
+ }
+ *opline_num = opline - new_opcodes;
+ opline->result.op_type = IS_UNUSED;
+ opline->result.u.opline_num = -1;
+ opline->opcode = ZEND_DECLARE_INHERITED_CLASS_DELAYED;
+ ZEND_VM_SET_OPCODE_HANDLER(opline);
+ }
+ break;
+ }
+ }
+
+#else /* if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO */
+
+ if (ZEND_DONE_PASS_TWO(op_array)) {
+ /* fix jumps to point to new array */
+ switch (opline->opcode) {
+ case ZEND_JMP:
+ case ZEND_GOTO:
+#if ZEND_EXTENSION_API_NO > PHP_5_4_X_API_NO
+ case ZEND_FAST_CALL:
+#endif
+ ZEND_OP1(opline).jmp_addr = &new_opcodes[ZEND_OP1(opline).jmp_addr - op_array->opcodes];
+ break;
+ case ZEND_JMPZ:
+ case ZEND_JMPNZ:
+ case ZEND_JMPZ_EX:
+ case ZEND_JMPNZ_EX:
+ case ZEND_JMP_SET:
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ case ZEND_JMP_SET_VAR:
+#endif
+ ZEND_OP2(opline).jmp_addr = &new_opcodes[ZEND_OP2(opline).jmp_addr - op_array->opcodes];
+ break;
+ }
+ }
+#endif /* if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO */
+ }
+
+ efree(op_array->opcodes);
+ op_array->opcodes = new_opcodes;
+
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ if (op_array->run_time_cache) {
+ efree(op_array->run_time_cache);
+ op_array->run_time_cache = NULL;
+ }
+#endif
+ }
+
+ if (op_array->function_name) {
+ char *new_name;
+ if ((new_name = zend_shared_alloc_get_xlat_entry(op_array->function_name))) {
+ op_array->function_name = new_name;
+ } else {
+ zend_accel_store(op_array->function_name, strlen(op_array->function_name) + 1);
+ }
+ }
+
+ if (op_array->arg_info) {
+ zend_arg_info *new_ptr;
+ if ((new_ptr = zend_shared_alloc_get_xlat_entry(op_array->arg_info))) {
+ op_array->arg_info = new_ptr;
+ } else {
+ zend_uint i;
+
+ zend_accel_store(op_array->arg_info, sizeof(zend_arg_info) * op_array->num_args);
+ for (i = 0; i < op_array->num_args; i++) {
+ if (op_array->arg_info[i].name) {
+ zend_accel_store_interned_string(op_array->arg_info[i].name, op_array->arg_info[i].name_len + 1);
+ }
+ if (op_array->arg_info[i].class_name) {
+ zend_accel_store_interned_string(op_array->arg_info[i].class_name, op_array->arg_info[i].class_name_len + 1);
+ }
+ }
+ }
+ }
+
+ if (op_array->brk_cont_array) {
+ zend_accel_store(op_array->brk_cont_array, sizeof(zend_brk_cont_element) * op_array->last_brk_cont);
+ }
+
+ if (op_array->static_variables) {
+ zend_hash_persist(op_array->static_variables, (zend_persist_func_t) zend_persist_zval_ptr, sizeof(zval**) TSRMLS_CC);
+ zend_accel_store(op_array->static_variables, sizeof(HashTable));
+ }
+
+ if (op_array->scope) {
+ op_array->scope = zend_shared_alloc_get_xlat_entry(op_array->scope);
+ }
+
+ if (op_array->doc_comment) {
+ if (ZCG(accel_directives).save_comments) {
+ zend_accel_store(op_array->doc_comment, op_array->doc_comment_len + 1);
+ } else {
+ if (!zend_shared_alloc_get_xlat_entry(op_array->doc_comment)) {
+ zend_shared_alloc_register_xlat_entry(op_array->doc_comment, op_array->doc_comment);
+ efree((char*)op_array->doc_comment);
+ }
+ op_array->doc_comment = NULL;
+ op_array->doc_comment_len = 0;
+ }
+ }
+
+ if (op_array->try_catch_array) {
+ zend_accel_store(op_array->try_catch_array, sizeof(zend_try_catch_element) * op_array->last_try_catch);
+ }
+
+ if (op_array->vars) {
+ if ((persist_ptr = zend_shared_alloc_get_xlat_entry(op_array->vars))) {
+ op_array->vars = (zend_compiled_variable*)persist_ptr;
+ } else {
+ int i;
+ zend_accel_store(op_array->vars, sizeof(zend_compiled_variable) * op_array->last_var);
+ for (i = 0; i < op_array->last_var; i++) {
+ zend_accel_store_interned_string(op_array->vars[i].name, op_array->vars[i].name_len + 1);
+ }
+ }
+ }
+
+ /* "prototype" may be undefined if "scope" isn't set */
+ if (op_array->scope && op_array->prototype) {
+ if ((persist_ptr = zend_shared_alloc_get_xlat_entry(op_array->prototype))) {
+ op_array->prototype = (union _zend_function*)persist_ptr;
+ /* we use refcount to show that op_array is referenced from several places */
+ op_array->prototype->op_array.refcount++;
+ }
+ } else {
+ op_array->prototype = NULL;
+ }
+}
+
+static void zend_persist_op_array(zend_op_array *op_array TSRMLS_DC)
+{
+ zend_persist_op_array_ex(op_array, NULL TSRMLS_CC);
+}
+
+static void zend_persist_property_info(zend_property_info *prop TSRMLS_DC)
+{
+ zend_accel_store_interned_string(prop->name, prop->name_length + 1);
+ if (prop->doc_comment) {
+ if (ZCG(accel_directives).save_comments) {
+ zend_accel_store(prop->doc_comment, prop->doc_comment_len + 1);
+ } else {
+ if (!zend_shared_alloc_get_xlat_entry(prop->doc_comment)) {
+ zend_shared_alloc_register_xlat_entry(prop->doc_comment, prop->doc_comment);
+ efree((char*)prop->doc_comment);
+ }
+ prop->doc_comment = NULL;
+ prop->doc_comment_len = 0;
+ }
+ }
+}
+
+static void zend_persist_class_entry(zend_class_entry **pce TSRMLS_DC)
+{
+ zend_class_entry *ce = *pce;
+
+ if (ce->type == ZEND_USER_CLASS) {
+ *pce = zend_accel_store(ce, sizeof(zend_class_entry));
+ zend_accel_store_interned_string(ce->name, ce->name_length + 1);
+ zend_hash_persist(&ce->function_table, (zend_persist_func_t) zend_persist_op_array, sizeof(zend_op_array) TSRMLS_CC);
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ if (ce->default_properties_table) {
+ int i;
+
+ zend_accel_store(ce->default_properties_table, sizeof(zval*) * ce->default_properties_count);
+ for (i = 0; i < ce->default_properties_count; i++) {
+ if (ce->default_properties_table[i]) {
+ zend_persist_zval_ptr(&ce->default_properties_table[i] TSRMLS_CC);
+ }
+ }
+ }
+ if (ce->default_static_members_table) {
+ int i;
+
+ zend_accel_store(ce->default_static_members_table, sizeof(zval*) * ce->default_static_members_count);
+ for (i = 0; i < ce->default_static_members_count; i++) {
+ if (ce->default_static_members_table[i]) {
+ zend_persist_zval_ptr(&ce->default_static_members_table[i] TSRMLS_CC);
+ }
+ }
+ }
+ ce->static_members_table = NULL;
+#else
+ zend_hash_persist(&ce->default_properties, (zend_persist_func_t) zend_persist_zval_ptr, sizeof(zval**) TSRMLS_CC);
+ zend_hash_persist(&ce->default_static_members, (zend_persist_func_t) zend_persist_zval_ptr, sizeof(zval**) TSRMLS_CC);
+ ce->static_members = NULL;
+#endif
+ zend_hash_persist(&ce->constants_table, (zend_persist_func_t) zend_persist_zval_ptr, sizeof(zval**) TSRMLS_CC);
+
+ if (ZEND_CE_FILENAME(ce)) {
+ /* do not free! PHP has centralized filename storage, compiler will free it */
+ ZEND_CE_FILENAME(ce) = zend_accel_memdup(ZEND_CE_FILENAME(ce), strlen(ZEND_CE_FILENAME(ce)) + 1);
+ }
+ if (ZEND_CE_DOC_COMMENT(ce)) {
+ if (ZCG(accel_directives).save_comments) {
+ zend_accel_store(ZEND_CE_DOC_COMMENT(ce), ZEND_CE_DOC_COMMENT_LEN(ce) + 1);
+ } else {
+ if (!zend_shared_alloc_get_xlat_entry(ZEND_CE_DOC_COMMENT(ce))) {
+ zend_shared_alloc_register_xlat_entry(ZEND_CE_DOC_COMMENT(ce), ZEND_CE_DOC_COMMENT(ce));
+ efree((char*)ZEND_CE_DOC_COMMENT(ce));
+ }
+ ZEND_CE_DOC_COMMENT(ce) = NULL;
+ ZEND_CE_DOC_COMMENT_LEN(ce) = 0;
+ }
+ }
+ zend_hash_persist(&ce->properties_info, (zend_persist_func_t) zend_persist_property_info, sizeof(zend_property_info) TSRMLS_CC);
+ if (ce->num_interfaces && ce->interfaces) {
+ efree(ce->interfaces);
+ }
+ ce->interfaces = NULL; /* will be filled in on fetch */
+
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ if (ce->num_traits && ce->traits) {
+ efree(ce->traits);
+ }
+ ce->traits = NULL;
+
+ if (ce->trait_aliases) {
+ int i = 0;
+ while (ce->trait_aliases[i]) {
+ if (ce->trait_aliases[i]->trait_method) {
+ if (ce->trait_aliases[i]->trait_method->method_name) {
+ zend_accel_store(ce->trait_aliases[i]->trait_method->method_name,
+ ce->trait_aliases[i]->trait_method->mname_len + 1);
+ }
+ if (ce->trait_aliases[i]->trait_method->class_name) {
+ zend_accel_store(ce->trait_aliases[i]->trait_method->class_name,
+ ce->trait_aliases[i]->trait_method->cname_len + 1);
+ }
+ ce->trait_aliases[i]->trait_method->ce = NULL;
+ zend_accel_store(ce->trait_aliases[i]->trait_method,
+ sizeof(zend_trait_method_reference));
+ }
+
+ if (ce->trait_aliases[i]->alias) {
+ zend_accel_store(ce->trait_aliases[i]->alias,
+ ce->trait_aliases[i]->alias_len + 1);
+ }
+
+#if ZEND_EXTENSION_API_NO <= PHP_5_4_X_API_NO
+ ce->trait_aliases[i]->function = NULL;
+#endif
+ zend_accel_store(ce->trait_aliases[i], sizeof(zend_trait_alias));
+ i++;
+ }
+
+ zend_accel_store(ce->trait_aliases, sizeof(zend_trait_alias*) * (i + 1));
+ }
+
+ if (ce->trait_precedences) {
+ int i = 0;
+
+ while (ce->trait_precedences[i]) {
+ zend_accel_store(ce->trait_precedences[i]->trait_method->method_name,
+ ce->trait_precedences[i]->trait_method->mname_len + 1);
+ zend_accel_store(ce->trait_precedences[i]->trait_method->class_name,
+ ce->trait_precedences[i]->trait_method->cname_len + 1);
+ ce->trait_precedences[i]->trait_method->ce = NULL;
+ zend_accel_store(ce->trait_precedences[i]->trait_method,
+ sizeof(zend_trait_method_reference));
+
+ if (ce->trait_precedences[i]->exclude_from_classes) {
+ int j = 0;
+
+ while (ce->trait_precedences[i]->exclude_from_classes[j]) {
+ zend_accel_store(ce->trait_precedences[i]->exclude_from_classes[j],
+ strlen((char*)ce->trait_precedences[i]->exclude_from_classes[j]) + 1);
+ j++;
+ }
+ zend_accel_store(ce->trait_precedences[i]->exclude_from_classes,
+ sizeof(zend_class_entry*) * (j + 1));
+ }
+
+#if ZEND_EXTENSION_API_NO <= PHP_5_4_X_API_NO
+ ce->trait_precedences[i]->function = NULL;
+#endif
+ zend_accel_store(ce->trait_precedences[i], sizeof(zend_trait_precedence));
+ i++;
+ }
+ zend_accel_store(
+ ce->trait_precedences, sizeof(zend_trait_precedence*) * (i + 1));
+ }
+#endif
+ }
+}
+
+static int zend_update_property_info_ce(zend_property_info *prop TSRMLS_DC)
+{
+ prop->ce = zend_shared_alloc_get_xlat_entry(prop->ce);
+ return 0;
+}
+
+static int zend_update_parent_ce(zend_class_entry **pce TSRMLS_DC)
+{
+ zend_class_entry *ce = *pce;
+
+ if (ce->parent) {
+ ce->parent = zend_shared_alloc_get_xlat_entry(ce->parent);
+ /* We use refcount to show if the class is used as a parent */
+ ce->parent->refcount++;
+ }
+
+ /* update methods */
+ if (ce->constructor) {
+ ce->constructor = zend_shared_alloc_get_xlat_entry(ce->constructor);
+ /* we use refcount to show that op_array is referenced from several places */
+ ce->constructor->op_array.refcount++;
+ }
+ if (ce->destructor) {
+ ce->destructor = zend_shared_alloc_get_xlat_entry(ce->destructor);
+ ce->destructor->op_array.refcount++;
+ }
+ if (ce->clone) {
+ ce->clone = zend_shared_alloc_get_xlat_entry(ce->clone);
+ ce->clone->op_array.refcount++;
+ }
+ if (ce->__get) {
+ ce->__get = zend_shared_alloc_get_xlat_entry(ce->__get);
+ ce->__get->op_array.refcount++;
+ }
+ if (ce->__set) {
+ ce->__set = zend_shared_alloc_get_xlat_entry(ce->__set);
+ ce->__set->op_array.refcount++;
+ }
+ if (ce->__call) {
+ ce->__call = zend_shared_alloc_get_xlat_entry(ce->__call);
+ ce->__call->op_array.refcount++;
+ }
+ if (ce->serialize_func) {
+ ce->serialize_func = zend_shared_alloc_get_xlat_entry(ce->serialize_func);
+ ce->serialize_func->op_array.refcount++;
+ }
+ if (ce->unserialize_func) {
+ ce->unserialize_func = zend_shared_alloc_get_xlat_entry(ce->unserialize_func);
+ ce->unserialize_func->op_array.refcount++;
+ }
+ if (ce->__isset) {
+ ce->__isset = zend_shared_alloc_get_xlat_entry(ce->__isset);
+ ce->__isset->op_array.refcount++;
+ }
+ if (ce->__unset) {
+ ce->__unset = zend_shared_alloc_get_xlat_entry(ce->__unset);
+ ce->__unset->op_array.refcount++;
+ }
+ if (ce->__tostring) {
+ ce->__tostring = zend_shared_alloc_get_xlat_entry(ce->__tostring);
+ ce->__tostring->op_array.refcount++;
+ }
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+ if (ce->__callstatic) {
+ ce->__callstatic = zend_shared_alloc_get_xlat_entry(ce->__callstatic);
+ ce->__callstatic->op_array.refcount++;
+ }
+#endif
+ zend_hash_apply(&ce->properties_info, (apply_func_t) zend_update_property_info_ce TSRMLS_CC);
+ return 0;
+}
+
+static void zend_accel_persist_class_table(HashTable *class_table TSRMLS_DC)
+{
+ zend_hash_persist(class_table, (zend_persist_func_t) zend_persist_class_entry, sizeof(zend_class_entry*) TSRMLS_CC);
+ zend_hash_apply(class_table, (apply_func_t) zend_update_parent_ce TSRMLS_CC);
+}
+
+zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script, char **key, unsigned int key_length TSRMLS_DC)
+{
+ zend_shared_alloc_clear_xlat_table();
+ zend_hash_persist(&script->function_table, (zend_persist_func_t) zend_persist_op_array, sizeof(zend_op_array) TSRMLS_CC);
+ zend_accel_persist_class_table(&script->class_table TSRMLS_CC);
+ zend_persist_op_array_ex(&script->main_op_array, script TSRMLS_CC);
+ *key = zend_accel_memdup(*key, key_length + 1);
+ zend_accel_store(script->full_path, script->full_path_len + 1);
+ zend_accel_store(script, sizeof(zend_persistent_script));
+
+ return script;
+}
+
+int zend_accel_script_persistable(zend_persistent_script *script)
+{
+ return 1;
+}
diff --git a/ext/opcache/zend_persist.h b/ext/opcache/zend_persist.h
new file mode 100644
index 0000000000..1b95a4ab04
--- /dev/null
+++ b/ext/opcache/zend_persist.h
@@ -0,0 +1,29 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2014 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: Andi Gutmans <andi@zend.com> |
+ | Zeev Suraski <zeev@zend.com> |
+ | Stanislav Malyshev <stas@zend.com> |
+ | Dmitry Stogov <dmitry@zend.com> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef ZEND_PERSIST_H
+#define ZEND_PERSIST_H
+
+int zend_accel_script_persistable(zend_persistent_script *script);
+uint zend_accel_script_persist_calc(zend_persistent_script *script, char *key, unsigned int key_length TSRMLS_DC);
+zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script, char **key, unsigned int key_length TSRMLS_DC);
+
+#endif /* ZEND_PERSIST_H */
diff --git a/ext/opcache/zend_persist_calc.c b/ext/opcache/zend_persist_calc.c
new file mode 100644
index 0000000000..e22b7d3952
--- /dev/null
+++ b/ext/opcache/zend_persist_calc.c
@@ -0,0 +1,345 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2014 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: Andi Gutmans <andi@zend.com> |
+ | Zeev Suraski <zeev@zend.com> |
+ | Stanislav Malyshev <stas@zend.com> |
+ | Dmitry Stogov <dmitry@zend.com> |
+ +----------------------------------------------------------------------+
+*/
+
+#include "zend.h"
+#include "ZendAccelerator.h"
+#include "zend_persist.h"
+#include "zend_extensions.h"
+#include "zend_shared_alloc.h"
+#include "zend_operators.h"
+
+#define START_SIZE() uint memory_used = 0
+#define ADD_DUP_SIZE(m,s) memory_used += zend_shared_memdup_size((void*)m, s)
+#define ADD_SIZE(m) memory_used += ZEND_ALIGNED_SIZE(m)
+#define RETURN_SIZE() return memory_used
+
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+# define ADD_INTERNED_STRING(str, len) do { \
+ if (!IS_INTERNED(str)) { \
+ const char *tmp = accel_new_interned_string((str), (len), 1 TSRMLS_CC); \
+ if (tmp != (str)) { \
+ (str) = (char*)tmp; \
+ } else { \
+ ADD_DUP_SIZE((str), (len)); \
+ } \
+ } \
+ } while (0)
+#else
+# define ADD_INTERNED_STRING(str, len) ADD_DUP_SIZE((str), (len))
+#endif
+
+static uint zend_persist_zval_ptr_calc(zval **zp TSRMLS_DC);
+
+static uint zend_hash_persist_calc(HashTable *ht, int (*pPersistElement)(void *pElement TSRMLS_DC), size_t el_size TSRMLS_DC)
+{
+ Bucket *p = ht->pListHead;
+ START_SIZE();
+
+ while (p) {
+ /* persist bucket and key */
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ ADD_DUP_SIZE(p, sizeof(Bucket));
+ if (p->nKeyLength) {
+ const char *tmp = accel_new_interned_string(p->arKey, p->nKeyLength, 0 TSRMLS_CC);
+ if (tmp != p->arKey) {
+ p->arKey = tmp;
+ } else {
+ ADD_DUP_SIZE(p->arKey, p->nKeyLength);
+ }
+ }
+#else
+ ADD_DUP_SIZE(p, sizeof(Bucket) - 1 + p->nKeyLength);
+#endif
+
+ /* persist data pointer in bucket */
+ if (!p->pDataPtr) {
+ ADD_DUP_SIZE(p->pData, el_size);
+ }
+
+ /* persist the data itself */
+ if (pPersistElement) {
+ ADD_SIZE(pPersistElement(p->pData TSRMLS_CC));
+ }
+
+ p = p->pListNext;
+ }
+
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ if (ht->nTableMask) {
+ ADD_DUP_SIZE(ht->arBuckets, sizeof(Bucket*) * ht->nTableSize);
+ }
+#else
+ ADD_DUP_SIZE(ht->arBuckets, sizeof(Bucket*) * ht->nTableSize);
+#endif
+
+ RETURN_SIZE();
+}
+
+static uint zend_persist_zval_calc(zval *z TSRMLS_DC)
+{
+ START_SIZE();
+
+#if ZEND_EXTENSION_API_NO >= PHP_5_3_X_API_NO
+ switch (z->type & IS_CONSTANT_TYPE_MASK) {
+#else
+ switch (z->type & ~IS_CONSTANT_INDEX) {
+#endif
+ case IS_STRING:
+ case IS_CONSTANT:
+ ADD_INTERNED_STRING(Z_STRVAL_P(z), Z_STRLEN_P(z) + 1);
+ break;
+ case IS_ARRAY:
+ case IS_CONSTANT_ARRAY:
+ ADD_DUP_SIZE(z->value.ht, sizeof(HashTable));
+ ADD_SIZE(zend_hash_persist_calc(z->value.ht, (int (*)(void* TSRMLS_DC)) zend_persist_zval_ptr_calc, sizeof(zval**) TSRMLS_CC));
+ break;
+ }
+ RETURN_SIZE();
+}
+
+static uint zend_persist_zval_ptr_calc(zval **zp TSRMLS_DC)
+{
+ START_SIZE();
+ zval *new_ptr = zend_shared_alloc_get_xlat_entry(*zp);
+
+ if (!new_ptr) {
+ ADD_DUP_SIZE(*zp, sizeof(zval));
+ ADD_SIZE(zend_persist_zval_calc(*zp TSRMLS_CC));
+ }
+ RETURN_SIZE();
+}
+
+static uint zend_persist_op_array_calc(zend_op_array *op_array TSRMLS_DC)
+{
+ START_SIZE();
+
+ if (op_array->type != ZEND_USER_FUNCTION) {
+ return 0;
+ }
+
+ if (op_array->filename) {
+ ADD_DUP_SIZE(op_array->filename, strlen(op_array->filename) + 1);
+ }
+
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ if (op_array->literals && !zend_shared_alloc_get_xlat_entry(op_array->literals)) {
+ zend_literal *p = op_array->literals;
+ zend_literal *end = p + op_array->last_literal;
+ ADD_DUP_SIZE(op_array->literals, sizeof(zend_literal) * op_array->last_literal);
+ while (p < end) {
+ ADD_SIZE(zend_persist_zval_calc(&p->constant TSRMLS_CC));
+ p++;
+ }
+ }
+#endif
+
+ if (!zend_shared_alloc_get_xlat_entry(op_array->opcodes)) {
+#if ZEND_EXTENSION_API_NO <= PHP_5_3_X_API_NO
+ zend_op *opline = op_array->opcodes;
+ zend_op *end = op_array->opcodes + op_array->last;
+
+ ADD_DUP_SIZE(op_array->opcodes, sizeof(zend_op) * op_array->last);
+ while (opline<end) {
+ if (opline->op1.op_type == IS_CONST) {
+ ADD_SIZE(zend_persist_zval_calc(&opline->op1.u.constant TSRMLS_CC));
+ }
+ if (opline->op2.op_type == IS_CONST) {
+ ADD_SIZE(zend_persist_zval_calc(&opline->op2.u.constant TSRMLS_CC));
+ }
+ opline++;
+ }
+#else
+ ADD_DUP_SIZE(op_array->opcodes, sizeof(zend_op) * op_array->last);
+#endif
+ }
+
+ if (op_array->function_name) {
+ ADD_DUP_SIZE(op_array->function_name, strlen(op_array->function_name) + 1);
+ }
+
+ if (op_array->arg_info &&
+ !zend_shared_alloc_get_xlat_entry(op_array->arg_info)) {
+ zend_uint i;
+
+ ADD_DUP_SIZE(op_array->arg_info, sizeof(zend_arg_info) * op_array->num_args);
+ for (i = 0; i < op_array->num_args; i++) {
+ if (op_array->arg_info[i].name) {
+ ADD_INTERNED_STRING(op_array->arg_info[i].name, op_array->arg_info[i].name_len + 1);
+ }
+ if (op_array->arg_info[i].class_name) {
+ ADD_INTERNED_STRING(op_array->arg_info[i].class_name, op_array->arg_info[i].class_name_len + 1);
+ }
+
+ }
+ }
+
+ if (op_array->brk_cont_array) {
+ ADD_DUP_SIZE(op_array->brk_cont_array, sizeof(zend_brk_cont_element) * op_array->last_brk_cont);
+ }
+
+ if (op_array->static_variables) {
+ ADD_DUP_SIZE(op_array->static_variables, sizeof(HashTable));
+ ADD_SIZE(zend_hash_persist_calc(op_array->static_variables, (int (*)(void* TSRMLS_DC)) zend_persist_zval_ptr_calc, sizeof(zval**) TSRMLS_CC));
+ }
+
+ if (ZCG(accel_directives).save_comments && op_array->doc_comment) {
+ ADD_DUP_SIZE(op_array->doc_comment, op_array->doc_comment_len + 1);
+ }
+
+ if (op_array->try_catch_array) {
+ ADD_DUP_SIZE(op_array->try_catch_array, sizeof(zend_try_catch_element) * op_array->last_try_catch);
+ }
+
+ if (op_array->vars && !zend_shared_alloc_get_xlat_entry(op_array->vars)) {
+ int i;
+
+ ADD_DUP_SIZE(op_array->vars, sizeof(zend_compiled_variable) * op_array->last_var);
+ for (i = 0; i < op_array->last_var; i++) {
+ ADD_INTERNED_STRING(op_array->vars[i].name, op_array->vars[i].name_len + 1);
+ }
+ }
+
+ RETURN_SIZE();
+}
+
+static uint zend_persist_property_info_calc(zend_property_info *prop TSRMLS_DC)
+{
+ START_SIZE();
+ ADD_INTERNED_STRING(prop->name, prop->name_length + 1);
+ if (ZCG(accel_directives).save_comments && prop->doc_comment) {
+ ADD_DUP_SIZE(prop->doc_comment, prop->doc_comment_len + 1);
+ }
+ RETURN_SIZE();
+}
+
+static uint zend_persist_class_entry_calc(zend_class_entry **pce TSRMLS_DC)
+{
+ zend_class_entry *ce = *pce;
+ START_SIZE();
+
+ if (ce->type == ZEND_USER_CLASS) {
+ ADD_DUP_SIZE(ce, sizeof(zend_class_entry));
+ ADD_INTERNED_STRING(ce->name, ce->name_length + 1);
+ ADD_SIZE(zend_hash_persist_calc(&ce->function_table, (int (*)(void* TSRMLS_DC)) zend_persist_op_array_calc, sizeof(zend_op_array) TSRMLS_CC));
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ if (ce->default_properties_table) {
+ int i;
+
+ ADD_SIZE(sizeof(zval*) * ce->default_properties_count);
+ for (i = 0; i < ce->default_properties_count; i++) {
+ if (ce->default_properties_table[i]) {
+ ADD_SIZE(zend_persist_zval_ptr_calc(&ce->default_properties_table[i] TSRMLS_CC));
+ }
+ }
+ }
+ if (ce->default_static_members_table) {
+ int i;
+
+ ADD_SIZE(sizeof(zval*) * ce->default_static_members_count);
+ for (i = 0; i < ce->default_static_members_count; i++) {
+ if (ce->default_static_members_table[i]) {
+ ADD_SIZE(zend_persist_zval_ptr_calc(&ce->default_static_members_table[i] TSRMLS_CC));
+ }
+ }
+ }
+#else
+ ADD_SIZE(zend_hash_persist_calc(&ce->default_properties, (int (*)(void* TSRMLS_DC)) zend_persist_zval_ptr_calc, sizeof(zval**) TSRMLS_CC));
+ ADD_SIZE(zend_hash_persist_calc(&ce->default_static_members, (int (*)(void* TSRMLS_DC)) zend_persist_zval_ptr_calc, sizeof(zval**) TSRMLS_CC));
+#endif
+ ADD_SIZE(zend_hash_persist_calc(&ce->constants_table, (int (*)(void* TSRMLS_DC)) zend_persist_zval_ptr_calc, sizeof(zval**) TSRMLS_CC));
+
+ if (ZEND_CE_FILENAME(ce)) {
+ ADD_DUP_SIZE(ZEND_CE_FILENAME(ce), strlen(ZEND_CE_FILENAME(ce)) + 1);
+ }
+ if (ZCG(accel_directives).save_comments && ZEND_CE_DOC_COMMENT(ce)) {
+ ADD_DUP_SIZE(ZEND_CE_DOC_COMMENT(ce), ZEND_CE_DOC_COMMENT_LEN(ce) + 1);
+ }
+
+ ADD_SIZE(zend_hash_persist_calc(&ce->properties_info, (int (*)(void* TSRMLS_DC)) zend_persist_property_info_calc, sizeof(zend_property_info) TSRMLS_CC));
+
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+ if (ce->trait_aliases) {
+ int i = 0;
+ while (ce->trait_aliases[i]) {
+ if (ce->trait_aliases[i]->trait_method) {
+ if (ce->trait_aliases[i]->trait_method->method_name) {
+ ADD_SIZE(ce->trait_aliases[i]->trait_method->mname_len + 1);
+ }
+ if (ce->trait_aliases[i]->trait_method->class_name) {
+ ADD_SIZE(ce->trait_aliases[i]->trait_method->cname_len + 1);
+ }
+ ADD_SIZE(sizeof(zend_trait_method_reference));
+ }
+
+ if (ce->trait_aliases[i]->alias) {
+ ADD_SIZE(ce->trait_aliases[i]->alias_len + 1);
+ }
+ ADD_SIZE(sizeof(zend_trait_alias));
+ i++;
+ }
+ ADD_SIZE(sizeof(zend_trait_alias*) * (i + 1));
+ }
+
+ if (ce->trait_precedences) {
+ int i = 0;
+
+ while (ce->trait_precedences[i]) {
+ ADD_SIZE(ce->trait_precedences[i]->trait_method->mname_len + 1);
+ ADD_SIZE(ce->trait_precedences[i]->trait_method->cname_len + 1);
+ ADD_SIZE(sizeof(zend_trait_method_reference));
+
+ if (ce->trait_precedences[i]->exclude_from_classes) {
+ int j = 0;
+
+ while (ce->trait_precedences[i]->exclude_from_classes[j]) {
+ ADD_SIZE(strlen((char*)ce->trait_precedences[i]->exclude_from_classes[j]) + 1);
+ j++;
+ }
+ ADD_SIZE(sizeof(zend_class_entry*) * (j + 1));
+ }
+ ADD_SIZE(sizeof(zend_trait_precedence));
+ i++;
+ }
+ ADD_SIZE(sizeof(zend_trait_precedence*) * (i + 1));
+ }
+#endif
+ }
+ RETURN_SIZE();
+}
+
+static uint zend_accel_persist_class_table_calc(HashTable *class_table TSRMLS_DC)
+{
+ return zend_hash_persist_calc(class_table, (int (*)(void* TSRMLS_DC)) zend_persist_class_entry_calc, sizeof(zend_class_entry*) TSRMLS_CC);
+}
+
+uint zend_accel_script_persist_calc(zend_persistent_script *new_persistent_script, char *key, unsigned int key_length TSRMLS_DC)
+{
+ START_SIZE();
+
+ ADD_SIZE(zend_hash_persist_calc(&new_persistent_script->function_table, (int (*)(void* TSRMLS_DC)) zend_persist_op_array_calc, sizeof(zend_op_array) TSRMLS_CC));
+ ADD_SIZE(zend_accel_persist_class_table_calc(&new_persistent_script->class_table TSRMLS_CC));
+ ADD_SIZE(zend_persist_op_array_calc(&new_persistent_script->main_op_array TSRMLS_CC));
+ ADD_DUP_SIZE(key, key_length + 1);
+ ADD_DUP_SIZE(new_persistent_script->full_path, new_persistent_script->full_path_len + 1);
+ ADD_DUP_SIZE(new_persistent_script, sizeof(zend_persistent_script));
+
+ RETURN_SIZE();
+}
diff --git a/ext/opcache/zend_shared_alloc.c b/ext/opcache/zend_shared_alloc.c
new file mode 100644
index 0000000000..e1a570a3a0
--- /dev/null
+++ b/ext/opcache/zend_shared_alloc.c
@@ -0,0 +1,494 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2014 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: Andi Gutmans <andi@zend.com> |
+ | Zeev Suraski <zeev@zend.com> |
+ | Stanislav Malyshev <stas@zend.com> |
+ | Dmitry Stogov <dmitry@zend.com> |
+ +----------------------------------------------------------------------+
+*/
+
+#include <errno.h>
+#include "ZendAccelerator.h"
+#include "zend_shared_alloc.h"
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#include <fcntl.h>
+#ifndef ZEND_WIN32
+# include <sys/types.h>
+# include <dirent.h>
+# include <signal.h>
+# include <sys/stat.h>
+# include <stdio.h>
+#endif
+
+#ifdef HAVE_MPROTECT
+# include "sys/mman.h"
+#endif
+
+#define TMP_DIR "/tmp"
+#define SEM_FILENAME_PREFIX ".ZendSem."
+#define S_H(s) g_shared_alloc_handler->s
+
+/* True globals */
+/* old/new mapping. We can use true global even for ZTS because its usage
+ is wrapped with exclusive lock anyway */
+static HashTable xlat_table;
+static const zend_shared_memory_handlers *g_shared_alloc_handler = NULL;
+static const char *g_shared_model;
+/* pointer to globals allocated in SHM and shared across processes */
+zend_smm_shared_globals *smm_shared_globals;
+
+#ifndef ZEND_WIN32
+#ifdef ZTS
+static MUTEX_T zts_lock;
+#endif
+int lock_file;
+static char lockfile_name[sizeof(TMP_DIR) + sizeof(SEM_FILENAME_PREFIX) + 8];
+#endif
+
+static const zend_shared_memory_handler_entry handler_table[] = {
+#ifdef USE_MMAP
+ { "mmap", &zend_alloc_mmap_handlers },
+#endif
+#ifdef USE_SHM
+ { "shm", &zend_alloc_shm_handlers },
+#endif
+#ifdef USE_SHM_OPEN
+ { "posix", &zend_alloc_posix_handlers },
+#endif
+#ifdef ZEND_WIN32
+ { "win32", &zend_alloc_win32_handlers },
+#endif
+ { NULL, NULL}
+};
+
+#ifndef ZEND_WIN32
+void zend_shared_alloc_create_lock(void)
+{
+ int val;
+
+#ifdef ZTS
+ zts_lock = tsrm_mutex_alloc();
+#endif
+
+ sprintf(lockfile_name, "%s/%sXXXXXX", TMP_DIR, SEM_FILENAME_PREFIX);
+ lock_file = mkstemp(lockfile_name);
+ fchmod(lock_file, 0666);
+
+ if (lock_file == -1) {
+ zend_accel_error(ACCEL_LOG_FATAL, "Unable to create lock file: %s (%d)", strerror(errno), errno);
+ }
+ val = fcntl(lock_file, F_GETFD, 0);
+ val |= FD_CLOEXEC;
+ fcntl(lock_file, F_SETFD, val);
+
+ unlink(lockfile_name);
+}
+#endif
+
+static void no_memory_bailout(size_t allocate_size, char *error)
+{
+ zend_accel_error(ACCEL_LOG_FATAL, "Unable to allocate shared memory segment of %ld bytes: %s: %s (%d)", allocate_size, error?error:"unknown", strerror(errno), errno );
+}
+
+static void copy_shared_segments(void *to, void *from, int count, int size)
+{
+ zend_shared_segment **shared_segments_v = (zend_shared_segment **)to;
+ void *shared_segments_to_p = ((char *)to + count*(sizeof(void *)));
+ void *shared_segments_from_p = from;
+ int i;
+
+ for (i = 0; i < count; i++) {
+ shared_segments_v[i] = shared_segments_to_p;
+ memcpy(shared_segments_to_p, shared_segments_from_p, size);
+ shared_segments_to_p = ((char *)shared_segments_to_p + size);
+ shared_segments_from_p = ((char *)shared_segments_from_p + size);
+ }
+}
+
+static int zend_shared_alloc_try(const zend_shared_memory_handler_entry *he, size_t requested_size, zend_shared_segment ***shared_segments_p, int *shared_segments_count, char **error_in)
+{
+ int res;
+ g_shared_alloc_handler = he->handler;
+ g_shared_model = he->name;
+ ZSMMG(shared_segments) = NULL;
+ ZSMMG(shared_segments_count) = 0;
+
+ res = S_H(create_segments)(requested_size, shared_segments_p, shared_segments_count, error_in);
+
+ if (res) {
+ /* this model works! */
+ return res;
+ }
+ if (*shared_segments_p) {
+ int i;
+ /* cleanup */
+ for (i = 0; i < *shared_segments_count; i++) {
+ if ((*shared_segments_p)[i]->p && (*shared_segments_p)[i]->p != (void *)-1) {
+ S_H(detach_segment)((*shared_segments_p)[i]);
+ }
+ }
+ free(*shared_segments_p);
+ *shared_segments_p = NULL;
+ }
+ g_shared_alloc_handler = NULL;
+ return ALLOC_FAILURE;
+}
+
+int zend_shared_alloc_startup(size_t requested_size)
+{
+ zend_shared_segment **tmp_shared_segments;
+ size_t shared_segments_array_size;
+ zend_smm_shared_globals tmp_shared_globals, *p_tmp_shared_globals;
+ char *error_in = NULL;
+ const zend_shared_memory_handler_entry *he;
+ int res = ALLOC_FAILURE;
+
+ TSRMLS_FETCH();
+
+ /* shared_free must be valid before we call zend_shared_alloc()
+ * - make it temporarily point to a local variable
+ */
+ smm_shared_globals = &tmp_shared_globals;
+ ZSMMG(shared_free) = requested_size; /* goes to tmp_shared_globals.shared_free */
+
+ zend_shared_alloc_create_lock();
+
+ if (ZCG(accel_directives).memory_model && ZCG(accel_directives).memory_model[0]) {
+ char *model = ZCG(accel_directives).memory_model;
+ /* "cgi" is really "shm"... */
+ if (strncmp(ZCG(accel_directives).memory_model, "cgi", sizeof("cgi")) == 0) {
+ model = "shm";
+ }
+
+ for (he = handler_table; he->name; he++) {
+ if (strcmp(model, he->name) == 0) {
+ res = zend_shared_alloc_try(he, requested_size, &ZSMMG(shared_segments), &ZSMMG(shared_segments_count), &error_in);
+ if (res) {
+ /* this model works! */
+ }
+ break;
+ }
+ }
+ }
+
+ if (res == FAILED_REATTACHED) {
+ smm_shared_globals = NULL;
+ return res;
+ }
+
+ if (!g_shared_alloc_handler) {
+ /* try memory handlers in order */
+ for (he = handler_table; he->name; he++) {
+ res = zend_shared_alloc_try(he, requested_size, &ZSMMG(shared_segments), &ZSMMG(shared_segments_count), &error_in);
+ if (res) {
+ /* this model works! */
+ break;
+ }
+ }
+ }
+
+ if (!g_shared_alloc_handler) {
+ no_memory_bailout(requested_size, error_in);
+ return ALLOC_FAILURE;
+ }
+
+ if (res == SUCCESSFULLY_REATTACHED) {
+ return res;
+ }
+
+ shared_segments_array_size = ZSMMG(shared_segments_count) * S_H(segment_type_size)();
+
+ /* move shared_segments and shared_free to shared memory */
+ ZCG(locked) = 1; /* no need to perform a real lock at this point */
+ p_tmp_shared_globals = (zend_smm_shared_globals *) zend_shared_alloc(sizeof(zend_smm_shared_globals));
+ if (!p_tmp_shared_globals) {
+ zend_accel_error(ACCEL_LOG_FATAL, "Insufficient shared memory!");
+ return ALLOC_FAILURE;;
+ }
+
+ tmp_shared_segments = zend_shared_alloc(shared_segments_array_size + ZSMMG(shared_segments_count) * sizeof(void *));
+ if (!tmp_shared_segments) {
+ zend_accel_error(ACCEL_LOG_FATAL, "Insufficient shared memory!");
+ return ALLOC_FAILURE;;
+ }
+
+ copy_shared_segments(tmp_shared_segments, ZSMMG(shared_segments)[0], ZSMMG(shared_segments_count), S_H(segment_type_size)());
+
+ *p_tmp_shared_globals = tmp_shared_globals;
+ smm_shared_globals = p_tmp_shared_globals;
+
+ free(ZSMMG(shared_segments));
+ ZSMMG(shared_segments) = tmp_shared_segments;
+
+ ZSMMG(shared_memory_state).positions = (int *)zend_shared_alloc(sizeof(int) * ZSMMG(shared_segments_count));
+ if (!ZSMMG(shared_memory_state).positions) {
+ zend_accel_error(ACCEL_LOG_FATAL, "Insufficient shared memory!");
+ return ALLOC_FAILURE;;
+ }
+
+ ZCG(locked) = 0;
+
+ return res;
+}
+
+void zend_shared_alloc_shutdown(void)
+{
+ zend_shared_segment **tmp_shared_segments;
+ size_t shared_segments_array_size;
+ zend_smm_shared_globals tmp_shared_globals;
+ int i;
+
+ tmp_shared_globals = *smm_shared_globals;
+ smm_shared_globals = &tmp_shared_globals;
+ shared_segments_array_size = ZSMMG(shared_segments_count) * (S_H(segment_type_size)() + sizeof(void *));
+ tmp_shared_segments = emalloc(shared_segments_array_size);
+ copy_shared_segments(tmp_shared_segments, ZSMMG(shared_segments)[0], ZSMMG(shared_segments_count), S_H(segment_type_size)());
+ ZSMMG(shared_segments) = tmp_shared_segments;
+
+ for (i = 0; i < ZSMMG(shared_segments_count); i++) {
+ S_H(detach_segment)(ZSMMG(shared_segments)[i]);
+ }
+ efree(ZSMMG(shared_segments));
+ ZSMMG(shared_segments) = NULL;
+ g_shared_alloc_handler = NULL;
+#ifndef ZEND_WIN32
+ close(lock_file);
+#endif
+}
+
+static size_t zend_shared_alloc_get_largest_free_block(void)
+{
+ int i;
+ size_t largest_block_size = 0;
+
+ for (i = 0; i < ZSMMG(shared_segments_count); i++) {
+ size_t block_size = ZSMMG(shared_segments)[i]->size - ZSMMG(shared_segments)[i]->pos;
+
+ if (block_size>largest_block_size) {
+ largest_block_size = block_size;
+ }
+ }
+ return largest_block_size;
+}
+
+#define MIN_FREE_MEMORY 64*1024
+
+#define SHARED_ALLOC_FAILED() do { \
+ zend_accel_error(ACCEL_LOG_WARNING, "Not enough free shared space to allocate %ld bytes (%ld bytes free)", (long)size, (long)ZSMMG(shared_free)); \
+ if (zend_shared_alloc_get_largest_free_block() < MIN_FREE_MEMORY) { \
+ ZSMMG(memory_exhausted) = 1; \
+ } \
+ } while (0)
+
+void *zend_shared_alloc(size_t size)
+{
+ int i;
+ unsigned int block_size = ZEND_ALIGNED_SIZE(size);
+ TSRMLS_FETCH();
+
+#if 1
+ if (!ZCG(locked)) {
+ zend_accel_error(ACCEL_LOG_ERROR, "Shared memory lock not obtained");
+ }
+#endif
+ if (block_size > ZSMMG(shared_free)) { /* No hope to find a big-enough block */
+ SHARED_ALLOC_FAILED();
+ return NULL;
+ }
+ for (i = 0; i < ZSMMG(shared_segments_count); i++) {
+ if (ZSMMG(shared_segments)[i]->size - ZSMMG(shared_segments)[i]->pos >= block_size) { /* found a valid block */
+ void *retval = (void *) (((char *) ZSMMG(shared_segments)[i]->p) + ZSMMG(shared_segments)[i]->pos);
+
+ ZSMMG(shared_segments)[i]->pos += block_size;
+ ZSMMG(shared_free) -= block_size;
+ memset(retval, 0, block_size);
+ return retval;
+ }
+ }
+ SHARED_ALLOC_FAILED();
+ return NULL;
+}
+
+int zend_shared_memdup_size(void *source, size_t size)
+{
+ void **old_p;
+
+ if (zend_hash_index_find(&xlat_table, (ulong)source, (void **)&old_p) == SUCCESS) {
+ /* we already duplicated this pointer */
+ return 0;
+ }
+ zend_shared_alloc_register_xlat_entry(source, source);
+ return ZEND_ALIGNED_SIZE(size);
+}
+
+void *_zend_shared_memdup(void *source, size_t size, zend_bool free_source TSRMLS_DC)
+{
+ void **old_p, *retval;
+
+ if (zend_hash_index_find(&xlat_table, (ulong)source, (void **)&old_p) == SUCCESS) {
+ /* we already duplicated this pointer */
+ return *old_p;
+ }
+ retval = ZCG(mem);;
+ ZCG(mem) = (void*)(((char*)ZCG(mem)) + ZEND_ALIGNED_SIZE(size));
+ memcpy(retval, source, size);
+ if (free_source) {
+ interned_efree((char*)source);
+ }
+ zend_shared_alloc_register_xlat_entry(source, retval);
+ return retval;
+}
+
+void zend_shared_alloc_safe_unlock(TSRMLS_D)
+{
+ if (ZCG(locked)) {
+ zend_shared_alloc_unlock(TSRMLS_C);
+ }
+}
+
+#ifndef ZEND_WIN32
+/* name l_type l_whence l_start l_len */
+static FLOCK_STRUCTURE(mem_write_lock, F_WRLCK, SEEK_SET, 0, 1);
+static FLOCK_STRUCTURE(mem_write_unlock, F_UNLCK, SEEK_SET, 0, 1);
+#endif
+
+void zend_shared_alloc_lock(TSRMLS_D)
+{
+#ifndef ZEND_WIN32
+
+#ifdef ZTS
+ tsrm_mutex_lock(zts_lock);
+#endif
+
+#if 0
+ /* this will happen once per process, and will un-globalize mem_write_lock */
+ if (mem_write_lock.l_pid == -1) {
+ mem_write_lock.l_pid = getpid();
+ }
+#endif
+
+ while (1) {
+ if (fcntl(lock_file, F_SETLKW, &mem_write_lock) == -1) {
+ if (errno == EINTR) {
+ continue;
+ }
+ zend_accel_error(ACCEL_LOG_ERROR, "Cannot create lock - %s (%d)", strerror(errno), errno);
+ }
+ break;
+ }
+#else
+ zend_shared_alloc_lock_win32();
+#endif
+
+ ZCG(locked) = 1;
+
+ /* Prepare translation table
+ *
+ * Make it persistent so that it uses malloc() and allocated blocks
+ * won't be taken from space which is freed by efree in memdup.
+ * Otherwise it leads to false matches in memdup check.
+ */
+ zend_hash_init(&xlat_table, 100, NULL, NULL, 1);
+}
+
+void zend_shared_alloc_unlock(TSRMLS_D)
+{
+ /* Destroy translation table */
+ zend_hash_destroy(&xlat_table);
+
+ ZCG(locked) = 0;
+
+#ifndef ZEND_WIN32
+ if (fcntl(lock_file, F_SETLK, &mem_write_unlock) == -1) {
+ zend_accel_error(ACCEL_LOG_ERROR, "Cannot remove lock - %s (%d)", strerror(errno), errno);
+ }
+#ifdef ZTS
+ tsrm_mutex_unlock(zts_lock);
+#endif
+#else
+ zend_shared_alloc_unlock_win32();
+#endif
+}
+
+void zend_shared_alloc_clear_xlat_table(void)
+{
+ zend_hash_clean(&xlat_table);
+}
+
+void zend_shared_alloc_register_xlat_entry(const void *old, const void *new)
+{
+ zend_hash_index_update(&xlat_table, (ulong)old, (void*)&new, sizeof(void *), NULL);
+}
+
+void *zend_shared_alloc_get_xlat_entry(const void *old)
+{
+ void **retval;
+
+ if (zend_hash_index_find(&xlat_table, (ulong)old, (void **)&retval) == FAILURE) {
+ return NULL;
+ }
+ return *retval;
+}
+
+size_t zend_shared_alloc_get_free_memory(void)
+{
+ return ZSMMG(shared_free);
+}
+
+void zend_shared_alloc_save_state(void)
+{
+ int i;
+
+ for (i = 0; i < ZSMMG(shared_segments_count); i++) {
+ ZSMMG(shared_memory_state).positions[i] = ZSMMG(shared_segments)[i]->pos;
+ }
+ ZSMMG(shared_memory_state).shared_free = ZSMMG(shared_free);
+}
+
+void zend_shared_alloc_restore_state(void)
+{
+ int i;
+
+ for (i = 0; i < ZSMMG(shared_segments_count); i++) {
+ ZSMMG(shared_segments)[i]->pos = ZSMMG(shared_memory_state).positions[i];
+ }
+ ZSMMG(shared_free) = ZSMMG(shared_memory_state).shared_free;
+ ZSMMG(memory_exhausted) = 0;
+ ZSMMG(wasted_shared_memory) = 0;
+}
+
+const char *zend_accel_get_shared_model(void)
+{
+ return g_shared_model;
+}
+
+void zend_accel_shared_protect(int mode TSRMLS_DC)
+{
+#ifdef HAVE_MPROTECT
+ int i;
+
+ if (mode) {
+ mode = PROT_READ;
+ } else {
+ mode = PROT_READ|PROT_WRITE;
+ }
+
+ for (i = 0; i < ZSMMG(shared_segments_count); i++) {
+ mprotect(ZSMMG(shared_segments)[i]->p, ZSMMG(shared_segments)[i]->size, mode);
+ }
+#endif
+}
diff --git a/ext/opcache/zend_shared_alloc.h b/ext/opcache/zend_shared_alloc.h
new file mode 100644
index 0000000000..57ea8d3fdd
--- /dev/null
+++ b/ext/opcache/zend_shared_alloc.h
@@ -0,0 +1,182 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2014 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: Andi Gutmans <andi@zend.com> |
+ | Zeev Suraski <zeev@zend.com> |
+ | Stanislav Malyshev <stas@zend.com> |
+ | Dmitry Stogov <dmitry@zend.com> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef ZEND_SHARED_ALLOC_H
+#define ZEND_SHARED_ALLOC_H
+
+#include "zend.h"
+#include "ZendAccelerator.h"
+
+#if defined(__APPLE__) && defined(__MACH__) /* darwin */
+# ifdef HAVE_SHM_MMAP_POSIX
+# define USE_SHM_OPEN 1
+# endif
+# ifdef HAVE_SHM_MMAP_ANON
+# define USE_MMAP 1
+# endif
+#elif defined(__linux__) || defined(_AIX)
+# ifdef HAVE_SHM_IPC
+# define USE_SHM 1
+# endif
+# ifdef HAVE_SHM_MMAP_ANON
+# define USE_MMAP 1
+# endif
+#elif defined(__sparc) || defined(__sun)
+# ifdef HAVE_SHM_MMAP_POSIX
+# define USE_SHM_OPEN 1
+# endif
+# ifdef HAVE_SHM_IPC
+# define USE_SHM 1
+# endif
+# if defined(__i386)
+# ifdef HAVE_SHM_MMAP_ANON
+# define USE_MMAP 1
+# endif
+# endif
+#else
+# ifdef HAVE_SHM_MMAP_POSIX
+# define USE_SHM_OPEN 1
+# endif
+# ifdef HAVE_SHM_MMAP_ANON
+# define USE_MMAP 1
+# endif
+# ifdef HAVE_SHM_IPC
+# define USE_SHM 1
+# endif
+#endif
+
+#define ALLOC_FAILURE 0
+#define ALLOC_SUCCESS 1
+#define FAILED_REATTACHED 2
+#define SUCCESSFULLY_REATTACHED 4
+#define ALLOC_FAIL_MAPPING 8
+
+typedef struct _zend_shared_segment {
+ size_t size;
+ size_t pos; /* position for simple stack allocator */
+ void *p;
+} zend_shared_segment;
+
+typedef int (*create_segments_t)(size_t requested_size, zend_shared_segment ***shared_segments, int *shared_segment_count, char **error_in);
+typedef int (*detach_segment_t)(zend_shared_segment *shared_segment);
+
+typedef struct {
+ create_segments_t create_segments;
+ detach_segment_t detach_segment;
+ size_t (*segment_type_size)(void);
+} zend_shared_memory_handlers;
+
+typedef struct _handler_entry {
+ const char *name;
+ zend_shared_memory_handlers *handler;
+} zend_shared_memory_handler_entry;
+
+typedef struct _zend_shared_memory_state {
+ int *positions; /* current positions for each segment */
+ int shared_free; /* amount of free shared memory */
+} zend_shared_memory_state;
+
+typedef struct _zend_smm_shared_globals {
+ /* Shared Memory Manager */
+ zend_shared_segment **shared_segments;
+ /* Number of allocated shared segments */
+ int shared_segments_count;
+ /* Amount of free shared memory */
+ size_t shared_free;
+ /* Amount of shared memory allocated by garbage */
+ int wasted_shared_memory;
+ /* No more shared memory flag */
+ zend_bool memory_exhausted;
+ /* Saved Shared Allocator State */
+ zend_shared_memory_state shared_memory_state;
+ /* Pointer to the application's shared data structures */
+ void *app_shared_globals;
+} zend_smm_shared_globals;
+
+extern zend_smm_shared_globals *smm_shared_globals;
+
+#define ZSMMG(element) (smm_shared_globals->element)
+
+#define SHARED_ALLOC_REATTACHED (SUCCESS+1)
+
+int zend_shared_alloc_startup(size_t requested_size);
+void zend_shared_alloc_shutdown(void);
+
+/* allocate shared memory block */
+void *zend_shared_alloc(size_t size);
+
+/* copy into shared memory */
+void *_zend_shared_memdup(void *p, size_t size, zend_bool free_source TSRMLS_DC);
+int zend_shared_memdup_size(void *p, size_t size);
+
+typedef union _align_test {
+ void *ptr;
+ double dbl;
+ long lng;
+} align_test;
+
+#if ZEND_GCC_VERSION >= 2000
+# define PLATFORM_ALIGNMENT (__alignof__ (align_test))
+#else
+# define PLATFORM_ALIGNMENT (sizeof(align_test))
+#endif
+
+#define ZEND_ALIGNED_SIZE(size) \
+ ((size + PLATFORM_ALIGNMENT - 1) & ~(PLATFORM_ALIGNMENT - 1))
+
+/* exclusive locking */
+void zend_shared_alloc_lock(TSRMLS_D);
+void zend_shared_alloc_unlock(TSRMLS_D); /* returns the allocated size during lock..unlock */
+void zend_shared_alloc_safe_unlock(TSRMLS_D);
+
+/* old/new mapping functions */
+void zend_shared_alloc_clear_xlat_table(void);
+void zend_shared_alloc_register_xlat_entry(const void *old, const void *new);
+void *zend_shared_alloc_get_xlat_entry(const void *old);
+
+size_t zend_shared_alloc_get_free_memory(void);
+void zend_shared_alloc_save_state(void);
+void zend_shared_alloc_restore_state(void);
+const char *zend_accel_get_shared_model(void);
+
+/* memory write protection */
+void zend_accel_shared_protect(int mode TSRMLS_DC);
+
+#ifdef USE_MMAP
+extern zend_shared_memory_handlers zend_alloc_mmap_handlers;
+#endif
+
+#ifdef USE_SHM
+extern zend_shared_memory_handlers zend_alloc_shm_handlers;
+#endif
+
+#ifdef USE_SHM_OPEN
+extern zend_shared_memory_handlers zend_alloc_posix_handlers;
+#endif
+
+#ifdef ZEND_WIN32
+extern zend_shared_memory_handlers zend_alloc_win32_handlers;
+void zend_shared_alloc_create_lock(void);
+void zend_shared_alloc_lock_win32(void);
+void zend_shared_alloc_unlock_win32(void);
+#endif
+
+#endif /* ZEND_SHARED_ALLOC_H */
diff --git a/ext/openssl/CREDITS b/ext/openssl/CREDITS
index c2f50d6308..b685ce13e5 100644
--- a/ext/openssl/CREDITS
+++ b/ext/openssl/CREDITS
@@ -1,2 +1,2 @@
OpenSSL
-Stig Venaas, Wez Furlong, Sascha Kettler
+Stig Venaas, Wez Furlong, Sascha Kettler, Scott MacVicar
diff --git a/ext/openssl/config0.m4 b/ext/openssl/config0.m4
index 2c7f4fb691..a97114f808 100644
--- a/ext/openssl/config0.m4
+++ b/ext/openssl/config0.m4
@@ -3,7 +3,7 @@ dnl $Id$
dnl
PHP_ARG_WITH(openssl, for OpenSSL support,
-[ --with-openssl[=DIR] Include OpenSSL support (requires OpenSSL >= 0.9.6)])
+[ --with-openssl[=DIR] Include OpenSSL support (requires OpenSSL >= 0.9.6)])
PHP_ARG_WITH(kerberos, for Kerberos support,
[ --with-kerberos[=DIR] OPENSSL: Include Kerberos support], no, no)
diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c
index 2baf086ca0..4e659a10db 100644
--- a/ext/openssl/openssl.c
+++ b/ext/openssl/openssl.c
@@ -16,7 +16,7 @@
| Wez Furlong <wez@thebrainroom.com> |
| Sascha Kettler <kettler@gmx.net> |
| Pierre-Alain Joye <pierre@php.net> |
- | Marc Delling <delling@silpion.de> (PKCS12 functions) |
+ | Marc Delling <delling@silpion.de> (PKCS12 functions) |
+----------------------------------------------------------------------+
*/
@@ -35,8 +35,7 @@
#include "ext/standard/php_fopen_wrappers.h"
#include "ext/standard/md5.h"
#include "ext/standard/base64.h"
-
-#if PHP_WIN32
+#ifdef PHP_WIN32
# include "win32/winutil.h"
#endif
@@ -248,6 +247,16 @@ ZEND_BEGIN_ARG_INFO(arginfo_openssl_pkey_get_details, 0)
ZEND_ARG_INFO(0, key)
ZEND_END_ARG_INFO()
+#if OPENSSL_VERSION_NUMBER >= 0x10000000L
+ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_pbkdf2, 0, 0, 4)
+ ZEND_ARG_INFO(0, password)
+ ZEND_ARG_INFO(0, salt)
+ ZEND_ARG_INFO(0, key_length)
+ ZEND_ARG_INFO(0, iterations)
+ ZEND_ARG_INFO(0, digest_algorithm)
+ZEND_END_ARG_INFO()
+#endif
+
ZEND_BEGIN_ARG_INFO_EX(arginfo_openssl_pkcs7_verify, 0, 0, 2)
ZEND_ARG_INFO(0, filename)
ZEND_ARG_INFO(0, flags)
@@ -434,6 +443,10 @@ const zend_function_entry openssl_functions[] = {
PHP_FE(openssl_seal, arginfo_openssl_seal)
PHP_FE(openssl_open, arginfo_openssl_open)
+#if OPENSSL_VERSION_NUMBER >= 0x10000000L
+ PHP_FE(openssl_pbkdf2, arginfo_openssl_pbkdf2)
+#endif
+
/* for S/MIME handling */
PHP_FE(openssl_pkcs7_verify, arginfo_openssl_pkcs7_verify)
PHP_FE(openssl_pkcs7_decrypt, arginfo_openssl_pkcs7_decrypt)
@@ -516,7 +529,7 @@ inline static int php_openssl_open_base_dir_chk(char *filename TSRMLS_DC)
if (php_check_open_basedir(filename TSRMLS_CC)) {
return -1;
}
-
+
return 0;
}
/* }}} */
@@ -563,7 +576,7 @@ static void add_assoc_name_entry(zval * val, char * key, X509_NAME * name, int s
{
zval **data;
zval *subitem, *subentries;
- int i, j = -1, last = -1, obj_cnt = 0;
+ int i;
char *sname;
int nid;
X509_NAME_ENTRY * ne;
@@ -576,7 +589,7 @@ static void add_assoc_name_entry(zval * val, char * key, X509_NAME * name, int s
} else {
subitem = val;
}
-
+
for (i = 0; i < X509_NAME_entry_count(name); i++) {
unsigned char *to_add;
int to_add_len = 0;
@@ -585,7 +598,6 @@ static void add_assoc_name_entry(zval * val, char * key, X509_NAME * name, int s
ne = X509_NAME_get_entry(name, i);
obj = X509_NAME_ENTRY_get_object(ne);
nid = OBJ_obj2nid(obj);
- obj_cnt = 0;
if (shortname) {
sname = (char *) OBJ_nid2sn(nid);
@@ -717,7 +729,7 @@ static inline int php_openssl_config_check_syntax(const char * section_label, co
#endif
{
X509V3_CTX ctx;
-
+
X509V3_set_ctx_test(&ctx);
X509V3_set_conf_lhash(&ctx, config);
if (!X509V3_EXT_add_conf(config, &ctx, (char *)section, NULL)) {
@@ -845,7 +857,7 @@ static int php_openssl_parse_config(struct php_x509_request * req, zval * option
}
-
+
/* digest alg */
if (req->digest_name == NULL) {
req->digest_name = CONF_get_string(req->req_config, req->section_name, "default_md");
@@ -867,7 +879,7 @@ static int php_openssl_parse_config(struct php_x509_request * req, zval * option
}
PHP_SSL_CONFIG_SYNTAX_CHECK(request_extensions_section);
-
+
return SUCCESS;
}
/* }}} */
@@ -1047,10 +1059,10 @@ PHP_MINIT_FUNCTION(openssl)
/* register a resource id number with OpenSSL so that we can map SSL -> stream structures in
* OpenSSL callbacks */
ssl_stream_data_index = SSL_get_ex_new_index(0, "PHP stream index", NULL, NULL, NULL);
-
+
REGISTER_STRING_CONSTANT("OPENSSL_VERSION_TEXT", OPENSSL_VERSION_TEXT, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OPENSSL_VERSION_NUMBER", OPENSSL_VERSION_NUMBER, CONST_CS|CONST_PERSISTENT);
-
+
/* purposes for cert purpose checking */
REGISTER_LONG_CONSTANT("X509_PURPOSE_SSL_CLIENT", X509_PURPOSE_SSL_CLIENT, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("X509_PURPOSE_SSL_SERVER", X509_PURPOSE_SSL_SERVER, CONST_CS|CONST_PERSISTENT);
@@ -1109,7 +1121,7 @@ PHP_MINIT_FUNCTION(openssl)
REGISTER_LONG_CONSTANT("OPENSSL_CIPHER_AES_192_CBC", PHP_OPENSSL_CIPHER_AES_192_CBC, CONST_CS|CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("OPENSSL_CIPHER_AES_256_CBC", PHP_OPENSSL_CIPHER_AES_256_CBC, CONST_CS|CONST_PERSISTENT);
#endif
-
+
/* Values for key types */
REGISTER_LONG_CONSTANT("OPENSSL_KEYTYPE_RSA", OPENSSL_KEYTYPE_RSA, CONST_CS|CONST_PERSISTENT);
#ifndef NO_DSA
@@ -1155,7 +1167,7 @@ PHP_MINIT_FUNCTION(openssl)
php_register_url_stream_wrapper("https", &php_stream_http_wrapper TSRMLS_CC);
php_register_url_stream_wrapper("ftps", &php_stream_ftp_wrapper TSRMLS_CC);
-
+
return SUCCESS;
}
/* }}} */
@@ -1375,14 +1387,14 @@ PHP_FUNCTION(openssl_x509_check_private_key)
long certresource = -1, keyresource = -1;
RETVAL_FALSE;
-
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ", &zcert, &zkey) == FAILURE) {
return;
}
cert = php_openssl_x509_from_zval(zcert, 0, &certresource TSRMLS_CC);
if (cert == NULL) {
RETURN_FALSE;
- }
+ }
key = php_openssl_evp_from_zval(zkey, 0, "", 1, &keyresource TSRMLS_CC);
if (key) {
RETVAL_BOOL(X509_check_private_key(cert, key));
@@ -1503,11 +1515,11 @@ PHP_FUNCTION(openssl_x509_parse)
snprintf(buf, sizeof(buf), "%08lx", X509_subject_name_hash(cert));
add_assoc_string(return_value, "hash", buf, 1);
}
-
+
add_assoc_name_entry(return_value, "issuer", X509_get_issuer_name(cert), useshortnames TSRMLS_CC);
add_assoc_long(return_value, "version", X509_get_version(cert));
- add_assoc_string(return_value, "serialNumber", i2s_ASN1_INTEGER(NULL, X509_get_serialNumber(cert)), 1);
+ add_assoc_string(return_value, "serialNumber", i2s_ASN1_INTEGER(NULL, X509_get_serialNumber(cert)), 1);
add_assoc_asn1_string(return_value, "validFrom", X509_get_notBefore(cert));
add_assoc_asn1_string(return_value, "validTo", X509_get_notAfter(cert));
@@ -1724,8 +1736,8 @@ clean_exit:
if (certresource == 1 && cert) {
X509_free(cert);
}
- if (cainfo) {
- X509_STORE_free(cainfo);
+ if (cainfo) {
+ X509_STORE_free(cainfo);
}
if (untrustedchain) {
sk_X509_pop_free(untrustedchain, X509_free);
@@ -1778,7 +1790,7 @@ static X509_STORE * setup_verify(zval * calist TSRMLS_DC)
dir_lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
if (dir_lookup == NULL || !X509_LOOKUP_add_dir(dir_lookup, Z_STRVAL_PP(item), X509_FILETYPE_PEM)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "error loading directory %s", Z_STRVAL_PP(item));
- } else {
+ } else {
ndirs++;
}
dir_lookup = NULL;
@@ -1872,11 +1884,11 @@ static STACK_OF(X509) * php_array_to_X509_sk(zval ** zcerts TSRMLS_DC) /* {{{ */
if (certresource != -1) {
cert = X509_dup(cert);
-
+
if (cert == NULL) {
goto clean_exit;
}
-
+
}
sk_X509_push(sk, cert);
@@ -1885,7 +1897,7 @@ static STACK_OF(X509) * php_array_to_X509_sk(zval ** zcerts TSRMLS_DC) /* {{{ */
} else {
/* a single certificate */
cert = php_openssl_x509_from_zval(zcerts, 0, &certresource TSRMLS_CC);
-
+
if (cert == NULL) {
goto clean_exit;
}
@@ -1926,7 +1938,7 @@ PHP_FUNCTION(openssl_pkcs12_export_to_file)
return;
RETVAL_FALSE;
-
+
cert = php_openssl_x509_from_zval(zcert, 0, &certresource TSRMLS_CC);
if (cert == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get cert from parameter 1");
@@ -1962,9 +1974,9 @@ PHP_FUNCTION(openssl_pkcs12_export_to_file)
p12 = PKCS12_create(pass, friendly_name, priv_key, cert, ca, 0, 0, 0, 0, 0);
- bio_out = BIO_new_file(filename, "w");
+ bio_out = BIO_new_file(filename, "w");
if (bio_out) {
-
+
i2d_PKCS12_bio(bio_out, p12);
RETVAL_TRUE;
@@ -1975,13 +1987,13 @@ PHP_FUNCTION(openssl_pkcs12_export_to_file)
BIO_free(bio_out);
PKCS12_free(p12);
php_sk_X509_free(ca);
-
+
cleanup:
if (keyresource == -1 && priv_key) {
EVP_PKEY_free(priv_key);
}
- if (certresource == -1 && cert) {
+ if (certresource == -1 && cert) {
X509_free(cert);
}
}
@@ -2007,7 +2019,7 @@ PHP_FUNCTION(openssl_pkcs12_export)
return;
RETVAL_FALSE;
-
+
cert = php_openssl_x509_from_zval(&zcert, 0, &certresource TSRMLS_CC);
if (cert == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get cert from parameter 1");
@@ -2030,7 +2042,7 @@ PHP_FUNCTION(openssl_pkcs12_export)
if (args && zend_hash_find(Z_ARRVAL_P(args), "extracerts", sizeof("extracerts"), (void**)&item) == SUCCESS)
ca = php_array_to_X509_sk(item TSRMLS_CC);
/* end parse extra config */
-
+
p12 = PKCS12_create(pass, friendly_name, priv_key, cert, ca, 0, 0, 0, 0, 0);
bio_out = BIO_new(BIO_s_mem());
@@ -2047,13 +2059,13 @@ PHP_FUNCTION(openssl_pkcs12_export)
BIO_free(bio_out);
PKCS12_free(p12);
php_sk_X509_free(ca);
-
+
cleanup:
if (keyresource == -1 && priv_key) {
EVP_PKEY_free(priv_key);
}
- if (certresource == -1 && cert) {
+ if (certresource == -1 && cert) {
X509_free(cert);
}
}
@@ -2077,12 +2089,12 @@ PHP_FUNCTION(openssl_pkcs12_read)
return;
RETVAL_FALSE;
-
+
bio_in = BIO_new(BIO_s_mem());
-
+
if(!BIO_write(bio_in, zp12, zp12_len))
goto cleanup;
-
+
if(d2i_PKCS12_bio(bio_in, &p12)) {
if(PKCS12_parse(p12, pass, &pkey, &cert, &ca)) {
BIO * bio_out;
@@ -2112,12 +2124,12 @@ PHP_FUNCTION(openssl_pkcs12_read)
MAKE_STD_ZVAL(zextracerts);
array_init(zextracerts);
-
+
for (i=0;;i++) {
zval * zextracert;
X509* aCA = sk_X509_pop(ca);
if (!aCA) break;
-
+
bio_out = BIO_new(BIO_s_mem());
if (PEM_write_bio_X509(bio_out, aCA)) {
BUF_MEM *bio_buf;
@@ -2125,7 +2137,7 @@ PHP_FUNCTION(openssl_pkcs12_read)
MAKE_STD_ZVAL(zextracert);
ZVAL_STRINGL(zextracert, bio_buf->data, bio_buf->length, 1);
add_index_zval(zextracerts, i, zextracert);
-
+
}
BIO_free(bio_out);
@@ -2137,13 +2149,13 @@ PHP_FUNCTION(openssl_pkcs12_read)
} else {
zval_dtor(zextracerts);
}
-
+
RETVAL_TRUE;
-
+
PKCS12_free(p12);
}
}
-
+
cleanup:
if (bio_in) {
BIO_free(bio_in);
@@ -2151,7 +2163,7 @@ PHP_FUNCTION(openssl_pkcs12_read)
if (pkey) {
EVP_PKEY_free(pkey);
}
- if (cert) {
+ if (cert) {
X509_free(cert);
}
}
@@ -2170,7 +2182,7 @@ static int php_openssl_make_REQ(struct php_x509_request * req, X509_REQ * csr, z
return FAILURE;
}
dn_sk = CONF_get_section(req->req_config, dn_sect);
- if (dn_sk == NULL) {
+ if (dn_sk == NULL) {
return FAILURE;
}
attr_sect = CONF_get_string(req->req_config, req->section_name, "attributes");
@@ -2190,15 +2202,15 @@ static int php_openssl_make_REQ(struct php_x509_request * req, X509_REQ * csr, z
X509_NAME * subj;
HashPosition hpos;
zval ** item;
-
+
subj = X509_REQ_get_subject_name(csr);
/* apply values from the dn hash */
zend_hash_internal_pointer_reset_ex(HASH_OF(dn), &hpos);
while(zend_hash_get_current_data_ex(HASH_OF(dn), (void**)&item, &hpos) == SUCCESS) {
- char * strindex = NULL;
+ char * strindex = NULL;
uint strindexlen = 0;
ulong intindex;
-
+
zend_hash_get_current_key_ex(HASH_OF(dn), &strindex, &strindexlen, &intindex, 0, &hpos);
convert_to_string_ex(item);
@@ -2208,7 +2220,7 @@ static int php_openssl_make_REQ(struct php_x509_request * req, X509_REQ * csr, z
nid = OBJ_txt2nid(strindex);
if (nid != NID_undef) {
- if (!X509_NAME_add_entry_by_NID(subj, nid, MBSTRING_UTF8,
+ if (!X509_NAME_add_entry_by_NID(subj, nid, MBSTRING_UTF8,
(unsigned char*)Z_STRVAL_PP(item), -1, -1, 0))
{
php_error_docref(NULL TSRMLS_CC, E_WARNING,
@@ -2229,10 +2241,10 @@ static int php_openssl_make_REQ(struct php_x509_request * req, X509_REQ * csr, z
for(i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) {
int len;
char buffer[200 + 1]; /*200 + \0 !*/
-
+
v = sk_CONF_VALUE_value(dn_sk, i);
type = v->name;
-
+
len = strlen(type);
if (len < sizeof("_default")) {
continue;
@@ -2247,7 +2259,7 @@ static int php_openssl_make_REQ(struct php_x509_request * req, X509_REQ * csr, z
memcpy(buffer, type, len);
buffer[len] = '\0';
type = buffer;
-
+
/* Skip past any leading X. X: X, etc to allow for multiple
* instances */
for (str = type; *str; str++) {
@@ -2328,7 +2340,7 @@ static X509_REQ * php_openssl_csr_from_zval(zval ** val, int makeresource, long
X509_REQ * csr = NULL;
char * filename = NULL;
BIO * in;
-
+
if (resourceval) {
*resourceval = -1;
}
@@ -2469,13 +2481,13 @@ PHP_FUNCTION(openssl_csr_sign)
long csr_resource, certresource = 0, keyresource = -1;
int i;
struct php_x509_request req;
-
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ!Zl|a!l", &zcsr, &zcert, &zpkey, &num_days, &args, &serial) == FAILURE)
return;
RETVAL_FALSE;
PHP_SSL_REQ_INIT(&req);
-
+
csr = php_openssl_csr_from_zval(zcsr, 0, &csr_resource TSRMLS_CC);
if (csr == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get CSR from parameter 1");
@@ -2497,7 +2509,7 @@ PHP_FUNCTION(openssl_csr_sign)
php_error_docref(NULL TSRMLS_CC, E_WARNING, "private key does not correspond to signing cert");
goto cleanup;
}
-
+
if (PHP_SSL_REQ_PARSE(&req, args) == FAILURE) {
goto cleanup;
}
@@ -2517,9 +2529,9 @@ PHP_FUNCTION(openssl_csr_sign)
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Signature did not match the certificate request");
goto cleanup;
}
-
+
/* Now we can get on with it */
-
+
new_cert = X509_new();
if (new_cert == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "No memory");
@@ -2530,7 +2542,7 @@ PHP_FUNCTION(openssl_csr_sign)
goto cleanup;
ASN1_INTEGER_set(X509_get_serialNumber(new_cert), serial);
-
+
X509_set_subject_name(new_cert, X509_REQ_get_subject_name(csr));
if (cert == NULL) {
@@ -2547,7 +2559,7 @@ PHP_FUNCTION(openssl_csr_sign)
}
if (req.extensions_section) {
X509V3_CTX ctx;
-
+
X509V3_set_ctx(&ctx, cert, new_cert, csr, NULL, 0);
X509V3_set_conf_lhash(&ctx, req.req_config);
if (!X509V3_EXT_add_conf(req.req_config, &ctx, req.extensions_section, new_cert)) {
@@ -2560,11 +2572,11 @@ PHP_FUNCTION(openssl_csr_sign)
php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to sign it");
goto cleanup;
}
-
+
/* Succeeded; lets return the cert */
RETVAL_RESOURCE(zend_list_insert(new_cert, le_x509 TSRMLS_CC));
new_cert = NULL;
-
+
cleanup:
if (cert == new_cert) {
@@ -2581,7 +2593,7 @@ cleanup:
if (csr_resource == -1 && csr) {
X509_REQ_free(csr);
}
- if (certresource == -1 && cert) {
+ if (certresource == -1 && cert) {
X509_free(cert);
}
if (new_cert) {
@@ -2600,12 +2612,12 @@ PHP_FUNCTION(openssl_csr_new)
X509_REQ * csr = NULL;
int we_made_the_key = 1;
long key_resource;
-
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "az|a!a!", &dn, &out_pkey, &args, &attribs) == FAILURE) {
return;
}
RETVAL_FALSE;
-
+
PHP_SSL_REQ_INIT(&req);
if (PHP_SSL_REQ_PARSE(&req, args) == SUCCESS) {
@@ -2637,10 +2649,10 @@ PHP_FUNCTION(openssl_csr_new)
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error loading extension section %s", req.request_extensions_section);
} else {
RETVAL_TRUE;
-
+
if (X509_REQ_sign(csr, req.priv_key, req.digest)) {
RETVAL_RESOURCE(zend_list_insert(csr, le_csr TSRMLS_CC));
- csr = NULL;
+ csr = NULL;
} else {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error signing request");
}
@@ -2765,14 +2777,14 @@ static EVP_PKEY * php_openssl_evp_from_zval(zval ** val, int public_key, char *
}
if (Z_TYPE_PP(val) == IS_ARRAY) {
zval ** zphrase;
-
+
/* get passphrase */
if (zend_hash_index_find(HASH_OF(*val), 1, (void **)&zphrase) == FAILURE) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "key array must be of the form array(0 => key, 1 => phrase)");
return NULL;
}
-
+
if (Z_TYPE_PP(zphrase) == IS_STRING) {
passphrase = Z_STRVAL_PP(zphrase);
} else {
@@ -2797,7 +2809,7 @@ static EVP_PKEY * php_openssl_evp_from_zval(zval ** val, int public_key, char *
if (!what) {
TMP_CLEAN;
}
- if (resourceval) {
+ if (resourceval) {
*resourceval = Z_LVAL_PP(val);
}
if (type == le_x509) {
@@ -2831,8 +2843,8 @@ static EVP_PKEY * php_openssl_evp_from_zval(zval ** val, int public_key, char *
}
} else {
/* force it to be a string and check if it refers to a file */
- /* passing non string values leaks, object uses toString, it returns NULL
- * See bug38255.phpt
+ /* passing non string values leaks, object uses toString, it returns NULL
+ * See bug38255.phpt
*/
if (!(Z_TYPE_PP(val) == IS_STRING || Z_TYPE_PP(val) == IS_OBJECT)) {
TMP_CLEAN;
@@ -2906,7 +2918,7 @@ static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req
char * randfile = NULL;
int egdsocket, seeded;
EVP_PKEY * return_val = NULL;
-
+
if (req->priv_key_bits < MIN_KEY_LENGTH) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "private key length is too short; it needs to be at least %d bits, not %d",
MIN_KEY_LENGTH, req->priv_key_bits);
@@ -2915,7 +2927,7 @@ static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req
randfile = CONF_get_string(req->req_config, req->section_name, "RANDFILE");
php_openssl_load_rand_file(randfile, &egdsocket, &seeded TSRMLS_CC);
-
+
if ((req->priv_key = EVP_PKEY_new()) != NULL) {
switch(req->priv_key_type) {
case OPENSSL_KEYTYPE_RSA:
@@ -2965,13 +2977,13 @@ static EVP_PKEY * php_openssl_generate_private_key(struct php_x509_request * req
}
php_openssl_write_rand_file(randfile, egdsocket, seeded);
-
+
if (return_val == NULL) {
EVP_PKEY_free(req->priv_key);
req->priv_key = NULL;
return NULL;
}
-
+
return return_val;
}
/* }}} */
@@ -3000,7 +3012,7 @@ static int php_openssl_is_private_key(EVP_PKEY* pkey TSRMLS_DC)
case EVP_PKEY_DSA4:
assert(pkey->pkey.dsa != NULL);
- if (NULL == pkey->pkey.dsa->p || NULL == pkey->pkey.dsa->q || NULL == pkey->pkey.dsa->priv_key){
+ if (NULL == pkey->pkey.dsa->p || NULL == pkey->pkey.dsa->q || NULL == pkey->pkey.dsa->priv_key){
return 0;
}
break;
@@ -3131,7 +3143,7 @@ PHP_FUNCTION(openssl_pkey_new)
}
RETURN_FALSE;
}
- }
+ }
PHP_SSL_REQ_INIT(&req);
@@ -3160,7 +3172,7 @@ PHP_FUNCTION(openssl_pkey_export_to_file)
EVP_PKEY * key;
BIO * bio_out = NULL;
const EVP_CIPHER * cipher;
-
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zp|s!a!", &zpkey, &filename, &filename_len, &passphrase, &passphrase_len, &args) == FAILURE) {
return;
}
@@ -3172,11 +3184,11 @@ PHP_FUNCTION(openssl_pkey_export_to_file)
php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get key from parameter 1");
RETURN_FALSE;
}
-
+
if (php_openssl_open_base_dir_chk(filename TSRMLS_CC)) {
RETURN_FALSE;
}
-
+
PHP_SSL_REQ_INIT(&req);
if (PHP_SSL_REQ_PARSE(&req, args) == SUCCESS) {
@@ -3219,7 +3231,7 @@ PHP_FUNCTION(openssl_pkey_export)
EVP_PKEY * key;
BIO * bio_out = NULL;
const EVP_CIPHER * cipher;
-
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zz|s!a!", &zpkey, &out, &passphrase, &passphrase_len, &args) == FAILURE) {
return;
}
@@ -3231,7 +3243,7 @@ PHP_FUNCTION(openssl_pkey_export)
php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get key from parameter 1");
RETURN_FALSE;
}
-
+
PHP_SSL_REQ_INIT(&req);
if (PHP_SSL_REQ_PARSE(&req, args) == SUCCESS) {
@@ -3353,7 +3365,7 @@ PHP_FUNCTION(openssl_pkey_get_details)
array_init(return_value);
add_assoc_long(return_value, "bits", EVP_PKEY_bits(pkey));
add_assoc_stringl(return_value, "key", pbio, pbio_len, 1);
- /*TODO: Use the real values once the openssl constants are used
+ /*TODO: Use the real values once the openssl constants are used
* See the enum at the top of this file
*/
switch (EVP_PKEY_type(pkey->type)) {
@@ -3377,7 +3389,7 @@ PHP_FUNCTION(openssl_pkey_get_details)
add_assoc_zval(return_value, "rsa", rsa);
}
- break;
+ break;
case EVP_PKEY_DSA:
case EVP_PKEY_DSA2:
case EVP_PKEY_DSA3:
@@ -3398,7 +3410,7 @@ PHP_FUNCTION(openssl_pkey_get_details)
}
break;
case EVP_PKEY_DH:
-
+
ktype = OPENSSL_KEYTYPE_DH;
if (pkey->pkey.dh != NULL) {
@@ -3414,7 +3426,7 @@ PHP_FUNCTION(openssl_pkey_get_details)
}
break;
-#ifdef EVP_PKEY_EC
+#ifdef EVP_PKEY_EC
case EVP_PKEY_EC:
ktype = OPENSSL_KEYTYPE_EC;
break;
@@ -3431,6 +3443,57 @@ PHP_FUNCTION(openssl_pkey_get_details)
/* }}} */
+#if OPENSSL_VERSION_NUMBER >= 0x10000000L
+
+/* {{{ proto string openssl_pbkdf2(string password, string salt, long key_length, long iterations [, string digest_method = "sha1"])
+ Generates a PKCS5 v2 PBKDF2 string, defaults to sha1 */
+PHP_FUNCTION(openssl_pbkdf2)
+{
+ long key_length = 0, iterations = 0;
+ char *password; int password_len;
+ char *salt; int salt_len;
+ char *method; int method_len = 0;
+ unsigned char *out_buffer;
+
+ const EVP_MD *digest;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssll|s",
+ &password, &password_len,
+ &salt, &salt_len,
+ &key_length, &iterations,
+ &method, &method_len) == FAILURE) {
+ return;
+ }
+
+ if (key_length <= 0) {
+ RETURN_FALSE;
+ }
+
+ if (method_len) {
+ digest = EVP_get_digestbyname(method);
+ } else {
+ digest = EVP_sha1();
+ }
+
+ if (!digest) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown signature algorithm");
+ RETURN_FALSE;
+ }
+
+ out_buffer = emalloc(key_length + 1);
+ out_buffer[key_length] = '\0';
+
+ if (PKCS5_PBKDF2_HMAC(password, password_len, (unsigned char *)salt, salt_len, iterations, digest, key_length, out_buffer) == 1) {
+ RETVAL_STRINGL((char *)out_buffer, key_length, 0);
+ } else {
+ efree(out_buffer);
+ RETURN_FALSE;
+ }
+}
+/* }}} */
+
+#endif
+
/* {{{ PKCS7 S/MIME functions */
/* {{{ proto bool openssl_pkcs7_verify(string filename, long flags [, string signerscerts [, array cainfo [, string extracerts [, string content]]]])
@@ -3448,7 +3511,7 @@ PHP_FUNCTION(openssl_pkcs7_verify)
char * extracerts = NULL; int extracerts_len = 0;
char * signersfilename = NULL; int signersfilename_len = 0;
char * datafilename = NULL; int datafilename_len = 0;
-
+
RETVAL_LONG(-1);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "pl|papp", &filename, &filename_len,
@@ -3456,7 +3519,7 @@ PHP_FUNCTION(openssl_pkcs7_verify)
&extracerts, &extracerts_len, &datafilename, &datafilename_len) == FAILURE) {
return;
}
-
+
if (extracerts) {
others = load_all_certs_from_file(extracerts);
if (others == NULL) {
@@ -3508,11 +3571,11 @@ PHP_FUNCTION(openssl_pkcs7_verify)
if (signersfilename) {
BIO *certout;
-
+
if (php_openssl_open_base_dir_chk(signersfilename TSRMLS_CC)) {
goto clean_exit;
}
-
+
certout = BIO_new_file(signersfilename, "w");
if (certout) {
int i;
@@ -3561,14 +3624,14 @@ PHP_FUNCTION(openssl_pkcs7_encrypt)
char * strindex;
char * infilename = NULL; int infilename_len;
char * outfilename = NULL; int outfilename_len;
-
+
RETVAL_FALSE;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ppZa!|ll", &infilename, &infilename_len,
&outfilename, &outfilename_len, &zrecipcerts, &zheaders, &flags, &cipherid) == FAILURE)
return;
-
+
if (php_openssl_open_base_dir_chk(infilename TSRMLS_CC) || php_openssl_open_base_dir_chk(outfilename TSRMLS_CC)) {
return;
}
@@ -3579,7 +3642,7 @@ PHP_FUNCTION(openssl_pkcs7_encrypt)
}
outfile = BIO_new_file(outfilename, "w");
- if (outfile == NULL) {
+ if (outfile == NULL) {
goto clean_exit;
}
@@ -3706,12 +3769,12 @@ PHP_FUNCTION(openssl_pkcs7_sign)
&extracertsfilename_len) == FAILURE) {
return;
}
-
+
RETVAL_FALSE;
if (extracertsfilename) {
others = load_all_certs_from_file(extracertsfilename);
- if (others == NULL) {
+ if (others == NULL) {
goto clean_exit;
}
}
@@ -3822,7 +3885,7 @@ PHP_FUNCTION(openssl_pkcs7_decrypt)
php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to get private key");
goto clean_exit;
}
-
+
if (php_openssl_open_base_dir_chk(infilename TSRMLS_CC) || php_openssl_open_base_dir_chk(outfilename TSRMLS_CC)) {
goto clean_exit;
}
@@ -3841,7 +3904,7 @@ PHP_FUNCTION(openssl_pkcs7_decrypt)
if (p7 == NULL) {
goto clean_exit;
}
- if (PKCS7_decrypt(p7, key, cert, out, PKCS7_DETACHED)) {
+ if (PKCS7_decrypt(p7, key, cert, out, PKCS7_DETACHED)) {
RETVAL_TRUE;
}
clean_exit:
@@ -3874,7 +3937,7 @@ PHP_FUNCTION(openssl_private_encrypt)
int data_len;
long padding = RSA_PKCS1_PADDING;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szZ|l", &data, &data_len, &crypted, &key, &padding) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szZ|l", &data, &data_len, &crypted, &key, &padding) == FAILURE) {
return;
}
RETVAL_FALSE;
@@ -3892,10 +3955,10 @@ PHP_FUNCTION(openssl_private_encrypt)
switch (pkey->type) {
case EVP_PKEY_RSA:
case EVP_PKEY_RSA2:
- successful = (RSA_private_encrypt(data_len,
- (unsigned char *)data,
- cryptedbuf,
- pkey->pkey.rsa,
+ successful = (RSA_private_encrypt(data_len,
+ (unsigned char *)data,
+ cryptedbuf,
+ pkey->pkey.rsa,
padding) == cryptedlen);
break;
default:
@@ -3912,7 +3975,7 @@ PHP_FUNCTION(openssl_private_encrypt)
if (cryptedbuf) {
efree(cryptedbuf);
}
- if (keyresource == -1) {
+ if (keyresource == -1) {
EVP_PKEY_free(pkey);
}
}
@@ -3950,10 +4013,10 @@ PHP_FUNCTION(openssl_private_decrypt)
switch (pkey->type) {
case EVP_PKEY_RSA:
case EVP_PKEY_RSA2:
- cryptedlen = RSA_private_decrypt(data_len,
- (unsigned char *)data,
- crypttemp,
- pkey->pkey.rsa,
+ cryptedlen = RSA_private_decrypt(data_len,
+ (unsigned char *)data,
+ crypttemp,
+ pkey->pkey.rsa,
padding);
if (cryptedlen != -1) {
cryptedbuf = emalloc(cryptedlen + 1);
@@ -3978,7 +4041,7 @@ PHP_FUNCTION(openssl_private_decrypt)
if (keyresource == -1) {
EVP_PKEY_free(pkey);
}
- if (cryptedbuf) {
+ if (cryptedbuf) {
efree(cryptedbuf);
}
}
@@ -4002,7 +4065,7 @@ PHP_FUNCTION(openssl_public_encrypt)
return;
RETVAL_FALSE;
-
+
pkey = php_openssl_evp_from_zval(key, 1, NULL, 0, &keyresource TSRMLS_CC);
if (pkey == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "key parameter is not a valid public key");
@@ -4015,10 +4078,10 @@ PHP_FUNCTION(openssl_public_encrypt)
switch (pkey->type) {
case EVP_PKEY_RSA:
case EVP_PKEY_RSA2:
- successful = (RSA_public_encrypt(data_len,
- (unsigned char *)data,
- cryptedbuf,
- pkey->pkey.rsa,
+ successful = (RSA_public_encrypt(data_len,
+ (unsigned char *)data,
+ cryptedbuf,
+ pkey->pkey.rsa,
padding) == cryptedlen);
break;
default:
@@ -4061,7 +4124,7 @@ PHP_FUNCTION(openssl_public_decrypt)
return;
}
RETVAL_FALSE;
-
+
pkey = php_openssl_evp_from_zval(key, 1, NULL, 0, &keyresource TSRMLS_CC);
if (pkey == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "key parameter is not a valid public key");
@@ -4074,10 +4137,10 @@ PHP_FUNCTION(openssl_public_decrypt)
switch (pkey->type) {
case EVP_PKEY_RSA:
case EVP_PKEY_RSA2:
- cryptedlen = RSA_public_decrypt(data_len,
- (unsigned char *)data,
- crypttemp,
- pkey->pkey.rsa,
+ cryptedlen = RSA_public_decrypt(data_len,
+ (unsigned char *)data,
+ crypttemp,
+ pkey->pkey.rsa,
padding);
if (cryptedlen != -1) {
cryptedbuf = emalloc(cryptedlen + 1);
@@ -4085,10 +4148,10 @@ PHP_FUNCTION(openssl_public_decrypt)
successful = 1;
}
break;
-
+
default:
php_error_docref(NULL TSRMLS_CC, E_WARNING, "key type not supported in this PHP build!");
-
+
}
efree(crypttemp);
@@ -4206,7 +4269,7 @@ PHP_FUNCTION(openssl_verify)
char * signature; int signature_len;
zval *method = NULL;
long signature_algo = OPENSSL_ALGO_SHA1;
-
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ssZ|z", &data, &data_len, &signature, &signature_len, &key, &method) == FAILURE) {
return;
}
@@ -4265,7 +4328,7 @@ PHP_FUNCTION(openssl_seal)
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "szza/|s", &data, &data_len, &sealdata, &ekeys, &pubkeys, &method, &method_len) == FAILURE) {
return;
}
-
+
pubkeysht = HASH_OF(pubkeys);
nkeys = pubkeysht ? zend_hash_num_elements(pubkeysht) : 0;
if (!nkeys) {
@@ -4360,7 +4423,7 @@ clean_exit:
if (key_resources[i] == -1) {
EVP_PKEY_free(pkeys[i]);
}
- if (eks[i]) {
+ if (eks[i]) {
efree(eks[i]);
}
}
@@ -4406,13 +4469,13 @@ PHP_FUNCTION(openssl_open)
} else {
cipher = EVP_rc4();
}
-
+
buf = emalloc(data_len + 1);
if (EVP_OpenInit(&ctx, cipher, (unsigned char *)ekey, ekey_len, NULL, pkey) && EVP_OpenUpdate(&ctx, buf, &len1, (unsigned char *)data, data_len)) {
if (!EVP_OpenFinal(&ctx, buf + len1, &len2) || (len1 + len2 == 0)) {
efree(buf);
- if (keyresource == -1) {
+ if (keyresource == -1) {
EVP_PKEY_free(pkey);
}
RETURN_FALSE;
@@ -4646,7 +4709,7 @@ SSL *php_SSL_new_from_context(SSL_CTX *ctx, php_stream *stream TSRMLS_DC) /* {{{
if (SSL_CTX_use_PrivateKey_file(ctx, resolved_path_buff, SSL_FILETYPE_PEM) != 1) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to set private key file `%s'", resolved_path_buff);
return NULL;
- }
+ }
}
#if OPENSSL_VERSION_NUMBER < 0x10001001L
@@ -4709,7 +4772,7 @@ PHP_FUNCTION(openssl_get_md_methods)
}
array_init(return_value);
OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH,
- aliases ? openssl_add_method_or_alias: openssl_add_method,
+ aliases ? openssl_add_method_or_alias: openssl_add_method,
return_value);
}
/* }}} */
@@ -4725,7 +4788,7 @@ PHP_FUNCTION(openssl_get_cipher_methods)
}
array_init(return_value);
OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH,
- aliases ? openssl_add_method_or_alias: openssl_add_method,
+ aliases ? openssl_add_method_or_alias: openssl_add_method,
return_value);
}
/* }}} */
@@ -5064,7 +5127,7 @@ PHP_FUNCTION(openssl_random_pseudo_bytes)
#ifdef PHP_WIN32
strong_result = 1;
/* random/urandom equivalent on Windows */
- if (php_win32_get_random_bytes(buffer, (size_t) buffer_length) == FAILURE) {
+ if (php_win32_get_random_bytes(buffer, (size_t) buffer_length) == FAILURE){
efree(buffer);
if (zstrong_result_returned) {
ZVAL_BOOL(zstrong_result_returned, 0);
diff --git a/ext/openssl/php_openssl.h b/ext/openssl/php_openssl.h
index 6b76106f32..e4cb7e890e 100644
--- a/ext/openssl/php_openssl.h
+++ b/ext/openssl/php_openssl.h
@@ -52,6 +52,8 @@ PHP_FUNCTION(openssl_private_decrypt);
PHP_FUNCTION(openssl_public_encrypt);
PHP_FUNCTION(openssl_public_decrypt);
+PHP_FUNCTION(openssl_pbkdf2);
+
PHP_FUNCTION(openssl_pkcs7_verify);
PHP_FUNCTION(openssl_pkcs7_decrypt);
PHP_FUNCTION(openssl_pkcs7_sign);
diff --git a/ext/openssl/tests/openssl_pbkdf2.phpt b/ext/openssl/tests/openssl_pbkdf2.phpt
new file mode 100644
index 0000000000..3ec4dce236
--- /dev/null
+++ b/ext/openssl/tests/openssl_pbkdf2.phpt
@@ -0,0 +1,26 @@
+--TEST--
+openssl_pbkdf2() tests
+--SKIPIF--
+<?php if (!extension_loaded("openssl") || !function_exists("openssl_pbkdf2")) print "skip"; ?>
+--FILE--
+<?php
+// official test vectors
+var_dump(bin2hex(openssl_pbkdf2('password', 'salt', 20, 1)));
+var_dump(bin2hex(openssl_pbkdf2('password', 'salt', 20, 2)));
+var_dump(bin2hex(openssl_pbkdf2('password', 'salt', 20, 4096)));
+
+/* really slow but should be:
+string(40) "eefe3d61cd4da4e4e9945b3d6ba2158c2634e984"
+var_dump(bin2hex(openssl_pbkdf2('password', 'salt', 20, 16777216)));
+*/
+
+var_dump(bin2hex(openssl_pbkdf2('passwordPASSWORDpassword', 'saltSALTsaltSALTsaltSALTsaltSALTsalt', 25, 4096)));
+var_dump(bin2hex(openssl_pbkdf2("pass\0word", "sa\0lt", 16, 4096)));
+
+?>
+--EXPECTF--
+string(40) "0c60c80f961f0e71f3a9b524af6012062fe037a6"
+string(40) "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957"
+string(40) "4b007901b765489abead49d926f721d065a429c1"
+string(50) "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038"
+string(32) "56fa6aa75548099dcc37d7f03425e0c3"
diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c
index 3082c839d9..6f41c217d6 100644
--- a/ext/openssl/xp_ssl.c
+++ b/ext/openssl/xp_ssl.c
@@ -422,8 +422,8 @@ static inline int php_openssl_setup_crypto(php_stream *stream,
if (cparam->inputs.session) {
if (cparam->inputs.session->ops != &php_openssl_socket_ops) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "supplied session stream must be an SSL enabled stream");
- } else if (((php_openssl_netstream_data_t*)cparam->inputs.session->abstract)->ssl_handle == NULL) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "supplied SSL session stream is not initialized");
+ } else if (((php_openssl_netstream_data_t*)cparam->inputs.session->abstract)->ssl_handle == NULL) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "supplied SSL session stream is not initialized");
} else {
SSL_copy_session_id(sslsock->ssl_handle, ((php_openssl_netstream_data_t*)cparam->inputs.session->abstract)->ssl_handle);
}
@@ -825,7 +825,7 @@ static int php_openssl_sockop_cast(php_stream *stream, int castas, void **ret TS
case PHP_STREAM_AS_FD_FOR_SELECT:
if (ret) {
- *(int *)ret = sslsock->s.socket;
+ *(php_socket_t *)ret = sslsock->s.socket;
}
return SUCCESS;
@@ -835,7 +835,7 @@ static int php_openssl_sockop_cast(php_stream *stream, int castas, void **ret TS
return FAILURE;
}
if (ret) {
- *(int *)ret = sslsock->s.socket;
+ *(php_socket_t *)ret = sslsock->s.socket;
}
return SUCCESS;
default:
diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c
index 7a8acafb5e..b7ef4c729c 100644
--- a/ext/pcntl/pcntl.c
+++ b/ext/pcntl/pcntl.c
@@ -795,7 +795,7 @@ PHP_FUNCTION(pcntl_exec)
snprintf(key, 100, "%ld", key_num);
key_length = strlen(key);
break;
- case HASH_KEY_NON_EXISTANT:
+ case HASH_KEY_NON_EXISTENT:
pair--;
continue;
}
@@ -868,7 +868,7 @@ PHP_FUNCTION(pcntl_signal)
}
/* Special long value case for SIG_DFL and SIG_IGN */
- if (Z_TYPE_P(handle)==IS_LONG) {
+ if (Z_TYPE_P(handle) == IS_LONG) {
if (Z_LVAL_P(handle) != (long) SIG_DFL && Z_LVAL_P(handle) != (long) SIG_IGN) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid value for handle argument specified");
RETURN_FALSE;
diff --git a/ext/pcntl/php_signal.c b/ext/pcntl/php_signal.c
index 003b0dd462..9f308d793c 100644
--- a/ext/pcntl/php_signal.c
+++ b/ext/pcntl/php_signal.c
@@ -32,7 +32,6 @@ Sigfunc *php_signal4(int signo, Sigfunc *func, int restart, int mask_all)
TSRMLS_FETCH();
#endif
act.sa_handler = func;
-
if (mask_all) {
sigfillset(&act.sa_mask);
} else {
@@ -56,7 +55,7 @@ Sigfunc *php_signal4(int signo, Sigfunc *func, int restart, int mask_all)
{
return SIG_ERR;
}
-
+
return oact.sa_handler;
}
diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c
index bd93f723d6..196ada0266 100644
--- a/ext/pcre/php_pcre.c
+++ b/ext/pcre/php_pcre.c
@@ -1052,6 +1052,10 @@ PHPAPI char *php_pcre_replace_impl(pcre_cache_entry *pce, char *subject, int sub
replace_end = replace + replace_len;
}
+ if (eval) {
+ php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "The /e modifier is deprecated, use preg_replace_callback instead");
+ }
+
/* Calculate the size of the offsets array, and allocate memory for it. */
rc = pcre_fullinfo(pce->re, extra, PCRE_INFO_CAPTURECOUNT, &num_subpats);
if (rc < 0) {
diff --git a/ext/pcre/tests/002.phpt b/ext/pcre/tests/002.phpt
index 00f68f3651..fd245633d3 100644
--- a/ext/pcre/tests/002.phpt
+++ b/ext/pcre/tests/002.phpt
@@ -34,6 +34,8 @@ string(12) "a${1b${1c${1"
Warning: preg_replace(): Compilation failed: missing terminating ] for character class at offset 8 in %s002.php on line 11
NULL
+Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in %s on line 12
+
Parse error: %s in %s002.php(12) : regexp code on line 1
Fatal error: preg_replace(): Failed evaluating code:
diff --git a/ext/pcre/tests/004.phpt b/ext/pcre/tests/004.phpt
index b1e9586626..1fae406b16 100644
--- a/ext/pcre/tests/004.phpt
+++ b/ext/pcre/tests/004.phpt
@@ -16,7 +16,7 @@ var_dump(preg_replace(array('@//.*@S', '@/\*.*\*/@SsUe'), array('', 'preg_replac
var_dump(preg_split('/PHP_(?:NAMED_)?(?:FUNCTION|METHOD)\s*\((\w+(?:,\s*\w+)?)\)/S', "PHP_FUNCTION(s, preg_match)\n{\nlalala", -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_OFFSET_CAPTURE));
?>
---EXPECT--
+--EXPECTF--
int(2)
array(2) {
[0]=>
@@ -117,6 +117,8 @@ array(1) {
}
}
}
+
+Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in %s on line %d
string(9) "hello
diff --git a/ext/pdo/Makefile.frag b/ext/pdo/Makefile.frag
index 98f5c5f2ad..5ba5f80840 100644
--- a/ext/pdo/Makefile.frag
+++ b/ext/pdo/Makefile.frag
@@ -6,7 +6,7 @@ PDO_HEADER_FILES= \
$(srcdir)/pdo_sql_parser.c: $(srcdir)/pdo_sql_parser.re
- (cd $(top_srcdir); $(RE2C) -o ext/pdo/pdo_sql_parser.c ext/pdo/pdo_sql_parser.re)
+ (cd $(top_srcdir); $(RE2C) --no-generation-date -o ext/pdo/pdo_sql_parser.c ext/pdo/pdo_sql_parser.re)
install-pdo-headers:
@echo "Installing PDO headers: $(INSTALL_ROOT)$(phpincludedir)/ext/pdo/"
diff --git a/ext/pdo/pdo_sql_parser.c b/ext/pdo/pdo_sql_parser.c
index f4392ab53d..341e664bbe 100644
--- a/ext/pdo/pdo_sql_parser.c
+++ b/ext/pdo/pdo_sql_parser.c
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.13.5 on Thu Nov 7 18:02:29 2013 */
+/* Generated by re2c 0.13.5 */
#line 1 "ext/pdo/pdo_sql_parser.re"
/*
+----------------------------------------------------------------------+
diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c
index 238f547503..2735aede41 100644
--- a/ext/pdo/pdo_stmt.c
+++ b/ext/pdo/pdo_stmt.c
@@ -2499,16 +2499,15 @@ static void pdo_stmt_iter_get_data(zend_object_iterator *iter, zval ***data TSRM
*data = &I->fetch_ahead;
}
-static int pdo_stmt_iter_get_key(zend_object_iterator *iter, char **str_key, uint *str_key_len,
- ulong *int_key TSRMLS_DC)
+static void pdo_stmt_iter_get_key(zend_object_iterator *iter, zval *key TSRMLS_DC)
{
struct php_pdo_iterator *I = (struct php_pdo_iterator*)iter->data;
if (I->key == (ulong)-1) {
- return HASH_KEY_NON_EXISTANT;
+ ZVAL_NULL(key);
+ } else {
+ ZVAL_LONG(key, I->key);
}
- *int_key = I->key;
- return HASH_KEY_IS_LONG;
}
static void pdo_stmt_iter_move_forwards(zend_object_iterator *iter TSRMLS_DC)
@@ -2733,6 +2732,7 @@ static union _zend_function *row_get_ctor(zval *object TSRMLS_DC)
ctor.function_name = "__construct";
ctor.scope = pdo_row_ce;
ctor.handler = ZEND_FN(dbstmt_constructor);
+ ctor.fn_flags = ZEND_ACC_PUBLIC;
return (union _zend_function*)&ctor;
}
diff --git a/ext/pdo/php_pdo_int.h b/ext/pdo/php_pdo_int.h
index 4ec97ac4d1..2740fc8e63 100644
--- a/ext/pdo/php_pdo_int.h
+++ b/ext/pdo/php_pdo_int.h
@@ -58,7 +58,7 @@ extern pdo_driver_t *pdo_find_driver(const char *name, int namelen);
extern void pdo_handle_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt TSRMLS_DC);
#define PDO_DBH_CLEAR_ERR() do { \
- strncpy(dbh->error_code, PDO_ERR_NONE, sizeof(PDO_ERR_NONE)); \
+ strlcpy(dbh->error_code, PDO_ERR_NONE, sizeof(PDO_ERR_NONE)); \
if (dbh->query_stmt) { \
dbh->query_stmt = NULL; \
zend_objects_store_del_ref(&dbh->query_stmt_zval TSRMLS_CC); \
diff --git a/ext/pdo/tests/pdo_036.phpt b/ext/pdo/tests/pdo_036.phpt
index 94006c9e80..55c88762ba 100644
--- a/ext/pdo/tests/pdo_036.phpt
+++ b/ext/pdo/tests/pdo_036.phpt
@@ -5,19 +5,19 @@ Testing PDORow and PDOStatement instances with Reflection
--FILE--
<?php
-$instance = new reflectionclass('pdorow');
+$instance = new reflectionclass('pdostatement');
$x = $instance->newInstance();
var_dump($x);
-$instance = new reflectionclass('pdostatement');
+$instance = new reflectionclass('pdorow');
$x = $instance->newInstance();
var_dump($x);
?>
--EXPECTF--
-object(PDORow)#%d (0) {
-}
object(PDOStatement)#%d (1) {
[%u|b%"queryString"]=>
NULL
}
+
+Fatal error: PDORow::__construct(): You should not create a PDOStatement manually in %spdo_036.php on line %d
diff --git a/ext/pdo_firebird/config.m4 b/ext/pdo_firebird/config.m4
index 7b6f669a50..a89ab2aea5 100644
--- a/ext/pdo_firebird/config.m4
+++ b/ext/pdo_firebird/config.m4
@@ -4,7 +4,7 @@ dnl
PHP_ARG_WITH(pdo-firebird,for Firebird support for PDO,
[ --with-pdo-firebird[=DIR] PDO: Firebird support. DIR is the Firebird base
- install directory [/opt/firebird]])
+ install directory [/opt/firebird]])
if test "$PHP_PDO_FIREBIRD" != "no"; then
diff --git a/ext/pdo_mysql/config.m4 b/ext/pdo_mysql/config.m4
index a2ba2fdbdd..f237f413be 100755
--- a/ext/pdo_mysql/config.m4
+++ b/ext/pdo_mysql/config.m4
@@ -4,12 +4,12 @@ dnl vim: se ts=2 sw=2 et:
PHP_ARG_WITH(pdo-mysql, for MySQL support for PDO,
[ --with-pdo-mysql[=DIR] PDO: MySQL support. DIR is the MySQL base directory
- If no value or mysqlnd is passed as DIR, the
- MySQL native driver will be used])
+ If no value or mysqlnd is passed as DIR, the
+ MySQL native driver will be used])
if test -z "$PHP_ZLIB_DIR"; then
PHP_ARG_WITH(zlib-dir, for the location of libz,
- [ --with-zlib-dir[=DIR] PDO_MySQL: Set the path to libz install prefix], no, no)
+ [ --with-zlib-dir[=DIR] PDO_MySQL: Set the path to libz install prefix], no, no)
fi
if test "$PHP_PDO_MYSQL" != "no"; then
diff --git a/ext/pdo_mysql/mysql_driver.c b/ext/pdo_mysql/mysql_driver.c
index 47a1be31c3..825fe2647f 100644
--- a/ext/pdo_mysql/mysql_driver.c
+++ b/ext/pdo_mysql/mysql_driver.c
@@ -709,6 +709,20 @@ static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_
efree(ssl_cipher);
}
}
+
+#if MYSQL_VERSION_ID > 50605 || defined(PDO_USE_MYSQLND)
+ {
+ char *public_key = pdo_attr_strval(driver_options, PDO_MYSQL_ATTR_SERVER_PUBLIC_KEY, NULL TSRMLS_CC);
+ if (public_key) {
+ if (mysql_options(H->server, MYSQL_SERVER_PUBLIC_KEY, public_key)) {
+ pdo_mysql_error(dbh);
+ efree(public_key);
+ goto cleanup;
+ }
+ efree(public_key);
+ }
+ }
+#endif
}
#ifdef PDO_MYSQL_HAS_CHARSET
diff --git a/ext/pdo_mysql/pdo_mysql.c b/ext/pdo_mysql/pdo_mysql.c
index 95f2840fcb..8ab1c344cc 100644
--- a/ext/pdo_mysql/pdo_mysql.c
+++ b/ext/pdo_mysql/pdo_mysql.c
@@ -118,6 +118,10 @@ static PHP_MINIT_FUNCTION(pdo_mysql)
REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_SSL_CA", (long)PDO_MYSQL_ATTR_SSL_CA);
REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_SSL_CAPATH", (long)PDO_MYSQL_ATTR_SSL_CAPATH);
REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_SSL_CIPHER", (long)PDO_MYSQL_ATTR_SSL_CIPHER);
+#if MYSQL_VERSION_ID > 50605 || defined(PDO_USE_MYSQLND)
+ REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_SERVER_PUBLIC_KEY", (long)PDO_MYSQL_ATTR_SERVER_PUBLIC_KEY);
+#endif
+
#ifdef PDO_USE_MYSQLND
mysqlnd_reverse_api_register_api(&pdo_mysql_reverse_api TSRMLS_CC);
diff --git a/ext/pdo_mysql/php_pdo_mysql_int.h b/ext/pdo_mysql/php_pdo_mysql_int.h
index 7533467cab..26263222b9 100644
--- a/ext/pdo_mysql/php_pdo_mysql_int.h
+++ b/ext/pdo_mysql/php_pdo_mysql_int.h
@@ -170,7 +170,10 @@ enum {
PDO_MYSQL_ATTR_SSL_CERT,
PDO_MYSQL_ATTR_SSL_CA,
PDO_MYSQL_ATTR_SSL_CAPATH,
- PDO_MYSQL_ATTR_SSL_CIPHER
+ PDO_MYSQL_ATTR_SSL_CIPHER,
+#if MYSQL_VERSION_ID > 50605 || defined(PDO_USE_MYSQLND)
+ PDO_MYSQL_ATTR_SERVER_PUBLIC_KEY
+#endif
};
#endif
diff --git a/ext/pdo_mysql/tests/bug_39858.phpt b/ext/pdo_mysql/tests/bug_39858.phpt
index 47457180a5..cb9cafd9f5 100644
--- a/ext/pdo_mysql/tests/bug_39858.phpt
+++ b/ext/pdo_mysql/tests/bug_39858.phpt
@@ -18,6 +18,8 @@ if ($version < 50000)
die(sprintf("skip Need MySQL Server 5.0.0+, found %d.%02d.%02d (%d)\n",
$matches[0], $matches[1], $matches[2], $version));
?>
+--XFAIL--
+nextRowset() problem with stored proc & emulation mode & mysqlnd
--FILE--
<?php
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
diff --git a/ext/pdo_mysql/tests/bug_41997.phpt b/ext/pdo_mysql/tests/bug_41997.phpt
index 38d55a0190..56cbe4b087 100644
--- a/ext/pdo_mysql/tests/bug_41997.phpt
+++ b/ext/pdo_mysql/tests/bug_41997.phpt
@@ -1,5 +1,7 @@
--TEST--
PDO MySQL Bug #41997 (stored procedure call returning single rowset blocks future queries)
+--XFAIL--
+nextRowset() problem with stored proc & emulation mode & mysqlnd
--SKIPIF--
<?php
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
diff --git a/ext/pdo_mysql/tests/bug_44454.phpt b/ext/pdo_mysql/tests/bug_44454.phpt
index 89a4e2a3f7..eb93d97952 100644
--- a/ext/pdo_mysql/tests/bug_44454.phpt
+++ b/ext/pdo_mysql/tests/bug_44454.phpt
@@ -73,8 +73,6 @@ require dirname(__FILE__) . '/mysql_pdo_test.inc';
$db = MySQLPDOTest::factory();
$db->exec('DROP TABLE IF EXISTS test');
?>
---XFAIL--
-For some reason the exception gets thrown at the wrong place
--EXPECTF--
Native Prepared Statements
... SELECT has returned 1 row...
diff --git a/ext/pdo_mysql/tests/pdo_mysql___construct.phpt b/ext/pdo_mysql/tests/pdo_mysql___construct.phpt
index c3f12df7a9..0cabfe6aa3 100644
--- a/ext/pdo_mysql/tests/pdo_mysql___construct.phpt
+++ b/ext/pdo_mysql/tests/pdo_mysql___construct.phpt
@@ -49,7 +49,8 @@ MySQLPDOTest::skip();
// should fail
$dsn = 'mysql:';
- print tryandcatch(10, '$db = new PDO("' . $dsn . '", "' . $user . '", "' . $pass . '");');
+ // don't print the message since it can be different
+ tryandcatch(10, '$db = new PDO("' . $dsn . '", "' . $user . '", "' . $pass . '");');
$dsn = PDO_MYSQL_TEST_DSN;
$user = PDO_MYSQL_TEST_USER;
@@ -57,14 +58,15 @@ MySQLPDOTest::skip();
// should work...
$db = new PDO($dsn, $user, $pass);
+ // Reaction on host not specified differs for different configs, so no printing
$dsn = 'mysql:invalid=foo';
- print tryandcatch(11, '$db = new PDO("' . $dsn . '", "' . $user . '", "' . $pass . '");');
+ tryandcatch(11, '$db = new PDO("' . $dsn . '", "' . $user . '", "' . $pass . '");');
$dsn = 'mysql:' . str_repeat('howmuch=canpdoeat;', 1000);
- print tryandcatch(12, '$db = new PDO("' . $dsn . '", "' . $user . '", "' . $pass . '");');
+ tryandcatch(12, '$db = new PDO("' . $dsn . '", "' . $user . '", "' . $pass . '");');
$dsn = 'mysql:' . str_repeat('abcdefghij', 1024 * 10) . '=somevalue';
- print tryandcatch(13, '$db = new PDO("' . $dsn . '", "' . $user . '", "' . $pass . '");');
+ tryandcatch(13, '$db = new PDO("' . $dsn . '", "' . $user . '", "' . $pass . '");');
if (PDO_MYSQL_TEST_HOST) {
$host = PDO_MYSQL_TEST_HOST;
@@ -295,6 +297,5 @@ MySQLPDOTest::skip();
[006] invalid data source name, [n/a] n/a
[007] could not find driver, [n/a] n/a
[009] SQLSTATE[%s] [1045] Access denied for user 'dont%s'@'%s' (using password: YES), [n/a] n/a
-[010] SQLSTATE[%s] [1045] Access denied for user 'dont%s'@'%s' (using password: YES), [n/a] n/a
[017] DSN=%s, SQLSTATE[%s] [%d] %s
done!
diff --git a/ext/pdo_mysql/tests/pdo_mysql_class_constants.phpt b/ext/pdo_mysql/tests/pdo_mysql_class_constants.phpt
index 17fa5d6059..ee0f12358d 100644
--- a/ext/pdo_mysql/tests/pdo_mysql_class_constants.phpt
+++ b/ext/pdo_mysql/tests/pdo_mysql_class_constants.phpt
@@ -3,6 +3,11 @@ PDO MySQL specific class constants
--SKIPIF--
<?php
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
+if (!extension_loaded('mysqli') && !extension_loaded('mysqlnd')) {
+ /* Need connection to detect library version */
+ require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc');
+ MySQLPDOTest::skip();
+}
?>
--FILE--
<?php
@@ -29,6 +34,19 @@ require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
$expected['MYSQL_ATTR_READ_DEFAULT_GROUP'] = true;
}
+ if (extension_loaded('mysqlnd')) {
+ $expected['MYSQL_ATTR_SERVER_PUBLIC_KEY'] = true;
+ } else if (extension_loaded('mysqli')) {
+ if (mysqli_get_client_version() > 50605) {
+ $expected['MYSQL_ATTR_SERVER_PUBLIC_KEY'] = true;
+ }
+ } else if (MySQLPDOTest::getClientVersion(MySQLPDOTest::factory()) > 50605) {
+ /* XXX the MySQL client library version isn't exposed with any
+ constants, the single possibility is to use the PDO::getAttribute().
+ This however will fail with no connection. */
+ $expected['MYSQL_ATTR_SERVER_PUBLIC_KEY'] = true;
+ }
+
/*
TODO
diff --git a/ext/pdo_mysql/tests/pdo_mysql_pconnect.phpt b/ext/pdo_mysql/tests/pdo_mysql_pconnect.phpt
index eb0fff13e6..5990ab812e 100644
--- a/ext/pdo_mysql/tests/pdo_mysql_pconnect.phpt
+++ b/ext/pdo_mysql/tests/pdo_mysql_pconnect.phpt
@@ -64,7 +64,7 @@ MySQLPDOTest::skip();
$tmp = $stmt->fetch(PDO::FETCH_ASSOC);
$con1 = $tmp['_con1'];
- $db2 = new PDO($dsn, $user, $pass, array(PDO::ATTR_PERSISTENT => true));
+ @$db2 = new PDO($dsn, $user, $pass, array(PDO::ATTR_PERSISTENT => true));
$stmt = $db2->query('SELECT CONNECTION_ID() as _con2');
$tmp = $stmt->fetch(PDO::FETCH_ASSOC);
$con2 = $tmp['_con2'];
@@ -94,4 +94,4 @@ MySQLPDOTest::skip();
print "done!";
?>
--EXPECTF--
-done! \ No newline at end of file
+done!
diff --git a/ext/pdo_mysql/tests/pdo_mysql_stmt_nextrowset.phpt b/ext/pdo_mysql/tests/pdo_mysql_stmt_nextrowset.phpt
index 7996245431..9165e70551 100644
--- a/ext/pdo_mysql/tests/pdo_mysql_stmt_nextrowset.phpt
+++ b/ext/pdo_mysql/tests/pdo_mysql_stmt_nextrowset.phpt
@@ -1,5 +1,7 @@
--TEST--
MySQL PDOStatement->nextRowSet()
+--XFAIL--
+nextRowset() problem with stored proc & emulation mode & mysqlnd
--SKIPIF--
<?php
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
@@ -310,4 +312,4 @@ array(3) {
}
}
bool(false)
-done! \ No newline at end of file
+done!
diff --git a/ext/pdo_mysql/tests/pdo_mysql_stmt_variable_columncount.phpt b/ext/pdo_mysql/tests/pdo_mysql_stmt_variable_columncount.phpt
index c34f4a9d35..e58d4a6578 100644
--- a/ext/pdo_mysql/tests/pdo_mysql_stmt_variable_columncount.phpt
+++ b/ext/pdo_mysql/tests/pdo_mysql_stmt_variable_columncount.phpt
@@ -1,5 +1,7 @@
--TEST--
MySQL Prepared Statements and different column counts
+--XFAIL--
+nextRowset() problem with stored proc & emulation mode & mysqlnd
--SKIPIF--
<?php
require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc');
@@ -120,4 +122,4 @@ if ($version < 50000)
print "done!";
?>
--EXPECTF--
-done! \ No newline at end of file
+done!
diff --git a/ext/pdo_oci/config.m4 b/ext/pdo_oci/config.m4
index 0e42d1f9a9..e3795db0ea 100755
--- a/ext/pdo_oci/config.m4
+++ b/ext/pdo_oci/config.m4
@@ -42,11 +42,11 @@ AC_DEFUN([AC_PDO_OCI_CHECK_LIB_DIR],[
PHP_ARG_WITH(pdo-oci, Oracle OCI support for PDO,
[ --with-pdo-oci[=DIR] PDO: Oracle OCI support. DIR defaults to \$ORACLE_HOME.
- Use --with-pdo-oci=instantclient,prefix,version
- for an Oracle Instant Client SDK.
- For example on Linux with 11.2 RPMs use:
+ Use --with-pdo-oci=instantclient,prefix,version
+ for an Oracle Instant Client SDK.
+ For example on Linux with 11.2 RPMs use:
--with-pdo-oci=instantclient,/usr,11.2
- With 10.2 RPMs use:
+ With 10.2 RPMs use:
--with-pdo-oci=instantclient,/usr,10.2.0.4])
if test "$PHP_PDO_OCI" != "no"; then
diff --git a/ext/pdo_odbc/config.m4 b/ext/pdo_odbc/config.m4
index b70dc9d539..74734c4d63 100755
--- a/ext/pdo_odbc/config.m4
+++ b/ext/pdo_odbc/config.m4
@@ -3,25 +3,25 @@ dnl config.m4 for extension pdo_odbc
dnl vim:et:sw=2:ts=2:
define([PDO_ODBC_HELP_TEXT],[[
- include and lib dirs are looked for under 'dir'.
-
- 'flavour' can be one of: ibm-db2, iODBC, unixODBC, generic
- If ',dir' part is omitted, default for the flavour
- you have selected will used. e.g.:
-
- --with-pdo-odbc=unixODBC
-
- will check for unixODBC under /usr/local. You may attempt
- to use an otherwise unsupported driver using the \"generic\"
- flavour. The syntax for generic ODBC support is:
-
- --with-pdo-odbc=generic,dir,libname,ldflags,cflags
-
- When build as shared the extension filename is always pdo_odbc.so]])
+ include and lib dirs are looked for under 'dir'.
+
+ 'flavour' can be one of: ibm-db2, iODBC, unixODBC, generic
+ If ',dir' part is omitted, default for the flavour
+ you have selected will be used. e.g.:
+
+ --with-pdo-odbc=unixODBC
+
+ will check for unixODBC under /usr/local. You may attempt
+ to use an otherwise unsupported driver using the \"generic\"
+ flavour. The syntax for generic ODBC support is:
+
+ --with-pdo-odbc=generic,dir,libname,ldflags,cflags
+
+ When built as 'shared' the extension filename is always pdo_odbc.so]])
PHP_ARG_WITH(pdo-odbc, for ODBC v3 support for PDO,
[ --with-pdo-odbc=flavour,dir
- PDO: Support for 'flavour' ODBC driver.]PDO_ODBC_HELP_TEXT)
+ PDO: Support for 'flavour' ODBC driver.]PDO_ODBC_HELP_TEXT)
AC_DEFUN([PDO_ODBC_CHECK_HEADER],[
diff --git a/ext/pdo_pgsql/config.m4 b/ext/pdo_pgsql/config.m4
index f9254a8fd9..afe42e06a5 100644
--- a/ext/pdo_pgsql/config.m4
+++ b/ext/pdo_pgsql/config.m4
@@ -4,7 +4,7 @@ dnl vim:et:sw=2:ts=2:
PHP_ARG_WITH(pdo-pgsql,for PostgreSQL support for PDO,
[ --with-pdo-pgsql[=DIR] PDO: PostgreSQL support. DIR is the PostgreSQL base
- install directory or the path to pg_config])
+ install directory or the path to pg_config])
if test "$PHP_PDO_PGSQL" != "no"; then
diff --git a/ext/pdo_sqlite/config.m4 b/ext/pdo_sqlite/config.m4
index b2b70a5038..0a7d0fe826 100644
--- a/ext/pdo_sqlite/config.m4
+++ b/ext/pdo_sqlite/config.m4
@@ -4,8 +4,8 @@ dnl vim:et:sw=2:ts=2:
PHP_ARG_WITH(pdo-sqlite, for sqlite 3 support for PDO,
[ --without-pdo-sqlite[=DIR]
- PDO: sqlite 3 support. DIR is the sqlite base
- install directory [BUNDLED]], $PHP_PDO)
+ PDO: sqlite 3 support. DIR is the sqlite base
+ install directory [BUNDLED]], $PHP_PDO)
if test "$PHP_PDO_SQLITE" != "no"; then
diff --git a/ext/pgsql/config.m4 b/ext/pgsql/config.m4
index bddb77a151..13837bd832 100644
--- a/ext/pgsql/config.m4
+++ b/ext/pgsql/config.m4
@@ -3,7 +3,7 @@ dnl $Id$
dnl
PHP_ARG_WITH(pgsql,for PostgreSQL support,
-[ --with-pgsql[=DIR] Include PostgreSQL support. DIR is the PostgreSQL
+[ --with-pgsql[=DIR] Include PostgreSQL support. DIR is the PostgreSQL
base install directory or the path to pg_config])
if test "$PHP_PGSQL" != "no"; then
diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c
index 3dc3057905..cab87cf450 100644
--- a/ext/pgsql/pgsql.c
+++ b/ext/pgsql/pgsql.c
@@ -1815,7 +1815,7 @@ PHP_FUNCTION(pg_query_params)
} else {
zval tmp_val = **tmp;
zval_copy_ctor(&tmp_val);
- convert_to_string(&tmp_val);
+ convert_to_cstring(&tmp_val);
if (Z_TYPE(tmp_val) != IS_STRING) {
php_error_docref(NULL TSRMLS_CC, E_WARNING,"Error converting parameter");
zval_dtor(&tmp_val);
@@ -4291,6 +4291,7 @@ PHP_FUNCTION(pg_unescape_bytea)
to = (char *)php_pgsql_unescape_bytea((unsigned char*)from, &to_len);
#endif
if (!to) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,"Invalid parameter");
RETURN_FALSE;
}
RETVAL_STRINGL(to, to_len, 0);
@@ -5438,7 +5439,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con
skip_field = 0;
new_val = NULL;
- if ((key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(values), &field, &field_len, &num_idx, 0, &pos)) == HASH_KEY_NON_EXISTANT) {
+ if ((key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(values), &field, &field_len, &num_idx, 0, &pos)) == HASH_KEY_NON_EXISTENT) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to get array key type");
err = 1;
}
@@ -5446,7 +5447,7 @@ PHP_PGSQL_API int php_pgsql_convert(PGconn *pg_link, const char *table_name, con
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Accepts only string key for values");
err = 1;
}
- if (!err && key_type == HASH_KEY_NON_EXISTANT) {
+ if (!err && key_type == HASH_KEY_NON_EXISTENT) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Accepts only string key for values");
err = 1;
}
@@ -6204,7 +6205,7 @@ PHP_PGSQL_API int php_pgsql_insert(PGconn *pg_link, const char *table, zval *var
zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(var_array), &pos);
while ((key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(var_array), &fld,
- &fld_len, &num_idx, 0, &pos)) != HASH_KEY_NON_EXISTANT) {
+ &fld_len, &num_idx, 0, &pos)) != HASH_KEY_NON_EXISTENT) {
if (key_type == HASH_KEY_IS_LONG) {
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Expects associative array for values to be inserted");
goto cleanup;
diff --git a/ext/pgsql/tests/09notice.phpt b/ext/pgsql/tests/09notice.phpt
index 67ef262fca..db671016e3 100644
--- a/ext/pgsql/tests/09notice.phpt
+++ b/ext/pgsql/tests/09notice.phpt
@@ -20,6 +20,9 @@ $db = pg_connect($conn_str);
_set_lc_messages();
+$res = pg_query($db, 'SET client_min_messages TO NOTICE;');
+var_dump($res);
+
pg_query($db, "BEGIN;");
pg_query($db, "BEGIN;");
@@ -33,6 +36,8 @@ echo "pg_last_notice() is Ok\n";
?>
--EXPECTF--
+resource(%d) of type (pgsql result)
+
Notice: pg_query(): %s already a transaction in progress in %s on line %d
%s already a transaction in progress
pg_last_notice() is Ok
diff --git a/ext/pgsql/tests/80_bug32223.phpt b/ext/pgsql/tests/80_bug32223.phpt
index cad5fb3a12..b9bbbf86ed 100644
--- a/ext/pgsql/tests/80_bug32223.phpt
+++ b/ext/pgsql/tests/80_bug32223.phpt
@@ -37,8 +37,10 @@ begin
end;
' LANGUAGE plpgsql;");
-
+$res = pg_query($dbh, 'SET client_min_messages TO NOTICE;');
+var_dump($res);
$res = pg_query($dbh, 'SELECT test_notice()');
+var_dump($res);
$row = pg_fetch_row($res, 0);
var_dump($row);
pg_free_result($res);
@@ -52,6 +54,8 @@ pg_close($dbh);
?>
===DONE===
--EXPECTF--
+resource(%d) of type (pgsql result)
+resource(%d) of type (pgsql result)
array(1) {
[0]=>
string(1) "f"
diff --git a/ext/pgsql/tests/80_bug32223b.phpt b/ext/pgsql/tests/80_bug32223b.phpt
index e79685c43d..418ccfc9ae 100644
--- a/ext/pgsql/tests/80_bug32223b.phpt
+++ b/ext/pgsql/tests/80_bug32223b.phpt
@@ -37,10 +37,13 @@ begin
end;
' LANGUAGE plpgsql;");
+$res = pg_query(dbh, 'SET client_min_messages TO NOTICE;');
+var_dump($res);
+
function tester() {
$res = pg_query(dbh, 'SELECT test_notice()');
$row = pg_fetch_row($res, 0);
- var_dump($row);
+ var_dump($row);
pg_free_result($res);
if ($row[0] == 'f')
{
@@ -54,6 +57,7 @@ pg_close(dbh);
?>
===DONE===
--EXPECTF--
+resource(%d) of type (pgsql result)
array(1) {
[0]=>
string(1) "f"
diff --git a/ext/pgsql/tests/bug46408.phpt b/ext/pgsql/tests/bug46408.phpt
new file mode 100644
index 0000000000..bf84290907
--- /dev/null
+++ b/ext/pgsql/tests/bug46408.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Bug #46408 (Locale number format settings can cause pg_query_params to break with numerics)
+--SKIPIF--
+<?php
+require_once('skipif.inc');
+if (false === setlocale(LC_ALL, 'hr_HR.utf-8', 'hr_HR')) {
+ echo "skip Locale hr_HR.utf-8 not present";
+}
+?>
+--FILE--
+<?php
+
+require_once('config.inc');
+
+$dbh = pg_connect($conn_str);
+setlocale(LC_ALL, 'hr_HR.utf-8', 'hr_HR');
+echo 3.5.PHP_EOL;
+pg_query_params("SELECT $1::numeric", array(3.5));
+pg_close($dbh);
+
+echo "Done".PHP_EOL;
+
+?>
+--EXPECTF--
+3,5
+Done
diff --git a/ext/phar/Makefile.frag b/ext/phar/Makefile.frag
index ed6de9fd67..faa9db0c70 100644
--- a/ext/phar/Makefile.frag
+++ b/ext/phar/Makefile.frag
@@ -1,5 +1,5 @@
$(srcdir)/phar_path_check.c: $(srcdir)/phar_path_check.re
- @(cd $(top_srcdir); $(RE2C) -b -o ext/phar/phar_path_check.c ext/phar/phar_path_check.re)
+ @(cd $(top_srcdir); $(RE2C) --no-generation-date -b -o ext/phar/phar_path_check.c ext/phar/phar_path_check.re)
pharcmd: $(builddir)/phar.php $(builddir)/phar.phar
diff --git a/ext/phar/config.m4 b/ext/phar/config.m4
index d424060f2a..614d672eab 100644
--- a/ext/phar/config.m4
+++ b/ext/phar/config.m4
@@ -28,5 +28,7 @@ if test "$PHP_PHAR" != "no"; then
PHP_ADD_EXTENSION_DEP(phar, spl, true)
PHP_ADD_MAKEFILE_FRAGMENT
+ PHP_INSTALL_HEADERS([ext/phar], [php_phar.h])
+
PHP_OUTPUT(ext/phar/phar.1 ext/phar/phar.phar.1)
fi
diff --git a/ext/phar/dirstream.c b/ext/phar/dirstream.c
index 1cbe522f11..c5c2c69448 100644
--- a/ext/phar/dirstream.c
+++ b/ext/phar/dirstream.c
@@ -103,7 +103,7 @@ static size_t phar_dir_read(php_stream *stream, char *buf, size_t count TSRMLS_D
return 0;
}
- if (HASH_KEY_NON_EXISTANT == zend_hash_get_current_key_ex(data, &key, &keylen, &unused, 0, NULL)) {
+ if (HASH_KEY_NON_EXISTENT == zend_hash_get_current_key_ex(data, &key, &keylen, &unused, 0, NULL)) {
return 0;
}
@@ -207,7 +207,7 @@ static php_stream *phar_make_dirstream(char *dir, HashTable *manifest TSRMLS_DC)
zend_hash_internal_pointer_reset(manifest);
while (FAILURE != zend_hash_has_more_elements(manifest)) {
- if (HASH_KEY_NON_EXISTANT == zend_hash_get_current_key_ex(manifest, &key, &keylen, &unused, 0, NULL)) {
+ if (HASH_KEY_NON_EXISTENT == zend_hash_get_current_key_ex(manifest, &key, &keylen, &unused, 0, NULL)) {
break;
}
@@ -399,7 +399,7 @@ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, char *path, char
/* search for directory */
zend_hash_internal_pointer_reset(&phar->manifest);
while (FAILURE != zend_hash_has_more_elements(&phar->manifest)) {
- if (HASH_KEY_NON_EXISTANT !=
+ if (HASH_KEY_NON_EXISTENT !=
zend_hash_get_current_key_ex(
&phar->manifest, &key, &keylen, &unused, 0, NULL)) {
PHAR_STR(key, str_key);
@@ -633,7 +633,7 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, char *url, int options, php_
if (!entry->is_deleted) {
for (zend_hash_internal_pointer_reset(&phar->manifest);
- HASH_KEY_NON_EXISTANT != zend_hash_get_current_key_ex(&phar->manifest, &key, &key_len, &unused, 0, NULL);
+ HASH_KEY_NON_EXISTENT != zend_hash_get_current_key_ex(&phar->manifest, &key, &key_len, &unused, 0, NULL);
zend_hash_move_forward(&phar->manifest)) {
PHAR_STR(key, str_key);
@@ -654,7 +654,7 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, char *url, int options, php_
}
for (zend_hash_internal_pointer_reset(&phar->virtual_dirs);
- HASH_KEY_NON_EXISTANT != zend_hash_get_current_key_ex(&phar->virtual_dirs, &key, &key_len, &unused, 0, NULL);
+ HASH_KEY_NON_EXISTENT != zend_hash_get_current_key_ex(&phar->virtual_dirs, &key, &key_len, &unused, 0, NULL);
zend_hash_move_forward(&phar->virtual_dirs)) {
PHAR_STR(key, str_key);
diff --git a/ext/phar/phar.c b/ext/phar/phar.c
index ec82351410..a5488937a8 100644
--- a/ext/phar/phar.c
+++ b/ext/phar/phar.c
@@ -27,9 +27,7 @@
static void destroy_phar_data(void *pDest);
ZEND_DECLARE_MODULE_GLOBALS(phar)
-#if PHP_VERSION_ID >= 50300
char *(*phar_save_resolve_path)(const char *filename, int filename_len TSRMLS_DC);
-#endif
/**
* set's phar->is_writeable based on the current INI value
@@ -1964,7 +1962,7 @@ woohoo:
zend_hash_internal_pointer_reset(&(PHAR_GLOBALS->phar_fname_map));
while (FAILURE != zend_hash_has_more_elements(&(PHAR_GLOBALS->phar_fname_map))) {
- if (HASH_KEY_NON_EXISTANT == zend_hash_get_current_key_ex(&(PHAR_GLOBALS->phar_fname_map), &key, &keylen, &unused, 0, NULL)) {
+ if (HASH_KEY_NON_EXISTENT == zend_hash_get_current_key_ex(&(PHAR_GLOBALS->phar_fname_map), &key, &keylen, &unused, 0, NULL)) {
break;
}
@@ -1994,7 +1992,7 @@ woohoo:
zend_hash_internal_pointer_reset(&cached_phars);
while (FAILURE != zend_hash_has_more_elements(&cached_phars)) {
- if (HASH_KEY_NON_EXISTANT == zend_hash_get_current_key_ex(&cached_phars, &key, &keylen, &unused, 0, NULL)) {
+ if (HASH_KEY_NON_EXISTENT == zend_hash_get_current_key_ex(&cached_phars, &key, &keylen, &unused, 0, NULL)) {
break;
}
@@ -3321,31 +3319,18 @@ static size_t phar_zend_stream_reader(void *handle, char *buf, size_t len TSRMLS
}
/* }}} */
-#if PHP_VERSION_ID >= 50300
static size_t phar_zend_stream_fsizer(void *handle TSRMLS_DC) /* {{{ */
{
return ((phar_archive_data*)handle)->halt_offset + 32;
} /* }}} */
-#else /* PHP_VERSION_ID */
-
-static long phar_stream_fteller_for_zend(void *handle TSRMLS_DC) /* {{{ */
-{
- return (long)php_stream_tell(phar_get_pharfp((phar_archive_data*)handle TSRMLS_CC));
-}
-/* }}} */
-#endif
-
zend_op_array *(*phar_orig_compile_file)(zend_file_handle *file_handle, int type TSRMLS_DC);
-#if PHP_VERSION_ID >= 50300
#define phar_orig_zend_open zend_stream_open_function
+
static char *phar_resolve_path(const char *filename, int filename_len TSRMLS_DC)
{
return phar_find_in_include_path((char *) filename, filename_len, NULL TSRMLS_CC);
}
-#else
-int (*phar_orig_zend_open)(const char *filename, zend_file_handle *handle TSRMLS_DC);
-#endif
static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC) /* {{{ */
{
@@ -3378,7 +3363,6 @@ static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type
}
} else if (phar->flags & PHAR_FILE_COMPRESSION_MASK) {
/* compressed phar */
-#if PHP_VERSION_ID >= 50300
file_handle->type = ZEND_HANDLE_STREAM;
/* we do our own reading directly from the phar, don't change the next line */
file_handle->handle.stream.handle = phar;
@@ -3390,18 +3374,6 @@ static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type
php_stream_rewind(PHAR_GLOBALS->cached_fp[phar->phar_pos].fp) :
php_stream_rewind(phar->fp);
memset(&file_handle->handle.stream.mmap, 0, sizeof(file_handle->handle.stream.mmap));
-#else /* PHP_VERSION_ID */
- file_handle->type = ZEND_HANDLE_STREAM;
- /* we do our own reading directly from the phar, don't change the next line */
- file_handle->handle.stream.handle = phar;
- file_handle->handle.stream.reader = phar_zend_stream_reader;
- file_handle->handle.stream.closer = NULL; /* don't close - let phar handle this one */
- file_handle->handle.stream.fteller = phar_stream_fteller_for_zend;
- file_handle->handle.stream.interactive = 0;
- phar->is_persistent ?
- php_stream_rewind(PHAR_GLOBALS->cached_fp[phar->phar_pos].fp) :
- php_stream_rewind(phar->fp);
-#endif
}
}
}
@@ -3426,60 +3398,6 @@ static zend_op_array *phar_compile_file(zend_file_handle *file_handle, int type
}
/* }}} */
-#if PHP_VERSION_ID < 50300
-int phar_zend_open(const char *filename, zend_file_handle *handle TSRMLS_DC) /* {{{ */
-{
- char *arch, *entry;
- int arch_len, entry_len;
-
- /* this code is obsoleted in php 5.3 */
- entry = (char *) filename;
- if (!IS_ABSOLUTE_PATH(entry, strlen(entry)) && !strstr(entry, "://")) {
- phar_archive_data **pphar = NULL;
- char *fname;
- int fname_len;
-
- fname = (char*)zend_get_executed_filename(TSRMLS_C);
- fname_len = strlen(fname);
-
- if (fname_len > 7 && !strncasecmp(fname, "phar://", 7)) {
- if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 1, 0 TSRMLS_CC)) {
- zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar);
- if (!pphar && PHAR_G(manifest_cached)) {
- zend_hash_find(&cached_phars, arch, arch_len, (void **) &pphar);
- }
- efree(arch);
- efree(entry);
- }
- }
-
- /* retrieving an include within the current directory, so use this if possible */
- if (!(entry = phar_find_in_include_path((char *) filename, strlen(filename), NULL TSRMLS_CC))) {
- /* this file is not in the phar, use the original path */
- goto skip_phar;
- }
-
- if (SUCCESS == phar_orig_zend_open(entry, handle TSRMLS_CC)) {
- if (!handle->opened_path) {
- handle->opened_path = entry;
- }
- if (entry != filename) {
- handle->free_filename = 1;
- }
- return SUCCESS;
- }
-
- if (entry != filename) {
- efree(entry);
- }
-
- return FAILURE;
- }
-skip_phar:
- return phar_orig_zend_open(filename, handle TSRMLS_CC);
-}
-/* }}} */
-#endif
typedef zend_op_array* (zend_compile_t)(zend_file_handle*, int TSRMLS_DC);
typedef zend_compile_t* (compile_hook)(zend_compile_t *ptr);
@@ -3556,13 +3474,8 @@ PHP_MINIT_FUNCTION(phar) /* {{{ */
phar_orig_compile_file = zend_compile_file;
zend_compile_file = phar_compile_file;
-#if PHP_VERSION_ID >= 50300
phar_save_resolve_path = zend_resolve_path;
zend_resolve_path = phar_resolve_path;
-#else
- phar_orig_zend_open = zend_stream_open_function;
- zend_stream_open_function = phar_zend_open;
-#endif
phar_object_init(TSRMLS_C);
@@ -3583,11 +3496,6 @@ PHP_MSHUTDOWN_FUNCTION(phar) /* {{{ */
zend_compile_file = phar_orig_compile_file;
}
-#if PHP_VERSION_ID < 50300
- if (zend_stream_open_function == phar_zend_open) {
- zend_stream_open_function = phar_orig_zend_open;
- }
-#endif
if (PHAR_G(manifest_cached)) {
zend_hash_destroy(&(cached_phars));
zend_hash_destroy(&(cached_alias));
diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h
index c9306c15f4..a24a5ace70 100644
--- a/ext/phar/phar_internal.h
+++ b/ext/phar/phar_internal.h
@@ -516,76 +516,17 @@ union _phar_entry_object {
#endif
#ifndef PHAR_MAIN
-# if PHP_VERSION_ID >= 50300
extern char *(*phar_save_resolve_path)(const char *filename, int filename_len TSRMLS_DC);
-# endif
#endif
-#if PHP_VERSION_ID < 50209
-static inline size_t phar_stream_copy_to_stream(php_stream *src, php_stream *dest, size_t maxlen, size_t *len STREAMS_DC TSRMLS_DC)
-{
- size_t ret = php_stream_copy_to_stream(src, dest, maxlen);
- if (len) {
- *len = ret;
- }
- if (ret) {
- return SUCCESS;
- }
- return FAILURE;
-}
-#else
# define phar_stream_copy_to_stream(src, dest, maxlen, len) _php_stream_copy_to_stream_ex((src), (dest), (maxlen), (len) STREAMS_CC TSRMLS_CC)
-#endif
-
-#if PHP_VERSION_ID >= 60000
-typedef zstr phar_zstr;
-#define PHAR_STR(a, b) \
- 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 ebaa620080..7857fa71c8 100644
--- a/ext/phar/phar_object.c
+++ b/ext/phar/phar_object.c
@@ -685,11 +685,7 @@ PHP_METHOD(Phar, webPhar)
ZVAL_STRINGL(params, entry, entry_len, 1);
zp[0] = &params;
-#if PHP_VERSION_ID < 50300
- if (FAILURE == zend_fcall_info_init(rewrite, &fci, &fcc TSRMLS_CC)) {
-#else
if (FAILURE == zend_fcall_info_init(rewrite, 0, &fci, &fcc, NULL, NULL TSRMLS_CC)) {
-#endif
zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "phar error: invalid rewrite callback");
if (free_pathinfo) {
@@ -701,11 +697,7 @@ PHP_METHOD(Phar, webPhar)
fci.param_count = 1;
fci.params = zp;
-#if PHP_VERSION_ID < 50300
- ++(params->refcount);
-#else
Z_ADDREF_P(params);
-#endif
fci.retval_ptr_ptr = &retval_ptr;
if (FAILURE == zend_call_function(&fci, &fcc TSRMLS_CC)) {
@@ -729,11 +721,6 @@ PHP_METHOD(Phar, webPhar)
}
switch (Z_TYPE_P(retval_ptr)) {
-#if PHP_VERSION_ID >= 60000
- case IS_UNICODE:
- zval_unicode_to_string(retval_ptr TSRMLS_CC);
- /* break intentionally omitted */
-#endif
case IS_STRING:
efree(entry);
@@ -1155,11 +1142,7 @@ PHP_METHOD(Phar, __construct)
#else
char *fname, *alias = NULL, *error, *arch = NULL, *entry = NULL, *save_fname;
int fname_len, alias_len = 0, arch_len, entry_len, is_data;
-#if PHP_VERSION_ID < 50300
- long flags = 0;
-#else
long flags = SPL_FILE_DIR_SKIPDOTS|SPL_FILE_DIR_UNIXPATHS;
-#endif
long format = 0;
phar_archive_object *phar_obj;
phar_archive_data *phar_data;
@@ -1434,16 +1417,13 @@ struct _phar_t {
static int phar_build(zend_object_iterator *iter, void *puser TSRMLS_DC) /* {{{ */
{
zval **value;
- zend_uchar key_type;
zend_bool close_fp = 1;
- ulong int_key;
struct _phar_t *p_obj = (struct _phar_t*) puser;
uint str_key_len, base_len = p_obj->l, fname_len;
phar_entry_data *data;
php_stream *fp;
size_t contents_len;
char *fname, *error = NULL, *base = p_obj->b, *opened, *save = NULL, *temp = NULL;
- phar_zstr key;
char *str_key;
zend_class_entry *ce = p_obj->c;
phar_archive_object *phar_obj = p_obj->p;
@@ -1462,11 +1442,6 @@ static int phar_build(zend_object_iterator *iter, void *puser TSRMLS_DC) /* {{{
}
switch (Z_TYPE_PP(value)) {
-#if PHP_VERSION_ID >= 60000
- case IS_UNICODE:
- zval_unicode_to_string(*(value) TSRMLS_CC);
- /* break intentionally omitted */
-#endif
case IS_STRING:
break;
case IS_RESOURCE:
@@ -1478,35 +1453,24 @@ static int phar_build(zend_object_iterator *iter, void *puser TSRMLS_DC) /* {{{
}
if (iter->funcs->get_current_key) {
- key_type = iter->funcs->get_current_key(iter, &key, &str_key_len, &int_key TSRMLS_CC);
+ zval key;
+ iter->funcs->get_current_key(iter, &key TSRMLS_CC);
if (EG(exception)) {
return ZEND_HASH_APPLY_STOP;
}
- if (key_type == HASH_KEY_IS_LONG) {
+ if (Z_TYPE(key) != IS_STRING) {
+ zval_dtor(&key);
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator %v returned an invalid key (must return a string)", ce->name);
return ZEND_HASH_APPLY_STOP;
}
- if (key_type > 9) { /* IS_UNICODE == 10 */
-#if PHP_VERSION_ID < 60000
-/* this can never happen, but fixes a compile warning */
- spprintf(&str_key, 0, "%s", key);
-#else
- spprintf(&str_key, 0, "%v", key);
- ezfree(key);
-#endif
- } else {
- PHAR_STR(key, str_key);
- }
+ str_key_len = Z_STRLEN(key);
+ str_key = estrndup(Z_STRVAL(key), str_key_len);
save = str_key;
-
- if (str_key[str_key_len - 1] == '\0') {
- str_key_len--;
- }
-
+ zval_dtor(&key);
} else {
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator %v returned an invalid key (must return a string)", ce->name);
return ZEND_HASH_APPLY_STOP;
@@ -1528,13 +1492,7 @@ static int phar_build(zend_object_iterator *iter, void *puser TSRMLS_DC) /* {{{
switch (intern->type) {
case SPL_FS_DIR:
-#if PHP_VERSION_ID >= 60000
- test = spl_filesystem_object_get_path(intern, NULL, NULL TSRMLS_CC).s;
-#elif PHP_VERSION_ID >= 50300
test = spl_filesystem_object_get_path(intern, NULL TSRMLS_CC);
-#else
- test = intern->path;
-#endif
fname_len = spprintf(&fname, 0, "%s%c%s", test, DEFAULT_SLASH, intern->u.dir.entry.d_name);
php_stat(fname, fname_len, FS_IS_DIR, &dummy TSRMLS_CC);
@@ -1559,25 +1517,7 @@ static int phar_build(zend_object_iterator *iter, void *puser TSRMLS_DC) /* {{{
goto phar_spl_fileinfo;
case SPL_FS_INFO:
case SPL_FS_FILE:
-#if PHP_VERSION_ID >= 60000
- 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
if (!fname) {
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Could not resolve file path");
return ZEND_HASH_APPLY_STOP;
@@ -1641,32 +1581,24 @@ phar_spl_fileinfo:
}
} else {
if (iter->funcs->get_current_key) {
- key_type = iter->funcs->get_current_key(iter, &key, &str_key_len, &int_key TSRMLS_CC);
+ zval key;
+ iter->funcs->get_current_key(iter, &key TSRMLS_CC);
if (EG(exception)) {
return ZEND_HASH_APPLY_STOP;
}
- if (key_type == HASH_KEY_IS_LONG) {
+ if (Z_TYPE(key) != IS_STRING) {
+ zval_dtor(&key);
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator %v returned an invalid key (must return a string)", ce->name);
return ZEND_HASH_APPLY_STOP;
}
- if (key_type > 9) { /* IS_UNICODE == 10 */
-#if PHP_VERSION_ID < 60000
-/* this can never happen, but fixes a compile warning */
- spprintf(&str_key, 0, "%s", key);
-#else
- spprintf(&str_key, 0, "%v", key);
- ezfree(key);
-#endif
- } else {
- PHAR_STR(key, str_key);
- }
+ str_key_len = Z_STRLEN(key);
+ str_key = estrndup(Z_STRVAL(key), str_key_len);
save = str_key;
-
- if (str_key[str_key_len - 1] == '\0') str_key_len--;
+ zval_dtor(&key);
} else {
zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Iterator %v returned an invalid key (must return a string)", ce->name);
return ZEND_HASH_APPLY_STOP;
@@ -1838,11 +1770,7 @@ PHP_METHOD(Phar, buildFromDirectory)
INIT_PZVAL(&arg);
ZVAL_STRINGL(&arg, dir, dir_len, 0);
INIT_PZVAL(&arg2);
-#if PHP_VERSION_ID < 50300
- ZVAL_LONG(&arg2, 0);
-#else
ZVAL_LONG(&arg2, SPL_FILE_DIR_SKIPDOTS|SPL_FILE_DIR_UNIXPATHS);
-#endif
zend_call_method_with_2_params(&iter, spl_ce_RecursiveDirectoryIterator,
&spl_ce_RecursiveDirectoryIterator->constructor, "__construct", NULL, &arg, &arg2);
@@ -2335,11 +2263,7 @@ static zval *phar_convert_to_other(phar_archive_data *source, int convert, char
ALLOC_ZVAL(phar->metadata);
*phar->metadata = *t;
zval_copy_ctor(phar->metadata);
-#if PHP_VERSION_ID < 50300
- phar->metadata->refcount = 1;
-#else
Z_SET_REFCOUNT_P(phar->metadata, 1);
-#endif
phar->metadata_len = 0;
}
@@ -2387,11 +2311,7 @@ no_copy:
ALLOC_ZVAL(newentry.metadata);
*newentry.metadata = *t;
zval_copy_ctor(newentry.metadata);
-#if PHP_VERSION_ID < 50300
- newentry.metadata->refcount = 1;
-#else
Z_SET_REFCOUNT_P(newentry.metadata, 1);
-#endif
newentry.metadata_str.c = NULL;
newentry.metadata_str.len = 0;
@@ -3574,11 +3494,7 @@ PHP_METHOD(Phar, copy)
ALLOC_ZVAL(newentry.metadata);
*newentry.metadata = *t;
zval_copy_ctor(newentry.metadata);
-#if PHP_VERSION_ID < 50300
- newentry.metadata->refcount = 1;
-#else
Z_SET_REFCOUNT_P(newentry.metadata, 1);
-#endif
newentry.metadata_str.c = NULL;
newentry.metadata_str.len = 0;
@@ -4393,11 +4309,6 @@ PHP_METHOD(Phar, extractTo)
switch (Z_TYPE_P(zval_files)) {
case IS_NULL:
goto all_files;
-#if PHP_VERSION_ID >= 60000
- case IS_UNICODE:
- zval_unicode_to_string(zval_files TSRMLS_CC);
- /* break intentionally omitted */
-#endif
case IS_STRING:
filename = Z_STRVAL_P(zval_files);
filename_len = Z_STRLEN_P(zval_files);
@@ -4411,11 +4322,6 @@ PHP_METHOD(Phar, extractTo)
zval **zval_file;
if (zend_hash_index_find(Z_ARRVAL_P(zval_files), i, (void **) &zval_file) == SUCCESS) {
switch (Z_TYPE_PP(zval_file)) {
-#if PHP_VERSION_ID >= 60000
- case IS_UNICODE:
- zval_unicode_to_string(*(zval_file) TSRMLS_CC);
- /* break intentionally omitted */
-#endif
case IS_STRING:
break;
default:
@@ -5436,11 +5342,7 @@ zend_function_entry phar_exception_methods[] = {
#define REGISTER_PHAR_CLASS_CONST_LONG(class_name, const_name, value) \
zend_declare_class_constant_long(class_name, const_name, sizeof(const_name)-1, (long)value TSRMLS_CC);
-#if PHP_VERSION_ID < 50200
-# define phar_exception_get_default() zend_exception_get_default()
-#else
-# define phar_exception_get_default() zend_exception_get_default(TSRMLS_C)
-#endif
+#define phar_exception_get_default() zend_exception_get_default(TSRMLS_C)
void phar_object_init(TSRMLS_D) /* {{{ */
{
diff --git a/ext/phar/phar_path_check.c b/ext/phar/phar_path_check.c
index c1aff7037d..db97efcbe3 100644
--- a/ext/phar/phar_path_check.c
+++ b/ext/phar/phar_path_check.c
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.13.5 on Fri Feb 25 04:35:39 2011 */
+/* Generated by re2c 0.13.5 */
#line 1 "ext/phar/phar_path_check.re"
/*
+----------------------------------------------------------------------+
diff --git a/ext/phar/php_phar.h b/ext/phar/php_phar.h
index 554489f478..41c379bfa9 100644
--- a/ext/phar/php_phar.h
+++ b/ext/phar/php_phar.h
@@ -22,7 +22,7 @@
#ifndef PHP_PHAR_H
#define PHP_PHAR_H
-#define PHP_PHAR_VERSION "2.0.1"
+#define PHP_PHAR_VERSION "2.0.2"
#include "ext/standard/basic_functions.h"
extern zend_module_entry phar_module_entry;
@@ -31,9 +31,11 @@ extern zend_module_entry phar_module_entry;
#ifdef PHP_WIN32
#define PHP_PHAR_API __declspec(dllexport)
#else
-#define PHP_PHAR_API
+#define PHP_PHAR_API PHPAPI
#endif
+PHP_PHAR_API int phar_resolve_alias(char *alias, int alias_len, char **filename, int *filename_len TSRMLS_DC);
+
#endif /* PHP_PHAR_H */
diff --git a/ext/phar/stream.c b/ext/phar/stream.c
index 4101008549..5db866c422 100644
--- a/ext/phar/stream.c
+++ b/ext/phar/stream.c
@@ -635,7 +635,7 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, char *url, int flags,
zend_hash_internal_pointer_reset_ex(&phar->mounted_dirs, &pos);
while (FAILURE != zend_hash_has_more_elements_ex(&phar->mounted_dirs, &pos)) {
- if (HASH_KEY_NON_EXISTANT == zend_hash_get_current_key_ex(&phar->mounted_dirs, &key, &keylen, &unused, 0, &pos)) {
+ if (HASH_KEY_NON_EXISTENT == zend_hash_get_current_key_ex(&phar->mounted_dirs, &key, &keylen, &unused, 0, &pos)) {
break;
}
PHAR_STR(key, str_key);
@@ -918,7 +918,7 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, char *url_from, char
uint to_len = strlen(resource_to->path+1);
for (zend_hash_internal_pointer_reset(&phar->manifest);
- HASH_KEY_NON_EXISTANT != (key_type = zend_hash_get_current_key_ex(&phar->manifest, &key, &key_len, &unused, 0, NULL)) &&
+ HASH_KEY_NON_EXISTENT != (key_type = zend_hash_get_current_key_ex(&phar->manifest, &key, &key_len, &unused, 0, NULL)) &&
SUCCESS == zend_hash_get_current_data(&phar->manifest, (void **) &entry);
zend_hash_move_forward(&phar->manifest)) {
@@ -942,17 +942,13 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, char *url_from, char
entry->filename_len = new_key_len;
PHAR_ZSTR(new_str_key, new_key);
-#if PHP_VERSION_ID < 50300
- zend_hash_update_current_key_ex(&phar->manifest, key_type, new_key, new_key_len, 0, NULL);
-#else
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);
- HASH_KEY_NON_EXISTANT != (key_type = zend_hash_get_current_key_ex(&phar->virtual_dirs, &key, &key_len, &unused, 0, NULL));
+ HASH_KEY_NON_EXISTENT != (key_type = zend_hash_get_current_key_ex(&phar->virtual_dirs, &key, &key_len, &unused, 0, NULL));
zend_hash_move_forward(&phar->virtual_dirs)) {
PHAR_STR(key, str_key);
@@ -968,18 +964,14 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, char *url_from, char
new_str_key[new_key_len] = 0;
PHAR_ZSTR(new_str_key, new_key);
-#if PHP_VERSION_ID < 50300
- zend_hash_update_current_key_ex(&phar->virtual_dirs, key_type, new_key, new_key_len, 0, NULL);
-#else
zend_hash_update_current_key_ex(&phar->virtual_dirs, key_type, new_key, new_key_len, 0, HASH_UPDATE_KEY_ANYWAY, NULL);
-#endif
efree(new_str_key);
}
PHAR_STR_FREE(str_key);
}
for (zend_hash_internal_pointer_reset(&phar->mounted_dirs);
- HASH_KEY_NON_EXISTANT != (key_type = zend_hash_get_current_key_ex(&phar->mounted_dirs, &key, &key_len, &unused, 0, NULL)) &&
+ HASH_KEY_NON_EXISTENT != (key_type = zend_hash_get_current_key_ex(&phar->mounted_dirs, &key, &key_len, &unused, 0, NULL)) &&
SUCCESS == zend_hash_get_current_data(&phar->mounted_dirs, (void **) &entry);
zend_hash_move_forward(&phar->mounted_dirs)) {
@@ -996,11 +988,7 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, char *url_from, char
new_str_key[new_key_len] = 0;
PHAR_ZSTR(new_str_key, new_key);
-#if PHP_VERSION_ID < 50300
- zend_hash_update_current_key_ex(&phar->mounted_dirs, key_type, new_key, new_key_len, 0, NULL);
-#else
zend_hash_update_current_key_ex(&phar->mounted_dirs, key_type, new_key, new_key_len, 0, HASH_UPDATE_KEY_ANYWAY, NULL);
-#endif
efree(new_str_key);
}
PHAR_STR_FREE(str_key);
diff --git a/ext/phar/tests/create_new_and_modify.phpt b/ext/phar/tests/create_new_and_modify.phpt
index d6c469d9cb..c03576cb2c 100644
--- a/ext/phar/tests/create_new_and_modify.phpt
+++ b/ext/phar/tests/create_new_and_modify.phpt
@@ -21,6 +21,14 @@ $sig1 = $phar->getSignature();
include $pname . '/a.php';
+if (function_exists("opcache_get_status")) {
+ $status = opcache_get_status();
+ if ($status["opcache_enabled"]) {
+ ini_set("opcache.revalidate_freq", "0");
+ sleep(2);
+ }
+}
+
file_put_contents($pname .'/a.php', "modified!\n");
file_put_contents($pname .'/b.php', "another!\n");
diff --git a/ext/phar/tests/delete_in_phar.phpt b/ext/phar/tests/delete_in_phar.phpt
index 4842d27913..d28f136f77 100644
--- a/ext/phar/tests/delete_in_phar.phpt
+++ b/ext/phar/tests/delete_in_phar.phpt
@@ -15,6 +15,15 @@ $files = array();
$files['a.php'] = '<?php echo "This is a\n"; ?>';
$files['b.php'] = '<?php echo "This is b\n"; ?>';
$files['b/c.php'] = '<?php echo "This is b/c\n"; ?>';
+
+if (function_exists("opcache_get_status")) {
+ $status = opcache_get_status();
+ if ($status["opcache_enabled"]) {
+ ini_set("opcache.revalidate_freq", "0");
+ sleep(2);
+ }
+}
+
include 'files/phar_test.inc';
include $pname . '/a.php';
diff --git a/ext/phar/tests/delete_in_phar_confirm.phpt b/ext/phar/tests/delete_in_phar_confirm.phpt
index 13a8d0db29..0d4eb1e2aa 100644
--- a/ext/phar/tests/delete_in_phar_confirm.phpt
+++ b/ext/phar/tests/delete_in_phar_confirm.phpt
@@ -15,6 +15,15 @@ $files = array();
$files['a.php'] = '<?php echo "This is a\n"; ?>';
$files['b.php'] = '<?php echo "This is b\n"; ?>';
$files['b/c.php'] = '<?php echo "This is b/c\n"; ?>';
+
+if (function_exists("opcache_get_status")) {
+ $status = opcache_get_status();
+ if ($status["opcache_enabled"]) {
+ ini_set("opcache.revalidate_freq", "0");
+ sleep(2);
+ }
+}
+
include 'files/phar_test.inc';
include $pname . '/a.php';
diff --git a/ext/phar/tests/phar_commitwrite.phpt b/ext/phar/tests/phar_commitwrite.phpt
index 8e36681338..36d473e5c2 100644
--- a/ext/phar/tests/phar_commitwrite.phpt
+++ b/ext/phar/tests/phar_commitwrite.phpt
@@ -39,4 +39,4 @@ Phar::mapPhar('brandnewphar.phar');
include 'phar://brandnewphar.phar/startup.php';
__HALT_COMPILER(); ?>
"
-===DONE===
+===DONE=== \ No newline at end of file
diff --git a/ext/phar/tests/phar_create_in_cwd.phpt b/ext/phar/tests/phar_create_in_cwd.phpt
index 1828fe745f..4b0e6594fb 100644
--- a/ext/phar/tests/phar_create_in_cwd.phpt
+++ b/ext/phar/tests/phar_create_in_cwd.phpt
@@ -42,4 +42,4 @@ Phar::mapPhar('brandnewphar.phar');
include 'phar://brandnewphar.phar/startup.php';
__HALT_COMPILER(); ?>
"
-===DONE===
+===DONE=== \ No newline at end of file
diff --git a/ext/phar/tests/phar_gobyebye.phpt b/ext/phar/tests/phar_gobyebye.phpt
index 93e153bdf2..608e950768 100644
--- a/ext/phar/tests/phar_gobyebye.phpt
+++ b/ext/phar/tests/phar_gobyebye.phpt
@@ -44,4 +44,4 @@ bool(false)
bool(false)
Warning: opendir(foo/hi): failed to open dir: No such file or directory in phar://%sphar_gobyebye.phar.php/foo/hi on line %d
-===DONE===
+===DONE=== \ No newline at end of file
diff --git a/ext/phar/tests/phar_mount.phpt b/ext/phar/tests/phar_mount.phpt
index 73bd489a2d..80f8cda389 100644
--- a/ext/phar/tests/phar_mount.phpt
+++ b/ext/phar/tests/phar_mount.phpt
@@ -60,4 +60,4 @@ Mounting of testit to %sphar_mount.php within phar %sphar_mount.phar.tar failed
Mounting of /oops to /home/oops/../../etc/passwd: within phar %sphar_mount.phar.php failed
<?php
$fname = dirname(__FILE__) . '/' . basename(
-===DONE===
+===DONE=== \ No newline at end of file
diff --git a/ext/phar/tests/phpinfo_001.phpt b/ext/phar/tests/phpinfo_001.phpt
index 5de74dac0e..d99ccd1803 100644
--- a/ext/phar/tests/phpinfo_001.phpt
+++ b/ext/phar/tests/phpinfo_001.phpt
@@ -26,7 +26,7 @@ phpinfo(INFO_MODULES);
Phar: PHP Archive support => enabled
Phar EXT version => %s
Phar API version => 1.1.1
-SVN revision => %sRevision: %s $
+SVN revision => %sId: %s $
Phar-based phar archives => enabled
Tar-based phar archives => enabled
ZIP-based phar archives => enabled
@@ -48,7 +48,7 @@ Phar
Phar: PHP Archive support => enabled
Phar EXT version => %s
Phar API version => 1.1.1
-SVN revision => %sRevision: %s $
+SVN revision => %sId: %s $
Phar-based phar archives => enabled
Tar-based phar archives => enabled
ZIP-based phar archives => enabled
diff --git a/ext/phar/tests/phpinfo_002.phpt b/ext/phar/tests/phpinfo_002.phpt
index da6db9571b..ef505fedad 100644
--- a/ext/phar/tests/phpinfo_002.phpt
+++ b/ext/phar/tests/phpinfo_002.phpt
@@ -24,7 +24,7 @@ Phar
Phar: PHP Archive support => enabled
Phar EXT version => %s
Phar API version => 1.1.1
-SVN revision => %sRevision: %s $
+SVN revision => %sId: %s $
Phar-based phar archives => enabled
Tar-based phar archives => enabled
ZIP-based phar archives => enabled
diff --git a/ext/phar/tests/phpinfo_004.phpt b/ext/phar/tests/phpinfo_004.phpt
index c49205c147..24263f07be 100644
--- a/ext/phar/tests/phpinfo_004.phpt
+++ b/ext/phar/tests/phpinfo_004.phpt
@@ -29,7 +29,7 @@ phpinfo(INFO_MODULES);
<tr class="h"><th>Phar: PHP Archive support</th><th>enabled</th></tr>
<tr><td class="e">Phar EXT version </td><td class="v">%s </td></tr>
<tr><td class="e">Phar API version </td><td class="v">1.1.1 </td></tr>
-<tr><td class="e">SVN revision </td><td class="v">%sRevision: %s $ </td></tr>
+<tr><td class="e">SVN revision </td><td class="v">%sId: %s $ </td></tr>
<tr><td class="e">Phar-based phar archives </td><td class="v">enabled </td></tr>
<tr><td class="e">Tar-based phar archives </td><td class="v">enabled </td></tr>
<tr><td class="e">ZIP-based phar archives </td><td class="v">enabled </td></tr>
@@ -53,7 +53,7 @@ Phar based on pear/PHP_Archive, original concept by Davey Shafik.<br />Phar full
<tr class="h"><th>Phar: PHP Archive support</th><th>enabled</th></tr>
<tr><td class="e">Phar EXT version </td><td class="v">%s </td></tr>
<tr><td class="e">Phar API version </td><td class="v">1.1.1 </td></tr>
-<tr><td class="e">SVN revision </td><td class="v">%sRevision: %s $ </td></tr>
+<tr><td class="e">SVN revision </td><td class="v">%sId: %s $ </td></tr>
<tr><td class="e">Phar-based phar archives </td><td class="v">enabled </td></tr>
<tr><td class="e">Tar-based phar archives </td><td class="v">enabled </td></tr>
<tr><td class="e">ZIP-based phar archives </td><td class="v">enabled </td></tr>
diff --git a/ext/phar/tests/tar/create_new_and_modify.phpt b/ext/phar/tests/tar/create_new_and_modify.phpt
index 8062fda769..905bfabc82 100644
--- a/ext/phar/tests/tar/create_new_and_modify.phpt
+++ b/ext/phar/tests/tar/create_new_and_modify.phpt
@@ -15,6 +15,14 @@ $pname = 'phar://' . $fname;
file_put_contents($pname . '/a.php', "brand new!\n");
+if (function_exists("opcache_get_status")) {
+ $status = opcache_get_status();
+ if ($status["opcache_enabled"]) {
+ ini_set("opcache.revalidate_freq", "0");
+ sleep(2);
+ }
+}
+
$phar = new Phar($fname);
var_dump($phar->isFileFormat(Phar::TAR));
$sig1 = md5_file($fname);
diff --git a/ext/phar/tests/tar/delete_in_phar.phpt b/ext/phar/tests/tar/delete_in_phar.phpt
index 91ef4a2046..1982b6bda9 100644
--- a/ext/phar/tests/tar/delete_in_phar.phpt
+++ b/ext/phar/tests/tar/delete_in_phar.phpt
@@ -18,6 +18,14 @@ $phar['b/c.php'] = '<?php echo "This is b/c\n"; ?>';
$phar->setStub('<?php __HALT_COMPILER(); ?>');
$phar->stopBuffering();
+if (function_exists("opcache_get_status")) {
+ $status = opcache_get_status();
+ if ($status["opcache_enabled"]) {
+ ini_set("opcache.revalidate_freq", "0");
+ sleep(2);
+ }
+}
+
include $alias . '/a.php';
include $alias . '/b.php';
include $alias . '/b/c.php';
diff --git a/ext/phar/tests/tar/delete_in_phar_confirm.phpt b/ext/phar/tests/tar/delete_in_phar_confirm.phpt
index 707bcbd0ed..7593ebc1fb 100644
--- a/ext/phar/tests/tar/delete_in_phar_confirm.phpt
+++ b/ext/phar/tests/tar/delete_in_phar_confirm.phpt
@@ -18,6 +18,14 @@ $phar['b/c.php'] = '<?php echo "This is b/c\n"; ?>';
$phar->setStub('<?php __HALT_COMPILER(); ?>');
$phar->stopBuffering();
+if (function_exists("opcache_get_status")) {
+ $status = opcache_get_status();
+ if ($status["opcache_enabled"]) {
+ ini_set("opcache.revalidate_freq", "0");
+ sleep(2);
+ }
+}
+
include $alias . '/a.php';
include $alias . '/b.php';
include $alias . '/b/c.php';
diff --git a/ext/phar/tests/zip/create_new_and_modify.phpt b/ext/phar/tests/zip/create_new_and_modify.phpt
index 5a3ec3317b..55d69cca0e 100644
--- a/ext/phar/tests/zip/create_new_and_modify.phpt
+++ b/ext/phar/tests/zip/create_new_and_modify.phpt
@@ -15,6 +15,14 @@ $pname = 'phar://' . $fname;
file_put_contents($pname . '/a.php', "brand new!\n");
+if (function_exists("opcache_get_status")) {
+ $status = opcache_get_status();
+ if ($status["opcache_enabled"]) {
+ ini_set("opcache.revalidate_freq", "0");
+ sleep(2);
+ }
+}
+
$phar = new Phar($fname);
var_dump($phar->isFileFormat(Phar::ZIP));
$sig1 = md5_file($fname);
diff --git a/ext/phar/tests/zip/delete_in_phar.phpt b/ext/phar/tests/zip/delete_in_phar.phpt
index b7bda7ca4b..f01280013f 100644
--- a/ext/phar/tests/zip/delete_in_phar.phpt
+++ b/ext/phar/tests/zip/delete_in_phar.phpt
@@ -18,6 +18,14 @@ $phar['b/c.php'] = '<?php echo "This is b/c\n"; ?>';
$phar->setStub('<?php __HALT_COMPILER(); ?>');
$phar->stopBuffering();
+if (function_exists("opcache_get_status")) {
+ $status = opcache_get_status();
+ if ($status["opcache_enabled"]) {
+ ini_set("opcache.revalidate_freq", "0");
+ sleep(2);
+ }
+}
+
include $alias . '/a.php';
include $alias . '/b.php';
include $alias . '/b/c.php';
diff --git a/ext/phar/tests/zip/delete_in_phar_confirm.phpt b/ext/phar/tests/zip/delete_in_phar_confirm.phpt
index fdd0b42b5c..0080499177 100644
--- a/ext/phar/tests/zip/delete_in_phar_confirm.phpt
+++ b/ext/phar/tests/zip/delete_in_phar_confirm.phpt
@@ -18,6 +18,14 @@ $phar['b/c.php'] = '<?php echo "This is b/c\n"; ?>';
$phar->setStub('<?php __HALT_COMPILER(); ?>');
$phar->stopBuffering();
+if (function_exists("opcache_get_status")) {
+ $status = opcache_get_status();
+ if ($status["opcache_enabled"]) {
+ ini_set("opcache.revalidate_freq", "0");
+ sleep(2);
+ }
+}
+
include $alias . '/a.php';
include $alias . '/b.php';
include $alias . '/b/c.php';
diff --git a/ext/phar/util.c b/ext/phar/util.c
index cd473ad425..d8152cf459 100644
--- a/ext/phar/util.c
+++ b/ext/phar/util.c
@@ -41,10 +41,6 @@
static int phar_call_openssl_signverify(int is_sign, php_stream *fp, off_t end, char *key, int key_len, char **signature, int *signature_len TSRMLS_DC);
#endif
-#if !defined(PHP_VERSION_ID) || PHP_VERSION_ID < 50300
-extern php_stream_wrapper php_stream_phar_wrapper;
-#endif
-
/* for links to relative location, prepend cwd of the entry */
static char *phar_get_link_location(phar_entry_info *entry TSRMLS_DC) /* {{{ */
{
@@ -256,7 +252,6 @@ int phar_mount_entry(phar_archive_data *phar, char *filename, int filename_len,
char *phar_find_in_include_path(char *filename, int filename_len, phar_archive_data **pphar TSRMLS_DC) /* {{{ */
{
-#if PHP_VERSION_ID >= 50300
char *path, *fname, *arch, *entry, *ret, *test;
int arch_len, entry_len, fname_len, ret_len;
phar_archive_data *phar;
@@ -344,223 +339,6 @@ splitted:
}
return ret;
-#else /* PHP 5.2 */
- char resolved_path[MAXPATHLEN];
- char trypath[MAXPATHLEN];
- char *ptr, *end, *path = PG(include_path);
- php_stream_wrapper *wrapper;
- const char *p;
- int n = 0;
- char *fname, *arch, *entry, *ret, *test;
- int arch_len, entry_len;
- phar_archive_data *phar = NULL;
-
- if (!filename) {
- return NULL;
- }
-
- if (!zend_is_executing(TSRMLS_C) || !PHAR_G(cwd)) {
- goto doit;
- }
-
- fname = (char*)zend_get_executed_filename(TSRMLS_C);
-
- if (SUCCESS != phar_split_fname(fname, strlen(fname), &arch, &arch_len, &entry, &entry_len, 1, 0 TSRMLS_CC)) {
- goto doit;
- }
-
- efree(entry);
-
- if (*filename == '.') {
- int try_len;
-
- if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) {
- efree(arch);
- goto doit;
- }
-
- try_len = filename_len;
- test = phar_fix_filepath(estrndup(filename, filename_len), &try_len, 1 TSRMLS_CC);
-
- if (*test == '/') {
- if (zend_hash_exists(&(phar->manifest), test + 1, try_len - 1)) {
- spprintf(&ret, 0, "phar://%s%s", arch, test);
- efree(arch);
- efree(test);
- return ret;
- }
- } else {
- if (zend_hash_exists(&(phar->manifest), test, try_len)) {
- spprintf(&ret, 0, "phar://%s/%s", arch, test);
- efree(arch);
- efree(test);
- return ret;
- }
- }
-
- efree(test);
- }
-
- efree(arch);
-doit:
- if (*filename == '.' || IS_ABSOLUTE_PATH(filename, filename_len) || !path || !*path) {
- if (tsrm_realpath(filename, resolved_path TSRMLS_CC)) {
- return estrdup(resolved_path);
- } else {
- return NULL;
- }
- }
-
- /* test for stream wrappers and return */
- for (p = filename; p - filename < filename_len && (isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'); ++p, ++n);
-
- if (n < filename_len - 3 && (*p == ':') && (!strncmp("//", p+1, 2) || ( filename_len > 4 && !memcmp("data", filename, 4)))) {
- /* found stream wrapper, this is an absolute path until stream wrappers implement realpath */
- return estrndup(filename, filename_len);
- }
-
- ptr = (char *) path;
- while (ptr && *ptr) {
- int len, is_stream_wrapper = 0, maybe_stream = 1;
-
- end = strchr(ptr, DEFAULT_DIR_SEPARATOR);
-#ifndef PHP_WIN32
- /* search for stream wrapper */
- if (end - ptr <= 1) {
- maybe_stream = 0;
- goto not_stream;
- }
-
- for (p = ptr, n = 0; p < end && (isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'); ++p, ++n);
-
- if (n == end - ptr && *p && !strncmp("//", p+1, 2)) {
- is_stream_wrapper = 1;
- /* seek to real end of include_path portion */
- end = strchr(end + 1, DEFAULT_DIR_SEPARATOR);
- } else {
- maybe_stream = 0;
- }
-not_stream:
-#endif
- if (end) {
- if ((end-ptr) + 1 + filename_len + 1 >= MAXPATHLEN) {
- ptr = end + 1;
- continue;
- }
-
- memcpy(trypath, ptr, end-ptr);
- len = end-ptr;
- trypath[end-ptr] = '/';
- memcpy(trypath+(end-ptr)+1, filename, filename_len+1);
- ptr = end+1;
- } else {
- len = strlen(ptr);
-
- if (len + 1 + filename_len + 1 >= MAXPATHLEN) {
- break;
- }
-
- memcpy(trypath, ptr, len);
- trypath[len] = '/';
- memcpy(trypath+len+1, filename, filename_len+1);
- ptr = NULL;
- }
-
- if (!is_stream_wrapper && maybe_stream) {
- /* search for stream wrapper */
- for (p = trypath, n = 0; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; ++p, ++n);
- }
-
- if (is_stream_wrapper || (n < len - 3 && (*p == ':') && (n > 1) && (!strncmp("//", p+1, 2) || !memcmp("data", trypath, 4)))) {
- char *actual;
-
- wrapper = php_stream_locate_url_wrapper(trypath, &actual, STREAM_OPEN_FOR_INCLUDE TSRMLS_CC);
- if (wrapper == &php_plain_files_wrapper) {
- strlcpy(trypath, actual, sizeof(trypath));
- } else if (!wrapper) {
- /* if wrapper is NULL, there was a mal-formed include_path stream wrapper, so skip this ptr */
- continue;
- } else {
- if (wrapper->wops->url_stat) {
- php_stream_statbuf ssb;
-
- if (SUCCESS == wrapper->wops->url_stat(wrapper, trypath, 0, &ssb, NULL TSRMLS_CC)) {
- if (wrapper == &php_stream_phar_wrapper) {
- char *arch, *entry;
- int arch_len, entry_len, ret_len;
-
- ret_len = strlen(trypath);
- /* found phar:// */
-
- if (SUCCESS != phar_split_fname(trypath, ret_len, &arch, &arch_len, &entry, &entry_len, 1, 0 TSRMLS_CC)) {
- return estrndup(trypath, ret_len);
- }
-
- zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **) &pphar);
-
- if (!pphar && PHAR_G(manifest_cached)) {
- zend_hash_find(&cached_phars, arch, arch_len, (void **) &pphar);
- }
-
- efree(arch);
- efree(entry);
-
- return estrndup(trypath, ret_len);
- }
- return estrdup(trypath);
- }
- }
- continue;
- }
- }
-
- if (tsrm_realpath(trypath, resolved_path TSRMLS_CC)) {
- return estrdup(resolved_path);
- }
- } /* end provided path */
-
- /* check in calling scripts' current working directory as a fall back case */
- if (zend_is_executing(TSRMLS_C)) {
- char *exec_fname = (char*)zend_get_executed_filename(TSRMLS_C);
- int exec_fname_length = strlen(exec_fname);
- const char *p;
- int n = 0;
-
- while ((--exec_fname_length >= 0) && !IS_SLASH(exec_fname[exec_fname_length]));
- if (exec_fname && exec_fname[0] != '[' &&
- exec_fname_length > 0 &&
- exec_fname_length + 1 + filename_len + 1 < MAXPATHLEN) {
- memcpy(trypath, exec_fname, exec_fname_length + 1);
- memcpy(trypath+exec_fname_length + 1, filename, filename_len+1);
-
- /* search for stream wrapper */
- for (p = trypath; isalnum((int)*p) || *p == '+' || *p == '-' || *p == '.'; ++p, ++n);
-
- if (n < exec_fname_length - 3 && (*p == ':') && (n > 1) && (!strncmp("//", p+1, 2) || !memcmp("data", trypath, 4))) {
- char *actual;
-
- wrapper = php_stream_locate_url_wrapper(trypath, &actual, STREAM_OPEN_FOR_INCLUDE TSRMLS_CC);
-
- if (wrapper == &php_plain_files_wrapper) {
- /* this should never technically happen, but we'll leave it here for completeness */
- strlcpy(trypath, actual, sizeof(trypath));
- } else if (!wrapper) {
- /* if wrapper is NULL, there was a malformed include_path stream wrapper
- this also should be impossible */
- return NULL;
- } else {
- return estrdup(trypath);
- }
- }
-
- if (tsrm_realpath(trypath, resolved_path TSRMLS_CC)) {
- return estrdup(resolved_path);
- }
- }
- }
-
- return NULL;
-#endif /* PHP 5.2 */
}
/* }}} */
@@ -850,11 +628,6 @@ int phar_open_archive_fp(phar_archive_data *phar TSRMLS_DC) /* {{{ */
if (phar_get_pharfp(phar TSRMLS_CC)) {
return SUCCESS;
}
-#if PHP_API_VERSION < 20100412
- if (PG(safe_mode) && (!php_checkuid(phar->fname, NULL, CHECKUID_ALLOW_ONLY_FILE))) {
- return FAILURE;
- }
-#endif
if (php_check_open_basedir(phar->fname TSRMLS_CC)) {
return FAILURE;
@@ -1031,47 +804,12 @@ int phar_open_entry_fp(phar_entry_info *entry, char **error, int follow_links TS
}
/* }}} */
-#if defined(PHP_VERSION_ID) && PHP_VERSION_ID < 50202
-typedef struct {
- char *data;
- size_t fpos;
- size_t fsize;
- size_t smax;
- int mode;
- php_stream **owner_ptr;
-} php_stream_memory_data;
-#endif
-
int phar_create_writeable_entry(phar_archive_data *phar, phar_entry_info *entry, char **error TSRMLS_DC) /* {{{ */
{
if (entry->fp_type == PHAR_MOD) {
/* already newly created, truncate */
-#if PHP_VERSION_ID >= 50202
php_stream_truncate_set_size(entry->fp, 0);
-#else
- if (php_stream_is(entry->fp, PHP_STREAM_IS_TEMP)) {
- if (php_stream_is(*(php_stream**)entry->fp->abstract, PHP_STREAM_IS_MEMORY)) {
- php_stream *inner = *(php_stream**)entry->fp->abstract;
- php_stream_memory_data *memfp = (php_stream_memory_data*)inner->abstract;
- memfp->fpos = 0;
- memfp->fsize = 0;
- } else if (php_stream_is(*(php_stream**)entry->fp->abstract, PHP_STREAM_IS_STDIO)) {
- php_stream_truncate_set_size(*(php_stream**)entry->fp->abstract, 0);
- } else {
- if (error) {
- spprintf(error, 0, "phar error: file \"%s\" cannot be opened for writing, no truncate support", phar->fname);
- }
- return FAILURE;
- }
- } else if (php_stream_is(entry->fp, PHP_STREAM_IS_STDIO)) {
- php_stream_truncate_set_size(entry->fp, 0);
- } else {
- if (error) {
- spprintf(error, 0, "phar error: file \"%s\" cannot be opened for writing, no truncate support", phar->fname);
- }
- return FAILURE;
- }
-#endif
+
entry->old_flags = entry->flags;
entry->is_modified = 1;
phar->is_modified = 1;
@@ -1185,6 +923,18 @@ phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry,
}
/* }}} */
+PHP_PHAR_API int phar_resolve_alias(char *alias, int alias_len, char **filename, int *filename_len TSRMLS_DC) /* {{{ */ {
+ phar_archive_data **fd_ptr;
+ if (PHAR_GLOBALS->phar_alias_map.arBuckets
+ && SUCCESS == zend_hash_find(&(PHAR_GLOBALS->phar_alias_map), alias, alias_len, (void**)&fd_ptr)) {
+ *filename = (*fd_ptr)->fname;
+ *filename_len = (*fd_ptr)->fname_len;
+ return SUCCESS;
+ }
+ return FAILURE;
+}
+/* }}} */
+
int phar_free_alias(phar_archive_data *phar, char *alias, int alias_len TSRMLS_DC) /* {{{ */
{
if (phar->refcount || phar->is_persistent) {
@@ -1556,7 +1306,7 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, in
zend_hash_internal_pointer_reset(&phar->mounted_dirs);
while (FAILURE != zend_hash_has_more_elements(&phar->mounted_dirs)) {
- if (HASH_KEY_NON_EXISTANT == zend_hash_get_current_key_ex(&phar->mounted_dirs, &key, &keylen, &unused, 0, NULL)) {
+ if (HASH_KEY_NON_EXISTENT == zend_hash_get_current_key_ex(&phar->mounted_dirs, &key, &keylen, &unused, 0, NULL)) {
break;
}
@@ -1677,11 +1427,7 @@ 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);
@@ -1693,11 +1439,7 @@ static int phar_call_openssl_signverify(int is_sign, php_stream *fp, off_t end,
return FAILURE;
}
-#if PHP_VERSION_ID < 50300
- if (FAILURE == zend_fcall_info_init(openssl, &fci, &fcc TSRMLS_CC)) {
-#else
if (FAILURE == zend_fcall_info_init(openssl, 0, &fci, &fcc, NULL, NULL TSRMLS_CC)) {
-#endif
zval_dtor(zdata);
zval_dtor(zsig);
zval_dtor(zkey);
@@ -1711,13 +1453,6 @@ static int phar_call_openssl_signverify(int is_sign, php_stream *fp, off_t end,
fci.param_count = 3;
fci.params = zp;
-#if PHP_VERSION_ID < 50300
- ++(zdata->refcount);
- if (!is_sign) {
- ++(zsig->refcount);
- }
- ++(zkey->refcount);
-#else
Z_ADDREF_P(zdata);
if (is_sign) {
Z_SET_ISREF_P(zsig);
@@ -1725,7 +1460,7 @@ static int phar_call_openssl_signverify(int is_sign, php_stream *fp, off_t end,
Z_ADDREF_P(zsig);
}
Z_ADDREF_P(zkey);
-#endif
+
fci.retval_ptr_ptr = &retval_ptr;
if (FAILURE == zend_call_function(&fci, &fcc TSRMLS_CC)) {
@@ -1742,21 +1477,15 @@ static int phar_call_openssl_signverify(int is_sign, php_stream *fp, off_t end,
zval_dtor(openssl);
efree(openssl);
-#if PHP_VERSION_ID < 50300
- --(zdata->refcount);
- if (!is_sign) {
- --(zsig->refcount);
- }
- --(zkey->refcount);
-#else
Z_DELREF_P(zdata);
+
if (is_sign) {
Z_UNSET_ISREF_P(zsig);
} else {
Z_DELREF_P(zsig);
}
Z_DELREF_P(zkey);
-#endif
+
zval_dtor(zdata);
efree(zdata);
zval_dtor(zkey);
@@ -2282,11 +2011,7 @@ static int phar_update_cached_entry(void *data, void *argument) /* {{{ */
ALLOC_ZVAL(entry->metadata);
*entry->metadata = *t;
zval_copy_ctor(entry->metadata);
-#if PHP_VERSION_ID < 50300
- entry->metadata->refcount = 1;
-#else
Z_SET_REFCOUNT_P(entry->metadata, 1);
-#endif
entry->metadata_str.c = NULL;
entry->metadata_str.len = 0;
}
@@ -2330,11 +2055,7 @@ static void phar_copy_cached_phar(phar_archive_data **pphar TSRMLS_DC) /* {{{ */
ALLOC_ZVAL(phar->metadata);
*phar->metadata = *t;
zval_copy_ctor(phar->metadata);
-#if PHP_VERSION_ID < 50300
- phar->metadata->refcount = 1;
-#else
Z_SET_REFCOUNT_P(phar->metadata, 1);
-#endif
}
}
diff --git a/ext/phar/zip.c b/ext/phar/zip.c
index 79203c8a9b..ba03687315 100644
--- a/ext/phar/zip.c
+++ b/ext/phar/zip.c
@@ -578,10 +578,6 @@ foundit:
/* construct actual offset to file start - local extra_len can be different from central extra_len */
entry.offset = entry.offset_abs =
sizeof(local) + entry.header_offset + PHAR_GET_16(local.filename_len) + PHAR_GET_16(local.extra_len);
-#if PHP_VERSION_ID < 50207
- /* work around Bug #46147 */
- fp->writepos = fp->readpos = 0;
-#endif
php_stream_seek(fp, entry.offset, SEEK_SET);
/* these next lines should be for php < 5.2.6 after 5.3 filters are fixed */
fp->writepos = 0;
@@ -605,9 +601,6 @@ foundit:
if (!(entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0)) || !actual_alias) {
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)");
-#endif
PHAR_ZIP_FAIL("unable to read in alias, truncated");
}
@@ -626,9 +619,6 @@ foundit:
if (!(entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0)) || !actual_alias) {
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)");
-#endif
PHAR_ZIP_FAIL("unable to read in alias, truncated");
}
diff --git a/ext/posix/tests/posix_getgrnam.phpt b/ext/posix/tests/posix_getgrnam.phpt
deleted file mode 100644
index 854db4ac16..0000000000
--- a/ext/posix/tests/posix_getgrnam.phpt
+++ /dev/null
@@ -1,19 +0,0 @@
---TEST--
-posix_getgrnam(): Basic tests
---SKIPIF--
-<?php
-if (!extension_loaded('posix')) die('skip - POSIX extension not loaded');
-if (!function_exists('posix_getgrnam')) die('skip posix_getgrnam() not found');
-?>
---FILE--
-<?php
-
-var_dump(posix_getgrnam(NULL));
-var_dump(posix_getgrnam(1));
-var_dump(posix_getgrnam(''));
-
-?>
---EXPECT--
-bool(false)
-bool(false)
-bool(false)
diff --git a/ext/posix/tests/posix_getgrnam_basic.phpt b/ext/posix/tests/posix_getgrnam_basic.phpt
deleted file mode 100644
index fd5bf23172..0000000000
--- a/ext/posix/tests/posix_getgrnam_basic.phpt
+++ /dev/null
@@ -1,23 +0,0 @@
---TEST--
-posix_getgrnam(): Basic tests
---SKIPIF--
-<?php
-if (!extension_loaded('posix')) die('skip - POSIX extension not loaded');
-if (!function_exists('posix_getgrnam')) die('skip posix_getgrnam() not found');
-?>
---FILE--
-<?php
-echo "Basic test of POSIX posix_getgrnam function\n";
-
-var_dump(posix_getgrnam(NULL));
-var_dump(posix_getgrnam(1));
-var_dump(posix_getgrnam(''));
-
-?>
-===DONE===
---EXPECT--
-Basic test of POSIX posix_getgrnam function
-bool(false)
-bool(false)
-bool(false)
-===DONE=== \ No newline at end of file
diff --git a/ext/posix/tests/posix_getpwnam.phpt b/ext/posix/tests/posix_getpwnam.phpt
deleted file mode 100644
index b5de1e4ce2..0000000000
--- a/ext/posix/tests/posix_getpwnam.phpt
+++ /dev/null
@@ -1,19 +0,0 @@
---TEST--
-posix_getpwnam(): Basic tests
---SKIPIF--
-<?php
-if (!extension_loaded('posix')) die('skip - POSIX extension not loaded');
-if (!function_exists('posix_getpwnam')) die('skip posix_getpwnam() not found');
-?>
---FILE--
-<?php
-
-var_dump(posix_getpwnam(1));
-var_dump(posix_getpwnam(''));
-var_dump(posix_getpwnam(NULL));
-
-?>
---EXPECT--
-bool(false)
-bool(false)
-bool(false)
diff --git a/ext/posix/tests/posix_getpwnam_basic.phpt b/ext/posix/tests/posix_getpwnam_basic.phpt
deleted file mode 100644
index d675d6c182..0000000000
--- a/ext/posix/tests/posix_getpwnam_basic.phpt
+++ /dev/null
@@ -1,23 +0,0 @@
---TEST--
-posix_getpwnam(): Basic tests
---SKIPIF--
-<?php
-if (!extension_loaded('posix')) die('skip - POSIX extension not loaded');
-if (!function_exists('posix_getpwnam')) die('skip posix_getpwnam() not found');
-?>
---FILE--
-<?php
-echo "Basic test of POSIX posix_getpwnam function\n";
-
-var_dump(posix_getpwnam(1));
-var_dump(posix_getpwnam(''));
-var_dump(posix_getpwnam(NULL));
-
-?>
-===DONE====
---EXPECT--
-Basic test of POSIX posix_getpwnam function
-bool(false)
-bool(false)
-bool(false)
-===DONE====
diff --git a/ext/pspell/config.m4 b/ext/pspell/config.m4
index 67e5b27605..481a9ae891 100644
--- a/ext/pspell/config.m4
+++ b/ext/pspell/config.m4
@@ -3,7 +3,7 @@ dnl $Id$
dnl
PHP_ARG_WITH(pspell,for PSPELL support,
-[ --with-pspell[=DIR] Include PSPELL support.
+[ --with-pspell[=DIR] Include PSPELL support.
GNU Aspell version 0.50.0 or higher required])
if test "$PHP_PSPELL" != "no"; then
diff --git a/ext/readline/config.m4 b/ext/readline/config.m4
index b1cb0b67e8..0a00370fce 100644
--- a/ext/readline/config.m4
+++ b/ext/readline/config.m4
@@ -3,11 +3,11 @@ dnl $Id$
dnl
PHP_ARG_WITH(libedit,for libedit readline replacement,
-[ --with-libedit[=DIR] Include libedit readline replacement (CLI/CGI only)])
+[ --with-libedit[=DIR] Include libedit readline replacement (CLI/CGI only)])
if test "$PHP_LIBEDIT" = "no"; then
PHP_ARG_WITH(readline,for readline support,
- [ --with-readline[=DIR] Include readline support (CLI/CGI only)])
+ [ --with-readline[=DIR] Include readline support (CLI/CGI only)])
else
dnl "register" the --with-readline option to preven invalid "unknown configure option" warning
php_with_readline=no
diff --git a/ext/readline/readline.c b/ext/readline/readline.c
index 14859a96bb..ecd5533350 100644
--- a/ext/readline/readline.c
+++ b/ext/readline/readline.c
@@ -170,7 +170,10 @@ ZEND_GET_MODULE(readline)
PHP_MINIT_FUNCTION(readline)
{
- using_history();
+#if HAVE_LIBREADLINE
+ /* libedit don't need this call which set the tty in cooked mode */
+ using_history();
+#endif
return PHP_MINIT(cli_readline)(INIT_FUNC_ARGS_PASSTHRU);
}
diff --git a/ext/recode/config.m4 b/ext/recode/config.m4
index 8df4cfc41a..7f394d0465 100644
--- a/ext/recode/config.m4
+++ b/ext/recode/config.m4
@@ -3,7 +3,7 @@ dnl $Id$
dnl
PHP_ARG_WITH(recode,for recode support,
-[ --with-recode[=DIR] Include recode support])
+[ --with-recode[=DIR] Include recode support])
if test "$PHP_RECODE" != "no"; then
RECODE_LIST="$PHP_RECODE /usr/local /usr /opt"
diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c
index f6367cdb4e..31d836a7ac 100644
--- a/ext/reflection/php_reflection.c
+++ b/ext/reflection/php_reflection.c
@@ -3084,6 +3084,14 @@ ZEND_METHOD(reflection_function, isDeprecated)
}
/* }}} */
+/* {{{ proto public bool ReflectionFunction::isGenerator()
+ Returns whether this function is a generator */
+ZEND_METHOD(reflection_function, isGenerator)
+{
+ _function_check_flag(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_GENERATOR);
+}
+/* }}} */
+
/* {{{ proto public bool ReflectionFunction::inNamespace()
Returns whether this function is defined in namespace */
ZEND_METHOD(reflection_function, inNamespace)
@@ -4182,32 +4190,40 @@ ZEND_METHOD(reflection_class, newInstance)
{
zval *retval_ptr = NULL;
reflection_object *intern;
- zend_class_entry *ce;
+ zend_class_entry *ce, *old_scope;
+ zend_function *constructor;
METHOD_NOTSTATIC(reflection_class_ptr);
GET_REFLECTION_OBJECT_PTR(ce);
+ object_init_ex(return_value, ce);
+
+ old_scope = EG(scope);
+ EG(scope) = ce;
+ constructor = Z_OBJ_HT_P(return_value)->get_constructor(return_value TSRMLS_CC);
+ EG(scope) = old_scope;
+
/* Run the constructor if there is one */
- if (ce->constructor) {
+ if (constructor) {
zval ***params = NULL;
int num_args = 0;
zend_fcall_info fci;
zend_fcall_info_cache fcc;
- if (!(ce->constructor->common.fn_flags & ZEND_ACC_PUBLIC)) {
+ if (!(constructor->common.fn_flags & ZEND_ACC_PUBLIC)) {
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Access to non-public constructor of class %s", ce->name);
- return;
+ zval_dtor(return_value);
+ RETURN_NULL();
}
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "*", &params, &num_args) == FAILURE) {
if (params) {
efree(params);
}
+ zval_dtor(return_value);
RETURN_FALSE;
}
- object_init_ex(return_value, ce);
-
fci.size = sizeof(fci);
fci.function_table = EG(function_table);
fci.function_name = NULL;
@@ -4219,7 +4235,7 @@ ZEND_METHOD(reflection_class, newInstance)
fci.no_separation = 1;
fcc.initialized = 1;
- fcc.function_handler = ce->constructor;
+ fcc.function_handler = constructor;
fcc.calling_scope = EG(scope);
fcc.called_scope = Z_OBJCE_P(return_value);
fcc.object_ptr = return_value;
@@ -4232,6 +4248,7 @@ ZEND_METHOD(reflection_class, newInstance)
zval_ptr_dtor(&retval_ptr);
}
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invocation of %s's constructor failed", ce->name);
+ zval_dtor(return_value);
RETURN_NULL();
}
if (retval_ptr) {
@@ -4240,9 +4257,7 @@ ZEND_METHOD(reflection_class, newInstance)
if (params) {
efree(params);
}
- } else if (!ZEND_NUM_ARGS()) {
- object_init_ex(return_value, ce);
- } else {
+ } else if (ZEND_NUM_ARGS()) {
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Class %s does not have a constructor, so you cannot pass any constructor arguments", ce->name);
}
}
@@ -4272,9 +4287,10 @@ ZEND_METHOD(reflection_class, newInstanceArgs)
{
zval *retval_ptr = NULL;
reflection_object *intern;
- zend_class_entry *ce;
+ zend_class_entry *ce, *old_scope;
int argc = 0;
HashTable *args;
+ zend_function *constructor;
METHOD_NOTSTATIC(reflection_class_ptr);
@@ -4283,19 +4299,28 @@ ZEND_METHOD(reflection_class, newInstanceArgs)
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|h", &args) == FAILURE) {
return;
}
+
if (ZEND_NUM_ARGS() > 0) {
argc = args->nNumOfElements;
}
+ object_init_ex(return_value, ce);
+
+ old_scope = EG(scope);
+ EG(scope) = ce;
+ constructor = Z_OBJ_HT_P(return_value)->get_constructor(return_value TSRMLS_CC);
+ EG(scope) = old_scope;
+
/* Run the constructor if there is one */
- if (ce->constructor) {
+ if (constructor) {
zval ***params = NULL;
zend_fcall_info fci;
zend_fcall_info_cache fcc;
- if (!(ce->constructor->common.fn_flags & ZEND_ACC_PUBLIC)) {
+ if (!(constructor->common.fn_flags & ZEND_ACC_PUBLIC)) {
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Access to non-public constructor of class %s", ce->name);
- return;
+ zval_dtor(return_value);
+ RETURN_NULL();
}
if (argc) {
@@ -4304,8 +4329,6 @@ ZEND_METHOD(reflection_class, newInstanceArgs)
params -= argc;
}
- object_init_ex(return_value, ce);
-
fci.size = sizeof(fci);
fci.function_table = EG(function_table);
fci.function_name = NULL;
@@ -4317,7 +4340,7 @@ ZEND_METHOD(reflection_class, newInstanceArgs)
fci.no_separation = 1;
fcc.initialized = 1;
- fcc.function_handler = ce->constructor;
+ fcc.function_handler = constructor;
fcc.calling_scope = EG(scope);
fcc.called_scope = Z_OBJCE_P(return_value);
fcc.object_ptr = return_value;
@@ -4330,6 +4353,7 @@ ZEND_METHOD(reflection_class, newInstanceArgs)
zval_ptr_dtor(&retval_ptr);
}
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invocation of %s's constructor failed", ce->name);
+ zval_dtor(return_value);
RETURN_NULL();
}
if (retval_ptr) {
@@ -4338,9 +4362,7 @@ ZEND_METHOD(reflection_class, newInstanceArgs)
if (params) {
efree(params);
}
- } else if (!ZEND_NUM_ARGS() || !argc) {
- object_init_ex(return_value, ce);
- } else {
+ } else if (argc) {
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Class %s does not have a constructor, so you cannot pass any constructor arguments", ce->name);
}
}
@@ -5683,6 +5705,7 @@ static const zend_function_entry reflection_function_abstract_functions[] = {
ZEND_ME(reflection_function, isDeprecated, arginfo_reflection__void, 0)
ZEND_ME(reflection_function, isInternal, arginfo_reflection__void, 0)
ZEND_ME(reflection_function, isUserDefined, arginfo_reflection__void, 0)
+ ZEND_ME(reflection_function, isGenerator, arginfo_reflection__void, 0)
ZEND_ME(reflection_function, getClosureThis, arginfo_reflection__void, 0)
ZEND_ME(reflection_function, getClosureScopeClass, arginfo_reflection__void, 0)
ZEND_ME(reflection_function, getDocComment, arginfo_reflection__void, 0)
diff --git a/ext/reflection/tests/005.phpt b/ext/reflection/tests/005.phpt
index f337e44ae6..e257699b6f 100644
--- a/ext/reflection/tests/005.phpt
+++ b/ext/reflection/tests/005.phpt
@@ -1,5 +1,8 @@
--TEST--
ReflectionMethod::getDocComment() uses wrong comment block
+--INI--
+opcache.save_comments=1
+opcache.load_comments=1
--FILE--
<?php
diff --git a/ext/reflection/tests/009.phpt b/ext/reflection/tests/009.phpt
index e96b21ebaf..b54e89e5bf 100644
--- a/ext/reflection/tests/009.phpt
+++ b/ext/reflection/tests/009.phpt
@@ -1,5 +1,8 @@
--TEST--
ReflectionFunction basic tests
+--INI--
+opcache.save_comments=1
+opcache.load_comments=1
--FILE--
<?php
diff --git a/ext/reflection/tests/025.phpt b/ext/reflection/tests/025.phpt
index a5f604f56d..92002007b6 100644
--- a/ext/reflection/tests/025.phpt
+++ b/ext/reflection/tests/025.phpt
@@ -2,6 +2,9 @@
ReflectionFunction basic tests
--SKIPIF--
<?php extension_loaded('reflection') or die('skip'); ?>
+--INI--
+opcache.save_comments=1
+opcache.load_comments=1
--FILE--
<?php
diff --git a/ext/reflection/tests/ReflectionClass_getDocComment_001.phpt b/ext/reflection/tests/ReflectionClass_getDocComment_001.phpt
index 5feb560ae1..efa7e9a10a 100644
--- a/ext/reflection/tests/ReflectionClass_getDocComment_001.phpt
+++ b/ext/reflection/tests/ReflectionClass_getDocComment_001.phpt
@@ -3,6 +3,9 @@ ReflectionClass::getDocComment()
--CREDITS--
Robin Fernandes <robinf@php.net>
Steve Seear <stevseea@php.net>
+--INI--
+opcache.save_comments=1
+opcache.load_comments=1
--FILE--
<?php
/**
diff --git a/ext/reflection/tests/ReflectionFunction_getDocComment.001.phpt b/ext/reflection/tests/ReflectionFunction_getDocComment.001.phpt
index 38c278d8a3..68d1d9d3a1 100644
--- a/ext/reflection/tests/ReflectionFunction_getDocComment.001.phpt
+++ b/ext/reflection/tests/ReflectionFunction_getDocComment.001.phpt
@@ -3,6 +3,9 @@ ReflectionFunction::getDocComment()
--CREDITS--
Robin Fernandes <robinf@php.net>
Steve Seear <stevseea@php.net>
+--INI--
+opcache.save_comments=1
+opcache.load_comments=1
--FILE--
<?php
diff --git a/ext/reflection/tests/ReflectionFunction_isGenerator_basic.phpt b/ext/reflection/tests/ReflectionFunction_isGenerator_basic.phpt
new file mode 100644
index 0000000000..c4889b12bc
--- /dev/null
+++ b/ext/reflection/tests/ReflectionFunction_isGenerator_basic.phpt
@@ -0,0 +1,52 @@
+--TEST--
+ReflectionFunction::isGenerator()
+--FILE--
+<?php
+
+$closure1 = function() {return "this is a closure"; };
+$closure2 = function($param) {
+ yield $param;
+};
+
+$rf1 = new ReflectionFunction($closure1);
+var_dump($rf1->isGenerator());
+
+$rf2 = new ReflectionFunction($closure2);
+var_dump($rf2->isGenerator());
+
+function func1() {
+ return 'func1';
+}
+
+function func2() {
+ yield 'func2';
+}
+
+$rf1 = new ReflectionFunction('func1');
+var_dump($rf1->isGenerator());
+
+$rf2 = new ReflectionFunction('func2');
+var_dump($rf2->isGenerator());
+
+
+class Foo {
+ public function f1() {
+ }
+
+ public function f2() {
+ yield;
+ }
+}
+
+$rc = new ReflectionClass('Foo');
+foreach($rc->getMethods() as $m) {
+ var_dump($m->isGenerator());
+}
+?>
+--EXPECTF--
+bool(false)
+bool(true)
+bool(false)
+bool(true)
+bool(false)
+bool(true)
diff --git a/ext/reflection/tests/ReflectionMethod_getDocComment_basic.phpt b/ext/reflection/tests/ReflectionMethod_getDocComment_basic.phpt
index c01f689cf4..b04fb6c9fc 100644
--- a/ext/reflection/tests/ReflectionMethod_getDocComment_basic.phpt
+++ b/ext/reflection/tests/ReflectionMethod_getDocComment_basic.phpt
@@ -1,5 +1,8 @@
--TEST--
ReflectionMethod::getDocComment()
+--INI--
+opcache.save_comments=1
+opcache.load_comments=1
--FILE--
<?php
/**
diff --git a/ext/reflection/tests/ReflectionProperty_basic2.phpt b/ext/reflection/tests/ReflectionProperty_basic2.phpt
index b7b21333d3..bc42d3f828 100644
--- a/ext/reflection/tests/ReflectionProperty_basic2.phpt
+++ b/ext/reflection/tests/ReflectionProperty_basic2.phpt
@@ -1,5 +1,8 @@
--TEST--
Test usage of ReflectionProperty methods isDefault(), getModifiers(), getDeclaringClass() and getDocComment().
+--INI--
+opcache.save_comments=1
+opcache.load_comments=1
--FILE--
<?php
diff --git a/ext/reflection/tests/ReflectionProperty_getDocComment_basic.phpt b/ext/reflection/tests/ReflectionProperty_getDocComment_basic.phpt
index 2c4815a35b..f94ee8ca4c 100644
--- a/ext/reflection/tests/ReflectionProperty_getDocComment_basic.phpt
+++ b/ext/reflection/tests/ReflectionProperty_getDocComment_basic.phpt
@@ -1,5 +1,8 @@
--TEST--
Test ReflectionProperty::getDocComment() usage.
+--INI--
+opcache.save_comments=1
+opcache.load_comments=1
--FILE--
<?php
diff --git a/ext/reflection/tests/bug36308.phpt b/ext/reflection/tests/bug36308.phpt
index 79aa5f8fa1..f923ee31ab 100644
--- a/ext/reflection/tests/bug36308.phpt
+++ b/ext/reflection/tests/bug36308.phpt
@@ -1,5 +1,8 @@
--TEST--
Reflection Bug #36308 (ReflectionProperty::getDocComment() does not reflect extended class commentary)
+--INI--
+opcache.save_comments=1
+opcache.load_comments=1
--FILE--
<?php
class Base {
diff --git a/ext/reflection/tests/bug64007.phpt b/ext/reflection/tests/bug64007.phpt
new file mode 100644
index 0000000000..32ec6a5610
--- /dev/null
+++ b/ext/reflection/tests/bug64007.phpt
@@ -0,0 +1,19 @@
+--TEST--
+Bug #64007 (There is an ability to create instance of Generator by hand)
+--FILE--
+<?php
+$reflection = new ReflectionClass('Generator');
+try {
+ $generator = $reflection->newInstanceWithoutConstructor();
+ var_dump($generator);
+} catch (Exception $e) {
+ var_dump($e->getMessage());
+}
+
+$generator = $reflection->newInstance();
+var_dump($generator);
+?>
+--EXPECTF--
+string(97) "Class Generator is an internal class that cannot be instantiated without invoking its constructor"
+
+Catchable fatal error: The "Generator" class is reserved for internal use and cannot be manually instantiated in %sbug64007.php on line %d
diff --git a/ext/session/mod_files.c b/ext/session/mod_files.c
index 615db85471..4d5a18b36b 100644
--- a/ext/session/mod_files.c
+++ b/ext/session/mod_files.c
@@ -61,40 +61,9 @@ typedef struct {
} ps_files;
ps_module ps_mod_files = {
- PS_MOD(files)
+ PS_MOD_SID(files)
};
-/* If you change the logic here, please also update the error message in
- * ps_files_open() appropriately */
-static int ps_files_valid_key(const char *key)
-{
- size_t len;
- const char *p;
- char c;
- int ret = 1;
-
- for (p = key; (c = *p); p++) {
- /* valid characters are a..z,A..Z,0..9 */
- if (!((c >= 'a' && c <= 'z')
- || (c >= 'A' && c <= 'Z')
- || (c >= '0' && c <= '9')
- || c == ','
- || c == '-')) {
- ret = 0;
- break;
- }
- }
-
- len = p - key;
-
- /* Somewhat arbitrary length limit here, but should be way more than
- anyone needs and avoids file-level warnings later on if we exceed MAX_PATH */
- if (len == 0 || len > 128) {
- ret = 0;
- }
-
- return ret;
-}
static char *ps_files_path_create(char *buf, size_t buflen, ps_files *data, const char *key)
{
@@ -155,11 +124,11 @@ static void ps_files_open(ps_files *data, const char *key TSRMLS_DC)
ps_files_close(data);
- if (!ps_files_valid_key(key)) {
+ if (php_session_valid_key(key) == FAILURE) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "The session id is too long or contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,'");
- PS(invalid_session_id) = 1;
return;
}
+
if (!ps_files_path_create(buf, sizeof(buf), data, key)) {
return;
}
@@ -253,6 +222,21 @@ static int ps_files_cleanup_dir(const char *dirname, int maxlifetime TSRMLS_DC)
return (nrdels);
}
+static int ps_files_key_exists(ps_files *data, const char *key TSRMLS_DC)
+{
+ char buf[MAXPATHLEN];
+ struct stat sbuf;
+
+ if (!key || !ps_files_path_create(buf, sizeof(buf), data, key)) {
+ return FAILURE;
+ }
+ if (VCWD_STAT(buf, &sbuf)) {
+ return FAILURE;
+ }
+ return SUCCESS;
+}
+
+
#define PS_FILES_DATA ps_files *data = PS_GET_MOD_DATA()
PS_OPEN_FUNC(files)
@@ -266,7 +250,7 @@ PS_OPEN_FUNC(files)
if (*save_path == '\0') {
/* if save path is an empty string, determine the temporary dir */
- save_path = php_get_temporary_directory();
+ save_path = php_get_temporary_directory(TSRMLS_C);
if (php_check_open_basedir(save_path TSRMLS_CC)) {
return FAILURE;
@@ -342,7 +326,26 @@ PS_READ_FUNC(files)
struct stat sbuf;
PS_FILES_DATA;
- ps_files_open(data, key TSRMLS_CC);
+ /* If strict mode, check session id existence */
+ if (PS(use_strict_mode) &&
+ ps_files_key_exists(data, key TSRMLS_CC) == FAILURE) {
+ /* key points to PS(id), but cannot change here. */
+ if (key) {
+ efree(PS(id));
+ PS(id) = NULL;
+ }
+ PS(id) = PS(mod)->s_create_sid((void **)&data, NULL TSRMLS_CC);
+ if (!PS(id)) {
+ return FAILURE;
+ }
+ if (PS(use_cookies)) {
+ PS(send_cookie) = 1;
+ }
+ php_session_reset_id(TSRMLS_C);
+ PS(session_status) = php_session_active;
+ }
+
+ ps_files_open(data, PS(id) TSRMLS_CC);
if (data->fd < 0) {
return FAILURE;
}
@@ -454,6 +457,30 @@ PS_GC_FUNC(files)
return SUCCESS;
}
+PS_CREATE_SID_FUNC(files)
+{
+ char *sid;
+ int maxfail = 3;
+ PS_FILES_DATA;
+
+ do {
+ sid = php_session_create_id((void **)&data, newlen TSRMLS_CC);
+ /* Check collision */
+ if (data && ps_files_key_exists(data, sid TSRMLS_CC) == SUCCESS) {
+ if (sid) {
+ efree(sid);
+ sid = NULL;
+ }
+ if (!(maxfail--)) {
+ return NULL;
+ }
+ }
+ } while(!sid);
+
+ return sid;
+}
+
+
/*
* Local variables:
* tab-width: 4
diff --git a/ext/session/mod_files.h b/ext/session/mod_files.h
index 80493212af..d1d26cd39b 100644
--- a/ext/session/mod_files.h
+++ b/ext/session/mod_files.h
@@ -24,6 +24,6 @@
extern ps_module ps_mod_files;
#define ps_files_ptr &ps_mod_files
-PS_FUNCS(files);
+PS_FUNCS_SID(files);
#endif
diff --git a/ext/session/mod_mm.c b/ext/session/mod_mm.c
index 01b4345ed3..319f1d3c79 100644
--- a/ext/session/mod_mm.c
+++ b/ext/session/mod_mm.c
@@ -124,7 +124,7 @@ static ps_sd *ps_sd_new(ps_mm *data, const char *key)
if (!sd) {
TSRMLS_FETCH();
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "mm_malloc failed, avail %d, err %s", mm_available(data->mm), mm_error());
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "mm_malloc failed, avail %ld, err %s", mm_available(data->mm), mm_error());
return NULL;
}
@@ -208,8 +208,22 @@ static ps_sd *ps_sd_lookup(ps_mm *data, const char *key, int rw)
return ret;
}
+static int ps_mm_key_exists(ps_mm *data, const char *key TSRMLS_DC)
+{
+ ps_sd *sd;
+
+ if (!key) {
+ return FAILURE;
+ }
+ sd = ps_sd_lookup(data, key, 0);
+ if (sd) {
+ return SUCCESS;
+ }
+ return FAILURE;
+}
+
ps_module ps_mod_mm = {
- PS_MOD(mm)
+ PS_MOD_SID(mm)
};
#define PS_MM_DATA ps_mm *data = PS_GET_MOD_DATA()
@@ -341,7 +355,26 @@ PS_READ_FUNC(mm)
mm_lock(data->mm, MM_LOCK_RD);
- sd = ps_sd_lookup(data, key, 0);
+ /* If there is an ID and strict mode, verify existence */
+ if (PS(use_strict_mode)
+ && ps_mm_key_exists(data, key TSRMLS_CC) == FAILURE) {
+ /* key points to PS(id), but cannot change here. */
+ if (key) {
+ efree(PS(id));
+ PS(id) = NULL;
+ }
+ PS(id) = PS(mod)->s_create_sid((void **)&data, NULL TSRMLS_CC);
+ if (!PS(id)) {
+ return FAILURE;
+ }
+ if (PS(use_cookies)) {
+ PS(send_cookie) = 1;
+ }
+ php_session_reset_id(TSRMLS_C);
+ PS(session_status) = php_session_active;
+ }
+
+ sd = ps_sd_lookup(data, PS(id), 0);
if (sd) {
*vallen = sd->datalen;
*val = emalloc(sd->datalen + 1);
@@ -444,6 +477,29 @@ PS_GC_FUNC(mm)
return SUCCESS;
}
+PS_CREATE_SID_FUNC(mm)
+{
+ char *sid;
+ int maxfail = 3;
+ PS_MM_DATA;
+
+ do {
+ sid = php_session_create_id((void **)&data, newlen TSRMLS_CC);
+ /* Check collision */
+ if (ps_mm_key_exists(data, sid TSRMLS_CC) == SUCCESS) {
+ if (sid) {
+ efree(sid);
+ sid = NULL;
+ }
+ if (!(maxfail--)) {
+ return NULL;
+ }
+ }
+ } while(!sid);
+
+ return sid;
+}
+
#endif
/*
diff --git a/ext/session/mod_user.c b/ext/session/mod_user.c
index 33d403c617..5573d4cdfd 100644
--- a/ext/session/mod_user.c
+++ b/ext/session/mod_user.c
@@ -23,7 +23,7 @@
#include "mod_user.h"
ps_module ps_mod_user = {
- PS_MOD(user)
+ PS_MOD_SID(user)
};
#define SESS_ZVAL_LONG(val, a) \
@@ -183,6 +183,38 @@ PS_GC_FUNC(user)
FINISH;
}
+PS_CREATE_SID_FUNC(user)
+{
+ /* maintain backwards compatibility */
+ if (PSF(create_sid) != NULL) {
+ char *id = NULL;
+ zval *retval = NULL;
+
+ retval = ps_call_handler(PSF(create_sid), 0, NULL TSRMLS_CC);
+
+ if (retval) {
+ if (Z_TYPE_P(retval) == IS_STRING) {
+ id = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
+ }
+ zval_ptr_dtor(&retval);
+ }
+ else {
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "No session id returned by function");
+ return NULL;
+ }
+
+ if (!id) {
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "Session id must be a string");
+ return NULL;
+ }
+
+ return id;
+ }
+
+ /* function as defined by PS_MOD */
+ return php_session_create_id(mod_data, newlen TSRMLS_CC);
+}
+
/*
* Local variables:
* tab-width: 4
diff --git a/ext/session/mod_user.h b/ext/session/mod_user.h
index dd37d8f9f5..b1f3688a25 100644
--- a/ext/session/mod_user.h
+++ b/ext/session/mod_user.h
@@ -24,6 +24,6 @@
extern ps_module ps_mod_user;
#define ps_user_ptr &ps_mod_user
-PS_FUNCS(user);
+PS_FUNCS_SID(user);
#endif
diff --git a/ext/session/mod_user_class.c b/ext/session/mod_user_class.c
index 718b92a690..3b6687741e 100644
--- a/ext/session/mod_user_class.c
+++ b/ext/session/mod_user_class.c
@@ -141,3 +141,19 @@ PHP_METHOD(SessionHandler, gc)
RETVAL_BOOL(SUCCESS == PS(default_mod)->s_gc(&PS(mod_data), maxlifetime, &nrdels TSRMLS_CC));
}
/* }}} */
+
+/* {{{ proto char SessionHandler::create_sid()
+ Wraps the old create_sid handler */
+PHP_METHOD(SessionHandler, create_sid)
+{
+ char *id;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ id = PS(default_mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC);
+
+ RETURN_STRING(id, 0);
+}
+/* }}} */
diff --git a/ext/session/php_session.h b/ext/session/php_session.h
index a9f11f6310..d4de7a5c80 100644
--- a/ext/session/php_session.h
+++ b/ext/session/php_session.h
@@ -29,6 +29,9 @@
#define PHP_SESSION_API 20020330
+/* To check php_session_valid_key()/php_session_reset_id() */
+#define PHP_SESSION_STRICT 1
+
#define PS_OPEN_ARGS void **mod_data, const char *save_path, const char *session_name TSRMLS_DC
#define PS_CLOSE_ARGS void **mod_data TSRMLS_DC
#define PS_READ_ARGS void **mod_data, const char *key, char **val, int *vallen TSRMLS_DC
@@ -75,7 +78,7 @@ typedef struct ps_module_struct {
#x, ps_open_##x, ps_close_##x, ps_read_##x, ps_write_##x, \
ps_delete_##x, ps_gc_##x, php_session_create_id
-/* SID enabled module handler definitions */
+/* SID creation enabled module handler definitions */
#define PS_FUNCS_SID(x) \
PS_OPEN_FUNC(x); \
PS_CLOSE_FUNC(x); \
@@ -138,7 +141,7 @@ typedef struct _php_ps_globals {
int module_number;
long cache_expire;
union {
- zval *names[6];
+ zval *names[7];
struct {
zval *ps_open;
zval *ps_close;
@@ -146,6 +149,7 @@ typedef struct _php_ps_globals {
zval *ps_write;
zval *ps_destroy;
zval *ps_gc;
+ zval *ps_create_sid;
} name;
} mod_user_names;
int mod_user_implemented;
@@ -174,6 +178,8 @@ typedef struct _php_ps_globals {
smart_str rfc1867_name; /* session.upload_progress.name */
long rfc1867_freq; /* session.upload_progress.freq */
double rfc1867_min_freq; /* session.upload_progress.min_freq */
+
+ zend_bool use_strict_mode; /* whether or not PHP accepts unknown session ids */
} php_ps_globals;
typedef php_ps_globals zend_ps_globals;
@@ -229,6 +235,9 @@ PHPAPI void php_session_start(TSRMLS_D);
PHPAPI ps_module *_php_find_ps_module(char *name TSRMLS_DC);
PHPAPI const ps_serializer *_php_find_ps_serializer(char *name TSRMLS_DC);
+PHPAPI int php_session_valid_key(const char *key);
+PHPAPI void php_session_reset_id(TSRMLS_D);
+
#define PS_ADD_VARL(name,namelen) do { \
php_add_session_var(name, namelen TSRMLS_CC); \
} while (0)
@@ -253,7 +262,7 @@ PHPAPI const ps_serializer *_php_find_ps_serializer(char *name TSRMLS_DC);
int key_type; \
\
for (zend_hash_internal_pointer_reset(_ht); \
- (key_type = zend_hash_get_current_key_ex(_ht, &key, &key_length, &num_key, 0, NULL)) != HASH_KEY_NON_EXISTANT; \
+ (key_type = zend_hash_get_current_key_ex(_ht, &key, &key_length, &num_key, 0, NULL)) != HASH_KEY_NON_EXISTENT; \
zend_hash_move_forward(_ht)) { \
if (key_type == HASH_KEY_IS_LONG) { \
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Skipping numeric key %ld", num_key); \
@@ -277,11 +286,15 @@ extern zend_class_entry *php_session_class_entry;
#define PS_IFACE_NAME "SessionHandlerInterface"
extern zend_class_entry *php_session_iface_entry;
+#define PS_SID_IFACE_NAME "SessionIdInterface"
+extern zend_class_entry *php_session_id_iface_entry;
+
extern PHP_METHOD(SessionHandler, open);
extern PHP_METHOD(SessionHandler, close);
extern PHP_METHOD(SessionHandler, read);
extern PHP_METHOD(SessionHandler, write);
extern PHP_METHOD(SessionHandler, destroy);
extern PHP_METHOD(SessionHandler, gc);
+extern PHP_METHOD(SessionHandler, create_sid);
#endif
diff --git a/ext/session/session.c b/ext/session/session.c
index 5b03d6362e..90d6ba7447 100644
--- a/ext/session/session.c
+++ b/ext/session/session.c
@@ -70,6 +70,9 @@ zend_class_entry *php_session_class_entry;
/* SessionHandlerInterface */
zend_class_entry *php_session_iface_entry;
+/* SessionIdInterface */
+zend_class_entry *php_session_id_iface_entry;
+
/* ***********
* Helpers *
*********** */
@@ -83,6 +86,8 @@ zend_class_entry *php_session_iface_entry;
return FAILURE; \
}
+static void php_session_send_cookie(TSRMLS_D);
+
/* Dispatched by RINIT and by php_session_destroy */
static inline void php_rinit_session_globals(TSRMLS_D) /* {{{ */
{
@@ -123,7 +128,7 @@ static int php_session_destroy(TSRMLS_D) /* {{{ */
return FAILURE;
}
- if (PS(mod)->s_destroy(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) {
+ if (PS(id) && PS(mod)->s_destroy(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) {
retval = FAILURE;
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Session object destruction failed");
}
@@ -425,17 +430,45 @@ PHPAPI char *php_session_create_id(PS_CREATE_SID_ARGS) /* {{{ */
}
/* }}} */
-static void php_session_initialize(TSRMLS_D) /* {{{ */
+/* Default session id char validation function allowed by ps_modules.
+ * If you change the logic here, please also update the error message in
+ * ps_modules appropriately */
+PHPAPI int php_session_valid_key(const char *key) /* {{{ */
{
- char *val;
- int vallen;
+ size_t len;
+ const char *p;
+ char c;
+ int ret = SUCCESS;
+
+ for (p = key; (c = *p); p++) {
+ /* valid characters are a..z,A..Z,0..9 */
+ if (!((c >= 'a' && c <= 'z')
+ || (c >= 'A' && c <= 'Z')
+ || (c >= '0' && c <= '9')
+ || c == ','
+ || c == '-')) {
+ ret = FAILURE;
+ break;
+ }
+ }
- /* check session name for invalid characters */
- if (PS(id) && strpbrk(PS(id), "\r\n\t <>'\"\\")) {
- efree(PS(id));
- PS(id) = NULL;
+ len = p - key;
+
+ /* Somewhat arbitrary length limit here, but should be way more than
+ anyone needs and avoids file-level warnings later on if we exceed MAX_PATH */
+ if (len == 0 || len > 128) {
+ ret = FAILURE;
}
+ return ret;
+}
+/* }}} */
+
+static void php_session_initialize(TSRMLS_D) /* {{{ */
+{
+ char *val = NULL;
+ int vallen;
+
if (!PS(mod)) {
php_error_docref(NULL TSRMLS_CC, E_ERROR, "No storage module chosen - failed to initialize session");
return;
@@ -449,28 +482,46 @@ static void php_session_initialize(TSRMLS_D) /* {{{ */
/* If there is no ID, use session module to create one */
if (!PS(id)) {
-new_session:
PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC);
+ if (!PS(id)) {
+ php_error_docref(NULL TSRMLS_CC, E_ERROR, "Failed to create session ID: %s (path: %s)", PS(mod)->s_name, PS(save_path));
+ return;
+ }
if (PS(use_cookies)) {
PS(send_cookie) = 1;
}
}
+ /* Set session ID for compatibility for older/3rd party save handlers */
+ if (!PS(use_strict_mode)) {
+ php_session_reset_id(TSRMLS_C);
+ PS(session_status) = php_session_active;
+ }
+
/* Read data */
- /* Question: if you create a SID here, should you also try to read data?
- * I'm not sure, but while not doing so will remove one session operation
- * it could prove usefull for those sites which wish to have "default"
- * session information. */
php_session_track_init(TSRMLS_C);
- PS(invalid_session_id) = 0;
- if (PS(mod)->s_read(&PS(mod_data), PS(id), &val, &vallen TSRMLS_CC) == SUCCESS) {
+ if (PS(mod)->s_read(&PS(mod_data), PS(id), &val, &vallen TSRMLS_CC) == FAILURE) {
+ /* Some broken save handler implementation returns FAILURE for non-existent session ID */
+ /* It's better to raise error for this, but disabled error for better compatibility */
+ /*
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Failed to read session data: %s (path: %s)", PS(mod)->s_name, PS(save_path));
+ */
+ }
+ /* Set session ID if session read didn't activated session */
+ if (PS(use_strict_mode) && PS(session_status) != php_session_active) {
+ php_session_reset_id(TSRMLS_C);
+ PS(session_status) = php_session_active;
+ }
+ if (val) {
php_session_decode(val, vallen TSRMLS_CC);
efree(val);
- } else if (PS(invalid_session_id)) { /* address instances where the session read fails due to an invalid id */
- PS(invalid_session_id) = 0;
- efree(PS(id));
- PS(id) = NULL;
- goto new_session;
+ }
+
+ if (!PS(use_cookies) && PS(send_cookie)) {
+ if (PS(use_trans_sid) && !PS(use_only_cookies)) {
+ PS(apply_trans_sid) = 1;
+ }
+ PS(send_cookie) = 0;
}
}
/* }}} */
@@ -744,6 +795,7 @@ PHP_INI_BEGIN()
STD_PHP_INI_BOOLEAN("session.cookie_httponly", "", PHP_INI_ALL, OnUpdateBool, cookie_httponly, php_ps_globals, ps_globals)
STD_PHP_INI_BOOLEAN("session.use_cookies", "1", PHP_INI_ALL, OnUpdateBool, use_cookies, php_ps_globals, ps_globals)
STD_PHP_INI_BOOLEAN("session.use_only_cookies", "1", PHP_INI_ALL, OnUpdateBool, use_only_cookies, php_ps_globals, ps_globals)
+ STD_PHP_INI_BOOLEAN("session.use_strict_mode", "0", PHP_INI_ALL, OnUpdateBool, use_strict_mode, php_ps_globals, ps_globals)
STD_PHP_INI_ENTRY("session.referer_check", "", PHP_INI_ALL, OnUpdateString, extern_referer_chk, php_ps_globals, ps_globals)
#if HAVE_DEV_URANDOM
STD_PHP_INI_ENTRY("session.entropy_file", "/dev/urandom", PHP_INI_ALL, OnUpdateString, entropy_file, php_ps_globals, ps_globals)
@@ -782,6 +834,44 @@ PHP_INI_END()
/* ***************
* Serializers *
*************** */
+PS_SERIALIZER_ENCODE_FUNC(php_serialize) /* {{{ */
+{
+ smart_str buf = {0};
+ php_serialize_data_t var_hash;
+
+ PHP_VAR_SERIALIZE_INIT(var_hash);
+ php_var_serialize(&buf, &PS(http_session_vars), &var_hash TSRMLS_CC);
+ PHP_VAR_SERIALIZE_DESTROY(var_hash);
+ if (newlen) {
+ *newlen = buf.len;
+ }
+ smart_str_0(&buf);
+ *newstr = buf.c;
+ return SUCCESS;
+}
+/* }}} */
+
+PS_SERIALIZER_DECODE_FUNC(php_serialize) /* {{{ */
+{
+ const char *endptr = val + vallen;
+ zval *session_vars;
+ php_unserialize_data_t var_hash;
+
+ PHP_VAR_UNSERIALIZE_INIT(var_hash);
+ ALLOC_INIT_ZVAL(session_vars);
+ php_var_unserialize(&session_vars, &val, endptr, &var_hash TSRMLS_CC);
+ PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
+ if (PS(http_session_vars)) {
+ zval_ptr_dtor(&PS(http_session_vars));
+ }
+ if (Z_TYPE_P(session_vars) == IS_NULL) {
+ array_init(session_vars);
+ }
+ PS(http_session_vars) = session_vars;
+ ZEND_SET_GLOBAL_VAR_WITH_LENGTH("_SESSION", sizeof("_SESSION"), PS(http_session_vars), 2, 1);
+ return SUCCESS;
+}
+/* }}} */
#define PS_BIN_NR_OF_BITS 8
#define PS_BIN_UNDEF (1<<(PS_BIN_NR_OF_BITS-1))
@@ -963,10 +1053,11 @@ break_outer_loop:
}
/* }}} */
-#define MAX_SERIALIZERS 10
-#define PREDEFINED_SERIALIZERS 2
+#define MAX_SERIALIZERS 32
+#define PREDEFINED_SERIALIZERS 3
static ps_serializer ps_serializers[MAX_SERIALIZERS + 1] = {
+ PS_SERIALIZER_ENTRY(php_serialize),
PS_SERIALIZER_ENTRY(php),
PS_SERIALIZER_ENTRY(php_binary)
};
@@ -1178,6 +1269,7 @@ static int php_session_cache_limiter(TSRMLS_D) /* {{{ */
#define COOKIE_SET_COOKIE "Set-Cookie: "
#define COOKIE_EXPIRES "; expires="
+#define COOKIE_MAX_AGE "; Max-Age="
#define COOKIE_PATH "; path="
#define COOKIE_DOMAIN "; domain="
#define COOKIE_SECURE "; secure"
@@ -1225,6 +1317,9 @@ static void php_session_send_cookie(TSRMLS_D) /* {{{ */
smart_str_appends(&ncookie, COOKIE_EXPIRES);
smart_str_appends(&ncookie, date_fmt);
efree(date_fmt);
+
+ smart_str_appends(&ncookie, COOKIE_MAX_AGE);
+ smart_str_append_long(&ncookie, PS(cookie_lifetime));
}
}
@@ -1289,10 +1384,15 @@ PHPAPI const ps_serializer *_php_find_ps_serializer(char *name TSRMLS_DC) /* {{{
convert_to_string((*ppid)); \
PS(id) = estrndup(Z_STRVAL_PP(ppid), Z_STRLEN_PP(ppid))
-static void php_session_reset_id(TSRMLS_D) /* {{{ */
+PHPAPI void php_session_reset_id(TSRMLS_D) /* {{{ */
{
int module_number = PS(module_number);
+ if (!PS(id)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot set session ID - session ID is not initialized");
+ return;
+ }
+
if (PS(use_cookies) && PS(send_cookie)) {
php_session_send_cookie(TSRMLS_C);
PS(send_cookie) = 0;
@@ -1439,19 +1539,14 @@ PHPAPI void php_session_start(TSRMLS_D) /* {{{ */
}
}
- php_session_initialize(TSRMLS_C);
-
- if (!PS(use_cookies) && PS(send_cookie)) {
- if (PS(use_trans_sid) && !PS(use_only_cookies)) {
- PS(apply_trans_sid) = 1;
- }
- PS(send_cookie) = 0;
+ /* Finally check session id for dangarous characters
+ * Security note: session id may be embedded in HTML pages.*/
+ if (PS(id) && strpbrk(PS(id), "\r\n\t <>'\"\\")) {
+ efree(PS(id));
+ PS(id) = NULL;
}
- php_session_reset_id(TSRMLS_C);
-
- PS(session_status) = php_session_active;
-
+ php_session_initialize(TSRMLS_C);
php_session_cache_limiter(TSRMLS_C);
if ((PS(mod_data) || PS(mod_user_implemented)) && PS(gc_probability) > 0) {
@@ -1597,7 +1692,7 @@ static PHP_FUNCTION(session_module_name)
}
/* }}} */
-/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc)
+/* {{{ proto void session_set_save_handler(string open, string close, string read, string write, string destroy, string gc, string create_sid)
Sets user-level functions */
static PHP_FUNCTION(session_set_save_handler)
{
@@ -1609,11 +1704,7 @@ static PHP_FUNCTION(session_set_save_handler)
RETURN_FALSE;
}
- if (argc != 1 && argc != 2 && argc != 6) {
- WRONG_PARAM_COUNT;
- }
-
- if (argc <= 2) {
+ if (argc > 0 && argc <= 2) {
zval *obj = NULL, *callback = NULL;
zend_uint func_name_len;
char *func_name;
@@ -1627,11 +1718,11 @@ static PHP_FUNCTION(session_set_save_handler)
RETURN_FALSE;
}
- /* Find implemented methods */
- zend_hash_internal_pointer_reset_ex(&php_session_class_entry->function_table, &pos);
+ /* Find implemented methods - SessionHandlerInterface */
+ zend_hash_internal_pointer_reset_ex(&php_session_iface_entry->function_table, &pos);
i = 0;
- while (zend_hash_get_current_data_ex(&php_session_class_entry->function_table, (void **) &default_mptr, &pos) == SUCCESS) {
- zend_hash_get_current_key_ex(&php_session_class_entry->function_table, &func_name, &func_name_len, &func_index, 0, &pos);
+ while (zend_hash_get_current_data_ex(&php_session_iface_entry->function_table, (void **) &default_mptr, &pos) == SUCCESS) {
+ zend_hash_get_current_key_ex(&php_session_iface_entry->function_table, &func_name, &func_name_len, &func_index, 0, &pos);
if (zend_hash_find(&Z_OBJCE_P(obj)->function_table, func_name, func_name_len, (void **)&current_mptr) == SUCCESS) {
if (PS(mod_user_names).names[i] != NULL) {
@@ -1649,7 +1740,29 @@ static PHP_FUNCTION(session_set_save_handler)
RETURN_FALSE;
}
- zend_hash_move_forward_ex(&php_session_class_entry->function_table, &pos);
+ zend_hash_move_forward_ex(&php_session_iface_entry->function_table, &pos);
+ ++i;
+ }
+
+ /* Find implemented methods - SessionIdInterface (optional) */
+ zend_hash_internal_pointer_reset_ex(&php_session_id_iface_entry->function_table, &pos);
+ while (zend_hash_get_current_data_ex(&php_session_id_iface_entry->function_table, (void **) &default_mptr, &pos) == SUCCESS) {
+ zend_hash_get_current_key_ex(&php_session_id_iface_entry->function_table, &func_name, &func_name_len, &func_index, 0, &pos);
+
+ if (zend_hash_find(&Z_OBJCE_P(obj)->function_table, func_name, func_name_len, (void **)&current_mptr) == SUCCESS) {
+ if (PS(mod_user_names).names[i] != NULL) {
+ zval_ptr_dtor(&PS(mod_user_names).names[i]);
+ }
+
+ MAKE_STD_ZVAL(callback);
+ array_init_size(callback, 2);
+ Z_ADDREF_P(obj);
+ add_next_index_zval(callback, obj);
+ add_next_index_stringl(callback, func_name, func_name_len - 1, 1);
+ PS(mod_user_names).names[i] = callback;
+ }
+
+ zend_hash_move_forward_ex(&php_session_id_iface_entry->function_table, &pos);
++i;
}
@@ -1681,6 +1794,10 @@ static PHP_FUNCTION(session_set_save_handler)
RETURN_TRUE;
}
+ if (argc != 6 && argc != 7) {
+ WRONG_PARAM_COUNT;
+ }
+
if (zend_parse_parameters(argc TSRMLS_CC, "+", &args, &num_args) == FAILURE) {
return;
}
@@ -1688,7 +1805,8 @@ static PHP_FUNCTION(session_set_save_handler)
/* remove shutdown function */
remove_user_shutdown_function("session_shutdown", sizeof("session_shutdown") TSRMLS_CC);
- for (i = 0; i < 6; i++) {
+ /* at this point argc can only be 6 or 7 */
+ for (i = 0; i < argc; i++) {
if (!zend_is_callable(*args[i], 0, &name TSRMLS_CC)) {
efree(args);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument %d is not a valid callback", i+1);
@@ -1702,7 +1820,7 @@ static PHP_FUNCTION(session_set_save_handler)
zend_alter_ini_entry("session.save_handler", sizeof("session.save_handler"), "user", sizeof("user")-1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
}
- for (i = 0; i < 6; i++) {
+ for (i = 0; i < argc; i++) {
if (PS(mod_user_names).names[i] != NULL) {
zval_ptr_dtor(&PS(mod_user_names).names[i]);
}
@@ -1744,9 +1862,9 @@ static PHP_FUNCTION(session_save_path)
static PHP_FUNCTION(session_id)
{
char *name = NULL;
- int name_len;
+ int name_len, argc = ZEND_NUM_ARGS();
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &name, &name_len) == FAILURE) {
+ if (zend_parse_parameters(argc TSRMLS_CC, "|s", &name, &name_len) == FAILURE) {
return;
}
@@ -1791,11 +1909,13 @@ static PHP_FUNCTION(session_regenerate_id)
}
PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC);
-
- PS(send_cookie) = 1;
- php_session_reset_id(TSRMLS_C);
-
- RETURN_TRUE;
+ if (PS(id)) {
+ PS(send_cookie) = 1;
+ php_session_reset_id(TSRMLS_C);
+ RETURN_TRUE;
+ } else {
+ PS(id) = STR_EMPTY_ALLOC();
+ }
}
RETURN_FALSE;
}
@@ -2012,13 +2132,14 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_session_void, 0)
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_INFO_EX(arginfo_session_set_save_handler, 0, 0, 6)
+ZEND_BEGIN_ARG_INFO_EX(arginfo_session_set_save_handler, 0, 0, 1)
ZEND_ARG_INFO(0, open)
ZEND_ARG_INFO(0, close)
ZEND_ARG_INFO(0, read)
ZEND_ARG_INFO(0, write)
ZEND_ARG_INFO(0, destroy)
ZEND_ARG_INFO(0, gc)
+ ZEND_ARG_INFO(0, create_sid)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_session_cache_limiter, 0, 0, 0)
@@ -2061,6 +2182,9 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_session_class_gc, 0)
ZEND_ARG_INFO(0, maxlifetime)
ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_session_class_create_sid, 0)
+ZEND_END_ARG_INFO()
/* }}} */
/* {{{ session_functions[]
@@ -2102,6 +2226,14 @@ static const zend_function_entry php_session_iface_functions[] = {
};
/* }}} */
+/* {{{ SessionIdInterface functions[]
+*/
+static const zend_function_entry php_session_id_iface_functions[] = {
+ PHP_ABSTRACT_ME(SessionIdInterface, create_sid, arginfo_session_class_create_sid)
+ { NULL, NULL, NULL }
+};
+/* }}} */
+
/* {{{ SessionHandler functions[]
*/
static const zend_function_entry php_session_class_functions[] = {
@@ -2111,6 +2243,7 @@ static const zend_function_entry php_session_class_functions[] = {
PHP_ME(SessionHandler, write, arginfo_session_class_write, ZEND_ACC_PUBLIC)
PHP_ME(SessionHandler, destroy, arginfo_session_class_destroy, ZEND_ACC_PUBLIC)
PHP_ME(SessionHandler, gc, arginfo_session_class_gc, ZEND_ACC_PUBLIC)
+ PHP_ME(SessionHandler, create_sid, arginfo_session_class_create_sid, ZEND_ACC_PUBLIC)
{ NULL, NULL, NULL }
};
/* }}} */
@@ -2170,7 +2303,7 @@ static PHP_RSHUTDOWN_FUNCTION(session) /* {{{ */
php_rshutdown_session_globals(TSRMLS_C);
/* this should NOT be done in php_rshutdown_session_globals() */
- for (i = 0; i < 6; i++) {
+ for (i = 0; i < 7; i++) {
if (PS(mod_user_names).names[i] != NULL) {
zval_ptr_dtor(&PS(mod_user_names).names[i]);
PS(mod_user_names).names[i] = NULL;
@@ -2195,7 +2328,7 @@ static PHP_GINIT_FUNCTION(ps) /* {{{ */
ps_globals->default_mod = NULL;
ps_globals->mod_user_implemented = 0;
ps_globals->mod_user_is_open = 0;
- for (i = 0; i < 6; i++) {
+ for (i = 0; i < 7; i++) {
ps_globals->mod_user_names.names[i] = NULL;
}
ps_globals->http_session_vars = NULL;
@@ -2219,15 +2352,20 @@ static PHP_MINIT_FUNCTION(session) /* {{{ */
php_session_rfc1867_orig_callback = php_rfc1867_callback;
php_rfc1867_callback = php_session_rfc1867_callback;
- /* Register interface */
+ /* Register interfaces */
INIT_CLASS_ENTRY(ce, PS_IFACE_NAME, php_session_iface_functions);
php_session_iface_entry = zend_register_internal_class(&ce TSRMLS_CC);
php_session_iface_entry->ce_flags |= ZEND_ACC_INTERFACE;
+ INIT_CLASS_ENTRY(ce, PS_SID_IFACE_NAME, php_session_id_iface_functions);
+ php_session_id_iface_entry = zend_register_internal_class(&ce TSRMLS_CC);
+ php_session_id_iface_entry->ce_flags |= ZEND_ACC_INTERFACE;
+
/* Register base class */
INIT_CLASS_ENTRY(ce, PS_CLASS_NAME, php_session_class_functions);
php_session_class_entry = zend_register_internal_class(&ce TSRMLS_CC);
zend_class_implements(php_session_class_entry TSRMLS_CC, 1, php_session_iface_entry);
+ zend_class_implements(php_session_class_entry TSRMLS_CC, 1, php_session_id_iface_entry);
REGISTER_LONG_CONSTANT("PHP_SESSION_DISABLED", php_session_disabled, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PHP_SESSION_NONE", php_session_none, CONST_CS | CONST_PERSISTENT);
diff --git a/ext/session/tests/003.phpt b/ext/session/tests/003.phpt
index 03c3b95766..8725f06a69 100644
--- a/ext/session/tests/003.phpt
+++ b/ext/session/tests/003.phpt
@@ -4,6 +4,7 @@ session object deserialization
<?php include('skipif.inc'); ?>
--INI--
session.use_cookies=0
+session.use_strict_mode=0
session.cache_limiter=
session.serialize_handler=php
session.save_handler=files
diff --git a/ext/session/tests/004.phpt b/ext/session/tests/004.phpt
index aeb2c8b363..4547c65574 100644
--- a/ext/session/tests/004.phpt
+++ b/ext/session/tests/004.phpt
@@ -4,6 +4,7 @@ session_set_save_handler test
<?php include('skipif.inc'); ?>
--INI--
session.use_cookies=0
+session.use_strict_mode=0
session.cache_limiter=
session.name=PHPSESSID
session.serialize_handler=php
diff --git a/ext/session/tests/005.phpt b/ext/session/tests/005.phpt
index a970e6b71d..796d9c377e 100644
--- a/ext/session/tests/005.phpt
+++ b/ext/session/tests/005.phpt
@@ -4,6 +4,7 @@ custom save handler, multiple session_start()s, complex data structure test.
<?php include('skipif.inc'); ?>
--INI--
session.use_cookies=0
+session.use_strict_mode=0
session.cache_limiter=
session.name=PHPSESSID
session.serialize_handler=php
diff --git a/ext/session/tests/006.phpt b/ext/session/tests/006.phpt
index 03fca10381..dba6894c7e 100644
--- a/ext/session/tests/006.phpt
+++ b/ext/session/tests/006.phpt
@@ -4,6 +4,7 @@ correct instantiation of references between variables in sessions
<?php include('skipif.inc'); ?>
--INI--
session.use_cookies=0
+session.use_strict_mode=0
session.cache_limiter=
session.serialize_handler=php
session.save_handler=files
diff --git a/ext/session/tests/009.phpt b/ext/session/tests/009.phpt
index d73bc238c9..6d8d11c331 100644
--- a/ext/session/tests/009.phpt
+++ b/ext/session/tests/009.phpt
@@ -4,6 +4,7 @@ unset($_SESSION["name"]); test
<?php include('skipif.inc'); ?>
--INI--
session.use_cookies=0
+session.use_strict_mode=0
session.cache_limiter=
session.serialize_handler=php
session.save_handler=files
diff --git a/ext/session/tests/012.phpt b/ext/session/tests/012.phpt
index 8708011273..c555d2ca1e 100644
--- a/ext/session/tests/012.phpt
+++ b/ext/session/tests/012.phpt
@@ -4,6 +4,7 @@ registering $_SESSION should not segfault
<?php include('skipif.inc'); ?>
--INI--
session.use_cookies=0
+session.use_strict_mode=0
session.cache_limiter=
session.serialize_handler=php
session.save_handler=files
diff --git a/ext/session/tests/013.phpt b/ext/session/tests/013.phpt
index 8d0f284b17..32909eb58c 100644
--- a/ext/session/tests/013.phpt
+++ b/ext/session/tests/013.phpt
@@ -4,6 +4,7 @@ redefining SID should not cause warnings
<?php include('skipif.inc'); ?>
--INI--
session.use_cookies=0
+session.use_strict_mode=0
session.cache_limiter=
session.serialize_handler=php
session.save_handler=files
diff --git a/ext/session/tests/014.phpt b/ext/session/tests/014.phpt
index 73bc28ea66..cbf22b142d 100644
--- a/ext/session/tests/014.phpt
+++ b/ext/session/tests/014.phpt
@@ -5,6 +5,7 @@ a script should not be able to modify session.use_trans_sid
--INI--
session.use_trans_sid=0
session.use_cookies=0
+session.use_strict_mode=0
session.cache_limiter=
session.name=PHPSESSID
session.serialize_handler=php
diff --git a/ext/session/tests/015.phpt b/ext/session/tests/015.phpt
index 7d7b737340..527b86bc1d 100644
--- a/ext/session/tests/015.phpt
+++ b/ext/session/tests/015.phpt
@@ -6,6 +6,7 @@ use_trans_sid should not affect SID
session.use_trans_sid=1
session.use_cookies=0
session.use_only_cookies=0
+session.use_strict_mode=0
session.cache_limiter=
arg_separator.output=&
session.name=PHPSESSID
diff --git a/ext/session/tests/016.phpt b/ext/session/tests/016.phpt
index 83703294a3..0e368e2f82 100644
--- a/ext/session/tests/016.phpt
+++ b/ext/session/tests/016.phpt
@@ -16,10 +16,11 @@ session.serialize_handler=php
<?php
error_reporting(E_ALL);
-@session_start();
+session_start();
$HTTP_SESSION_VARS["test"] = 1;
-@session_write_close();
+session_write_close();
print "I live\n";
?>
---EXPECT--
+--EXPECTF--
+Warning: session_write_close(): Failed to write session data (files). Please verify that the current setting of session.save_path is correct (123;:/really\completely:::/invalid;;,23123;213) in %s on line %d
I live
diff --git a/ext/session/tests/018.phpt b/ext/session/tests/018.phpt
index def1f419ce..5ec132b34f 100644
--- a/ext/session/tests/018.phpt
+++ b/ext/session/tests/018.phpt
@@ -5,6 +5,7 @@ rewriter correctly handles attribute names which contain dashes
--INI--
session.use_cookies=0
session.use_only_cookies=0
+session.use_strict_mode=0
session.cache_limiter=
session.use_trans_sid=1
session.name=PHPSESSID
diff --git a/ext/session/tests/019.phpt b/ext/session/tests/019.phpt
index 3ee8ccd420..0f06add5a1 100644
--- a/ext/session/tests/019.phpt
+++ b/ext/session/tests/019.phpt
@@ -4,6 +4,7 @@ serializing references test case using globals
<?php include('skipif.inc'); ?>
--INI--
session.use_cookies=0
+session.use_strict_mode=0
session.cache_limiter=
session.serialize_handler=php
session.save_handler=files
diff --git a/ext/session/tests/020.phpt b/ext/session/tests/020.phpt
index 0141129820..267e52191c 100644
--- a/ext/session/tests/020.phpt
+++ b/ext/session/tests/020.phpt
@@ -5,6 +5,7 @@ rewriter uses arg_separator.output for modifying URLs
--INI--
session.use_cookies=0
session.use_only_cookies=0
+session.use_strict_mode=0
session.cache_limiter=
session.use_trans_sid=1
arg_separator.output="&amp;"
diff --git a/ext/session/tests/021.phpt b/ext/session/tests/021.phpt
index 1ad3c5d5f7..e199972899 100644
--- a/ext/session/tests/021.phpt
+++ b/ext/session/tests/021.phpt
@@ -5,6 +5,7 @@ rewriter handles form and fieldset tags correctly
--INI--
session.use_cookies=0
session.use_only_cookies=0
+session.use_strict_mode=0
session.cache_limiter=
session.use_trans_sid=1
url_rewriter.tags="a=href,area=href,frame=src,input=src,form=,fieldset="
diff --git a/ext/session/tests/023.phpt b/ext/session/tests/023.phpt
index 42b1e5b1be..592b4a8c3b 100644
--- a/ext/session/tests/023.phpt
+++ b/ext/session/tests/023.phpt
@@ -4,6 +4,7 @@ session object deserialization
<?php include('skipif.inc'); ?>
--INI--
session.use_cookies=0
+session.use_strict_mode=0
session.cache_limiter=
session.serialize_handler=php
session.save_handler=files
diff --git a/ext/session/tests/024.phpt b/ext/session/tests/024.phpt
index 2ad26067a5..2b273e2b2e 100644
--- a/ext/session/tests/024.phpt
+++ b/ext/session/tests/024.phpt
@@ -4,6 +4,7 @@ session_set_save_handler test
<?php include('skipif.inc'); ?>
--INI--
session.use_cookies=0
+session.use_strict_mode=0
session.cache_limiter=
session.name=PHPSESSID
session.serialize_handler=php
diff --git a/ext/session/tests/025.phpt b/ext/session/tests/025.phpt
index 4fd095f817..a9ad8fb649 100644
--- a/ext/session/tests/025.phpt
+++ b/ext/session/tests/025.phpt
@@ -4,6 +4,7 @@ custom save handler, multiple session_start()s, complex data structure test.
<?php include('skipif.inc'); ?>
--INI--
session.use_cookies=0
+session.use_strict_mode=0
session.cache_limiter=
session.name=PHPSESSID
session.serialize_handler=php
diff --git a/ext/session/tests/026.phpt b/ext/session/tests/026.phpt
index 06c135d046..44f0ae0ec0 100644
--- a/ext/session/tests/026.phpt
+++ b/ext/session/tests/026.phpt
@@ -4,6 +4,7 @@ correct instantiation of references between variables in sessions
<?php include('skipif.inc'); ?>
--INI--
session.use_cookies=0
+session.use_strict_mode=0
session.cache_limiter=
session.serialize_handler=php
session.save_handler=files
diff --git a/ext/session/tests/027.phpt b/ext/session/tests/027.phpt
index 600a992f7f..63828522fb 100644
--- a/ext/session/tests/027.phpt
+++ b/ext/session/tests/027.phpt
@@ -4,6 +4,7 @@ unset($_SESSION["name"]); should work
<?php include('skipif.inc'); ?>
--INI--
session.use_cookies=0
+session.use_strict_mode=0
session.cache_limiter=
session.serialize_handler=php
session.save_handler=files
diff --git a/ext/session/tests/030.phpt b/ext/session/tests/030.phpt
index 8d0f284b17..32909eb58c 100644
--- a/ext/session/tests/030.phpt
+++ b/ext/session/tests/030.phpt
@@ -4,6 +4,7 @@ redefining SID should not cause warnings
<?php include('skipif.inc'); ?>
--INI--
session.use_cookies=0
+session.use_strict_mode=0
session.cache_limiter=
session.serialize_handler=php
session.save_handler=files
diff --git a/ext/session/tests/bug41600.phpt b/ext/session/tests/bug41600.phpt
index 690347ac8d..79d5e12841 100644
--- a/ext/session/tests/bug41600.phpt
+++ b/ext/session/tests/bug41600.phpt
@@ -5,6 +5,7 @@ Bug #41600 (url rewriter tags doesn't work with namespaced tags)
--INI--
session.use_cookies=0
session.use_only_cookies=0
+session.use_strict_mode=0
session.cache_limiter=
session.use_trans_sid=1
arg_separator.output="&amp;"
diff --git a/ext/session/tests/bug60634.phpt b/ext/session/tests/bug60634.phpt
index 2ec0c26c13..e2dfd15b37 100644
--- a/ext/session/tests/bug60634.phpt
+++ b/ext/session/tests/bug60634.phpt
@@ -1,7 +1,5 @@
--TEST--
Bug #60634 (Segmentation fault when trying to die() in SessionHandler::write())
---XFAIL--
-Long term low priority bug, working on it
--INI--
session.save_path=
session.name=PHPSESSID
@@ -44,3 +42,4 @@ echo "um, hi\n";
?>
--EXPECTF--
write: goodbye cruel world
+close: goodbye cruel world
diff --git a/ext/session/tests/bug60634_error_1.phpt b/ext/session/tests/bug60634_error_1.phpt
index 3b6e394eed..e41592f18d 100644
--- a/ext/session/tests/bug60634_error_1.phpt
+++ b/ext/session/tests/bug60634_error_1.phpt
@@ -1,7 +1,5 @@
--TEST--
Bug #60634 (Segmentation fault when trying to die() in SessionHandler::write()) - fatal error in write during exec
---XFAIL--
-Long term low priority bug, working on it
--INI--
session.save_path=
session.name=PHPSESSID
@@ -47,3 +45,4 @@ echo "um, hi\n";
write: goodbye cruel world
Fatal error: Call to undefined function undefined_function() in %s on line %d
+close: goodbye cruel world
diff --git a/ext/session/tests/bug60634_error_2.phpt b/ext/session/tests/bug60634_error_2.phpt
index 265fb303f7..7c50948ba8 100644
--- a/ext/session/tests/bug60634_error_2.phpt
+++ b/ext/session/tests/bug60634_error_2.phpt
@@ -1,7 +1,5 @@
--TEST--
Bug #60634 (Segmentation fault when trying to die() in SessionHandler::write()) - exception in write during exec
---XFAIL--
-Long term low priority bug, working on it
--INI--
session.save_path=
session.name=PHPSESSID
@@ -47,3 +45,8 @@ echo "um, hi\n";
write: goodbye cruel world
Fatal error: Uncaught exception 'Exception' in %s
+Stack trace:
+#0 [internal function]: write('%s', '')
+#1 %s(%d): session_write_close()
+#2 {main}
+ thrown in %s on line %d
diff --git a/ext/session/tests/bug60634_error_3.phpt b/ext/session/tests/bug60634_error_3.phpt
index b2004d68bc..4a508a4d8f 100644
--- a/ext/session/tests/bug60634_error_3.phpt
+++ b/ext/session/tests/bug60634_error_3.phpt
@@ -1,7 +1,5 @@
--TEST--
Bug #60634 (Segmentation fault when trying to die() in SessionHandler::write()) - fatal error in write after exec
---XFAIL--
-Long term low priority bug, working on it
--INI--
session.save_path=
session.name=PHPSESSID
@@ -46,3 +44,4 @@ session_start();
write: goodbye cruel world
Fatal error: Call to undefined function undefined_function() in %s on line %d
+close: goodbye cruel world
diff --git a/ext/session/tests/bug60634_error_4.phpt b/ext/session/tests/bug60634_error_4.phpt
index 60bc0dcf54..f21d077b54 100644
--- a/ext/session/tests/bug60634_error_4.phpt
+++ b/ext/session/tests/bug60634_error_4.phpt
@@ -1,7 +1,5 @@
--TEST--
Bug #60634 (Segmentation fault when trying to die() in SessionHandler::write()) - exception in write after exec
---XFAIL--
-Long term low priority bug, working on it
--INI--
session.save_path=
session.name=PHPSESSID
@@ -46,3 +44,8 @@ session_start();
write: goodbye cruel world
Fatal error: Uncaught exception 'Exception' in %s
+Stack trace:
+#0 [internal function]: write('%s', '')
+#1 {main}
+ thrown in %s on line %d
+close: goodbye cruel world
diff --git a/ext/session/tests/bug65475.phpt b/ext/session/tests/bug65475.phpt
new file mode 100644
index 0000000000..7dc5463879
--- /dev/null
+++ b/ext/session/tests/bug65475.phpt
@@ -0,0 +1,34 @@
+--TEST--
+Bug #65475: Session ID is not initialized when session.usr_strict_mode=1
+--INI--
+session.save_handler=files
+session.name=PHPSESSID
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--FILE--
+<?php
+ob_start();
+
+echo "Testing file module".PHP_EOL;
+session_start();
+$_SESSION['foo'] = 1234;
+$_SESSION['cnt'] = 1;
+$session_id = session_id();
+session_write_close();
+
+session_start();
+var_dump($session_id === session_id());
+$_SESSION['cnt']++;
+session_write_close();
+
+session_start();
+var_dump($session_id === session_id());
+var_dump($_SESSION['cnt']); // Should be int(2)
+session_write_close();
+
+--EXPECTF--
+Testing file module
+bool(true)
+bool(true)
+int(2)
+
diff --git a/ext/session/tests/rfc1867.phpt b/ext/session/tests/rfc1867.phpt
index dc44e8b443..6b14bcb4ef 100644
--- a/ext/session/tests/rfc1867.phpt
+++ b/ext/session/tests/rfc1867.phpt
@@ -7,6 +7,7 @@ comment=debug builds show some additional E_NOTICE errors
upload_max_filesize=1024
session.save_path=
session.name=PHPSESSID
+session.use_strict_mode=0
session.use_cookies=1
session.use_only_cookies=0
session.upload_progress.enabled=1
diff --git a/ext/session/tests/rfc1867_cleanup.phpt b/ext/session/tests/rfc1867_cleanup.phpt
index f70b395d22..f84385bada 100644
--- a/ext/session/tests/rfc1867_cleanup.phpt
+++ b/ext/session/tests/rfc1867_cleanup.phpt
@@ -7,6 +7,7 @@ comment=debug builds show some additional E_NOTICE errors
upload_max_filesize=1024
session.save_path=
session.name=PHPSESSID
+session.use_strict_mode=0
session.use_cookies=1
session.use_only_cookies=0
session.upload_progress.enabled=1
diff --git a/ext/session/tests/rfc1867_disabled.phpt b/ext/session/tests/rfc1867_disabled.phpt
index 4490055791..550ee3a7a2 100644
--- a/ext/session/tests/rfc1867_disabled.phpt
+++ b/ext/session/tests/rfc1867_disabled.phpt
@@ -7,6 +7,7 @@ comment=debug builds show some additional E_NOTICE errors
upload_max_filesize=1024
session.save_path=
session.name=PHPSESSID
+session.use_strict_mode=0
session.use_cookies=1
session.use_only_cookies=0
session.upload_progress.enabled=0
diff --git a/ext/session/tests/rfc1867_disabled_2.phpt b/ext/session/tests/rfc1867_disabled_2.phpt
index e878f4619f..83e97eeed1 100644
--- a/ext/session/tests/rfc1867_disabled_2.phpt
+++ b/ext/session/tests/rfc1867_disabled_2.phpt
@@ -7,6 +7,7 @@ comment=debug builds show some additional E_NOTICE errors
upload_max_filesize=1024
session.save_path=
session.name=PHPSESSID
+session.use_strict_mode=0
session.use_cookies=1
session.use_only_cookies=0
session.upload_progress.enabled=1
diff --git a/ext/session/tests/rfc1867_inter.phpt b/ext/session/tests/rfc1867_inter.phpt
index 768637105c..4d9b262230 100644
--- a/ext/session/tests/rfc1867_inter.phpt
+++ b/ext/session/tests/rfc1867_inter.phpt
@@ -7,6 +7,7 @@ comment=debug builds show some additional E_NOTICE errors
upload_max_filesize=1024
session.save_path=
session.name=PHPSESSID
+session.use_strict_mode=0
session.use_cookies=1
session.use_only_cookies=0
session.upload_progress.enabled=1
diff --git a/ext/session/tests/rfc1867_no_name.phpt b/ext/session/tests/rfc1867_no_name.phpt
index c1dda8156e..d68a61d929 100644
--- a/ext/session/tests/rfc1867_no_name.phpt
+++ b/ext/session/tests/rfc1867_no_name.phpt
@@ -7,6 +7,7 @@ comment=debug builds show some additional E_NOTICE errors
upload_max_filesize=1024
session.save_path=
session.name=PHPSESSID
+session.use_strict_mode=0
session.use_cookies=1
session.use_only_cookies=0
session.upload_progress.enabled=1
diff --git a/ext/session/tests/rfc1867_sid_cookie.phpt b/ext/session/tests/rfc1867_sid_cookie.phpt
index 735a5ac201..2864799335 100644
--- a/ext/session/tests/rfc1867_sid_cookie.phpt
+++ b/ext/session/tests/rfc1867_sid_cookie.phpt
@@ -7,6 +7,7 @@ comment=debug builds show some additional E_NOTICE errors
upload_max_filesize=1024
session.save_path=
session.name=PHPSESSID
+session.use_strict_mode=0
session.use_cookies=1
session.use_only_cookies=0
session.upload_progress.enabled=1
diff --git a/ext/session/tests/rfc1867_sid_get.phpt b/ext/session/tests/rfc1867_sid_get.phpt
index cc5a793e7b..e3a48a1c13 100644
--- a/ext/session/tests/rfc1867_sid_get.phpt
+++ b/ext/session/tests/rfc1867_sid_get.phpt
@@ -7,6 +7,7 @@ comment=debug builds show some additional E_NOTICE errors
upload_max_filesize=1024
session.save_path=
session.name=PHPSESSID
+session.use_strict_mode=0
session.use_cookies=1
session.use_only_cookies=0
session.upload_progress.enabled=1
diff --git a/ext/session/tests/rfc1867_sid_get_2.phpt b/ext/session/tests/rfc1867_sid_get_2.phpt
index 1d22e5930b..e21ca4ca2b 100644
--- a/ext/session/tests/rfc1867_sid_get_2.phpt
+++ b/ext/session/tests/rfc1867_sid_get_2.phpt
@@ -7,6 +7,7 @@ comment=debug builds show some additional E_NOTICE errors
upload_max_filesize=1024
session.save_path=
session.name=PHPSESSID
+session.use_strict_mode=0
session.use_cookies=0
session.use_only_cookies=0
session.upload_progress.enabled=1
diff --git a/ext/session/tests/rfc1867_sid_invalid.phpt b/ext/session/tests/rfc1867_sid_invalid.phpt
index b28a2e341b..4dd8f1f979 100644
--- a/ext/session/tests/rfc1867_sid_invalid.phpt
+++ b/ext/session/tests/rfc1867_sid_invalid.phpt
@@ -46,6 +46,16 @@ session_destroy();
?>
--EXPECTF--
Warning: Unknown: The session id is too long or contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,' in Unknown on line 0
+
+Warning: Unknown: The session id is too long or contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,' in Unknown on line 0
+
+Warning: Unknown: Failed to write session data (files). Please verify that the current setting of session.save_path is correct () in Unknown on line 0
+
+Warning: Unknown: The session id is too long or contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,' in Unknown on line 0
+
+Warning: Unknown: The session id is too long or contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,' in Unknown on line 0
+
+Warning: Unknown: Failed to write session data (files). Please verify that the current setting of session.save_path is correct () in Unknown on line 0
string(%d) "%s"
bool(true)
array(2) {
diff --git a/ext/session/tests/rfc1867_sid_only_cookie.phpt b/ext/session/tests/rfc1867_sid_only_cookie.phpt
index 9a0105668f..41f6761fb9 100644
--- a/ext/session/tests/rfc1867_sid_only_cookie.phpt
+++ b/ext/session/tests/rfc1867_sid_only_cookie.phpt
@@ -7,6 +7,7 @@ comment=debug builds show some additional E_NOTICE errors
upload_max_filesize=1024
session.save_path=
session.name=PHPSESSID
+session.use_strict_mode=0
session.use_cookies=1
session.use_only_cookies=1
session.upload_progress.enabled=1
diff --git a/ext/session/tests/rfc1867_sid_post.phpt b/ext/session/tests/rfc1867_sid_post.phpt
index 7c1eb2de5d..107957f8db 100644
--- a/ext/session/tests/rfc1867_sid_post.phpt
+++ b/ext/session/tests/rfc1867_sid_post.phpt
@@ -7,6 +7,7 @@ comment=debug builds show some additional E_NOTICE errors
upload_max_filesize=1024
session.save_path=
session.name=PHPSESSID
+session.use_strict_mode=0
session.use_cookies=1
session.use_only_cookies=0
session.upload_progress.enabled=1
diff --git a/ext/session/tests/session_commit_variation4.phpt b/ext/session/tests/session_commit_variation4.phpt
index 57f42539d2..69854a6cf9 100644
--- a/ext/session/tests/session_commit_variation4.phpt
+++ b/ext/session/tests/session_commit_variation4.phpt
@@ -2,6 +2,8 @@
Test session_commit() function : variation
--SKIPIF--
<?php include('skipif.inc'); ?>
+--INI--
+session.use_strict_mode=0
--FILE--
<?php
diff --git a/ext/session/tests/session_decode_basic_serialize.phpt b/ext/session/tests/session_decode_basic_serialize.phpt
new file mode 100644
index 0000000000..dd88438e15
--- /dev/null
+++ b/ext/session/tests/session_decode_basic_serialize.phpt
@@ -0,0 +1,274 @@
+--TEST--
+Test session_decode() function : basic functionality
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--FILE--
+<?php
+
+ob_start();
+
+/*
+ * Prototype : string session_decode(void)
+ * Description : Decodes session data from a string
+ * Source code : ext/session/session.c
+ */
+
+echo "*** Testing session_decode() : basic functionality ***\n";
+
+// Get an unset variable
+$unset_var = 10;
+unset($unset_var);
+
+class classA
+{
+ public function __toString() {
+ return "Hello World!";
+ }
+}
+
+$heredoc = <<<EOT
+Hello World!
+EOT;
+
+$fp = fopen(__FILE__, "r");
+
+// Unexpected values to be passed as arguments
+$inputs = array(
+
+ // Integer data
+/*1*/ 0,
+ 1,
+ 12345,
+ -2345,
+
+ // Float data
+/*5*/ 10.5,
+ -10.5,
+ 12.3456789000e10,
+ 12.3456789000E-10,
+ .5,
+
+ // Null data
+/*10*/ NULL,
+ null,
+
+ // Boolean data
+/*12*/ true,
+ false,
+ TRUE,
+ FALSE,
+
+ // Empty strings
+/*16*/ "",
+ '',
+
+ // Invalid string data
+/*18*/ "Nothing",
+ 'Nothing',
+ $heredoc,
+
+ // Object data
+/*21*/ new classA(),
+
+ // Undefined data
+/*22*/ @$undefined_var,
+
+ // Unset data
+/*23*/ @$unset_var,
+
+ // Resource variable
+/*24*/ $fp
+);
+
+ini_set('session.serialize_handler', 'php_serialize');
+var_dump(session_start());
+$iterator = 1;
+foreach($inputs as $input) {
+ echo "\n-- Iteration $iterator --\n";
+ $_SESSION["data"] = $input;
+ $encoded = session_encode();
+ var_dump(session_decode($encoded));
+ var_dump($_SESSION);
+ $iterator++;
+};
+
+var_dump(session_destroy());
+fclose($fp);
+echo "Done";
+ob_end_flush();
+?>
+--EXPECTF--
+*** Testing session_decode() : basic functionality ***
+bool(true)
+
+-- Iteration 1 --
+bool(true)
+array(1) {
+ ["data"]=>
+ int(0)
+}
+
+-- Iteration 2 --
+bool(true)
+array(1) {
+ ["data"]=>
+ int(1)
+}
+
+-- Iteration 3 --
+bool(true)
+array(1) {
+ ["data"]=>
+ int(12345)
+}
+
+-- Iteration 4 --
+bool(true)
+array(1) {
+ ["data"]=>
+ int(-2345)
+}
+
+-- Iteration 5 --
+bool(true)
+array(1) {
+ ["data"]=>
+ float(10.5)
+}
+
+-- Iteration 6 --
+bool(true)
+array(1) {
+ ["data"]=>
+ float(-10.5)
+}
+
+-- Iteration 7 --
+bool(true)
+array(1) {
+ ["data"]=>
+ float(123456789000)
+}
+
+-- Iteration 8 --
+bool(true)
+array(1) {
+ ["data"]=>
+ float(1.23456789E-9)
+}
+
+-- Iteration 9 --
+bool(true)
+array(1) {
+ ["data"]=>
+ float(0.5)
+}
+
+-- Iteration 10 --
+bool(true)
+array(1) {
+ ["data"]=>
+ NULL
+}
+
+-- Iteration 11 --
+bool(true)
+array(1) {
+ ["data"]=>
+ NULL
+}
+
+-- Iteration 12 --
+bool(true)
+array(1) {
+ ["data"]=>
+ bool(true)
+}
+
+-- Iteration 13 --
+bool(true)
+array(1) {
+ ["data"]=>
+ bool(false)
+}
+
+-- Iteration 14 --
+bool(true)
+array(1) {
+ ["data"]=>
+ bool(true)
+}
+
+-- Iteration 15 --
+bool(true)
+array(1) {
+ ["data"]=>
+ bool(false)
+}
+
+-- Iteration 16 --
+bool(true)
+array(1) {
+ ["data"]=>
+ string(0) ""
+}
+
+-- Iteration 17 --
+bool(true)
+array(1) {
+ ["data"]=>
+ string(0) ""
+}
+
+-- Iteration 18 --
+bool(true)
+array(1) {
+ ["data"]=>
+ string(7) "Nothing"
+}
+
+-- Iteration 19 --
+bool(true)
+array(1) {
+ ["data"]=>
+ string(7) "Nothing"
+}
+
+-- Iteration 20 --
+bool(true)
+array(1) {
+ ["data"]=>
+ string(12) "Hello World!"
+}
+
+-- Iteration 21 --
+bool(true)
+array(1) {
+ ["data"]=>
+ object(classA)#2 (0) {
+ }
+}
+
+-- Iteration 22 --
+bool(true)
+array(1) {
+ ["data"]=>
+ NULL
+}
+
+-- Iteration 23 --
+bool(true)
+array(1) {
+ ["data"]=>
+ NULL
+}
+
+-- Iteration 24 --
+bool(true)
+array(1) {
+ ["data"]=>
+ int(0)
+}
+bool(true)
+Done
+
diff --git a/ext/session/tests/session_encode_serialize.phpt b/ext/session/tests/session_encode_serialize.phpt
new file mode 100644
index 0000000000..41c79c3e51
--- /dev/null
+++ b/ext/session/tests/session_encode_serialize.phpt
@@ -0,0 +1,24 @@
+--TEST--
+Test session_encode() function : Numeric key raise error. bug65359
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--FILE--
+<?php
+ob_start();
+
+ini_set('session.serialize_handler', 'php_serialize');
+var_dump(session_start());
+$_SESSION[-3] = 'foo';
+$_SESSION[3] = 'bar';
+$_SESSION['var'] = 123;
+var_dump(session_encode());
+session_write_close();
+
+// Should finish without errors
+echo 'Done'.PHP_EOL;
+?>
+--EXPECTF--
+bool(true)
+string(51) "a:3:{i:-3;s:3:"foo";i:3;s:3:"bar";s:3:"var";i:123;}"
+Done
+
diff --git a/ext/session/tests/session_id_basic.phpt b/ext/session/tests/session_id_basic.phpt
index 5cb13c25ea..852d2f9578 100644
--- a/ext/session/tests/session_id_basic.phpt
+++ b/ext/session/tests/session_id_basic.phpt
@@ -20,6 +20,8 @@ var_dump(session_id("test"));
var_dump(session_id());
var_dump(session_id("1234567890"));
var_dump(session_id());
+// Turn off strice mode, since it does not allow uninitialized session ID
+ini_set('session.use_strict_mode',false);
var_dump(session_start());
var_dump(session_id());
var_dump(session_destroy());
diff --git a/ext/session/tests/session_name_error.phpt b/ext/session/tests/session_name_error.phpt
index 1b99d4ea35..9f0101d98b 100644
--- a/ext/session/tests/session_name_error.phpt
+++ b/ext/session/tests/session_name_error.phpt
@@ -231,6 +231,6 @@ string(12) "Hello World!"
-- Iteration 24 --
Warning: session_name() expects parameter 1 to be string, resource given in %s on line %d
-resource(5) of type (stream)
+resource(%d) of type (stream)
NULL
Done \ No newline at end of file
diff --git a/ext/session/tests/session_save_path_variation2.phpt b/ext/session/tests/session_save_path_variation2.phpt
index 6b08480312..dff070100c 100644
--- a/ext/session/tests/session_save_path_variation2.phpt
+++ b/ext/session/tests/session_save_path_variation2.phpt
@@ -32,7 +32,7 @@ ob_end_flush();
*** Testing session_save_path() : variation ***
string(5) "/blah"
-Warning: session_start(): open(%s, O_RDWR) failed: No such file or directory (2) in %s on line %d
+Warning: session_start(): open(/blah/%s, O_RDWR) failed: No such file or directory (2) in %s on line %d
bool(true)
string(5) "/blah"
bool(true)
diff --git a/ext/session/tests/session_save_path_variation5.phpt b/ext/session/tests/session_save_path_variation5.phpt
index 5407b5e15a..c015dcc95c 100644
--- a/ext/session/tests/session_save_path_variation5.phpt
+++ b/ext/session/tests/session_save_path_variation5.phpt
@@ -9,7 +9,6 @@ if(substr(PHP_OS, 0, 3) == "WIN")
session.save_handler=files
session.save_path=
session.name=PHPSESSID
-open_basedir=.
--FILE--
<?php
@@ -25,7 +24,7 @@ $directory = dirname(__FILE__);
$sessions = ($directory."/sessions");
chdir($directory);
-
+ini_set('open_basedir', '.');
// Delete the existing directory
if (file_exists($sessions) === TRUE) {
@rmdir($sessions);
diff --git a/ext/session/tests/session_set_save_handler_class_016.phpt b/ext/session/tests/session_set_save_handler_class_016.phpt
new file mode 100644
index 0000000000..2de03c0682
--- /dev/null
+++ b/ext/session/tests/session_set_save_handler_class_016.phpt
@@ -0,0 +1,90 @@
+--TEST--
+Test session_set_save_handler() function: class with create_sid
+--INI--
+session.save_handler=files
+session.name=PHPSESSID
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--FILE--
+<?php
+
+ob_start();
+
+/*
+ * Prototype : bool session_set_save_handler(SessionHandlerInterface $handler [, bool $register_shutdown_function = true])
+ * Description : Sets user-level session storage functions
+ * Source code : ext/session/session.c
+ */
+
+echo "*** Testing session_set_save_handler() function: class with create_sid ***\n";
+
+class MySession2 extends SessionHandler {
+ public $path;
+
+ public function open($path, $name) {
+ if (!$path) {
+ $path = sys_get_temp_dir();
+ }
+ $this->path = $path . '/u_sess_' . $name;
+ return true;
+ }
+
+ public function close() {
+ return true;
+ }
+
+ public function read($id) {
+ return @file_get_contents($this->path . $id);
+ }
+
+ public function write($id, $data) {
+ return file_put_contents($this->path . $id, $data);
+ }
+
+ public function destroy($id) {
+ @unlink($this->path . $id);
+ }
+
+ public function gc($maxlifetime) {
+ foreach (glob($this->path . '*') as $filename) {
+ if (filemtime($filename) + $maxlifetime < time()) {
+ @unlink($filename);
+ }
+ }
+ return true;
+ }
+
+ public function create_sid() {
+ return parent::create_sid();
+ }
+}
+
+$handler = new MySession2;
+session_set_save_handler($handler);
+session_start();
+
+$_SESSION['foo'] = "hello";
+
+var_dump(session_id(), ini_get('session.save_handler'), $_SESSION);
+
+session_write_close();
+session_unset();
+
+session_start();
+var_dump($_SESSION);
+
+session_write_close();
+session_unset();
+
+--EXPECTF--
+*** Testing session_set_save_handler() function: class with create_sid ***
+string(%d) "%s"
+string(4) "user"
+array(1) {
+ ["foo"]=>
+ string(5) "hello"
+}
+array(1) {
+ ["foo"]=>
+ string(5) "hello"
+}
diff --git a/ext/session/tests/session_set_save_handler_class_017.phpt b/ext/session/tests/session_set_save_handler_class_017.phpt
new file mode 100644
index 0000000000..756dc55d03
--- /dev/null
+++ b/ext/session/tests/session_set_save_handler_class_017.phpt
@@ -0,0 +1,90 @@
+--TEST--
+Test session_set_save_handler() function: class with create_sid
+--INI--
+session.save_handler=files
+session.name=PHPSESSID
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--FILE--
+<?php
+
+ob_start();
+
+/*
+ * Prototype : bool session_set_save_handler(SessionHandlerInterface $handler [, bool $register_shutdown_function = true])
+ * Description : Sets user-level session storage functions
+ * Source code : ext/session/session.c
+ */
+
+echo "*** Testing session_set_save_handler() function: class with create_sid ***\n";
+
+class MySession2 extends SessionHandler {
+ public $path;
+
+ public function open($path, $name) {
+ if (!$path) {
+ $path = sys_get_temp_dir();
+ }
+ $this->path = $path . '/u_sess_' . $name;
+ return true;
+ }
+
+ public function close() {
+ return true;
+ }
+
+ public function read($id) {
+ return @file_get_contents($this->path . $id);
+ }
+
+ public function write($id, $data) {
+ return file_put_contents($this->path . $id, $data);
+ }
+
+ public function destroy($id) {
+ @unlink($this->path . $id);
+ }
+
+ public function gc($maxlifetime) {
+ foreach (glob($this->path . '*') as $filename) {
+ if (filemtime($filename) + $maxlifetime < time()) {
+ @unlink($filename);
+ }
+ }
+ return true;
+ }
+
+ public function create_sid() {
+ return 'my_sid';
+ }
+}
+
+$handler = new MySession2;
+session_set_save_handler($handler);
+session_start();
+
+$_SESSION['foo'] = "hello";
+
+var_dump(session_id(), ini_get('session.save_handler'), $_SESSION);
+
+session_write_close();
+session_unset();
+
+session_start();
+var_dump($_SESSION);
+
+session_write_close();
+session_unset();
+
+--EXPECTF--
+*** Testing session_set_save_handler() function: class with create_sid ***
+string(%d) "my_sid"
+string(4) "user"
+array(1) {
+ ["foo"]=>
+ string(5) "hello"
+}
+array(1) {
+ ["foo"]=>
+ string(5) "hello"
+}
diff --git a/ext/session/tests/session_set_save_handler_error2.phpt b/ext/session/tests/session_set_save_handler_error2.phpt
index 03ba3b04d0..1f2a8b9e6a 100644
--- a/ext/session/tests/session_set_save_handler_error2.phpt
+++ b/ext/session/tests/session_set_save_handler_error2.phpt
@@ -2,6 +2,8 @@
Test session_set_save_handler() function : error functionality
--SKIPIF--
<?php include('skipif.inc'); ?>
+--INI--
+error_reporting=0
--FILE--
<?php
diff --git a/ext/session/tests/session_set_save_handler_error3.phpt b/ext/session/tests/session_set_save_handler_error3.phpt
index 446ef7b75b..cb07b0d8de 100644
--- a/ext/session/tests/session_set_save_handler_error3.phpt
+++ b/ext/session/tests/session_set_save_handler_error3.phpt
@@ -40,4 +40,3 @@ Stack trace:
#1 %s(%d): session_start()
#2 {main}
thrown in %s on line %d
-
diff --git a/ext/session/tests/session_set_save_handler_error4.phpt b/ext/session/tests/session_set_save_handler_error4.phpt
index 4debde5b0f..d286f07d99 100644
--- a/ext/session/tests/session_set_save_handler_error4.phpt
+++ b/ext/session/tests/session_set_save_handler_error4.phpt
@@ -39,4 +39,3 @@ Warning: session_set_save_handler(): Argument 4 is not a valid callback in %s on
Warning: session_set_save_handler(): Argument 5 is not a valid callback in %s on line %d
Warning: session_set_save_handler(): Argument 6 is not a valid callback in %s on line %d
-
diff --git a/ext/session/tests/session_set_save_handler_iface_003.phpt b/ext/session/tests/session_set_save_handler_iface_003.phpt
new file mode 100644
index 0000000000..bd757dce63
--- /dev/null
+++ b/ext/session/tests/session_set_save_handler_iface_003.phpt
@@ -0,0 +1,90 @@
+--TEST--
+Test session_set_save_handler() function: id interface
+--INI--
+session.save_handler=files
+session.name=PHPSESSID
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--FILE--
+<?php
+
+ob_start();
+
+/*
+ * Prototype : bool session_set_save_handler(SessionHandlerInterface $handler [, bool $register_shutdown_function = true])
+ * Description : Sets user-level session storage functions
+ * Source code : ext/session/session.c
+ */
+
+echo "*** Testing session_set_save_handler() function: id interface ***\n";
+
+class MySession2 implements SessionHandlerInterface, SessionIdInterface {
+ public $path;
+
+ public function open($path, $name) {
+ if (!$path) {
+ $path = sys_get_temp_dir();
+ }
+ $this->path = $path . '/u_sess_' . $name;
+ return true;
+ }
+
+ public function close() {
+ return true;
+ }
+
+ public function read($id) {
+ return @file_get_contents($this->path . $id);
+ }
+
+ public function write($id, $data) {
+ return file_put_contents($this->path . $id, $data);
+ }
+
+ public function destroy($id) {
+ @unlink($this->path . $id);
+ }
+
+ public function gc($maxlifetime) {
+ foreach (glob($this->path . '*') as $filename) {
+ if (filemtime($filename) + $maxlifetime < time()) {
+ @unlink($filename);
+ }
+ }
+ return true;
+ }
+
+ public function create_sid() {
+ return 'my_sid';
+ }
+}
+
+$handler = new MySession2;
+session_set_save_handler($handler);
+session_start();
+
+$_SESSION['foo'] = "hello";
+
+var_dump(session_id(), ini_get('session.save_handler'), $_SESSION);
+
+session_write_close();
+session_unset();
+
+session_start();
+var_dump($_SESSION);
+
+session_write_close();
+session_unset();
+
+--EXPECTF--
+*** Testing session_set_save_handler() function: id interface ***
+string(%d) "my_sid"
+string(4) "user"
+array(1) {
+ ["foo"]=>
+ string(5) "hello"
+}
+array(1) {
+ ["foo"]=>
+ string(5) "hello"
+}
diff --git a/ext/session/tests/session_set_save_handler_sid_001.phpt b/ext/session/tests/session_set_save_handler_sid_001.phpt
new file mode 100644
index 0000000000..0dc4fc11cf
--- /dev/null
+++ b/ext/session/tests/session_set_save_handler_sid_001.phpt
@@ -0,0 +1,85 @@
+--TEST--
+Test session_set_save_handler() function: create_sid
+--INI--
+session.save_handler=files
+session.name=PHPSESSID
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--FILE--
+<?php
+
+ob_start();
+
+echo "*** Testing session_set_save_handler() function: create_sid ***\n";
+
+class MySession2 {
+ public $path;
+
+ public function open($path, $name) {
+ if (!$path) {
+ $path = sys_get_temp_dir();
+ }
+ $this->path = $path . '/u_sess_' . $name;
+ return true;
+ }
+
+ public function close() {
+ return true;
+ }
+
+ public function read($id) {
+ return @file_get_contents($this->path . $id);
+ }
+
+ public function write($id, $data) {
+ return file_put_contents($this->path . $id, $data);
+ }
+
+ public function destroy($id) {
+ @unlink($this->path . $id);
+ }
+
+ public function gc($maxlifetime) {
+ foreach (glob($this->path . '*') as $filename) {
+ if (filemtime($filename) + $maxlifetime < time()) {
+ @unlink($filename);
+ }
+ }
+ return true;
+ }
+
+ public function create_sid() {
+ return 'my_sid';
+ }
+}
+
+$handler = new MySession2;
+session_set_save_handler(array($handler, 'open'), array($handler, 'close'),
+ array($handler, 'read'), array($handler, 'write'), array($handler, 'destroy'), array($handler, 'gc'), array($handler, 'create_sid'));
+session_start();
+
+$_SESSION['foo'] = "hello";
+
+var_dump(session_id(), ini_get('session.save_handler'), $_SESSION);
+
+session_write_close();
+session_unset();
+
+session_start();
+var_dump($_SESSION);
+
+session_write_close();
+session_unset();
+
+--EXPECTF--
+*** Testing session_set_save_handler() function: create_sid ***
+string(%d) "my_sid"
+string(4) "user"
+array(1) {
+ ["foo"]=>
+ string(5) "hello"
+}
+array(1) {
+ ["foo"]=>
+ string(5) "hello"
+}
diff --git a/ext/session/tests/session_set_save_handler_sid_002.phpt b/ext/session/tests/session_set_save_handler_sid_002.phpt
new file mode 100644
index 0000000000..f9a72aebca
--- /dev/null
+++ b/ext/session/tests/session_set_save_handler_sid_002.phpt
@@ -0,0 +1,77 @@
+--TEST--
+Test session_set_save_handler() function: create_sid
+--INI--
+session.save_handler=files
+session.name=PHPSESSID
+--SKIPIF--
+<?php include('skipif.inc'); ?>
+--FILE--
+<?php
+
+ob_start();
+
+echo "*** Testing session_set_save_handler() function: create_sid ***\n";
+
+class MySession2 {
+ public $path;
+
+ public function open($path, $name) {
+ if (!$path) {
+ $path = sys_get_temp_dir();
+ }
+ $this->path = $path . '/u_sess_' . $name;
+ return true;
+ }
+
+ public function close() {
+ return true;
+ }
+
+ public function read($id) {
+ return @file_get_contents($this->path . $id);
+ }
+
+ public function write($id, $data) {
+ return file_put_contents($this->path . $id, $data);
+ }
+
+ public function destroy($id) {
+ @unlink($this->path . $id);
+ }
+
+ public function gc($maxlifetime) {
+ foreach (glob($this->path . '*') as $filename) {
+ if (filemtime($filename) + $maxlifetime < time()) {
+ @unlink($filename);
+ }
+ }
+ return true;
+ }
+
+ public function create_sid() {
+ return null;
+ }
+}
+
+$handler = new MySession2;
+session_set_save_handler(array($handler, 'open'), array($handler, 'close'),
+ array($handler, 'read'), array($handler, 'write'), array($handler, 'destroy'), array($handler, 'gc'), array($handler, 'create_sid'));
+session_start();
+
+$_SESSION['foo'] = "hello";
+
+var_dump(session_id(), ini_get('session.save_handler'), $_SESSION);
+
+session_write_close();
+session_unset();
+
+session_start();
+var_dump($_SESSION);
+
+session_write_close();
+session_unset();
+
+--EXPECTF--
+*** Testing session_set_save_handler() function: create_sid ***
+
+Fatal error: session_start(): Session id must be a string in %s on line %d
diff --git a/ext/session/tests/session_write_close_variation4.phpt b/ext/session/tests/session_write_close_variation4.phpt
index 249c1555c0..9076dcf4a4 100644
--- a/ext/session/tests/session_write_close_variation4.phpt
+++ b/ext/session/tests/session_write_close_variation4.phpt
@@ -2,6 +2,8 @@
Test session_write_close() function : variation
--SKIPIF--
<?php include('skipif.inc'); ?>
+--INI--
+session.use_strict_mode=0
--FILE--
<?php
diff --git a/ext/simplexml/config.m4 b/ext/simplexml/config.m4
index 2145e23d88..387a24ea21 100644
--- a/ext/simplexml/config.m4
+++ b/ext/simplexml/config.m4
@@ -6,7 +6,7 @@ PHP_ARG_ENABLE(simplexml, whether to enable SimpleXML support,
if test -z "$PHP_LIBXML_DIR"; then
PHP_ARG_WITH(libxml-dir, libxml2 install dir,
- [ --with-libxml-dir=DIR SimpleXML: libxml2 install prefix], no, no)
+ [ --with-libxml-dir=DIR SimpleXML: libxml2 install prefix], no, no)
fi
if test "$PHP_SIMPLEXML" != "no"; then
diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c
index b9966ddcce..363ea1fc44 100644
--- a/ext/simplexml/simplexml.c
+++ b/ext/simplexml/simplexml.c
@@ -59,7 +59,7 @@ static zval *sxe_get_value(zval *z TSRMLS_DC);
static void php_sxe_iterator_dtor(zend_object_iterator *iter TSRMLS_DC);
static int php_sxe_iterator_valid(zend_object_iterator *iter TSRMLS_DC);
static void php_sxe_iterator_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC);
-static int php_sxe_iterator_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC);
+static void php_sxe_iterator_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC);
static void php_sxe_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC);
static void php_sxe_iterator_rewind(zend_object_iterator *iter TSRMLS_DC);
@@ -694,7 +694,7 @@ static void sxe_dimension_write(zval *object, zval *offset, zval *value TSRMLS_D
}
/* }}} */
-static zval** sxe_property_get_adr(zval *object, zval *member, const zend_literal *key TSRMLS_DC) /* {{{ */
+static zval** sxe_property_get_adr(zval *object, zval *member, int fetch_type, const zend_literal *key TSRMLS_DC) /* {{{ */
{
php_sxe_object *sxe;
xmlNodePtr node;
@@ -2376,29 +2376,22 @@ static void php_sxe_iterator_current_data(zend_object_iterator *iter, zval ***da
}
/* }}} */
-static int php_sxe_iterator_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) /* {{{ */
+static void php_sxe_iterator_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC) /* {{{ */
{
- zval *curobj;
- xmlNodePtr curnode = NULL;
- php_sxe_object *intern;
- int namelen;
-
php_sxe_iterator *iterator = (php_sxe_iterator *)iter;
- curobj = iterator->sxe->iter.data;
+ zval *curobj = iterator->sxe->iter.data;
+ php_sxe_object *intern = (php_sxe_object *)zend_object_store_get_object(curobj TSRMLS_CC);
- intern = (php_sxe_object *)zend_object_store_get_object(curobj TSRMLS_CC);
+ xmlNodePtr curnode = NULL;
if (intern != NULL && intern->node != NULL) {
curnode = (xmlNodePtr)((php_libxml_node_ptr *)intern->node)->node;
}
- if (!curnode) {
- return HASH_KEY_NON_EXISTANT;
- }
-
- namelen = xmlStrlen(curnode->name);
- *str_key = estrndup((char *)curnode->name, namelen);
- *str_key_len = namelen + 1;
- return HASH_KEY_IS_STRING;
+ if (curnode) {
+ ZVAL_STRINGL(key, (char *) curnode->name, xmlStrlen(curnode->name), 1);
+ } else {
+ ZVAL_NULL(key);
+ }
}
/* }}} */
diff --git a/ext/snmp/config.m4 b/ext/snmp/config.m4
index 9c0b82f778..dd7a3bf68d 100644
--- a/ext/snmp/config.m4
+++ b/ext/snmp/config.m4
@@ -3,7 +3,7 @@ dnl $Id$
dnl
PHP_ARG_WITH(snmp,for SNMP support,
-[ --with-snmp[=DIR] Include SNMP support])
+[ --with-snmp[=DIR] Include SNMP support])
PHP_ARG_WITH(openssl-dir,OpenSSL dir for SNMP,
[ --with-openssl-dir[=DIR] SNMP: openssl install prefix], no, no)
diff --git a/ext/snmp/snmp.c b/ext/snmp/snmp.c
index ce09c3b762..4dd4badcd2 100644
--- a/ext/snmp/snmp.c
+++ b/ext/snmp/snmp.c
@@ -2488,20 +2488,26 @@ PHP_MINFO_FUNCTION(snmp)
/* {{{ snmp_module_deps[]
*/
+#if ZEND_MODULE_API_NO >= 20050922
static const zend_module_dep snmp_module_deps[] = {
#ifdef HAVE_SPL
ZEND_MOD_REQUIRED("spl")
#endif
ZEND_MOD_END
};
+#endif
/* }}} */
/* {{{ snmp_module_entry
*/
zend_module_entry snmp_module_entry = {
+#if ZEND_MODULE_API_NO >= 20050922
STANDARD_MODULE_HEADER_EX,
NULL,
snmp_module_deps,
+#else
+ STANDARD_MODULE_HEADER,
+#endif
"snmp",
snmp_functions,
PHP_MINIT(snmp),
diff --git a/ext/soap/config.m4 b/ext/soap/config.m4
index 8acad8dee3..7fa8c6f0ec 100644
--- a/ext/soap/config.m4
+++ b/ext/soap/config.m4
@@ -6,7 +6,7 @@ PHP_ARG_ENABLE(soap, whether to enable SOAP support,
if test -z "$PHP_LIBXML_DIR"; then
PHP_ARG_WITH(libxml-dir, libxml2 install dir,
- [ --with-libxml-dir=DIR SOAP: libxml2 install prefix], no, no)
+ [ --with-libxml-dir=DIR SOAP: libxml2 install prefix], no, no)
fi
if test "$PHP_SOAP" != "no"; then
diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c
index 5e93b8af0d..32e88510e7 100644
--- a/ext/soap/php_encoding.c
+++ b/ext/soap/php_encoding.c
@@ -2313,10 +2313,6 @@ static xmlNodePtr to_xml_array(encodeTypePtr type, zval *data, int style, xmlNod
zend_object_iterator *iter;
zend_class_entry *ce = Z_OBJCE_P(data);
zval **val;
- char *str_key;
- uint str_key_len;
- ulong int_key;
- int key_type;
ALLOC_ZVAL(array_copy);
INIT_PZVAL(array_copy);
@@ -2345,19 +2341,14 @@ static xmlNodePtr to_xml_array(encodeTypePtr type, zval *data, int style, xmlNod
goto iterator_done;
}
if (iter->funcs->get_current_key) {
- key_type = iter->funcs->get_current_key(iter, &str_key, &str_key_len, &int_key TSRMLS_CC);
+ zval key;
+ iter->funcs->get_current_key(iter, &key TSRMLS_CC);
if (EG(exception)) {
goto iterator_done;
}
- switch(key_type) {
- case HASH_KEY_IS_STRING:
- add_assoc_zval_ex(array_copy, str_key, str_key_len, *val);
- efree(str_key);
- break;
- case HASH_KEY_IS_LONG:
- add_index_zval(array_copy, int_key, *val);
- break;
- }
+ array_set_zval_key(Z_ARRVAL_P(array_copy), &key, *val);
+ zval_ptr_dtor(val);
+ zval_dtor(&key);
} else {
add_next_index_zval(array_copy, *val);
}
diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c
index 9e74a7cc40..3d62bbe2f8 100644
--- a/ext/soap/php_http.c
+++ b/ext/soap/php_http.c
@@ -162,6 +162,7 @@ static php_stream* http_connect(zval* this_ptr, php_url *phpurl, int use_ssl, ph
zval **proxy_host, **proxy_port, **tmp;
char *host;
char *name;
+ char *protocol;
long namelen;
int port;
int old_error_reporting;
@@ -189,7 +190,41 @@ static php_stream* http_connect(zval* this_ptr, php_url *phpurl, int use_ssl, ph
old_error_reporting = EG(error_reporting);
EG(error_reporting) &= ~(E_WARNING|E_NOTICE|E_USER_WARNING|E_USER_NOTICE);
- namelen = spprintf(&name, 0, "%s://%s:%d", (use_ssl && !*use_proxy)? "ssl" : "tcp", host, port);
+ /* Changed ternary operator to an if/else so that additional comparisons can be done on the ssl_method property */
+ if (use_ssl && !*use_proxy) {
+ if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_ssl_method", sizeof("_ssl_method"), (void **) &tmp) == SUCCESS &&
+ Z_TYPE_PP(tmp) == IS_LONG) {
+ /* uses constants declared in soap.c to determine ssl uri protocol */
+ switch (Z_LVAL_PP(tmp)) {
+ case SOAP_SSL_METHOD_TLS:
+ protocol = "tls";
+ break;
+
+ case SOAP_SSL_METHOD_SSLv2:
+ protocol = "sslv2";
+ break;
+
+ case SOAP_SSL_METHOD_SSLv3:
+ protocol = "sslv3";
+ break;
+
+ case SOAP_SSL_METHOD_SSLv23:
+ protocol = "ssl";
+ break;
+
+ default:
+ protocol = "ssl";
+ break;
+
+ }
+ } else {
+ protocol = "ssl";
+ }
+ } else {
+ protocol = "tcp";
+ }
+
+ namelen = spprintf(&name, 0, "%s://%s:%d", protocol, host, port);
stream = php_stream_xport_create(name, namelen,
REPORT_ERRORS,
@@ -237,7 +272,34 @@ static php_stream* http_connect(zval* this_ptr, php_url *phpurl, int use_ssl, ph
}
/* enable SSL transport layer */
if (stream) {
- if (php_stream_xport_crypto_setup(stream, STREAM_CRYPTO_METHOD_SSLv23_CLIENT, NULL TSRMLS_CC) < 0 ||
+ /* if a stream is created without encryption, check to see if SSL method parameter is specified and use
+ proper encrypyion method based on constants defined in soap.c */
+ int crypto_method = STREAM_CRYPTO_METHOD_SSLv23_CLIENT;
+ if (zend_hash_find(Z_OBJPROP_P(this_ptr), "_ssl_method", sizeof("_ssl_method"), (void **) &tmp) == SUCCESS &&
+ Z_TYPE_PP(tmp) == IS_LONG) {
+ switch (Z_LVAL_PP(tmp)) {
+ case SOAP_SSL_METHOD_TLS:
+ crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT;
+ break;
+
+ case SOAP_SSL_METHOD_SSLv2:
+ crypto_method = STREAM_CRYPTO_METHOD_SSLv2_CLIENT;
+ break;
+
+ case SOAP_SSL_METHOD_SSLv3:
+ crypto_method = STREAM_CRYPTO_METHOD_SSLv3_CLIENT;
+ break;
+
+ case SOAP_SSL_METHOD_SSLv23:
+ crypto_method = STREAM_CRYPTO_METHOD_SSLv23_CLIENT;
+ break;
+
+ default:
+ crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT;
+ break;
+ }
+ }
+ if (php_stream_xport_crypto_setup(stream, crypto_method, NULL TSRMLS_CC) < 0 ||
php_stream_xport_crypto_enable(stream, 1 TSRMLS_CC) < 0) {
php_stream_close(stream);
stream = NULL;
diff --git a/ext/soap/php_soap.h b/ext/soap/php_soap.h
index 86facd0b6b..fb8d1d60fb 100644
--- a/ext/soap/php_soap.h
+++ b/ext/soap/php_soap.h
@@ -149,6 +149,13 @@ struct _soapService {
#define WSDL_CACHE_MEMORY 0x2
#define WSDL_CACHE_BOTH 0x3
+/* New SOAP SSL Method Constants */
+#define SOAP_SSL_METHOD_TLS 0
+#define SOAP_SSL_METHOD_SSLv2 1
+#define SOAP_SSL_METHOD_SSLv3 2
+#define SOAP_SSL_METHOD_SSLv23 3
+
+
ZEND_BEGIN_MODULE_GLOBALS(soap)
HashTable defEncNs; /* mapping of default namespaces to prefixes */
HashTable defEnc;
diff --git a/ext/soap/soap.c b/ext/soap/soap.c
index ca7f206bdd..60f6e21380 100644
--- a/ext/soap/soap.c
+++ b/ext/soap/soap.c
@@ -753,6 +753,12 @@ PHP_MINIT_FUNCTION(soap)
REGISTER_LONG_CONSTANT("WSDL_CACHE_MEMORY", WSDL_CACHE_MEMORY, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("WSDL_CACHE_BOTH", WSDL_CACHE_BOTH, CONST_CS | CONST_PERSISTENT);
+ /* New SOAP SSL Method Constants */
+ REGISTER_LONG_CONSTANT("SOAP_SSL_METHOD_TLS", SOAP_SSL_METHOD_TLS, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("SOAP_SSL_METHOD_SSLv2", SOAP_SSL_METHOD_SSLv2, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("SOAP_SSL_METHOD_SSLv3", SOAP_SSL_METHOD_SSLv3, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("SOAP_SSL_METHOD_SSLv23", SOAP_SSL_METHOD_SSLv23, CONST_CS | CONST_PERSISTENT);
+
old_error_handler = zend_error_cb;
zend_error_cb = soap_error_handler;
@@ -2497,6 +2503,11 @@ PHP_METHOD(SoapClient, SoapClient)
(Z_TYPE_PP(tmp) == IS_BOOL || Z_TYPE_PP(tmp) == IS_LONG) && Z_LVAL_PP(tmp) == 0) {
add_property_long(this_ptr, "_keep_alive", 0);
}
+
+ if (zend_hash_find(ht, "ssl_method", sizeof("ssl_method"), (void**)&tmp) == SUCCESS &&
+ Z_TYPE_PP(tmp) == IS_LONG) {
+ add_property_long(this_ptr, "_ssl_method", Z_LVAL_PP(tmp));
+ }
} else if (Z_TYPE_P(wsdl) == IS_NULL) {
php_error_docref(NULL TSRMLS_CC, E_ERROR, "'location' and 'uri' options are required in nonWSDL mode");
}
@@ -2535,7 +2546,7 @@ static int do_request(zval *this_ptr, xmlDoc *request, char *location, char *act
int ret = TRUE;
char *buf;
int buf_size;
- zval func, param0, param1, param2, param3, param4;
+ zval func;
zval *params[5];
zval **trace;
zval **fault;
@@ -2555,29 +2566,24 @@ static int do_request(zval *this_ptr, xmlDoc *request, char *location, char *act
INIT_ZVAL(func);
ZVAL_STRINGL(&func,"__doRequest",sizeof("__doRequest")-1,0);
- INIT_ZVAL(param0);
- params[0] = &param0;
- ZVAL_STRINGL(params[0], buf, buf_size, 0);
- INIT_ZVAL(param1);
- params[1] = &param1;
+ ALLOC_INIT_ZVAL(params[0]);
+ ZVAL_STRINGL(params[0], buf, buf_size, 1);
+ ALLOC_INIT_ZVAL(params[1]);
if (location == NULL) {
ZVAL_NULL(params[1]);
} else {
- ZVAL_STRING(params[1], location, 0);
+ ZVAL_STRING(params[1], location, 1);
}
- INIT_ZVAL(param2);
- params[2] = &param2;
+ ALLOC_INIT_ZVAL(params[2]);
if (action == NULL) {
ZVAL_NULL(params[2]);
} else {
- ZVAL_STRING(params[2], action, 0);
+ ZVAL_STRING(params[2], action, 1);
}
- INIT_ZVAL(param3);
- params[3] = &param3;
+ ALLOC_INIT_ZVAL(params[3]);
ZVAL_LONG(params[3], version);
- INIT_ZVAL(param4);
- params[4] = &param4;
+ ALLOC_INIT_ZVAL(params[4]);
ZVAL_LONG(params[4], one_way);
if (call_user_function(NULL, &this_ptr, &func, response, 5, params TSRMLS_CC) != SUCCESS) {
@@ -2592,6 +2598,11 @@ static int do_request(zval *this_ptr, xmlDoc *request, char *location, char *act
Z_LVAL_PP(trace) > 0) {
add_property_stringl(this_ptr, "__last_response", Z_STRVAL_P(response), Z_STRLEN_P(response), 1);
}
+ zval_ptr_dtor(&params[4]);
+ zval_ptr_dtor(&params[3]);
+ zval_ptr_dtor(&params[2]);
+ zval_ptr_dtor(&params[1]);
+ zval_ptr_dtor(&params[0]);
xmlFree(buf);
if (ret && zend_hash_find(Z_OBJPROP_P(this_ptr), "__soap_fault", sizeof("__soap_fault"), (void **) &fault) == SUCCESS) {
return FALSE;
@@ -2683,124 +2694,134 @@ static void do_soap_call(zval* this_ptr,
SOAP_GLOBAL(features) = 0;
}
- if (sdl != NULL) {
- fn = get_function(sdl, function);
- if (fn != NULL) {
- sdlBindingPtr binding = fn->binding;
- int one_way = 0;
-
- if (fn->responseName == NULL &&
- fn->responseParameters == NULL &&
- soap_headers == NULL) {
- one_way = 1;
- }
-
- if (location == NULL) {
- location = binding->location;
- }
- if (binding->bindingType == BINDING_SOAP) {
- sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)fn->bindingAttributes;
- request = serialize_function_call(this_ptr, fn, NULL, fnb->input.ns, real_args, arg_count, soap_version, soap_headers TSRMLS_CC);
- ret = do_request(this_ptr, request, location, fnb->soapAction, soap_version, one_way, &response TSRMLS_CC);
- } else {
- request = serialize_function_call(this_ptr, fn, NULL, sdl->target_ns, real_args, arg_count, soap_version, soap_headers TSRMLS_CC);
- ret = do_request(this_ptr, request, location, NULL, soap_version, one_way, &response TSRMLS_CC);
- }
-
- xmlFreeDoc(request);
-
- if (ret && Z_TYPE(response) == IS_STRING) {
- encode_reset_ns();
- ret = parse_packet_soap(this_ptr, Z_STRVAL(response), Z_STRLEN(response), fn, NULL, return_value, output_headers TSRMLS_CC);
- encode_finish();
- }
+ zend_try {
+ if (sdl != NULL) {
+ fn = get_function(sdl, function);
+ if (fn != NULL) {
+ sdlBindingPtr binding = fn->binding;
+ int one_way = 0;
+
+ if (fn->responseName == NULL &&
+ fn->responseParameters == NULL &&
+ soap_headers == NULL) {
+ one_way = 1;
+ }
- zval_dtor(&response);
+ if (location == NULL) {
+ location = binding->location;
+ }
+ if (binding->bindingType == BINDING_SOAP) {
+ sdlSoapBindingFunctionPtr fnb = (sdlSoapBindingFunctionPtr)fn->bindingAttributes;
+ request = serialize_function_call(this_ptr, fn, NULL, fnb->input.ns, real_args, arg_count, soap_version, soap_headers TSRMLS_CC);
+ ret = do_request(this_ptr, request, location, fnb->soapAction, soap_version, one_way, &response TSRMLS_CC);
+ } else {
+ request = serialize_function_call(this_ptr, fn, NULL, sdl->target_ns, real_args, arg_count, soap_version, soap_headers TSRMLS_CC);
+ ret = do_request(this_ptr, request, location, NULL, soap_version, one_way, &response TSRMLS_CC);
+ }
+
+ xmlFreeDoc(request);
+
+ if (ret && Z_TYPE(response) == IS_STRING) {
+ encode_reset_ns();
+ ret = parse_packet_soap(this_ptr, Z_STRVAL(response), Z_STRLEN(response), fn, NULL, return_value, output_headers TSRMLS_CC);
+ encode_finish();
+ }
- } else {
- smart_str error = {0};
- smart_str_appends(&error,"Function (\"");
- smart_str_appends(&error,function);
- smart_str_appends(&error,"\") is not a valid method for this service");
- smart_str_0(&error);
- add_soap_fault(this_ptr, "Client", error.c, NULL, NULL TSRMLS_CC);
- smart_str_free(&error);
- }
- } else {
- zval **uri;
- smart_str action = {0};
+ zval_dtor(&response);
- if (zend_hash_find(Z_OBJPROP_P(this_ptr), "uri", sizeof("uri"), (void *)&uri) == FAILURE) {
- add_soap_fault(this_ptr, "Client", "Error finding \"uri\" property", NULL, NULL TSRMLS_CC);
- } else if (location == NULL) {
- add_soap_fault(this_ptr, "Client", "Error could not find \"location\" property", NULL, NULL TSRMLS_CC);
- } else {
- if (call_uri == NULL) {
- call_uri = Z_STRVAL_PP(uri);
+ } else {
+ smart_str error = {0};
+ smart_str_appends(&error,"Function (\"");
+ smart_str_appends(&error,function);
+ smart_str_appends(&error,"\") is not a valid method for this service");
+ smart_str_0(&error);
+ add_soap_fault(this_ptr, "Client", error.c, NULL, NULL TSRMLS_CC);
+ smart_str_free(&error);
}
- request = serialize_function_call(this_ptr, NULL, function, call_uri, real_args, arg_count, soap_version, soap_headers TSRMLS_CC);
+ } else {
+ zval **uri;
+ smart_str action = {0};
- if (soap_action == NULL) {
- smart_str_appends(&action, call_uri);
- smart_str_appendc(&action, '#');
- smart_str_appends(&action, function);
+ if (zend_hash_find(Z_OBJPROP_P(this_ptr), "uri", sizeof("uri"), (void *)&uri) == FAILURE) {
+ add_soap_fault(this_ptr, "Client", "Error finding \"uri\" property", NULL, NULL TSRMLS_CC);
+ } else if (location == NULL) {
+ add_soap_fault(this_ptr, "Client", "Error could not find \"location\" property", NULL, NULL TSRMLS_CC);
} else {
- smart_str_appends(&action, soap_action);
- }
- smart_str_0(&action);
+ if (call_uri == NULL) {
+ call_uri = Z_STRVAL_PP(uri);
+ }
+ request = serialize_function_call(this_ptr, NULL, function, call_uri, real_args, arg_count, soap_version, soap_headers TSRMLS_CC);
- ret = do_request(this_ptr, request, location, action.c, soap_version, 0, &response TSRMLS_CC);
+ if (soap_action == NULL) {
+ smart_str_appends(&action, call_uri);
+ smart_str_appendc(&action, '#');
+ smart_str_appends(&action, function);
+ } else {
+ smart_str_appends(&action, soap_action);
+ }
+ smart_str_0(&action);
- smart_str_free(&action);
- xmlFreeDoc(request);
+ ret = do_request(this_ptr, request, location, action.c, soap_version, 0, &response TSRMLS_CC);
- if (ret && Z_TYPE(response) == IS_STRING) {
- encode_reset_ns();
- ret = parse_packet_soap(this_ptr, Z_STRVAL(response), Z_STRLEN(response), NULL, function, return_value, output_headers TSRMLS_CC);
- encode_finish();
- }
+ smart_str_free(&action);
+ xmlFreeDoc(request);
- zval_dtor(&response);
- }
- }
+ if (ret && Z_TYPE(response) == IS_STRING) {
+ encode_reset_ns();
+ ret = parse_packet_soap(this_ptr, Z_STRVAL(response), Z_STRLEN(response), NULL, function, return_value, output_headers TSRMLS_CC);
+ encode_finish();
+ }
+
+ zval_dtor(&response);
+ }
+ }
- if (!ret) {
- zval** fault;
- if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__soap_fault", sizeof("__soap_fault"), (void **) &fault) == SUCCESS) {
- *return_value = **fault;
- zval_copy_ctor(return_value);
+ if (!ret) {
+ zval** fault;
+ if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__soap_fault", sizeof("__soap_fault"), (void **) &fault) == SUCCESS) {
+ *return_value = **fault;
+ zval_copy_ctor(return_value);
+ } else {
+ *return_value = *add_soap_fault(this_ptr, "Client", "Unknown Error", NULL, NULL TSRMLS_CC);
+ zval_copy_ctor(return_value);
+ }
} else {
- *return_value = *add_soap_fault(this_ptr, "Client", "Unknown Error", NULL, NULL TSRMLS_CC);
- zval_copy_ctor(return_value);
- }
- } else {
- zval** fault;
- if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__soap_fault", sizeof("__soap_fault"), (void **) &fault) == SUCCESS) {
- *return_value = **fault;
- zval_copy_ctor(return_value);
+ zval** fault;
+ if (zend_hash_find(Z_OBJPROP_P(this_ptr), "__soap_fault", sizeof("__soap_fault"), (void **) &fault) == SUCCESS) {
+ *return_value = **fault;
+ zval_copy_ctor(return_value);
+ }
}
- }
- if (!EG(exception) &&
- Z_TYPE_P(return_value) == IS_OBJECT &&
- instanceof_function(Z_OBJCE_P(return_value), soap_fault_class_entry TSRMLS_CC) &&
- (zend_hash_find(Z_OBJPROP_P(this_ptr), "_exceptions", sizeof("_exceptions"), (void **) &tmp) != SUCCESS ||
- Z_TYPE_PP(tmp) != IS_BOOL || Z_LVAL_PP(tmp) != 0)) {
- zval *exception;
+ if (!EG(exception) &&
+ Z_TYPE_P(return_value) == IS_OBJECT &&
+ instanceof_function(Z_OBJCE_P(return_value), soap_fault_class_entry TSRMLS_CC) &&
+ (zend_hash_find(Z_OBJPROP_P(this_ptr), "_exceptions", sizeof("_exceptions"), (void **) &tmp) != SUCCESS ||
+ Z_TYPE_PP(tmp) != IS_BOOL || Z_LVAL_PP(tmp) != 0)) {
+ zval *exception;
- MAKE_STD_ZVAL(exception);
- MAKE_COPY_ZVAL(&return_value, exception);
- zend_throw_exception_object(exception TSRMLS_CC);
- }
+ MAKE_STD_ZVAL(exception);
+ MAKE_COPY_ZVAL(&return_value, exception);
+ zend_throw_exception_object(exception TSRMLS_CC);
+ }
+ } zend_catch {
+ _bailout = 1;
+ } zend_end_try();
+
if (SOAP_GLOBAL(encoding) != NULL) {
xmlCharEncCloseFunc(SOAP_GLOBAL(encoding));
}
+
SOAP_GLOBAL(features) = old_features;
SOAP_GLOBAL(typemap) = old_typemap;
SOAP_GLOBAL(class_map) = old_class_map;
SOAP_GLOBAL(encoding) = old_encoding;
SOAP_GLOBAL(sdl) = old_sdl;
+ if (_bailout) {
+ _bailout = 0;
+ zend_bailout();
+ }
SOAP_CLIENT_END_CODE();
}
diff --git a/ext/soap/tests/bugs/bug34657.phpt b/ext/soap/tests/bugs/bug34657.phpt
index d974d02cc6..9b67ec69ad 100644
--- a/ext/soap/tests/bugs/bug34657.phpt
+++ b/ext/soap/tests/bugs/bug34657.phpt
@@ -25,11 +25,6 @@ try {
}
?>
--EXPECTF--
-Warning: SoapClient::SoapClient(): %s %sbug34657.php on line 3
-
-Warning: SoapClient::SoapClient(http://i_dont_exist.com/some.wsdl): failed to open stream: %sbug34657.php on line 3
-
-Warning: SoapClient::SoapClient(): I/O warning : failed to load external entity "http://i_dont_exist.com/some.wsdl" in %sbug34657.php on line 3
SoapFault
-SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://i_dont_exist.com/some.wsdl'%S
+SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://i_dont_exist.com/some.wsdl'%A
ok
diff --git a/ext/soap/tests/bugs/bug47273.phpt b/ext/soap/tests/bugs/bug47273.phpt
index 174948f59f..1cfb0f3cd9 100644
--- a/ext/soap/tests/bugs/bug47273.phpt
+++ b/ext/soap/tests/bugs/bug47273.phpt
@@ -2,9 +2,6 @@
Bug #47273 (Encoding bug in SoapServer->fault)
--SKIPIF--
<?php require_once('skipif.inc'); ?>
---INI--
-unicode.script_encoding=ISO-8859-1
-unicode.output_encoding=ISO-8859-1
--FILE--
<?php
$request1 = <<<EOF
diff --git a/ext/soap/tests/bugs/bug66112.phpt b/ext/soap/tests/bugs/bug66112.phpt
new file mode 100644
index 0000000000..4d5be79296
--- /dev/null
+++ b/ext/soap/tests/bugs/bug66112.phpt
@@ -0,0 +1,36 @@
+--TEST--
+Bug #66112 (Use after free condition in SOAP extension)
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--INI--
+soap.wsdl_cache_enabled=0
+--FILE--
+<?php
+define('WSDL', dirname(__FILE__)."/bug66112.wsdl");
+function Mist($p) {
+ $client=new soapclient(WSDL, array('typemap'=>array(array("type_ns"=>"uri:mist", "type_name"=>"A"))));
+ try{
+ $client->Mist(array("XX"=>"xx"));
+ }catch(SoapFault $x){
+ }
+ return array("A"=>"ABC","B"=>"sss");
+}
+$s = new SoapServer(WSDL, array('typemap'=>array(array("type_ns"=>"uri:mist", "type_name"=>"A"))));
+$s->addFunction("Mist");
+$_SERVER["REQUEST_METHOD"] = "POST";
+$HTTP_RAW_POST_DATA=<<<EOF
+<?xml version="1.0" encoding="UTF-8"?>
+<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:uri="uri:mist">
+ <soapenv:Header/>
+ <soapenv:Body>
+ <uri:Request><uri:A>XXX</uri:A><uri:B>yyy</uri:B></uri:Request>
+ </soapenv:Body>
+</soapenv:Envelope>
+EOF;
+$s->handle($HTTP_RAW_POST_DATA);
+echo "OK\n";
+?>
+--EXPECT--
+<?xml version="1.0" encoding="UTF-8"?>
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="uri:mist"><SOAP-ENV:Body><ns1:Response><A>ABC</A><B>sss</B></ns1:Response></SOAP-ENV:Body></SOAP-ENV:Envelope>
+OK
diff --git a/ext/soap/tests/bugs/bug66112.wsdl b/ext/soap/tests/bugs/bug66112.wsdl
new file mode 100644
index 0000000000..8589a46bf2
--- /dev/null
+++ b/ext/soap/tests/bugs/bug66112.wsdl
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<wsdl:definitions xmlns:tns="uri:mist" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="test" targetNamespace="uri:mist">
+ <wsdl:types>
+ <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="uri:mist">
+ <xs:complexType name="T1">
+ <xs:sequence>
+ <xs:element name="A" type="xsd:string"/><xs:element name="B" type="xsd:string"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:element name="Request" type="tns:T1"/><xs:element name="Response" type="tns:T1"/>
+ </xs:schema>
+ </wsdl:types>
+ <wsdl:message name="Request">
+ <wsdl:part name="Request" element="tns:Request"/>
+ </wsdl:message>
+ <wsdl:message name="Response">
+ <wsdl:part name="Response" element="tns:Response"/>
+ </wsdl:message>
+ <wsdl:portType name="test">
+ <wsdl:operation name="Mist">
+ <wsdl:input message="tns:Request"/>
+ <wsdl:output message="tns:Response"/>
+ </wsdl:operation>
+ </wsdl:portType>
+ <wsdl:binding name="test" type="tns:test">
+ <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
+ <wsdl:operation name="Mist">
+ <soap:operation soapAction="Mist"/>
+ <wsdl:input>
+ <soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output>
+ <soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ </wsdl:binding>
+ <wsdl:service name="test">
+ <wsdl:port name="test" binding="tns:test">
+ <soap:address location="http://127.0.0.1:81/mist.php"/>
+ </wsdl:port>
+ </wsdl:service>
+</wsdl:definitions>
diff --git a/ext/sockets/config.m4 b/ext/sockets/config.m4
index 4032621ce6..a5a63dfb61 100644
--- a/ext/sockets/config.m4
+++ b/ext/sockets/config.m4
@@ -16,10 +16,10 @@ if test "$PHP_SOCKETS" != "no"; then
if test "$ac_cv_cmsghdr" = yes; then
AC_DEFINE(HAVE_CMSGHDR,1,[Whether you have struct cmsghdr])
- fi
+ fi
AC_CHECK_FUNCS([hstrerror socketpair if_nametoindex if_indextoname])
- AC_CHECK_HEADERS([netdb.h netinet/tcp.h sys/un.h sys/sockio.h errno.h])
+ AC_CHECK_HEADERS([netdb.h netinet/tcp.h sys/un.h sys/sockio.h errno.h])
AC_TRY_COMPILE([
#include <sys/types.h>
#include <sys/socket.h>
@@ -27,7 +27,7 @@ if test "$PHP_SOCKETS" != "no"; then
[AC_DEFINE(MISSING_MSGHDR_MSGFLAGS, 1, [ ])]
)
AC_DEFINE([HAVE_SOCKETS], 1, [ ])
-
+
dnl Check for fied ss_family in sockaddr_storage (missing in AIX until 5.3)
AC_CACHE_CHECK([for field ss_family in struct sockaddr_storage], ac_cv_ss_family,
[
@@ -38,11 +38,24 @@ if test "$PHP_SOCKETS" != "no"; then
], [struct sockaddr_storage sa_store; sa_store.ss_family = AF_INET6;],
ac_cv_ss_family=yes, ac_cv_ss_family=no)
])
-
+
if test "$ac_cv_ss_family" = yes; then
AC_DEFINE(HAVE_SA_SS_FAMILY,1,[Whether you have sockaddr_storage.ss_family])
fi
- PHP_NEW_EXTENSION([sockets], [sockets.c multicast.c], [$ext_shared])
+ dnl Check for AI_V4MAPPED flag
+ AC_CACHE_CHECK([if getaddrinfo supports AI_V4MAPPED],[ac_cv_gai_ai_v4mapped],
+ [
+ AC_TRY_COMPILE([
+#include <netdb.h>
+ ], [int flag = AI_V4MAPPED;],
+ ac_cv_gai_ai_v4mapped=yes, ac_cv_gai_ai_v4mapped=no)
+ ])
+
+ if test "$ac_cv_gai_ai_v4mapped" = yes; then
+ AC_DEFINE(HAVE_AI_V4MAPPED,1,[Whether you have AI_V4MAPPED])
+ fi
+
+ PHP_NEW_EXTENSION([sockets], [sockets.c multicast.c conversions.c sockaddr_conv.c sendrecvmsg.c], [$ext_shared])
PHP_INSTALL_HEADERS([ext/sockets/], [php_sockets.h])
fi
diff --git a/ext/sockets/config.w32 b/ext/sockets/config.w32
index 9c234db8f8..aeaa8ed425 100644
--- a/ext/sockets/config.w32
+++ b/ext/sockets/config.w32
@@ -7,7 +7,7 @@ if (PHP_SOCKETS != "no") {
if (CHECK_LIB("ws2_32.lib", "sockets", PHP_SOCKETS)
&& CHECK_LIB("Iphlpapi.lib", "sockets", PHP_SOCKETS)
&& CHECK_HEADER_ADD_INCLUDE("winsock.h", "CFLAGS_SOCKETS")) {
- EXTENSION('sockets', 'sockets.c multicast.c');
+ EXTENSION('sockets', 'sockets.c multicast.c conversions.c sockaddr_conv.c sendrecvmsg.c');
AC_DEFINE('HAVE_SOCKETS', 1);
PHP_INSTALL_HEADERS("ext/sockets", "php_sockets.h");
} else {
diff --git a/ext/sockets/conversions.c b/ext/sockets/conversions.c
new file mode 100644
index 0000000000..d81484521d
--- /dev/null
+++ b/ext/sockets/conversions.c
@@ -0,0 +1,1561 @@
+#include "sockaddr_conv.h"
+#include "conversions.h"
+#include "sendrecvmsg.h" /* for ancillary registry */
+#ifdef PHP_WIN32
+# include "windows_common.h"
+#endif
+
+#include <Zend/zend_llist.h>
+#include <ext/standard/php_smart_str.h>
+
+#ifndef PHP_WIN32
+# include <sys/types.h>
+# include <sys/socket.h>
+# include <arpa/inet.h>
+# include <netinet/in.h>
+# include <sys/un.h>
+# include <sys/ioctl.h>
+# include <net/if.h>
+#else
+# include <win32/php_stdint.h>
+#endif
+
+#include <limits.h>
+#include <stdarg.h>
+#include <stddef.h>
+
+#ifdef PHP_WIN32
+typedef unsigned short sa_family_t;
+# define msghdr _WSAMSG
+/*
+struct _WSAMSG {
+ LPSOCKADDR name; //void *msg_name
+ INT namelen; //socklen_t msg_namelen
+ LPWSABUF lpBuffers; //struct iovec *msg_iov
+ ULONG dwBufferCount; //size_t msg_iovlen
+ WSABUF Control; //void *msg_control, size_t msg_controllen
+ DWORD dwFlags; //int msg_flags
+}
+struct __WSABUF {
+ u_long len; //size_t iov_len (2nd member)
+ char FAR *buf; //void *iov_base (1st member)
+}
+struct _WSACMSGHDR {
+ UINT cmsg_len; //socklen_t cmsg_len
+ INT cmsg_level; //int cmsg_level
+ INT cmsg_type; //int cmsg_type;
+ followed by UCHAR cmsg_data[]
+}
+*/
+# define msg_name name
+# define msg_namelen namelen
+# define msg_iov lpBuffers
+# define msg_iovlen dwBufferCount
+# define msg_control Control.buf
+# define msg_controllen Control.len
+# define msg_flags dwFlags
+# define iov_base buf
+# define iov_len len
+
+# define cmsghdr _WSACMSGHDR
+# ifdef CMSG_DATA
+# undef CMSG_DATA
+# endif
+# define CMSG_DATA WSA_CMSG_DATA
+#endif
+
+#define MAX_USER_BUFF_SIZE ((size_t)(100*1024*1024))
+#define DEFAULT_BUFF_SIZE 8192
+
+struct _ser_context {
+ HashTable params; /* stores pointers; has to be first */
+ struct err_s err;
+ zend_llist keys,
+ /* common part to res_context ends here */
+ allocations;
+ php_socket *sock;
+};
+struct _res_context {
+ HashTable params; /* stores pointers; has to be first */
+ struct err_s err;
+ zend_llist keys;
+};
+
+typedef struct {
+ /* zval info */
+ const char *name;
+ unsigned name_size;
+ int required;
+
+ /* structure info */
+ size_t field_offset; /* 0 to pass full structure, e.g. when more than
+ one field is to be changed; in that case the
+ callbacks need to know the name of the fields */
+
+ /* callbacks */
+ from_zval_write_field *from_zval;
+ to_zval_read_field *to_zval;
+} field_descriptor;
+
+#define KEY_FILL_SOCKADDR "fill_sockaddr"
+#define KEY_RECVMSG_RET "recvmsg_ret"
+#define KEY_CMSG_LEN "cmsg_len"
+
+const struct key_value empty_key_value_list[] = {{0}};
+
+/* PARAMETERS */
+static int param_get_bool(void *ctx, const char *key, int def)
+{
+ int **elem;
+ if (zend_hash_find(ctx, key, strlen(key) + 1, (void**)&elem) == SUCCESS) {
+ return **elem;
+ } else {
+ return def;
+ }
+}
+
+/* MEMORY */
+static inline void *accounted_emalloc(size_t alloc_size, ser_context *ctx)
+{
+ void *ret = emalloc(alloc_size);
+ zend_llist_add_element(&ctx->allocations, &ret);
+ return ret;
+}
+static inline void *accounted_ecalloc(size_t nmemb, size_t alloc_size, ser_context *ctx)
+{
+ void *ret = ecalloc(nmemb, alloc_size);
+ zend_llist_add_element(&ctx->allocations, &ret);
+ return ret;
+}
+static inline void *accounted_safe_ecalloc(size_t nmemb, size_t alloc_size, size_t offset, ser_context *ctx)
+{
+ void *ret = safe_emalloc(nmemb, alloc_size, offset);
+ memset(ret, '\0', nmemb * alloc_size + offset);
+ zend_llist_add_element(&ctx->allocations, &ret);
+ return ret;
+}
+
+/* ERRORS */
+static void do_from_to_zval_err(struct err_s *err,
+ zend_llist *keys,
+ const char *what_conv,
+ const char *fmt,
+ va_list ap)
+{
+ smart_str path = {0};
+ const char **node;
+ char *user_msg;
+ int user_msg_size;
+ zend_llist_position pos;
+
+ if (err->has_error) {
+ return;
+ }
+
+ for (node = zend_llist_get_first_ex(keys, &pos);
+ node != NULL;
+ node = zend_llist_get_next_ex(keys, &pos)) {
+ smart_str_appends(&path, *node);
+ smart_str_appends(&path, " > ");
+ }
+
+ if (path.len > 3) {
+ path.len -= 3;
+ }
+ smart_str_0(&path);
+
+ user_msg_size = vspprintf(&user_msg, 0, fmt, ap);
+
+ err->has_error = 1;
+ err->level = E_WARNING;
+ spprintf(&err->msg, 0, "error converting %s data (path: %s): %.*s",
+ what_conv,
+ path.c && path.c != '\0' ? path.c : "unavailable",
+ user_msg_size, user_msg);
+ err->should_free = 1;
+
+ efree(user_msg);
+ smart_str_free_ex(&path, 0);
+}
+ZEND_ATTRIBUTE_FORMAT(printf, 2 ,3)
+static void do_from_zval_err(ser_context *ctx, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ do_from_to_zval_err(&ctx->err, &ctx->keys, "user", fmt, ap);
+ va_end(ap);
+}
+ZEND_ATTRIBUTE_FORMAT(printf, 2 ,3)
+static void do_to_zval_err(res_context *ctx, const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ do_from_to_zval_err(&ctx->err, &ctx->keys, "native", fmt, ap);
+ va_end(ap);
+}
+
+void err_msg_dispose(struct err_s *err TSRMLS_DC)
+{
+ if (err->msg != NULL) {
+ php_error_docref0(NULL TSRMLS_CC, err->level, "%s", err->msg);
+ if (err->should_free) {
+ efree(err->msg);
+ }
+ }
+}
+void allocations_dispose(zend_llist **allocations)
+{
+ zend_llist_destroy(*allocations);
+ efree(*allocations);
+ *allocations = NULL;
+}
+
+static unsigned from_array_iterate(const zval *arr,
+ void (*func)(zval **elem, unsigned i, void **args, ser_context *ctx),
+ void **args,
+ ser_context *ctx)
+{
+ HashPosition pos;
+ unsigned i;
+ zval **elem;
+ char buf[sizeof("element #4294967295")];
+ char *bufp = buf;
+
+ /* Note i starts at 1, not 0! */
+ for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(arr), &pos), i = 1;
+ !ctx->err.has_error
+ && zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (void **)&elem, &pos) == SUCCESS;
+ zend_hash_move_forward_ex(Z_ARRVAL_P(arr), &pos), i++) {
+ if (snprintf(buf, sizeof(buf), "element #%u", i) >= sizeof(buf)) {
+ memcpy(buf, "element", sizeof("element"));
+ }
+ zend_llist_add_element(&ctx->keys, &bufp);
+
+ func(elem, i, args, ctx);
+
+ zend_llist_remove_tail(&ctx->keys);
+ }
+
+ return i -1;
+}
+
+/* Generic Aggregated conversions */
+static void from_zval_write_aggregation(const zval *container,
+ char *structure,
+ const field_descriptor *descriptors,
+ ser_context *ctx)
+{
+ const field_descriptor *descr;
+ zval **elem;
+
+ if (Z_TYPE_P(container) != IS_ARRAY) {
+ do_from_zval_err(ctx, "%s", "expected an array here");
+ }
+
+ for (descr = descriptors; descr->name != NULL && !ctx->err.has_error; descr++) {
+ if (zend_hash_find(Z_ARRVAL_P(container),
+ descr->name, descr->name_size, (void**)&elem) == SUCCESS) {
+
+ if (descr->from_zval == NULL) {
+ do_from_zval_err(ctx, "No information on how to convert value "
+ "of key '%s'", descr->name);
+ break;
+ }
+
+ zend_llist_add_element(&ctx->keys, (void*)&descr->name);
+ descr->from_zval(*elem, ((char*)structure) + descr->field_offset, ctx);
+ zend_llist_remove_tail(&ctx->keys);
+
+ } else if (descr->required) {
+ do_from_zval_err(ctx, "The key '%s' is required", descr->name);
+ break;
+ }
+ }
+}
+static void to_zval_read_aggregation(const char *structure,
+ zval *zarr, /* initialized array */
+ const field_descriptor *descriptors,
+ res_context *ctx)
+{
+ const field_descriptor *descr;
+
+ assert(Z_TYPE_P(zarr) == IS_ARRAY);
+ assert(Z_ARRVAL_P(zarr) != NULL);
+
+ for (descr = descriptors; descr->name != NULL && !ctx->err.has_error; descr++) {
+ zval *new_zv;
+
+ if (descr->to_zval == NULL) {
+ do_to_zval_err(ctx, "No information on how to convert native "
+ "field into value for key '%s'", descr->name);
+ break;
+ }
+
+ ALLOC_INIT_ZVAL(new_zv);
+ add_assoc_zval_ex(zarr, descr->name, descr->name_size, new_zv);
+
+ zend_llist_add_element(&ctx->keys, (void*)&descr->name);
+ descr->to_zval(structure + descr->field_offset, new_zv, ctx);
+ zend_llist_remove_tail(&ctx->keys);
+ }
+}
+
+/* CONVERSIONS for integers */
+static long from_zval_integer_common(const zval *arr_value, ser_context *ctx)
+{
+ long ret = 0;
+ zval lzval = zval_used_for_init;
+
+ if (Z_TYPE_P(arr_value) != IS_LONG) {
+ ZVAL_COPY_VALUE(&lzval, arr_value);
+ zval_copy_ctor(&lzval);
+ arr_value = &lzval;
+ }
+
+ switch (Z_TYPE_P(arr_value)) {
+ case IS_LONG:
+long_case:
+ ret = Z_LVAL_P(arr_value);
+ break;
+
+ /* if not long we're operating on lzval */
+ case IS_DOUBLE:
+double_case:
+ convert_to_long(&lzval);
+ goto long_case;
+
+ case IS_OBJECT:
+ case IS_STRING: {
+ long lval;
+ double dval;
+
+ convert_to_string(&lzval);
+
+ switch (is_numeric_string(Z_STRVAL(lzval), Z_STRLEN(lzval), &lval, &dval, 0)) {
+ case IS_DOUBLE:
+ zval_dtor(&lzval);
+ Z_TYPE(lzval) = IS_DOUBLE;
+ Z_DVAL(lzval) = dval;
+ goto double_case;
+
+ case IS_LONG:
+ zval_dtor(&lzval);
+ Z_TYPE(lzval) = IS_LONG;
+ Z_LVAL(lzval) = lval;
+ goto long_case;
+ }
+
+ /* if we get here, we don't have a numeric string */
+ do_from_zval_err(ctx, "expected an integer, but got a non numeric "
+ "string (possibly from a converted object): '%s'", Z_STRVAL_P(arr_value));
+ break;
+ }
+
+ default:
+ do_from_zval_err(ctx, "%s", "expected an integer, either of a PHP "
+ "integer type or of a convertible type");
+ break;
+ }
+
+ zval_dtor(&lzval);
+
+ return ret;
+}
+void from_zval_write_int(const zval *arr_value, char *field, ser_context *ctx)
+{
+ long lval;
+ int ival;
+
+ lval = from_zval_integer_common(arr_value, ctx);
+ if (ctx->err.has_error) {
+ return;
+ }
+
+ if (lval > INT_MAX || lval < INT_MIN) {
+ do_from_zval_err(ctx, "%s", "given PHP integer is out of bounds "
+ "for a native int");
+ return;
+ }
+
+ ival = (int)lval;
+ memcpy(field, &ival, sizeof(ival));
+}
+static void from_zval_write_uint32(const zval *arr_value, char *field, ser_context *ctx)
+{
+ long lval;
+ uint32_t ival;
+
+ lval = from_zval_integer_common(arr_value, ctx);
+ if (ctx->err.has_error) {
+ return;
+ }
+
+ if (sizeof(long) > sizeof(uint32_t) && (lval < 0 || lval > 0xFFFFFFFF)) {
+ do_from_zval_err(ctx, "%s", "given PHP integer is out of bounds "
+ "for an unsigned 32-bit integer");
+ return;
+ }
+
+ ival = (uint32_t)lval;
+ memcpy(field, &ival, sizeof(ival));
+}
+static void from_zval_write_net_uint16(const zval *arr_value, char *field, ser_context *ctx)
+{
+ long lval;
+ uint16_t ival;
+
+ lval = from_zval_integer_common(arr_value, ctx);
+ if (ctx->err.has_error) {
+ return;
+ }
+
+ if (lval < 0 || lval > 0xFFFF) {
+ do_from_zval_err(ctx, "%s", "given PHP integer is out of bounds "
+ "for an unsigned 16-bit integer");
+ return;
+ }
+
+ ival = htons((uint16_t)lval);
+ memcpy(field, &ival, sizeof(ival));
+}
+static void from_zval_write_sa_family(const zval *arr_value, char *field, ser_context *ctx)
+{
+ long lval;
+ sa_family_t ival;
+
+ lval = from_zval_integer_common(arr_value, ctx);
+ if (ctx->err.has_error) {
+ return;
+ }
+
+ if (lval < 0 || lval > (sa_family_t)-1) { /* sa_family_t is unsigned */
+ do_from_zval_err(ctx, "%s", "given PHP integer is out of bounds "
+ "for a sa_family_t value");
+ return;
+ }
+
+ ival = (sa_family_t)lval;
+ memcpy(field, &ival, sizeof(ival));
+}
+static void from_zval_write_pid_t(const zval *arr_value, char *field, ser_context *ctx)
+{
+ long lval;
+ pid_t ival;
+
+ lval = from_zval_integer_common(arr_value, ctx);
+ if (ctx->err.has_error) {
+ return;
+ }
+
+ if (lval < 0 || (pid_t)lval != lval) { /* pid_t is signed */
+ do_from_zval_err(ctx, "%s", "given PHP integer is out of bounds "
+ "for a pid_t value");
+ return;
+ }
+
+ ival = (pid_t)lval;
+ memcpy(field, &ival, sizeof(ival));
+}
+static void from_zval_write_uid_t(const zval *arr_value, char *field, ser_context *ctx)
+{
+ long lval;
+ uid_t ival;
+
+ lval = from_zval_integer_common(arr_value, ctx);
+ if (ctx->err.has_error) {
+ return;
+ }
+
+ /* uid_t can be signed or unsigned (generally unsigned) */
+ if ((uid_t)-1 > (uid_t)0) {
+ if (sizeof(long) > sizeof(uid_t) && (lval < 0 || (uid_t)lval != lval)) {
+ do_from_zval_err(ctx, "%s", "given PHP integer is out of bounds "
+ "for a uid_t value");
+ return;
+ }
+ } else {
+ if (sizeof(long) > sizeof(uid_t) && (uid_t)lval != lval) {
+ do_from_zval_err(ctx, "%s", "given PHP integer is out of bounds "
+ "for a uid_t value");
+ return;
+ }
+ }
+
+ ival = (uid_t)lval;
+ memcpy(field, &ival, sizeof(ival));
+}
+
+void to_zval_read_int(const char *data, zval *zv, res_context *ctx)
+{
+ int ival;
+ memcpy(&ival, data, sizeof(ival));
+
+ ZVAL_LONG(zv, (long)ival);
+}
+static void to_zval_read_unsigned(const char *data, zval *zv, res_context *ctx)
+{
+ unsigned ival;
+ memcpy(&ival, data, sizeof(ival));
+
+ ZVAL_LONG(zv, (long)ival);
+}
+static void to_zval_read_net_uint16(const char *data, zval *zv, res_context *ctx)
+{
+ uint16_t ival;
+ memcpy(&ival, data, sizeof(ival));
+
+ ZVAL_LONG(zv, (long)ntohs(ival));
+}
+static void to_zval_read_uint32(const char *data, zval *zv, res_context *ctx)
+{
+ uint32_t ival;
+ memcpy(&ival, data, sizeof(ival));
+
+ ZVAL_LONG(zv, (long)ival);
+}
+static void to_zval_read_sa_family(const char *data, zval *zv, res_context *ctx)
+{
+ sa_family_t ival;
+ memcpy(&ival, data, sizeof(ival));
+
+ ZVAL_LONG(zv, (long)ival);
+}
+static void to_zval_read_pid_t(const char *data, zval *zv, res_context *ctx)
+{
+ pid_t ival;
+ memcpy(&ival, data, sizeof(ival));
+
+ ZVAL_LONG(zv, (long)ival);
+}
+static void to_zval_read_uid_t(const char *data, zval *zv, res_context *ctx)
+{
+ uid_t ival;
+ memcpy(&ival, data, sizeof(ival));
+
+ ZVAL_LONG(zv, (long)ival);
+}
+
+/* CONVERSIONS for sockaddr */
+static void from_zval_write_sin_addr(const zval *zaddr_str, char *inaddr, ser_context *ctx)
+{
+ int res;
+ struct sockaddr_in saddr = {0};
+ zval lzval = zval_used_for_init;
+ TSRMLS_FETCH();
+
+ if (Z_TYPE_P(zaddr_str) != IS_STRING) {
+ ZVAL_COPY_VALUE(&lzval, zaddr_str);
+ zval_copy_ctor(&lzval);
+ convert_to_string(&lzval);
+ zaddr_str = &lzval;
+ }
+
+ res = php_set_inet_addr(&saddr, Z_STRVAL_P(zaddr_str), ctx->sock TSRMLS_CC);
+ if (res) {
+ memcpy(inaddr, &saddr.sin_addr, sizeof saddr.sin_addr);
+ } else {
+ /* error already emitted, but let's emit another more relevant */
+ do_from_zval_err(ctx, "could not resolve address '%s' to get an AF_INET "
+ "address", Z_STRVAL_P(zaddr_str));
+ }
+
+ zval_dtor(&lzval);
+}
+static void to_zval_read_sin_addr(const char *data, zval *zv, res_context *ctx)
+{
+ const struct in_addr *addr = (const struct in_addr *)data;
+ socklen_t size = INET_ADDRSTRLEN;
+
+ Z_TYPE_P(zv) = IS_STRING;
+ Z_STRVAL_P(zv) = ecalloc(1, size);
+ Z_STRLEN_P(zv) = 0;
+
+ if (inet_ntop(AF_INET, addr, Z_STRVAL_P(zv), size) == NULL) {
+ do_to_zval_err(ctx, "could not convert IPv4 address to string "
+ "(errno %d)", errno);
+ return;
+ }
+
+ Z_STRLEN_P(zv) = strlen(Z_STRVAL_P(zv));
+}
+static const field_descriptor descriptors_sockaddr_in[] = {
+ {"family", sizeof("family"), 0, offsetof(struct sockaddr_in, sin_family), from_zval_write_sa_family, to_zval_read_sa_family},
+ {"addr", sizeof("addr"), 0, offsetof(struct sockaddr_in, sin_addr), from_zval_write_sin_addr, to_zval_read_sin_addr},
+ {"port", sizeof("port"), 0, offsetof(struct sockaddr_in, sin_port), from_zval_write_net_uint16, to_zval_read_net_uint16},
+ {0}
+};
+static void from_zval_write_sockaddr_in(const zval *container, char *sockaddr, ser_context *ctx)
+{
+ from_zval_write_aggregation(container, sockaddr, descriptors_sockaddr_in, ctx);
+}
+static void to_zval_read_sockaddr_in(const char *data, zval *zv, res_context *ctx)
+{
+ to_zval_read_aggregation(data, zv, descriptors_sockaddr_in, ctx);
+}
+#if HAVE_IPV6
+static void from_zval_write_sin6_addr(const zval *zaddr_str, char *addr6, ser_context *ctx)
+{
+ int res;
+ struct sockaddr_in6 saddr6 = {0};
+ zval lzval = zval_used_for_init;
+ TSRMLS_FETCH();
+
+ if (Z_TYPE_P(zaddr_str) != IS_STRING) {
+ ZVAL_COPY_VALUE(&lzval, zaddr_str);
+ zval_copy_ctor(&lzval);
+ convert_to_string(&lzval);
+ zaddr_str = &lzval;
+ }
+
+ res = php_set_inet6_addr(&saddr6,
+ Z_STRVAL_P(zaddr_str), ctx->sock TSRMLS_CC);
+ if (res) {
+ memcpy(addr6, &saddr6.sin6_addr, sizeof saddr6.sin6_addr);
+ } else {
+ /* error already emitted, but let's emit another more relevant */
+ do_from_zval_err(ctx, "could not resolve address '%s' to get an AF_INET6 "
+ "address", Z_STRVAL_P(zaddr_str));
+ }
+
+ zval_dtor(&lzval);
+}
+static void to_zval_read_sin6_addr(const char *data, zval *zv, res_context *ctx)
+{
+ const struct in6_addr *addr = (const struct in6_addr *)data;
+ socklen_t size = INET6_ADDRSTRLEN;
+
+ Z_TYPE_P(zv) = IS_STRING;
+ Z_STRVAL_P(zv) = ecalloc(1, size);
+ Z_STRLEN_P(zv) = 0;
+
+ if (inet_ntop(AF_INET6, addr, Z_STRVAL_P(zv), size) == NULL) {
+ do_to_zval_err(ctx, "could not convert IPv6 address to string "
+ "(errno %d)", errno);
+ return;
+ }
+
+ Z_STRLEN_P(zv) = strlen(Z_STRVAL_P(zv));
+}
+static const field_descriptor descriptors_sockaddr_in6[] = {
+ {"family", sizeof("family"), 0, offsetof(struct sockaddr_in6, sin6_family), from_zval_write_sa_family, to_zval_read_sa_family},
+ {"addr", sizeof("addr"), 0, offsetof(struct sockaddr_in6, sin6_addr), from_zval_write_sin6_addr, to_zval_read_sin6_addr},
+ {"port", sizeof("port"), 0, offsetof(struct sockaddr_in6, sin6_port), from_zval_write_net_uint16, to_zval_read_net_uint16},
+ {"flowinfo", sizeof("flowinfo"), 0, offsetof(struct sockaddr_in6, sin6_flowinfo), from_zval_write_uint32, to_zval_read_uint32},
+ {"scope_id", sizeof("scope_id"), 0, offsetof(struct sockaddr_in6, sin6_scope_id), from_zval_write_uint32, to_zval_read_uint32},
+ {0}
+};
+static void from_zval_write_sockaddr_in6(const zval *container, char *sockaddr6, ser_context *ctx)
+{
+ from_zval_write_aggregation(container, sockaddr6, descriptors_sockaddr_in6, ctx);
+}
+static void to_zval_read_sockaddr_in6(const char *data, zval *zv, res_context *ctx)
+{
+ to_zval_read_aggregation(data, zv, descriptors_sockaddr_in6, ctx);
+}
+#endif /* HAVE_IPV6 */
+static void from_zval_write_sun_path(const zval *path, char *sockaddr_un_c, ser_context *ctx)
+{
+ zval lzval = zval_used_for_init;
+ struct sockaddr_un *saddr = (struct sockaddr_un*)sockaddr_un_c;
+
+ if (Z_TYPE_P(path) != IS_STRING) {
+ ZVAL_COPY_VALUE(&lzval, path);
+ zval_copy_ctor(&lzval);
+ convert_to_string(&lzval);
+ path = &lzval;
+ }
+
+ /* code in this file relies on the path being nul terminated, even though
+ * this is not required, at least on linux for abstract paths. It also
+ * assumes that the path is not empty */
+ if (Z_STRLEN_P(path) == 0) {
+ do_from_zval_err(ctx, "%s", "the path is cannot be empty");
+ return;
+ }
+ if (Z_STRLEN_P(path) >= sizeof(saddr->sun_path)) {
+ do_from_zval_err(ctx, "the path is too long, the maximum permitted "
+ "length is %ld", sizeof(saddr->sun_path) - 1);
+ return;
+ }
+
+ memcpy(&saddr->sun_path, Z_STRVAL_P(path), Z_STRLEN_P(path));
+ saddr->sun_path[Z_STRLEN_P(path)] = '\0';
+
+ zval_dtor(&lzval);
+}
+static void to_zval_read_sun_path(const char *data, zval *zv, res_context *ctx) {
+ struct sockaddr_un *saddr = (struct sockaddr_un*)data;
+ char *nul_pos;
+
+ nul_pos = memchr(&saddr->sun_path, '\0', sizeof(saddr->sun_path));
+ if (nul_pos == NULL) {
+ do_to_zval_err(ctx, "could not find a NUL in the path");
+ return;
+ }
+
+ ZVAL_STRINGL(zv, saddr->sun_path, nul_pos - (char*)&saddr->sun_path, 1);
+}
+static const field_descriptor descriptors_sockaddr_un[] = {
+ {"family", sizeof("family"), 0, offsetof(struct sockaddr_un, sun_family), from_zval_write_sa_family, to_zval_read_sa_family},
+ {"path", sizeof("path"), 0, 0, from_zval_write_sun_path, to_zval_read_sun_path},
+ {0}
+};
+static void from_zval_write_sockaddr_un(const zval *container, char *sockaddr, ser_context *ctx)
+{
+ from_zval_write_aggregation(container, sockaddr, descriptors_sockaddr_un, ctx);
+}
+static void to_zval_read_sockaddr_un(const char *data, zval *zv, res_context *ctx)
+{
+ to_zval_read_aggregation(data, zv, descriptors_sockaddr_un, ctx);
+}
+static void from_zval_write_sockaddr_aux(const zval *container,
+ struct sockaddr **sockaddr_ptr,
+ socklen_t *sockaddr_len,
+ ser_context *ctx)
+{
+ int family;
+ zval **elem;
+ int fill_sockaddr;
+
+ if (Z_TYPE_P(container) != IS_ARRAY) {
+ do_from_zval_err(ctx, "%s", "expected an array here");
+ return;
+ }
+
+ fill_sockaddr = param_get_bool(ctx, KEY_FILL_SOCKADDR, 1);
+
+ if (zend_hash_find(Z_ARRVAL_P(container), "family", sizeof("family"), (void**)&elem) == SUCCESS
+ && Z_TYPE_PP(elem) != IS_NULL) {
+ const char *node = "family";
+ zend_llist_add_element(&ctx->keys, &node);
+ from_zval_write_int(*elem, (char*)&family, ctx);
+ zend_llist_remove_tail(&ctx->keys);
+ } else {
+ family = ctx->sock->type;
+ }
+
+ switch (family) {
+ case AF_INET:
+ /* though not all OSes support sockaddr_in used in IPv6 sockets */
+ if (ctx->sock->type != AF_INET && ctx->sock->type != AF_INET6) {
+ do_from_zval_err(ctx, "the specified family (number %d) is not "
+ "supported on this socket", family);
+ return;
+ }
+ *sockaddr_ptr = accounted_ecalloc(1, sizeof(struct sockaddr_in), ctx);
+ *sockaddr_len = sizeof(struct sockaddr_in);
+ if (fill_sockaddr) {
+ from_zval_write_sockaddr_in(container, (char*)*sockaddr_ptr, ctx);
+ (*sockaddr_ptr)->sa_family = AF_INET;
+ }
+ break;
+
+#if HAVE_IPV6
+ case AF_INET6:
+ if (ctx->sock->type != AF_INET6) {
+ do_from_zval_err(ctx, "the specified family (AF_INET6) is not "
+ "supported on this socket");
+ return;
+ }
+ *sockaddr_ptr = accounted_ecalloc(1, sizeof(struct sockaddr_in6), ctx);
+ *sockaddr_len = sizeof(struct sockaddr_in6);
+ if (fill_sockaddr) {
+ from_zval_write_sockaddr_in6(container, (char*)*sockaddr_ptr, ctx);
+ (*sockaddr_ptr)->sa_family = AF_INET6;
+ }
+ break;
+#endif /* HAVE_IPV6 */
+
+ case AF_UNIX:
+ if (ctx->sock->type != AF_UNIX) {
+ do_from_zval_err(ctx, "the specified family (AF_UNIX) is not "
+ "supported on this socket");
+ return;
+ }
+ *sockaddr_ptr = accounted_ecalloc(1, sizeof(struct sockaddr_un), ctx);
+ if (fill_sockaddr) {
+ struct sockaddr_un *sock_un = (struct sockaddr_un*)*sockaddr_ptr;
+
+ from_zval_write_sockaddr_un(container, (char*)*sockaddr_ptr, ctx);
+ (*sockaddr_ptr)->sa_family = AF_UNIX;
+
+ /* calculating length is more complicated here. Giving the size of
+ * struct sockaddr_un here and relying on the nul termination of
+ * sun_path does not work for paths in the abstract namespace. Note
+ * that we always assume the path is not empty and nul terminated */
+ *sockaddr_len = offsetof(struct sockaddr_un, sun_path) +
+ (sock_un->sun_path[0] == '\0'
+ ? (1 + strlen(&sock_un->sun_path[1]))
+ : strlen(sock_un->sun_path));
+ } else {
+ *sockaddr_len = sizeof(struct sockaddr_un);
+ }
+ break;
+
+ default:
+ do_from_zval_err(ctx, "%s", "the only families currently supported are "
+ "AF_INET, AF_INET6 and AF_UNIX");
+ break;
+ }
+}
+static void to_zval_read_sockaddr_aux(const char *sockaddr_c, zval *zv, res_context *ctx)
+{
+ const struct sockaddr *saddr = (struct sockaddr *)sockaddr_c;
+
+ if (saddr->sa_family == 0) {
+ ZVAL_NULL(zv);
+ return;
+ }
+
+ array_init(zv);
+
+ switch (saddr->sa_family) {
+ case AF_INET:
+ to_zval_read_sockaddr_in(sockaddr_c, zv, ctx);
+ break;
+
+#if HAVE_IPV6
+ case AF_INET6:
+ to_zval_read_sockaddr_in6(sockaddr_c, zv, ctx);
+ break;
+#endif /* HAVE_IPV6 */
+
+ case AF_UNIX:
+ to_zval_read_sockaddr_un(sockaddr_c, zv, ctx);
+ break;
+
+ default:
+ do_to_zval_err(ctx, "cannot read struct sockaddr with family %d; "
+ "not supported",
+ (int)saddr->sa_family);
+ break;
+ }
+}
+
+/* CONVERSIONS for cmsghdr */
+/*
+ * [ level => , type => , data => [],]
+ * struct cmsghdr {
+ * socklen_t cmsg_len; // data byte count, including header
+ * int cmsg_level; // originating protocol
+ * int cmsg_type; // protocol-specific type
+ * // followed by unsigned char cmsg_data[];
+ * };
+ */
+static void from_zval_write_control(const zval *arr,
+ void **control_buf,
+ zend_llist_element *alloc,
+ size_t *control_len,
+ size_t *offset,
+ ser_context *ctx)
+{
+ struct cmsghdr *cmsghdr;
+ int level,
+ type;
+ size_t data_len,
+ req_space,
+ space_left;
+ ancillary_reg_entry *entry;
+
+ static const field_descriptor descriptor_level[] = {
+ {"level", sizeof("level"), 0, 0, from_zval_write_int, 0},
+ {0}
+ };
+ static const field_descriptor descriptor_type[] = {
+ {"type", sizeof("type"), 0, 0, from_zval_write_int, 0},
+ {0}
+ };
+ field_descriptor descriptor_data[] = {
+ {"data", sizeof("data"), 0, 0, 0, 0},
+ {0}
+ };
+
+ from_zval_write_aggregation(arr, (char *)&level, descriptor_level, ctx);
+ if (ctx->err.has_error) {
+ return;
+ }
+ from_zval_write_aggregation(arr, (char *)&type, descriptor_type, ctx);
+ if (ctx->err.has_error) {
+ return;
+ }
+
+ entry = get_ancillary_reg_entry(level, type);
+ if (entry == NULL) {
+ do_from_zval_err(ctx, "cmsghdr with level %d and type %d not supported",
+ level, type);
+ return;
+ }
+
+ if (entry->calc_space) {
+ zval **data_elem;
+ /* arr must be an array at this point */
+ if (zend_hash_find(Z_ARRVAL_P(arr), "data", sizeof("data"),
+ (void**)&data_elem) == FAILURE) {
+ do_from_zval_err(ctx, "cmsghdr should have a 'data' element here");
+ return;
+ }
+ data_len = entry->calc_space(*data_elem, ctx);
+ if (ctx->err.has_error) {
+ return;
+ }
+ } else {
+ data_len = entry->size;
+ }
+ req_space = CMSG_SPACE(data_len);
+ space_left = *control_len - *offset;
+ assert(*control_len >= *offset);
+
+ if (space_left < req_space) {
+ *control_buf = safe_erealloc(*control_buf, 2, req_space, *control_len);
+ *control_len += 2 * req_space;
+ memset(*control_buf, '\0', *control_len - *offset);
+ memcpy(&alloc->data, *control_buf, sizeof *control_buf);
+ }
+
+ cmsghdr = (struct cmsghdr*)(((char*)*control_buf) + *offset);
+ cmsghdr->cmsg_level = level;
+ cmsghdr->cmsg_type = type;
+ cmsghdr->cmsg_len = CMSG_LEN(data_len);
+
+ descriptor_data[0].from_zval = entry->from_array;
+ from_zval_write_aggregation(arr, (char*)CMSG_DATA(cmsghdr), descriptor_data, ctx);
+
+ *offset += req_space;
+}
+static void from_zval_write_control_array(const zval *arr, char *msghdr_c, ser_context *ctx)
+{
+ HashPosition pos;
+ char buf[sizeof("element #4294967295")];
+ char *bufp = buf;
+ zval **elem;
+ uint32_t i;
+ int num_elems;
+ void *control_buf;
+ zend_llist_element *alloc;
+ size_t control_len,
+ cur_offset;
+ struct msghdr *msg = (struct msghdr*)msghdr_c;
+
+ if (Z_TYPE_P(arr) != IS_ARRAY) {
+ do_from_zval_err(ctx, "%s", "expected an array here");
+ return;
+ }
+
+ num_elems = zend_hash_num_elements(Z_ARRVAL_P(arr));
+ if (num_elems == 0) {
+ return;
+ }
+
+ /* estimate each message at 20 bytes */
+ control_buf = accounted_safe_ecalloc(num_elems, CMSG_SPACE(20), 0, ctx);
+ alloc = ctx->allocations.tail;
+ control_len = (size_t)num_elems * CMSG_SPACE(20);
+ cur_offset = 0;
+
+ for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(arr), &pos), i = 0;
+ !ctx->err.has_error
+ && zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), (void **)&elem, &pos) == SUCCESS;
+ zend_hash_move_forward_ex(Z_ARRVAL_P(arr), &pos)) {
+
+ if (snprintf(buf, sizeof(buf), "element #%u", (unsigned)i++) >= sizeof(buf)) {
+ memcpy(buf, "element", sizeof("element"));
+ }
+ zend_llist_add_element(&ctx->keys, &bufp);
+
+ from_zval_write_control(*elem, &control_buf, alloc, &control_len,
+ &cur_offset, ctx);
+
+ zend_llist_remove_tail(&ctx->keys);
+ }
+
+ msg->msg_control = control_buf;
+ msg->msg_controllen = cur_offset; /* not control_len, which may be larger */
+}
+static void to_zval_read_cmsg_data(const char *cmsghdr_c, zval *zv, res_context *ctx)
+{
+ const struct cmsghdr *cmsg = (const struct cmsghdr *)cmsghdr_c;
+ ancillary_reg_entry *entry;
+ size_t len,
+ *len_p = &len;
+
+ entry = get_ancillary_reg_entry(cmsg->cmsg_level, cmsg->cmsg_type);
+ if (entry == NULL) {
+ do_to_zval_err(ctx, "cmsghdr with level %d and type %d not supported",
+ cmsg->cmsg_level, cmsg->cmsg_type);
+ return;
+ }
+ if (CMSG_LEN(entry->size) > cmsg->cmsg_len) {
+ do_to_zval_err(ctx, "the cmsghdr structure is unexpectedly small; "
+ "expected a length of at least %ld, but got %ld",
+ (long)CMSG_LEN(entry->size), (long)cmsg->cmsg_len);
+ return;
+ }
+
+ len = (size_t)cmsg->cmsg_len; /* use another var because type of cmsg_len varies */
+ if (zend_hash_add(&ctx->params, KEY_CMSG_LEN, sizeof(KEY_CMSG_LEN),
+ &len_p, sizeof(len_p), NULL) == FAILURE) {
+ do_to_zval_err(ctx, "%s", "could not set parameter " KEY_CMSG_LEN);
+ return;
+ }
+
+ entry->to_array((const char *)CMSG_DATA(cmsg), zv, ctx);
+
+ zend_hash_del(&ctx->params, KEY_CMSG_LEN, sizeof(KEY_CMSG_LEN));
+}
+static void to_zval_read_control(const char *cmsghdr_c, zval *zv, res_context *ctx)
+{
+ /* takes a cmsghdr, not a msghdr like from_zval_write_control */
+ static const field_descriptor descriptors[] = {
+ {"level", sizeof("level"), 0, offsetof(struct cmsghdr, cmsg_level), 0, to_zval_read_int},
+ {"type", sizeof("type"), 0, offsetof(struct cmsghdr, cmsg_type), 0, to_zval_read_int},
+ {"data", sizeof("data"), 0, 0 /* cmsghdr passed */, 0, to_zval_read_cmsg_data},
+ {0}
+ };
+
+ array_init_size(zv, 3);
+ to_zval_read_aggregation(cmsghdr_c, zv, descriptors, ctx);
+}
+static void to_zval_read_control_array(const char *msghdr_c, zval *zv, res_context *ctx)
+{
+ struct msghdr *msg = (struct msghdr *)msghdr_c;
+ struct cmsghdr *cmsg;
+ char buf[sizeof("element #4294967295")];
+ char *bufp = buf;
+ uint32_t i = 1;
+
+ /*if (msg->msg_flags & MSG_CTRUNC) {
+ php_error_docref0(NULL, E_WARNING, "The MSG_CTRUNC flag is present; will not "
+ "attempt to read control messages");
+ ZVAL_FALSE(zv);
+ return;
+ }*/
+
+ array_init(zv);
+
+ for (cmsg = CMSG_FIRSTHDR(msg);
+ cmsg != NULL && !ctx->err.has_error;
+ cmsg = CMSG_NXTHDR(msg, cmsg)) {
+ zval *elem;
+
+ ALLOC_INIT_ZVAL(elem);
+ add_next_index_zval(zv, elem);
+
+ if (snprintf(buf, sizeof(buf), "element #%u", (unsigned)i++) >= sizeof(buf)) {
+ memcpy(buf, "element", sizeof("element"));
+ }
+ zend_llist_add_element(&ctx->keys, &bufp);
+
+ to_zval_read_control((const char *)cmsg, elem, ctx);
+
+ zend_llist_remove_tail(&ctx->keys);
+ }
+}
+
+/* CONVERSIONS for msghdr */
+static void from_zval_write_name(const zval *zname_arr, char *msghdr_c, ser_context *ctx)
+{
+ struct sockaddr *sockaddr;
+ socklen_t sockaddr_len;
+ struct msghdr *msghdr = (struct msghdr *)msghdr_c;
+
+ from_zval_write_sockaddr_aux(zname_arr, &sockaddr, &sockaddr_len, ctx);
+
+ msghdr->msg_name = sockaddr;
+ msghdr->msg_namelen = sockaddr_len;
+}
+static void to_zval_read_name(const char *sockaddr_p, zval *zv, res_context *ctx)
+{
+ void *name = (void*)*(void**)sockaddr_p;
+ if (name == NULL) {
+ ZVAL_NULL(zv);
+ } else {
+ to_zval_read_sockaddr_aux(name, zv, ctx);
+ }
+}
+static void from_zval_write_msghdr_buffer_size(const zval *elem, char *msghdr_c, ser_context *ctx)
+{
+ long lval;
+ struct msghdr *msghdr = (struct msghdr *)msghdr_c;
+
+ lval = from_zval_integer_common(elem, ctx);
+ if (ctx->err.has_error) {
+ return;
+ }
+
+ if (lval < 0 || lval > MAX_USER_BUFF_SIZE) {
+ do_from_zval_err(ctx, "the buffer size must be between 1 and %ld; "
+ "given %ld", (long)MAX_USER_BUFF_SIZE, lval);
+ return;
+ }
+
+ msghdr->msg_iovlen = 1;
+ msghdr->msg_iov = accounted_emalloc(sizeof(*msghdr->msg_iov) * 1, ctx);
+ msghdr->msg_iov[0].iov_base = accounted_emalloc((size_t)lval, ctx);
+ msghdr->msg_iov[0].iov_len = (size_t)lval;
+}
+static void from_zval_write_iov_array_aux(zval **elem, unsigned i, void **args, ser_context *ctx)
+{
+ struct msghdr *msg = args[0];
+ size_t len;
+
+ zval_add_ref(elem);
+ convert_to_string_ex(elem);
+
+ len = Z_STRLEN_PP(elem);
+ msg->msg_iov[i - 1].iov_base = accounted_emalloc(len, ctx);
+ msg->msg_iov[i - 1].iov_len = len;
+ memcpy(msg->msg_iov[i - 1].iov_base, Z_STRVAL_PP(elem), len);
+
+ zval_ptr_dtor(elem);
+}
+static void from_zval_write_iov_array(const zval *arr, char *msghdr_c, ser_context *ctx)
+{
+ int num_elem;
+ struct msghdr *msg = (struct msghdr*)msghdr_c;
+
+ if (Z_TYPE_P(arr) != IS_ARRAY) {
+ do_from_zval_err(ctx, "%s", "expected an array here");
+ return;
+ }
+
+ num_elem = zend_hash_num_elements(Z_ARRVAL_P(arr));
+ if (num_elem == 0) {
+ return;
+ }
+
+ msg->msg_iov = accounted_safe_ecalloc(num_elem, sizeof *msg->msg_iov, 0, ctx);
+ msg->msg_iovlen = (size_t)num_elem;
+
+ from_array_iterate(arr, from_zval_write_iov_array_aux, (void**)&msg, ctx);
+}
+static void from_zval_write_controllen(const zval *elem, char *msghdr_c, ser_context *ctx)
+{
+ struct msghdr *msghdr = (struct msghdr *)msghdr_c;
+ uint32_t len;
+
+ /* controllen should be an unsigned with at least 32-bit. Let's assume
+ * this least common denominator
+ */
+ from_zval_write_uint32(elem, (char*)&len, ctx);
+ if (!ctx->err.has_error && len == 0) {
+ do_from_zval_err(ctx, "controllen cannot be 0");
+ return;
+ }
+ msghdr->msg_control = accounted_emalloc(len, ctx);
+ msghdr->msg_controllen = len;
+}
+void from_zval_write_msghdr_send(const zval *container, char *msghdr_c, ser_context *ctx)
+{
+ static const field_descriptor descriptors[] = {
+ {"name", sizeof("name"), 0, 0, from_zval_write_name, 0},
+ {"iov", sizeof("iov"), 0, 0, from_zval_write_iov_array, 0},
+ {"control", sizeof("control"), 0, 0, from_zval_write_control_array, 0},
+ {0}
+ };
+
+ from_zval_write_aggregation(container, msghdr_c, descriptors, ctx);
+}
+void from_zval_write_msghdr_recv(const zval *container, char *msghdr_c, ser_context *ctx)
+{
+ /* zval to struct msghdr, version for recvmsg(). It differs from the version
+ * for sendmsg() in that it:
+ * - has a buffer_size instead of an iov array;
+ * - has no control element; has a controllen element instead
+ * struct msghdr {
+ * void *msg_name;
+ * socklen_t msg_namelen;
+ * struct iovec *msg_iov;
+ * size_t msg_iovlen;
+ * void *msg_control;
+ * size_t msg_controllen; //can also be socklen_t
+ * int msg_flags;
+ * };
+ */
+ static const field_descriptor descriptors[] = {
+ {"name", sizeof("name"), 0, 0, from_zval_write_name, 0},
+ {"buffer_size", sizeof("buffer_size"), 0, 0, from_zval_write_msghdr_buffer_size, 0},
+ {"controllen", sizeof("controllen"), 1, 0, from_zval_write_controllen, 0},
+ {0}
+ };
+ struct msghdr *msghdr = (struct msghdr *)msghdr_c;
+ const int falsev = 0,
+ *falsevp = &falsev;
+
+ if (zend_hash_add(&ctx->params, KEY_FILL_SOCKADDR, sizeof(KEY_FILL_SOCKADDR),
+ (void*)&falsevp, sizeof(falsevp), NULL) == FAILURE) {
+ do_from_zval_err(ctx, "could not add fill_sockaddr; this is a bug");
+ return;
+ }
+
+ from_zval_write_aggregation(container, msghdr_c, descriptors, ctx);
+
+ zend_hash_del(&ctx->params, KEY_FILL_SOCKADDR, sizeof(KEY_FILL_SOCKADDR));
+ if (ctx->err.has_error) {
+ return;
+ }
+
+ if (msghdr->msg_iovlen == 0) {
+ msghdr->msg_iovlen = 1;
+ msghdr->msg_iov = accounted_emalloc(sizeof(*msghdr->msg_iov) * 1, ctx);
+ msghdr->msg_iov[0].iov_base = accounted_emalloc((size_t)DEFAULT_BUFF_SIZE, ctx);
+ msghdr->msg_iov[0].iov_len = (size_t)DEFAULT_BUFF_SIZE;
+ }
+}
+
+static void to_zval_read_iov(const char *msghdr_c, zval *zv, res_context *ctx)
+{
+ const struct msghdr *msghdr = (const struct msghdr *)msghdr_c;
+ size_t iovlen = msghdr->msg_iovlen;
+ ssize_t **recvmsg_ret,
+ bytes_left;
+ uint i;
+
+ if (iovlen > UINT_MAX) {
+ do_to_zval_err(ctx, "unexpectedly large value for iov_len: %lu",
+ (unsigned long)iovlen);
+ }
+ array_init_size(zv, (uint)iovlen);
+
+ if (zend_hash_find(&ctx->params, KEY_RECVMSG_RET, sizeof(KEY_RECVMSG_RET),
+ (void**)&recvmsg_ret) == FAILURE) {
+ do_to_zval_err(ctx, "recvmsg_ret not found in params. This is a bug");
+ return;
+ }
+ bytes_left = **recvmsg_ret;
+
+ for (i = 0; bytes_left > 0 && i < (uint)iovlen; i++) {
+ zval *elem;
+ size_t len = MIN(msghdr->msg_iov[i].iov_len, (size_t)bytes_left);
+ char *buf = safe_emalloc(1, len, 1);
+
+ MAKE_STD_ZVAL(elem);
+ memcpy(buf, msghdr->msg_iov[i].iov_base, len);
+ buf[len] = '\0';
+
+ ZVAL_STRINGL(elem, buf, len, 0);
+ add_next_index_zval(zv, elem);
+ bytes_left -= len;
+ }
+}
+void to_zval_read_msghdr(const char *msghdr_c, zval *zv, res_context *ctx)
+{
+ static const field_descriptor descriptors[] = {
+ {"name", sizeof("name"), 0, offsetof(struct msghdr, msg_name), 0, to_zval_read_name},
+ {"control", sizeof("control"), 0, 0, 0, to_zval_read_control_array},
+ {"iov", sizeof("iov"), 0, 0, 0, to_zval_read_iov},
+ {"flags", sizeof("flags"), 0, offsetof(struct msghdr, msg_flags), 0, to_zval_read_int},
+ {0}
+ };
+
+ array_init_size(zv, 4);
+
+ to_zval_read_aggregation(msghdr_c, zv, descriptors, ctx);
+}
+
+/* CONVERSIONS for if_index */
+static void from_zval_write_ifindex(const zval *zv, char *uinteger, ser_context *ctx)
+{
+ unsigned ret = 0;
+ zval lzval = zval_used_for_init;
+
+ if (Z_TYPE_P(zv) == IS_LONG) {
+ if (Z_LVAL_P(zv) < 0 || Z_LVAL_P(zv) > UINT_MAX) { /* allow 0 (unspecified interface) */
+ do_from_zval_err(ctx, "the interface index cannot be negative or "
+ "larger than %u; given %ld", UINT_MAX, Z_LVAL_P(zv));
+ } else {
+ ret = (unsigned)Z_LVAL_P(zv);
+ }
+ } else {
+ if (Z_TYPE_P(zv) != IS_STRING) {
+ ZVAL_COPY_VALUE(&lzval, zv);
+ zval_copy_ctor(&lzval);
+ convert_to_string(&lzval);
+ zv = &lzval;
+ }
+
+#if HAVE_IF_NAMETOINDEX
+ ret = if_nametoindex(Z_STRVAL_P(zv));
+ if (ret == 0) {
+ do_from_zval_err(ctx, "no interface with name \"%s\" could be "
+ "found", Z_STRVAL_P(zv));
+ }
+#elif defined(SIOCGIFINDEX)
+ {
+ struct ifreq ifr;
+ if (strlcpy(ifr.ifr_name, Z_STRVAL_P(zv), sizeof(ifr.ifr_name))
+ >= sizeof(ifr.ifr_name)) {
+ do_from_zval_err(ctx, "the interface name \"%s\" is too large ",
+ Z_STRVAL_P(zv));
+ } else if (ioctl(ctx->sock->bsd_socket, SIOCGIFINDEX, &ifr) < 0) {
+ if (errno == ENODEV) {
+ do_from_zval_err(ctx, "no interface with name \"%s\" could be "
+ "found", Z_STRVAL_P(zv));
+ } else {
+ do_from_zval_err(ctx, "error fetching interface index for "
+ "interface with name \"%s\" (errno %d)",
+ Z_STRVAL_P(zv), errno);
+ }
+ } else {
+ ret = (unsigned)ifr.ifr_ifindex;
+ }
+ }
+#else
+ do_from_zval_err(ctx,
+ "this platform does not support looking up an interface by "
+ "name, an integer interface index must be supplied instead");
+#endif
+ }
+
+ if (!ctx->err.has_error) {
+ memcpy(uinteger, &ret, sizeof(ret));
+ }
+
+ zval_dtor(&lzval);
+}
+
+/* CONVERSIONS for struct in6_pktinfo */
+#if defined(IPV6_PKTINFO) && HAVE_IPV6
+static const field_descriptor descriptors_in6_pktinfo[] = {
+ {"addr", sizeof("addr"), 1, offsetof(struct in6_pktinfo, ipi6_addr), from_zval_write_sin6_addr, to_zval_read_sin6_addr},
+ {"ifindex", sizeof("ifindex"), 1, offsetof(struct in6_pktinfo, ipi6_ifindex), from_zval_write_ifindex, to_zval_read_unsigned},
+ {0}
+};
+void from_zval_write_in6_pktinfo(const zval *container, char *in6_pktinfo_c, ser_context *ctx)
+{
+ from_zval_write_aggregation(container, in6_pktinfo_c, descriptors_in6_pktinfo, ctx);
+}
+void to_zval_read_in6_pktinfo(const char *data, zval *zv, res_context *ctx)
+{
+ array_init_size(zv, 2);
+
+ to_zval_read_aggregation(data, zv, descriptors_in6_pktinfo, ctx);
+}
+#endif
+
+/* CONVERSIONS for struct ucred */
+#ifdef SO_PASSCRED
+static const field_descriptor descriptors_ucred[] = {
+ {"pid", sizeof("pid"), 1, offsetof(struct ucred, pid), from_zval_write_pid_t, to_zval_read_pid_t},
+ {"uid", sizeof("uid"), 1, offsetof(struct ucred, uid), from_zval_write_uid_t, to_zval_read_uid_t},
+ /* assume the type gid_t is the same as uid_t: */
+ {"gid", sizeof("gid"), 1, offsetof(struct ucred, gid), from_zval_write_uid_t, to_zval_read_uid_t},
+ {0}
+};
+void from_zval_write_ucred(const zval *container, char *ucred_c, ser_context *ctx)
+{
+ from_zval_write_aggregation(container, ucred_c, descriptors_ucred, ctx);
+}
+void to_zval_read_ucred(const char *data, zval *zv, res_context *ctx)
+{
+ array_init_size(zv, 3);
+
+ to_zval_read_aggregation(data, zv, descriptors_ucred, ctx);
+}
+#endif
+
+/* CONVERSIONS for SCM_RIGHTS */
+#ifdef SCM_RIGHTS
+size_t calculate_scm_rights_space(const zval *arr, ser_context *ctx)
+{
+ int num_elems;
+
+ if (Z_TYPE_P(arr) != IS_ARRAY) {
+ do_from_zval_err(ctx, "%s", "expected an array here");
+ return (size_t)-1;
+ }
+
+ num_elems = zend_hash_num_elements(Z_ARRVAL_P(arr));
+ if (num_elems == 0) {
+ do_from_zval_err(ctx, "%s", "expected at least one element in this array");
+ return (size_t)-1;
+ }
+
+ return zend_hash_num_elements(Z_ARRVAL_P(arr)) * sizeof(int);
+}
+static void from_zval_write_fd_array_aux(zval **elem, unsigned i, void **args, ser_context *ctx)
+{
+ int *iarr = args[0];
+ TSRMLS_FETCH();
+
+ if (Z_TYPE_PP(elem) == IS_RESOURCE) {
+ php_stream *stream;
+ php_socket *sock;
+
+ ZEND_FETCH_RESOURCE_NO_RETURN(sock, php_socket *, elem, -1,
+ NULL, php_sockets_le_socket());
+ if (sock) {
+ iarr[i] = sock->bsd_socket;
+ return;
+ }
+
+ ZEND_FETCH_RESOURCE2_NO_RETURN(stream, php_stream *, elem, -1,
+ NULL, php_file_le_stream(), php_file_le_pstream());
+ if (stream == NULL) {
+ do_from_zval_err(ctx, "resource is not a stream or a socket");
+ return;
+ }
+
+ if (php_stream_cast(stream, PHP_STREAM_AS_FD, (void **)&iarr[i - 1],
+ REPORT_ERRORS) == FAILURE) {
+ do_from_zval_err(ctx, "cast stream to file descriptor failed");
+ return;
+ }
+ } else {
+ do_from_zval_err(ctx, "expected a resource variable");
+ }
+}
+void from_zval_write_fd_array(const zval *arr, char *int_arr, ser_context *ctx)
+{
+ if (Z_TYPE_P(arr) != IS_ARRAY) {
+ do_from_zval_err(ctx, "%s", "expected an array here");
+ return;
+ }
+
+ from_array_iterate(arr, &from_zval_write_fd_array_aux, (void**)&int_arr, ctx);
+}
+void to_zval_read_fd_array(const char *data, zval *zv, res_context *ctx)
+{
+ size_t **cmsg_len;
+ int num_elems,
+ i;
+ struct cmsghdr *dummy_cmsg = 0;
+ size_t data_offset;
+ TSRMLS_FETCH();
+
+ data_offset = (unsigned char *)CMSG_DATA(dummy_cmsg)
+ - (unsigned char *)dummy_cmsg;
+
+ if (zend_hash_find(&ctx->params, KEY_CMSG_LEN, sizeof(KEY_CMSG_LEN),
+ (void **)&cmsg_len) == FAILURE) {
+ do_to_zval_err(ctx, "could not get value of parameter " KEY_CMSG_LEN);
+ return;
+ }
+
+ if (**cmsg_len < data_offset) {
+ do_to_zval_err(ctx, "length of cmsg is smaller than its data member "
+ "offset (%ld vs %ld)", (long)**cmsg_len, (long)data_offset);
+ return;
+ }
+ num_elems = (**cmsg_len - data_offset) / sizeof(int);
+
+ array_init_size(zv, num_elems);
+
+ for (i = 0; i < num_elems; i++) {
+ zval *elem;
+ int fd;
+ struct stat statbuf;
+
+ MAKE_STD_ZVAL(elem);
+
+ fd = *((int *)data + i);
+
+ /* determine whether we have a socket */
+ if (fstat(fd, &statbuf) == -1) {
+ do_to_zval_err(ctx, "error creating resource for received file "
+ "descriptor %d: fstat() call failed with errno %d", fd, errno);
+ efree(elem);
+ return;
+ }
+ if (S_ISSOCK(statbuf.st_mode)) {
+ php_socket *sock = socket_import_file_descriptor(fd TSRMLS_CC);
+ zend_register_resource(elem, sock, php_sockets_le_socket() TSRMLS_CC);
+ } else {
+ php_stream *stream = php_stream_fopen_from_fd(fd, "rw", NULL);
+ php_stream_to_zval(stream, elem);
+ }
+
+ add_next_index_zval(zv, elem);
+ }
+}
+#endif
+
+/* ENTRY POINT for conversions */
+static void free_from_zval_allocation(void *alloc_ptr_ptr)
+{
+ efree(*(void**)alloc_ptr_ptr);
+}
+void *from_zval_run_conversions(const zval *container,
+ php_socket *sock,
+ from_zval_write_field *writer,
+ size_t struct_size,
+ const char *top_name,
+ zend_llist **allocations /* out */,
+ struct err_s *err /* in/out */)
+{
+ ser_context ctx = {{0}};
+ char *structure = NULL;
+
+ *allocations = NULL;
+
+ if (err->has_error) {
+ return NULL;
+ }
+
+ zend_hash_init(&ctx.params, 8, NULL, NULL, 0);
+ zend_llist_init(&ctx.keys, sizeof(const char *), NULL, 0);
+ zend_llist_init(&ctx.allocations, sizeof(void *), &free_from_zval_allocation, 0);
+ ctx.sock = sock;
+
+ structure = ecalloc(1, struct_size);
+
+ zend_llist_add_element(&ctx.keys, &top_name);
+ zend_llist_add_element(&ctx.allocations, &structure);
+
+ /* main call */
+ writer(container, structure, &ctx);
+
+ if (ctx.err.has_error) {
+ zend_llist_destroy(&ctx.allocations); /* deallocates structure as well */
+ structure = NULL;
+ *err = ctx.err;
+ } else {
+ *allocations = emalloc(sizeof **allocations);
+ **allocations = ctx.allocations;
+ }
+
+ zend_llist_destroy(&ctx.keys);
+ zend_hash_destroy(&ctx.params);
+
+ return structure;
+}
+zval *to_zval_run_conversions(const char *structure,
+ to_zval_read_field *reader,
+ const char *top_name,
+ const struct key_value *key_value_pairs,
+ struct err_s *err)
+{
+ res_context ctx = {{0}, {0}};
+ const struct key_value *kv;
+ zval *zv = NULL;
+
+ if (err->has_error) {
+ return NULL;
+ }
+
+ ALLOC_INIT_ZVAL(zv);
+
+ zend_llist_init(&ctx.keys, sizeof(const char *), NULL, 0);
+ zend_llist_add_element(&ctx.keys, &top_name);
+
+ zend_hash_init(&ctx.params, 8, NULL, NULL, 0);
+ for (kv = key_value_pairs; kv->key != NULL; kv++) {
+ zend_hash_update(&ctx.params, kv->key, kv->key_size,
+ (void*)&kv->value, sizeof(kv->value), NULL);
+ }
+
+ /* main call */
+ reader(structure, zv, &ctx);
+
+ if (ctx.err.has_error) {
+ zval_ptr_dtor(&zv);
+ zv = NULL;
+ *err = ctx.err;
+ }
+
+ zend_llist_destroy(&ctx.keys);
+ zend_hash_destroy(&ctx.params);
+
+ return zv;
+}
diff --git a/ext/sockets/conversions.h b/ext/sockets/conversions.h
new file mode 100644
index 0000000000..7d515246a0
--- /dev/null
+++ b/ext/sockets/conversions.h
@@ -0,0 +1,84 @@
+#ifndef PHP_SOCK_CONVERSIONS_H
+#define PHP_SOCK_CONVERSIONS_H 1
+
+#include <php.h>
+
+#ifndef PHP_WIN32
+# include <netinet/in.h>
+# include <sys/socket.h>
+#else
+# include <Ws2tcpip.h>
+#endif
+
+#include "php_sockets.h"
+
+/* TYPE DEFINITIONS */
+struct err_s {
+ int has_error;
+ char *msg;
+ int level;
+ int should_free;
+};
+
+struct key_value {
+ const char *key;
+ unsigned key_size;
+ void *value;
+};
+
+/* the complete types of these two are not relevant to the outside */
+typedef struct _ser_context ser_context;
+typedef struct _res_context res_context;
+
+#define KEY_RECVMSG_RET "recvmsg_ret"
+
+typedef void (from_zval_write_field)(const zval *arr_value, char *field, ser_context *ctx);
+typedef void (to_zval_read_field)(const char *data, zval *zv, res_context *ctx);
+
+/* VARIABLE DECLARATIONS */
+extern const struct key_value empty_key_value_list[];
+
+/* AUX FUNCTIONS */
+void err_msg_dispose(struct err_s *err TSRMLS_DC);
+void allocations_dispose(zend_llist **allocations);
+
+/* CONVERSION FUNCTIONS */
+void from_zval_write_int(const zval *arr_value, char *field, ser_context *ctx);
+void to_zval_read_int(const char *data, zval *zv, res_context *ctx);
+
+#ifdef IPV6_PKTINFO
+void from_zval_write_in6_pktinfo(const zval *container, char *in6_pktinfo_c, ser_context *ctx);
+void to_zval_read_in6_pktinfo(const char *data, zval *zv, res_context *ctx);
+#endif
+
+#ifdef SO_PASSCRED
+void from_zval_write_ucred(const zval *container, char *ucred_c, ser_context *ctx);
+void to_zval_read_ucred(const char *data, zval *zv, res_context *ctx);
+#endif
+
+#ifdef SCM_RIGHTS
+size_t calculate_scm_rights_space(const zval *arr, ser_context *ctx);
+void from_zval_write_fd_array(const zval *arr, char *int_arr, ser_context *ctx);
+void to_zval_read_fd_array(const char *data, zval *zv, res_context *ctx);
+#endif
+
+void from_zval_write_msghdr_send(const zval *container, char *msghdr_c, ser_context *ctx);
+void from_zval_write_msghdr_recv(const zval *container, char *msghdr_c, ser_context *ctx);
+void to_zval_read_msghdr(const char *msghdr_c, zval *zv, res_context *ctx);
+
+/* ENTRY POINTS FOR CONVERSIONS */
+void *from_zval_run_conversions(const zval *container,
+ php_socket *sock,
+ from_zval_write_field *writer,
+ size_t struct_size,
+ const char *top_name,
+ zend_llist **allocations /* out */,
+ struct err_s *err /* in/out */);
+
+zval *to_zval_run_conversions(const char *structure,
+ to_zval_read_field *reader,
+ const char *top_name,
+ const struct key_value *key_value_pairs,
+ struct err_s *err);
+
+#endif
diff --git a/ext/sockets/multicast.c b/ext/sockets/multicast.c
index 7e311ec48a..dc3151a137 100644
--- a/ext/sockets/multicast.c
+++ b/ext/sockets/multicast.c
@@ -24,20 +24,9 @@
#include "php.h"
-#if HAVE_SOCKETS
-
#include "php_network.h"
#ifdef PHP_WIN32
-# include "win32/inet.h"
-# include <winsock2.h>
-# include <windows.h>
-# include <Ws2tcpip.h>
-# include <Ws2ipdef.h>
-# include "php_sockets.h"
-# include "win32/sockets.h"
-# define NTDDI_XP NTDDI_WINXP /* bug in SDK */
-# include <IPHlpApi.h>
-# undef NTDDI_XP
+# include "windows_common.h"
#else
#include <sys/socket.h>
#include <sys/ioctl.h>
@@ -51,6 +40,7 @@
#include "php_sockets.h"
#include "multicast.h"
+#include "sockaddr_conv.h"
#include "main/php_network.h"
@@ -73,6 +63,317 @@ static const char *_php_source_op_to_string(enum source_op sop);
static int _php_source_op_to_ipv4_op(enum source_op sop);
#endif
+int php_string_to_if_index(const char *val, unsigned *out TSRMLS_DC)
+{
+#if HAVE_IF_NAMETOINDEX
+ unsigned int ind;
+
+ ind = if_nametoindex(val);
+ if (ind == 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "no interface with name \"%s\" could be found", val);
+ return FAILURE;
+ } else {
+ *out = ind;
+ return SUCCESS;
+ }
+#else
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "this platform does not support looking up an interface by "
+ "name, an integer interface index must be supplied instead");
+ return FAILURE;
+#endif
+}
+
+static int php_get_if_index_from_zval(zval *val, unsigned *out TSRMLS_DC)
+{
+ int ret;
+
+ if (Z_TYPE_P(val) == IS_LONG) {
+ if (Z_LVAL_P(val) < 0 || Z_LVAL_P(val) > UINT_MAX) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "the interface index cannot be negative or larger than %u;"
+ " given %ld", UINT_MAX, Z_LVAL_P(val));
+ ret = FAILURE;
+ } else {
+ *out = Z_LVAL_P(val);
+ ret = SUCCESS;
+ }
+ } else {
+ zval_add_ref(&val);
+ convert_to_string_ex(&val);
+ ret = php_string_to_if_index(Z_STRVAL_P(val), out TSRMLS_CC);
+ zval_ptr_dtor(&val);
+ }
+
+ return ret;
+}
+
+
+
+static int php_get_if_index_from_array(const HashTable *ht, const char *key,
+ php_socket *sock, unsigned int *if_index TSRMLS_DC)
+{
+ zval **val;
+
+ if (zend_hash_find(ht, key, strlen(key) + 1, (void **)&val) == FAILURE) {
+ *if_index = 0; /* default: 0 */
+ return SUCCESS;
+ }
+
+ return php_get_if_index_from_zval(*val, if_index TSRMLS_CC);
+}
+
+static int php_get_address_from_array(const HashTable *ht, const char *key,
+ php_socket *sock, php_sockaddr_storage *ss, socklen_t *ss_len TSRMLS_DC)
+{
+ zval **val,
+ *valcp;
+
+ if (zend_hash_find(ht, key, strlen(key) + 1, (void **)&val) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "no key \"%s\" passed in optval", key);
+ return FAILURE;
+ }
+ valcp = *val;
+ zval_add_ref(&valcp);
+ convert_to_string_ex(val);
+ if (!php_set_inet46_addr(ss, ss_len, Z_STRVAL_P(valcp), sock TSRMLS_CC)) {
+ zval_ptr_dtor(&valcp);
+ return FAILURE;
+ }
+ zval_ptr_dtor(&valcp);
+ return SUCCESS;
+}
+
+static int php_do_mcast_opt(php_socket *php_sock, int level, int optname, zval **arg4 TSRMLS_DC)
+{
+ HashTable *opt_ht;
+ unsigned int if_index;
+ int retval;
+ int (*mcast_req_fun)(php_socket *, int, struct sockaddr *, socklen_t,
+ unsigned TSRMLS_DC);
+#ifdef HAS_MCAST_EXT
+ int (*mcast_sreq_fun)(php_socket *, int, struct sockaddr *, socklen_t,
+ struct sockaddr *, socklen_t, unsigned TSRMLS_DC);
+#endif
+
+ switch (optname) {
+ case PHP_MCAST_JOIN_GROUP:
+ mcast_req_fun = &php_mcast_join;
+ goto mcast_req_fun;
+ case PHP_MCAST_LEAVE_GROUP:
+ {
+ php_sockaddr_storage group = {0};
+ socklen_t glen;
+
+ mcast_req_fun = &php_mcast_leave;
+mcast_req_fun:
+ convert_to_array_ex(arg4);
+ opt_ht = HASH_OF(*arg4);
+
+ if (php_get_address_from_array(opt_ht, "group", php_sock, &group,
+ &glen TSRMLS_CC) == FAILURE) {
+ return FAILURE;
+ }
+ if (php_get_if_index_from_array(opt_ht, "interface", php_sock,
+ &if_index TSRMLS_CC) == FAILURE) {
+ return FAILURE;
+ }
+
+ retval = mcast_req_fun(php_sock, level, (struct sockaddr*)&group,
+ glen, if_index TSRMLS_CC);
+ break;
+ }
+
+#ifdef HAS_MCAST_EXT
+ case PHP_MCAST_BLOCK_SOURCE:
+ mcast_sreq_fun = &php_mcast_block_source;
+ goto mcast_sreq_fun;
+ case PHP_MCAST_UNBLOCK_SOURCE:
+ mcast_sreq_fun = &php_mcast_unblock_source;
+ goto mcast_sreq_fun;
+ case PHP_MCAST_JOIN_SOURCE_GROUP:
+ mcast_sreq_fun = &php_mcast_join_source;
+ goto mcast_sreq_fun;
+ case PHP_MCAST_LEAVE_SOURCE_GROUP:
+ {
+ php_sockaddr_storage group = {0},
+ source = {0};
+ socklen_t glen,
+ slen;
+
+ mcast_sreq_fun = &php_mcast_leave_source;
+ mcast_sreq_fun:
+ convert_to_array_ex(arg4);
+ opt_ht = HASH_OF(*arg4);
+
+ if (php_get_address_from_array(opt_ht, "group", php_sock, &group,
+ &glen TSRMLS_CC) == FAILURE) {
+ return FAILURE;
+ }
+ if (php_get_address_from_array(opt_ht, "source", php_sock, &source,
+ &slen TSRMLS_CC) == FAILURE) {
+ return FAILURE;
+ }
+ if (php_get_if_index_from_array(opt_ht, "interface", php_sock,
+ &if_index TSRMLS_CC) == FAILURE) {
+ return FAILURE;
+ }
+
+ retval = mcast_sreq_fun(php_sock, level, (struct sockaddr*)&group,
+ glen, (struct sockaddr*)&source, slen, if_index TSRMLS_CC);
+ break;
+ }
+#endif
+ default:
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "unexpected option in php_do_mcast_opt (level %d, option %d). "
+ "This is a bug.", level, optname);
+ return FAILURE;
+ }
+
+ if (retval != 0) {
+ if (retval != -2) { /* error, but message already emitted */
+ PHP_SOCKET_ERROR(php_sock, "unable to set socket option", errno);
+ }
+ return FAILURE;
+ }
+ return SUCCESS;
+}
+
+int php_do_setsockopt_ip_mcast(php_socket *php_sock,
+ int level,
+ int optname,
+ zval **arg4 TSRMLS_DC)
+{
+ unsigned int if_index;
+ struct in_addr if_addr;
+ void *opt_ptr;
+ socklen_t optlen;
+ unsigned char ipv4_mcast_ttl_lback;
+ int retval;
+
+ switch (optname) {
+ case PHP_MCAST_JOIN_GROUP:
+ case PHP_MCAST_LEAVE_GROUP:
+#ifdef HAS_MCAST_EXT
+ case PHP_MCAST_BLOCK_SOURCE:
+ case PHP_MCAST_UNBLOCK_SOURCE:
+ case PHP_MCAST_JOIN_SOURCE_GROUP:
+ case PHP_MCAST_LEAVE_SOURCE_GROUP:
+#endif
+ if (php_do_mcast_opt(php_sock, level, optname, arg4 TSRMLS_CC) == FAILURE) {
+ return FAILURE;
+ } else {
+ return SUCCESS;
+ }
+
+ case IP_MULTICAST_IF:
+ if (php_get_if_index_from_zval(*arg4, &if_index TSRMLS_CC) == FAILURE) {
+ return FAILURE;
+ }
+
+ if (php_if_index_to_addr4(if_index, php_sock, &if_addr TSRMLS_CC) == FAILURE) {
+ return FAILURE;
+ }
+ opt_ptr = &if_addr;
+ optlen = sizeof(if_addr);
+ goto dosockopt;
+
+ case IP_MULTICAST_LOOP:
+ convert_to_boolean_ex(arg4);
+ goto ipv4_loop_ttl;
+
+ case IP_MULTICAST_TTL:
+ convert_to_long_ex(arg4);
+ if (Z_LVAL_PP(arg4) < 0L || Z_LVAL_PP(arg4) > 255L) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "Expected a value between 0 and 255");
+ return FAILURE;
+ }
+ipv4_loop_ttl:
+ ipv4_mcast_ttl_lback = (unsigned char) Z_LVAL_PP(arg4);
+ opt_ptr = &ipv4_mcast_ttl_lback;
+ optlen = sizeof(ipv4_mcast_ttl_lback);
+ goto dosockopt;
+ }
+
+ return 1;
+
+dosockopt:
+ retval = setsockopt(php_sock->bsd_socket, level, optname, opt_ptr, optlen);
+ if (retval != 0) {
+ PHP_SOCKET_ERROR(php_sock, "unable to set socket option", errno);
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+int php_do_setsockopt_ipv6_mcast(php_socket *php_sock,
+ int level,
+ int optname,
+ zval **arg4 TSRMLS_DC)
+{
+ unsigned int if_index;
+ void *opt_ptr;
+ socklen_t optlen;
+ int ov;
+ int retval;
+
+ switch (optname) {
+ case PHP_MCAST_JOIN_GROUP:
+ case PHP_MCAST_LEAVE_GROUP:
+#ifdef HAS_MCAST_EXT
+ case PHP_MCAST_BLOCK_SOURCE:
+ case PHP_MCAST_UNBLOCK_SOURCE:
+ case PHP_MCAST_JOIN_SOURCE_GROUP:
+ case PHP_MCAST_LEAVE_SOURCE_GROUP:
+#endif
+ if (php_do_mcast_opt(php_sock, level, optname, arg4 TSRMLS_CC) == FAILURE) {
+ return FAILURE;
+ } else {
+ return SUCCESS;
+ }
+
+ case IPV6_MULTICAST_IF:
+ if (php_get_if_index_from_zval(*arg4, &if_index TSRMLS_CC) == FAILURE) {
+ return FAILURE;
+ }
+
+ opt_ptr = &if_index;
+ optlen = sizeof(if_index);
+ goto dosockopt;
+
+ case IPV6_MULTICAST_LOOP:
+ convert_to_boolean_ex(arg4);
+ goto ipv6_loop_hops;
+ case IPV6_MULTICAST_HOPS:
+ convert_to_long_ex(arg4);
+ if (Z_LVAL_PP(arg4) < -1L || Z_LVAL_PP(arg4) > 255L) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "Expected a value between -1 and 255");
+ return FAILURE;
+ }
+ipv6_loop_hops:
+ ov = (int) Z_LVAL_PP(arg4);
+ opt_ptr = &ov;
+ optlen = sizeof(ov);
+ goto dosockopt;
+ }
+
+ return 1; /* not handled */
+
+dosockopt:
+ retval = setsockopt(php_sock->bsd_socket, level, optname, opt_ptr, optlen);
+ if (retval != 0) {
+ PHP_SOCKET_ERROR(php_sock, "unable to set socket option", errno);
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
int php_mcast_join(
php_socket *sock,
int level,
@@ -154,21 +455,21 @@ static int _php_mcast_join_leave(
{
#ifdef RFC3678_API
struct group_req greq = {0};
-
+
memcpy(&greq.gr_group, group, group_len);
assert(greq.gr_group.ss_family != 0); /* the caller has set this */
greq.gr_interface = if_index;
return setsockopt(sock->bsd_socket, level,
join ? MCAST_JOIN_GROUP : MCAST_LEAVE_GROUP, (char*)&greq,
- sizeof(greq));
+ sizeof(greq));
#else
if (sock->type == AF_INET) {
struct ip_mreq mreq = {0};
struct in_addr addr;
-
+
assert(group_len == sizeof(struct sockaddr_in));
-
+
if (if_index != 0) {
if (php_if_index_to_addr4(if_index, sock, &addr TSRMLS_CC) ==
FAILURE)
@@ -185,12 +486,12 @@ static int _php_mcast_join_leave(
#if HAVE_IPV6
else if (sock->type == AF_INET6) {
struct ipv6_mreq mreq = {0};
-
+
assert(group_len == sizeof(struct sockaddr_in6));
mreq.ipv6mr_multiaddr = ((struct sockaddr_in6*)group)->sin6_addr;
mreq.ipv6mr_interface = if_index;
-
+
return setsockopt(sock->bsd_socket, level,
join ? IPV6_JOIN_GROUP : IPV6_LEAVE_GROUP, (char*)&mreq,
sizeof(mreq));
@@ -218,26 +519,26 @@ static int _php_mcast_source_op(
{
#ifdef RFC3678_API
struct group_source_req gsreq = {0};
-
+
memcpy(&gsreq.gsr_group, group, group_len);
assert(gsreq.gsr_group.ss_family != 0);
memcpy(&gsreq.gsr_source, source, source_len);
assert(gsreq.gsr_source.ss_family != 0);
gsreq.gsr_interface = if_index;
-
+
return setsockopt(sock->bsd_socket, level,
_php_source_op_to_rfc3678_op(sop), (char*)&gsreq, sizeof(gsreq));
#else
if (sock->type == AF_INET) {
struct ip_mreq_source mreqs = {0};
struct in_addr addr;
-
+
mreqs.imr_multiaddr = ((struct sockaddr_in*)group)->sin_addr;
mreqs.imr_sourceaddr = ((struct sockaddr_in*)source)->sin_addr;
-
+
assert(group_len == sizeof(struct sockaddr_in));
assert(source_len == sizeof(struct sockaddr_in));
-
+
if (if_index != 0) {
if (php_if_index_to_addr4(if_index, sock, &addr TSRMLS_CC) ==
FAILURE)
@@ -246,7 +547,7 @@ static int _php_mcast_source_op(
} else {
mreqs.imr_interface.s_addr = htonl(INADDR_ANY);
}
-
+
return setsockopt(sock->bsd_socket, level,
_php_source_op_to_ipv4_op(sop), (char*)&mreqs, sizeof(mreqs));
}
@@ -280,7 +581,7 @@ static int _php_source_op_to_rfc3678_op(enum source_op sop)
case UNBLOCK_SOURCE:
return MCAST_UNBLOCK_SOURCE;
}
-
+
assert(0);
return 0;
}
@@ -297,7 +598,7 @@ static const char *_php_source_op_to_string(enum source_op sop)
case UNBLOCK_SOURCE:
return "MCAST_UNBLOCK_SOURCE";
}
-
+
assert(0);
return "";
}
@@ -314,7 +615,7 @@ static int _php_source_op_to_ipv4_op(enum source_op sop)
case UNBLOCK_SOURCE:
return IP_UNBLOCK_SOURCE;
}
-
+
assert(0);
return 0;
}
@@ -413,16 +714,16 @@ retry:
int php_if_index_to_addr4(unsigned if_index, php_socket *php_sock, struct in_addr *out_addr TSRMLS_DC)
{
struct ifreq if_req;
-
+
if (if_index == 0) {
out_addr->s_addr = INADDR_ANY;
return SUCCESS;
}
-
+
#if !defined(ifr_ifindex) && defined(ifr_index)
#define ifr_ifindex ifr_index
#endif
-
+
#if defined(SIOCGIFNAME)
if_req.ifr_ifindex = if_index;
if (ioctl(php_sock->bsd_socket, SIOCGIFNAME, &if_req) == -1) {
@@ -435,13 +736,13 @@ int php_if_index_to_addr4(unsigned if_index, php_socket *php_sock, struct in_add
"Failed obtaining address for interface %u: error %d", if_index, errno);
return FAILURE;
}
-
+
if (ioctl(php_sock->bsd_socket, SIOCGIFADDR, &if_req) == -1) {
php_error_docref(NULL TSRMLS_CC, E_WARNING,
"Failed obtaining address for interface %u: error %d", if_index, errno);
return FAILURE;
}
-
+
memcpy(out_addr, &((struct sockaddr_in *) &if_req.ifr_addr)->sin_addr,
sizeof *out_addr);
return SUCCESS;
@@ -455,25 +756,25 @@ int php_add4_to_if_index(struct in_addr *addr, php_socket *php_sock, unsigned *i
int size = 0,
lastsize = 0;
size_t entry_len;
-
+
if (addr->s_addr == INADDR_ANY) {
*if_index = 0;
return SUCCESS;
}
-
+
for(;;) {
size += 5 * sizeof(struct ifreq);
buf = ecalloc(size, 1);
if_conf.ifc_len = size;
if_conf.ifc_buf = buf;
-
+
if (ioctl(php_sock->bsd_socket, SIOCGIFCONF, (char*)&if_conf) == -1 &&
(errno != EINVAL || lastsize != 0)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING,
"Failed obtaining interfaces list: error %d", errno);
goto err;
}
-
+
if (if_conf.ifc_len == lastsize)
/* not increasing anymore */
break;
@@ -483,15 +784,15 @@ int php_add4_to_if_index(struct in_addr *addr, php_socket *php_sock, unsigned *i
buf = NULL;
}
}
-
+
for (p = if_conf.ifc_buf;
p < if_conf.ifc_buf + if_conf.ifc_len;
p += entry_len) {
struct ifreq *cur_req;
-
+
/* let's hope the pointer is aligned */
cur_req = (struct ifreq*) p;
-
+
#ifdef HAVE_SOCKADDR_SA_LEN
entry_len = cur_req->ifr_addr.sa_len + sizeof(cur_req->ifr_name);
#else
@@ -499,7 +800,7 @@ int php_add4_to_if_index(struct in_addr *addr, php_socket *php_sock, unsigned *i
entry_len = sizeof(struct sockaddr) + sizeof(cur_req->ifr_name);
#endif
entry_len = MAX(entry_len, sizeof(*cur_req));
-
+
if ((((struct sockaddr*)&cur_req->ifr_addr)->sa_family == AF_INET) &&
(((struct sockaddr_in*)&cur_req->ifr_addr)->sin_addr.s_addr ==
addr->s_addr)) {
@@ -534,12 +835,10 @@ int php_add4_to_if_index(struct in_addr *addr, php_socket *php_sock, unsigned *i
php_error_docref(NULL TSRMLS_CC, E_WARNING,
"The interface with IP address %s was not found", addr_str);
}
-
+
err:
if (buf != NULL)
efree(buf);
return FAILURE;
}
#endif
-
-#endif /* HAVE_SOCKETS */
diff --git a/ext/sockets/multicast.h b/ext/sockets/multicast.h
index 04f352f70e..f89f56ed39 100644
--- a/ext/sockets/multicast.h
+++ b/ext/sockets/multicast.h
@@ -18,17 +18,43 @@
/* $Id$ */
-#if defined(MCAST_JOIN_GROUP) && \
- (!defined(PHP_WIN32) || (_WIN32_WINNT >= 0x600 && SOCKETS_ENABLE_VISTA_API)) && \
- !defined(__APPLE__)
-#define RFC3678_API 1
+#if defined(MCAST_JOIN_GROUP) && !defined(__APPLE__)
+# define RFC3678_API 1
/* has block/unblock and source membership, in this case for both IPv4 and IPv6 */
-#define HAS_MCAST_EXT 1
+# define HAS_MCAST_EXT 1
#elif defined(IP_ADD_SOURCE_MEMBERSHIP) && !defined(__APPLE__)
/* has block/unblock and source membership, but only for IPv4 */
-#define HAS_MCAST_EXT 1
+# define HAS_MCAST_EXT 1
#endif
+#ifndef RFC3678_API
+# define PHP_MCAST_JOIN_GROUP IP_ADD_MEMBERSHIP
+# define PHP_MCAST_LEAVE_GROUP IP_DROP_MEMBERSHIP
+# ifdef HAS_MCAST_EXT
+# define PHP_MCAST_BLOCK_SOURCE IP_BLOCK_SOURCE
+# define PHP_MCAST_UNBLOCK_SOURCE IP_UNBLOCK_SOURCE
+# define PHP_MCAST_JOIN_SOURCE_GROUP IP_ADD_SOURCE_MEMBERSHIP
+# define PHP_MCAST_LEAVE_SOURCE_GROUP IP_DROP_SOURCE_MEMBERSHIP
+# endif
+#else
+# define PHP_MCAST_JOIN_GROUP MCAST_JOIN_GROUP
+# define PHP_MCAST_LEAVE_GROUP MCAST_LEAVE_GROUP
+# define PHP_MCAST_BLOCK_SOURCE MCAST_BLOCK_SOURCE
+# define PHP_MCAST_UNBLOCK_SOURCE MCAST_UNBLOCK_SOURCE
+# define PHP_MCAST_JOIN_SOURCE_GROUP MCAST_JOIN_SOURCE_GROUP
+# define PHP_MCAST_LEAVE_SOURCE_GROUP MCAST_LEAVE_SOURCE_GROUP
+#endif
+
+int php_do_setsockopt_ip_mcast(php_socket *php_sock,
+ int level,
+ int optname,
+ zval **arg4 TSRMLS_DC);
+
+int php_do_setsockopt_ipv6_mcast(php_socket *php_sock,
+ int level,
+ int optname,
+ zval **arg4 TSRMLS_DC);
+
int php_if_index_to_addr4(
unsigned if_index,
php_socket *php_sock,
@@ -39,6 +65,8 @@ int php_add4_to_if_index(
php_socket *php_sock,
unsigned *if_index TSRMLS_DC);
+int php_string_to_if_index(const char *val, unsigned *out TSRMLS_DC);
+
int php_mcast_join(
php_socket *sock,
int level,
diff --git a/ext/sockets/php_sockets.h b/ext/sockets/php_sockets.h
index 48e8a7ee85..e872635f9a 100644
--- a/ext/sockets/php_sockets.h
+++ b/ext/sockets/php_sockets.h
@@ -24,13 +24,22 @@
/* $Id$ */
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#if HAVE_SOCKETS
+#include <php.h>
+#ifdef PHP_WIN32
+# include "windows_common.h"
+#endif
+
extern zend_module_entry sockets_module_entry;
#define phpext_sockets_ptr &sockets_module_entry
#ifdef PHP_WIN32
-#include <winsock.h>
+#include <Winsock2.h>
#else
#if HAVE_SYS_SOCKET_H
#include <sys/socket.h>
@@ -64,6 +73,16 @@ PHP_SOCKETS_API int php_sockets_le_socket(void);
#define php_sockets_le_socket_name "Socket"
+#define PHP_SOCKET_ERROR(socket, msg, errn) \
+ do { \
+ int _err = (errn); /* save value to avoid repeated calls to WSAGetLastError() on Windows */ \
+ (socket)->error = _err; \
+ SOCKETS_G(last_error) = _err; \
+ if (_err != EAGAIN && _err != EWOULDBLOCK && _err != EINPROGRESS) { \
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s [%d]: %s", msg, _err, sockets_strerror(_err TSRMLS_CC)); \
+ } \
+ } while (0)
+
ZEND_BEGIN_MODULE_GLOBALS(sockets)
int last_error;
char *strerror_buf;
@@ -75,10 +94,25 @@ ZEND_END_MODULE_GLOBALS(sockets)
#define SOCKETS_G(v) (sockets_globals.v)
#endif
+ZEND_EXTERN_MODULE_GLOBALS(sockets);
+
+enum sockopt_return {
+ SOCKOPT_ERROR,
+ SOCKOPT_CONTINUE,
+ SOCKOPT_SUCCESS
+};
+
+char *sockets_strerror(int error TSRMLS_DC);
+php_socket *socket_import_file_descriptor(PHP_SOCKET sock TSRMLS_DC);
+
#else
#define phpext_sockets_ptr NULL
#endif
+#if defined(_AIX) && !defined(HAVE_SA_SS_FAMILY)
+# define ss_family __ss_family
+#endif
+
#endif
/*
diff --git a/ext/sockets/sendrecvmsg.c b/ext/sockets/sendrecvmsg.c
new file mode 100644
index 0000000000..d9a8190736
--- /dev/null
+++ b/ext/sockets/sendrecvmsg.c
@@ -0,0 +1,454 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2012 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: Gustavo Lopes <cataphract@php.net> |
+ +----------------------------------------------------------------------+
+ */
+
+#include <php.h>
+#include "php_sockets.h"
+#include "sendrecvmsg.h"
+#include "conversions.h"
+#include <limits.h>
+#include <Zend/zend_llist.h>
+#ifdef ZTS
+#include <TSRM/TSRM.h>
+#endif
+
+#define MAX_USER_BUFF_SIZE ((size_t)(100*1024*1024))
+#define DEFAULT_BUFF_SIZE 8192
+#define MAX_ARRAY_KEY_SIZE 128
+
+#ifdef PHP_WIN32
+#include "windows_common.h"
+#include <Mswsock.h>
+#define IPV6_RECVPKTINFO IPV6_PKTINFO
+#define IPV6_RECVHOPLIMIT IPV6_HOPLIMIT
+#define msghdr _WSAMSG
+
+static GUID WSARecvMsg_GUID = WSAID_WSARECVMSG;
+static __declspec(thread) LPFN_WSARECVMSG WSARecvMsg = NULL;
+inline ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags)
+{
+ DWORD recvd = 0,
+ bytesReturned;
+
+ if (WSARecvMsg == NULL) {
+ int res = WSAIoctl((SOCKET) sockfd, SIO_GET_EXTENSION_FUNCTION_POINTER,
+ &WSARecvMsg_GUID, sizeof(WSARecvMsg_GUID),
+ &WSARecvMsg, sizeof(WSARecvMsg),
+ &bytesReturned, NULL, NULL);
+ if (res != 0) {
+ return -1;
+ }
+ }
+
+ msg->dwFlags = (DWORD)flags;
+ return WSARecvMsg((SOCKET)sockfd, msg, &recvd, NULL, NULL) == 0
+ ? (ssize_t)recvd
+ : -1;
+}
+inline ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags)
+{
+ DWORD sent = 0;
+ return WSASendMsg((SOCKET)sockfd, (struct msghdr*)msg, (DWORD)flags, &sent, NULL, NULL) == 0
+ ? (ssize_t)sent
+ : -1;
+}
+#endif
+
+#define LONG_CHECK_VALID_INT(l) \
+ do { \
+ if ((l) < INT_MIN && (l) > INT_MAX) { \
+ php_error_docref0(NULL TSRMLS_CC, E_WARNING, "The value %ld does not fit inside " \
+ "the boundaries of a native integer", (l)); \
+ return; \
+ } \
+ } while (0)
+
+static struct {
+ int initialized;
+ HashTable ht;
+} ancillary_registry;
+
+
+#ifdef ZTS
+static MUTEX_T ancillary_mutex;
+#endif
+static void init_ancillary_registry(void)
+{
+ ancillary_reg_entry entry;
+ anc_reg_key key;
+ ancillary_registry.initialized = 1;
+
+ zend_hash_init(&ancillary_registry.ht, 32, NULL, NULL, 1);
+
+#define PUT_ENTRY(sizev, var_size, calc, from, to, level, type) \
+ entry.size = sizev; \
+ entry.var_el_size = var_size; \
+ entry.calc_space = calc; \
+ entry.from_array = from; \
+ entry.to_array = to; \
+ key.cmsg_level = level; \
+ key.cmsg_type = type; \
+ zend_hash_update(&ancillary_registry.ht, (char*)&key, sizeof(key), \
+ (void*)&entry, sizeof(entry), NULL)
+
+#if defined(IPV6_PKTINFO) && HAVE_IPV6
+ PUT_ENTRY(sizeof(struct in6_pktinfo), 0, 0, from_zval_write_in6_pktinfo,
+ to_zval_read_in6_pktinfo, IPPROTO_IPV6, IPV6_PKTINFO);
+#endif
+
+#if defined(IPV6_HOPLIMIT) && HAVE_IPV6
+ PUT_ENTRY(sizeof(int), 0, 0, from_zval_write_int,
+ to_zval_read_int, IPPROTO_IPV6, IPV6_HOPLIMIT);
+#endif
+
+#if defined(IPV6_TCLASS) && HAVE_IPV6
+ PUT_ENTRY(sizeof(int), 0, 0, from_zval_write_int,
+ to_zval_read_int, IPPROTO_IPV6, IPV6_TCLASS);
+#endif
+
+#ifdef SO_PASSCRED
+ PUT_ENTRY(sizeof(struct ucred), 0, 0, from_zval_write_ucred,
+ to_zval_read_ucred, SOL_SOCKET, SCM_CREDENTIALS);
+#endif
+
+#ifdef SCM_RIGHTS
+ PUT_ENTRY(0, sizeof(int), calculate_scm_rights_space, from_zval_write_fd_array,
+ to_zval_read_fd_array, SOL_SOCKET, SCM_RIGHTS);
+#endif
+
+}
+static void destroy_ancillary_registry(void)
+{
+ if (ancillary_registry.initialized) {
+ zend_hash_destroy(&ancillary_registry.ht);
+ ancillary_registry.initialized = 0;
+ }
+}
+ancillary_reg_entry *get_ancillary_reg_entry(int cmsg_level, int msg_type)
+{
+ anc_reg_key key = { cmsg_level, msg_type };
+ ancillary_reg_entry *entry;
+
+#ifdef ZTS
+ tsrm_mutex_lock(ancillary_mutex);
+#endif
+ if (!ancillary_registry.initialized) {
+ init_ancillary_registry();
+ }
+#ifdef ZTS
+ tsrm_mutex_unlock(ancillary_mutex);
+#endif
+
+ if (zend_hash_find(&ancillary_registry.ht, (char*)&key, sizeof(key),
+ (void**)&entry) == SUCCESS) {
+ return entry;
+ } else {
+ return NULL;
+ }
+}
+
+PHP_FUNCTION(socket_sendmsg)
+{
+ zval *zsocket,
+ *zmsg;
+ long flags = 0;
+ php_socket *php_sock;
+ struct msghdr *msghdr;
+ zend_llist *allocations;
+ struct err_s err = {0};
+ ssize_t res;
+
+ /* zmsg should be passed by ref */
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra|l", &zsocket, &zmsg, &flags) == FAILURE) {
+ return;
+ }
+
+ LONG_CHECK_VALID_INT(flags);
+
+ ZEND_FETCH_RESOURCE(php_sock, php_socket *, &zsocket, -1,
+ php_sockets_le_socket_name, php_sockets_le_socket());
+
+ msghdr = from_zval_run_conversions(zmsg, php_sock, from_zval_write_msghdr_send,
+ sizeof(*msghdr), "msghdr", &allocations, &err);
+
+ if (err.has_error) {
+ err_msg_dispose(&err TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ res = sendmsg(php_sock->bsd_socket, msghdr, (int)flags);
+
+ if (res != -1) {
+ zend_llist_destroy(allocations);
+ efree(allocations);
+
+ RETURN_LONG((long)res);
+ } else {
+ PHP_SOCKET_ERROR(php_sock, "error in sendmsg", errno);
+ RETURN_FALSE;
+ }
+}
+
+PHP_FUNCTION(socket_recvmsg)
+{
+ zval *zsocket,
+ *zmsg;
+ long flags = 0;
+ php_socket *php_sock;
+ ssize_t res;
+ struct msghdr *msghdr;
+ zend_llist *allocations;
+ struct err_s err = {0};
+
+ //ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra|l",
+ &zsocket, &zmsg, &flags) == FAILURE) {
+ return;
+ }
+
+ LONG_CHECK_VALID_INT(flags);
+
+ ZEND_FETCH_RESOURCE(php_sock, php_socket *, &zsocket, -1,
+ php_sockets_le_socket_name, php_sockets_le_socket());
+
+ msghdr = from_zval_run_conversions(zmsg, php_sock, from_zval_write_msghdr_recv,
+ sizeof(*msghdr), "msghdr", &allocations, &err);
+
+ if (err.has_error) {
+ err_msg_dispose(&err TSRMLS_CC);
+ RETURN_FALSE;
+ }
+
+ res = recvmsg(php_sock->bsd_socket, msghdr, (int)flags);
+
+ if (res != -1) {
+ zval *zres;
+ struct key_value kv[] = {
+ {KEY_RECVMSG_RET, sizeof(KEY_RECVMSG_RET), &res},
+ {0}
+ };
+
+
+ zres = to_zval_run_conversions((char *)msghdr, to_zval_read_msghdr,
+ "msghdr", kv, &err);
+
+ /* we don;t need msghdr anymore; free it */
+ msghdr = NULL;
+ allocations_dispose(&allocations);
+
+ zval_dtor(zmsg);
+ if (!err.has_error) {
+ ZVAL_COPY_VALUE(zmsg, zres);
+ efree(zres); /* only shallow destruction */
+ } else {
+ err_msg_dispose(&err TSRMLS_CC);
+ ZVAL_FALSE(zmsg);
+ /* no need to destroy/free zres -- it's NULL in this circumstance */
+ assert(zres == NULL);
+ }
+ } else {
+ SOCKETS_G(last_error) = errno;
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "error in recvmsg [%d]: %s",
+ errno, sockets_strerror(errno TSRMLS_CC));
+ RETURN_FALSE;
+ }
+
+ RETURN_LONG((long)res);
+}
+
+PHP_FUNCTION(socket_cmsg_space)
+{
+ long level,
+ type,
+ n = 0;
+ ancillary_reg_entry *entry;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll|l",
+ &level, &type, &n) == FAILURE) {
+ return;
+ }
+
+ LONG_CHECK_VALID_INT(level);
+ LONG_CHECK_VALID_INT(type);
+ LONG_CHECK_VALID_INT(n);
+
+ if (n < 0) {
+ php_error_docref0(NULL TSRMLS_CC, E_WARNING, "The third argument "
+ "cannot be negative");
+ return;
+ }
+
+ entry = get_ancillary_reg_entry(level, type);
+ if (entry == NULL) {
+ php_error_docref0(NULL TSRMLS_CC, E_WARNING, "The pair level %ld/type %ld is "
+ "not supported by PHP", level, type);
+ return;
+ }
+
+ if (entry->var_el_size > 0 && n > (LONG_MAX - (long)entry->size -
+ (long)CMSG_SPACE(0) - 15L) / entry->var_el_size) {
+ /* the -15 is to account for any padding CMSG_SPACE may add after the data */
+ php_error_docref0(NULL TSRMLS_CC, E_WARNING, "The value for the "
+ "third argument (%ld) is too large", n);
+ return;
+ }
+
+ RETURN_LONG((long)CMSG_SPACE(entry->size + n * entry->var_el_size));
+}
+
+#if HAVE_IPV6
+int php_do_setsockopt_ipv6_rfc3542(php_socket *php_sock, int level, int optname, zval **arg4 TSRMLS_DC)
+{
+ struct err_s err = {0};
+ zend_llist *allocations = NULL;
+ void *opt_ptr;
+ socklen_t optlen;
+ int retval;
+
+ assert(level == IPPROTO_IPV6);
+
+ switch (optname) {
+#ifdef IPV6_PKTINFO
+ case IPV6_PKTINFO:
+#ifdef PHP_WIN32
+ if (Z_TYPE_PP(arg4) == IS_ARRAY) {
+ php_error_docref0(NULL TSRMLS_CC, E_WARNING, "Windows does not "
+ "support sticky IPV6_PKTINFO");
+ return FAILURE;
+ } else {
+ /* windows has no IPV6_RECVPKTINFO, and uses IPV6_PKTINFO
+ * for the same effect. We define IPV6_RECVPKTINFO to be
+ * IPV6_PKTINFO, so assume the assume user used IPV6_RECVPKTINFO */
+ return 1;
+ }
+#endif
+ opt_ptr = from_zval_run_conversions(*arg4, php_sock, from_zval_write_in6_pktinfo,
+ sizeof(struct in6_pktinfo), "in6_pktinfo", &allocations, &err);
+ if (err.has_error) {
+ err_msg_dispose(&err TSRMLS_CC);
+ return FAILURE;
+ }
+
+ optlen = sizeof(struct in6_pktinfo);
+ goto dosockopt;
+#endif
+ }
+
+ /* we also support IPV6_TCLASS, but that can be handled by the default
+ * integer optval handling in the caller */
+ return 1;
+
+dosockopt:
+ retval = setsockopt(php_sock->bsd_socket, level, optname, opt_ptr, optlen);
+ if (retval != 0) {
+ PHP_SOCKET_ERROR(php_sock, "unable to set socket option", errno);
+ }
+ allocations_dispose(&allocations);
+
+ return retval != 0 ? FAILURE : SUCCESS;
+}
+
+int php_do_getsockopt_ipv6_rfc3542(php_socket *php_sock, int level, int optname, zval *result TSRMLS_DC)
+{
+ struct err_s err = {0};
+ void *buffer;
+ socklen_t size;
+ int res;
+ to_zval_read_field *reader;
+
+ assert(level == IPPROTO_IPV6);
+
+ switch (optname) {
+#ifdef IPV6_PKTINFO
+ case IPV6_PKTINFO:
+ size = sizeof(struct in6_pktinfo);
+ reader = &to_zval_read_in6_pktinfo;
+ break;
+#endif
+ default:
+ return 1;
+ }
+
+ buffer = ecalloc(1, size);
+ res = getsockopt(php_sock->bsd_socket, level, optname, buffer, &size);
+ if (res != 0) {
+ PHP_SOCKET_ERROR(php_sock, "unable to get socket option", errno);
+ } else {
+ zval *zv = to_zval_run_conversions(buffer, reader, "in6_pktinfo",
+ empty_key_value_list, &err);
+ if (err.has_error) {
+ err_msg_dispose(&err TSRMLS_CC);
+ res = -1;
+ } else {
+ ZVAL_COPY_VALUE(result, zv);
+ efree(zv);
+ }
+ }
+ efree(buffer);
+
+ return res == 0 ? SUCCESS : FAILURE;
+}
+#endif /* HAVE_IPV6 */
+
+void php_socket_sendrecvmsg_init(INIT_FUNC_ARGS)
+{
+ /* IPv6 ancillary data */
+#if defined(IPV6_RECVPKTINFO) && HAVE_IPV6
+ REGISTER_LONG_CONSTANT("IPV6_RECVPKTINFO", IPV6_RECVPKTINFO, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IPV6_PKTINFO", IPV6_PKTINFO, CONST_CS | CONST_PERSISTENT);
+#endif
+#if defined(IPV6_RECVHOPLIMIT) && HAVE_IPV6
+ REGISTER_LONG_CONSTANT("IPV6_RECVHOPLIMIT", IPV6_RECVHOPLIMIT, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IPV6_HOPLIMIT", IPV6_HOPLIMIT, CONST_CS | CONST_PERSISTENT);
+#endif
+ /* would require some effort:
+ REGISTER_LONG_CONSTANT("IPV6_RECVRTHDR", IPV6_RECVRTHDR, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IPV6_RECVHOPOPTS", IPV6_RECVHOPOPTS, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IPV6_RECVDSTOPTS", IPV6_RECVDSTOPTS, CONST_CS | CONST_PERSISTENT);
+ */
+#if defined(IPV6_RECVTCLASS) && HAVE_IPV6
+ REGISTER_LONG_CONSTANT("IPV6_RECVTCLASS", IPV6_RECVTCLASS, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IPV6_TCLASS", IPV6_TCLASS, CONST_CS | CONST_PERSISTENT);
+#endif
+
+ /*
+ REGISTER_LONG_CONSTANT("IPV6_RTHDR", IPV6_RTHDR, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IPV6_HOPOPTS", IPV6_HOPOPTS, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("IPV6_DSTOPTS", IPV6_DSTOPTS, CONST_CS | CONST_PERSISTENT);
+ */
+
+#ifdef SCM_RIGHTS
+ REGISTER_LONG_CONSTANT("SCM_RIGHTS", SCM_RIGHTS, CONST_CS | CONST_PERSISTENT);
+#endif
+#ifdef SO_PASSCRED
+ REGISTER_LONG_CONSTANT("SCM_CREDENTIALS", SCM_CREDENTIALS, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("SO_PASSCRED", SO_PASSCRED, CONST_CS | CONST_PERSISTENT);
+#endif
+
+#ifdef ZTS
+ ancillary_mutex = tsrm_mutex_alloc();
+#endif
+}
+
+void php_socket_sendrecvmsg_shutdown(SHUTDOWN_FUNC_ARGS)
+{
+#ifdef ZTS
+ tsrm_mutex_free(ancillary_mutex);
+#endif
+
+ destroy_ancillary_registry();
+}
diff --git a/ext/sockets/sendrecvmsg.h b/ext/sockets/sendrecvmsg.h
new file mode 100644
index 0000000000..5a3798274f
--- /dev/null
+++ b/ext/sockets/sendrecvmsg.h
@@ -0,0 +1,36 @@
+#ifndef PHP_SENDRECVMSG_H
+#define PHP_SENDRECVMSG_H 1
+
+#include <php.h>
+#include "conversions.h"
+
+/* for sockets.c */
+PHP_FUNCTION(socket_sendmsg);
+PHP_FUNCTION(socket_recvmsg);
+PHP_FUNCTION(socket_cmsg_space);
+
+void php_socket_sendrecvmsg_init(INIT_FUNC_ARGS);
+void php_socket_sendrecvmsg_shutdown(SHUTDOWN_FUNC_ARGS);
+
+int php_do_setsockopt_ipv6_rfc3542(php_socket *php_sock, int level, int optname, zval **arg4 TSRMLS_DC);
+int php_do_getsockopt_ipv6_rfc3542(php_socket *php_sock, int level, int optname, zval *result TSRMLS_DC);
+
+/* for conversions.c */
+typedef struct {
+ int cmsg_level; /* originating protocol */
+ int cmsg_type; /* protocol-specific type */
+} anc_reg_key;
+
+typedef size_t (calculate_req_space)(const zval *value, ser_context *ctx);
+
+typedef struct {
+ socklen_t size; /* size of native structure */
+ socklen_t var_el_size; /* size of repeatable component */
+ calculate_req_space *calc_space;
+ from_zval_write_field *from_array;
+ to_zval_read_field *to_array;
+} ancillary_reg_entry;
+
+ancillary_reg_entry *get_ancillary_reg_entry(int cmsg_level, int msg_type);
+
+#endif
diff --git a/ext/sockets/sockaddr_conv.c b/ext/sockets/sockaddr_conv.c
new file mode 100644
index 0000000000..1c1a90d58f
--- /dev/null
+++ b/ext/sockets/sockaddr_conv.c
@@ -0,0 +1,142 @@
+#include <php.h>
+#include <php_network.h>
+#include "php_sockets.h"
+
+#ifdef PHP_WIN32
+#include "windows_common.h"
+#else
+#include <netdb.h>
+#include <arpa/inet.h>
+#endif
+
+extern int php_string_to_if_index(const char *val, unsigned *out TSRMLS_DC);
+
+#if HAVE_IPV6
+/* Sets addr by hostname, or by ip in string form (AF_INET6) */
+int php_set_inet6_addr(struct sockaddr_in6 *sin6, char *string, php_socket *php_sock TSRMLS_DC) /* {{{ */
+{
+ struct in6_addr tmp;
+#if HAVE_GETADDRINFO
+ struct addrinfo hints;
+ struct addrinfo *addrinfo = NULL;
+#endif
+ char *scope = strchr(string, '%');
+
+ if (inet_pton(AF_INET6, string, &tmp)) {
+ memcpy(&(sin6->sin6_addr.s6_addr), &(tmp.s6_addr), sizeof(struct in6_addr));
+ } else {
+#if HAVE_GETADDRINFO
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_INET6;
+#if HAVE_AI_V4MAPPED
+ hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG;
+#else
+ hints.ai_flags = AI_ADDRCONFIG;
+#endif
+ getaddrinfo(string, NULL, &hints, &addrinfo);
+ if (!addrinfo) {
+#ifdef PHP_WIN32
+ PHP_SOCKET_ERROR(php_sock, "Host lookup failed", WSAGetLastError());
+#else
+ PHP_SOCKET_ERROR(php_sock, "Host lookup failed", (-10000 - h_errno));
+#endif
+ return 0;
+ }
+ if (addrinfo->ai_family != PF_INET6 || addrinfo->ai_addrlen != sizeof(struct sockaddr_in6)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Host lookup failed: Non AF_INET6 domain returned on AF_INET6 socket");
+ freeaddrinfo(addrinfo);
+ return 0;
+ }
+
+ memcpy(&(sin6->sin6_addr.s6_addr), ((struct sockaddr_in6*)(addrinfo->ai_addr))->sin6_addr.s6_addr, sizeof(struct in6_addr));
+ freeaddrinfo(addrinfo);
+
+#else
+ /* No IPv6 specific hostname resolution is available on this system? */
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Host lookup failed: getaddrinfo() not available on this system");
+ return 0;
+#endif
+
+ }
+
+ if (scope++) {
+ long lval = 0;
+ double dval = 0;
+ unsigned scope_id = 0;
+
+ if (IS_LONG == is_numeric_string(scope, strlen(scope), &lval, &dval, 0)) {
+ if (lval > 0 && lval <= UINT_MAX) {
+ scope_id = lval;
+ }
+ } else {
+ php_string_to_if_index(scope, &scope_id TSRMLS_CC);
+ }
+
+ sin6->sin6_scope_id = scope_id;
+ }
+
+ return 1;
+}
+/* }}} */
+#endif
+
+/* Sets addr by hostname, or by ip in string form (AF_INET) */
+int php_set_inet_addr(struct sockaddr_in *sin, char *string, php_socket *php_sock TSRMLS_DC) /* {{{ */
+{
+ struct in_addr tmp;
+ struct hostent *host_entry;
+
+ if (inet_aton(string, &tmp)) {
+ sin->sin_addr.s_addr = tmp.s_addr;
+ } else {
+ if (! (host_entry = gethostbyname(string))) {
+ /* Note: < -10000 indicates a host lookup error */
+#ifdef PHP_WIN32
+ PHP_SOCKET_ERROR(php_sock, "Host lookup failed", WSAGetLastError());
+#else
+ PHP_SOCKET_ERROR(php_sock, "Host lookup failed", (-10000 - h_errno));
+#endif
+ return 0;
+ }
+ if (host_entry->h_addrtype != AF_INET) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Host lookup failed: Non AF_INET domain returned on AF_INET socket");
+ return 0;
+ }
+ memcpy(&(sin->sin_addr.s_addr), host_entry->h_addr_list[0], host_entry->h_length);
+ }
+
+ return 1;
+}
+/* }}} */
+
+/* Sets addr by hostname or by ip in string form (AF_INET or AF_INET6,
+ * depending on the socket) */
+int php_set_inet46_addr(php_sockaddr_storage *ss, socklen_t *ss_len, char *string, php_socket *php_sock TSRMLS_DC) /* {{{ */
+{
+ if (php_sock->type == AF_INET) {
+ struct sockaddr_in t = {0};
+ if (php_set_inet_addr(&t, string, php_sock TSRMLS_CC)) {
+ memcpy(ss, &t, sizeof t);
+ ss->ss_family = AF_INET;
+ *ss_len = sizeof(t);
+ return 1;
+ }
+ }
+#if HAVE_IPV6
+ else if (php_sock->type == AF_INET6) {
+ struct sockaddr_in6 t = {0};
+ if (php_set_inet6_addr(&t, string, php_sock TSRMLS_CC)) {
+ memcpy(ss, &t, sizeof t);
+ ss->ss_family = AF_INET6;
+ *ss_len = sizeof(t);
+ return 1;
+ }
+ }
+#endif
+ else {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "IP address used in the context of an unexpected type of socket");
+ }
+ return 0;
+}
diff --git a/ext/sockets/sockaddr_conv.h b/ext/sockets/sockaddr_conv.h
new file mode 100644
index 0000000000..8e51edac8f
--- /dev/null
+++ b/ext/sockets/sockaddr_conv.h
@@ -0,0 +1,31 @@
+#ifndef PHP_SOCKADR_CONV_H
+#define PHP_SOCKADR_CONV_H
+
+#include <php_network.h>
+#include "php_sockets.h" /* php_socket */
+
+#ifndef PHP_WIN32
+# include <netinet/in.h>
+#else
+# include <Winsock2.h>
+#endif
+
+
+/*
+ * Convert an IPv6 literal or a hostname info a sockaddr_in6.
+ * The IPv6 literal can be a IPv4 mapped address (like ::ffff:127.0.0.1).
+ * If the hostname yields no IPv6 addresses, a mapped IPv4 address may be returned (AI_V4MAPPED)
+ */
+int php_set_inet6_addr(struct sockaddr_in6 *sin6, char *string, php_socket *php_sock TSRMLS_DC);
+
+/*
+ * Convert an IPv4 literal or a hostname into a sockaddr_in.
+ */
+int php_set_inet_addr(struct sockaddr_in *sin, char *string, php_socket *php_sock TSRMLS_DC);
+
+/*
+ * Calls either php_set_inet6_addr() or php_set_inet_addr(), depending on the type of the socket.
+ */
+int php_set_inet46_addr(php_sockaddr_storage *ss, socklen_t *ss_len, char *string, php_socket *php_sock TSRMLS_DC);
+
+#endif
diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c
index 7768d1f758..bd0a8f2f70 100644
--- a/ext/sockets/sockets.c
+++ b/ext/sockets/sockets.c
@@ -28,38 +28,17 @@
#include "php.h"
-#if HAVE_SOCKETS
-
#include "php_network.h"
#include "ext/standard/file.h"
#include "ext/standard/info.h"
#include "php_ini.h"
#ifdef PHP_WIN32
-# include "win32/inet.h"
-# include <winsock2.h>
+# include "windows_common.h"
+# include <win32/inet.h>
# include <windows.h>
# include <Ws2tcpip.h>
# include "php_sockets.h"
-# include "win32/sockets.h"
-# define IS_INVALID_SOCKET(a) (a->bsd_socket == INVALID_SOCKET)
-# ifdef EPROTONOSUPPORT
-# undef EPROTONOSUPPORT
-# endif
-# ifdef ECONNRESET
-# undef ECONNRESET
-# endif
-# define EPROTONOSUPPORT WSAEPROTONOSUPPORT
-# define ECONNRESET WSAECONNRESET
-# ifdef errno
-# undef errno
-# endif
-# define errno WSAGetLastError()
-# define h_errno WSAGetLastError()
-# define set_errno(a) WSASetLastError(a)
-# define close(a) closesocket(a)
-# if _WIN32_WINNT >= 0x0600 && SOCKETS_ENABLE_VISTA_API
-# define HAVE_IF_NAMETOINDEX 1
-# endif
+# include <win32/sockets.h>
#else
# include <sys/types.h>
# include <sys/socket.h>
@@ -77,18 +56,18 @@
# define IS_INVALID_SOCKET(a) (a->bsd_socket < 0)
# define set_errno(a) (errno = a)
# include "php_sockets.h"
-# if defined(_AIX) && !defined(HAVE_SA_SS_FAMILY)
-# define ss_family __ss_family
-# endif
# if HAVE_IF_NAMETOINDEX
# include <net/if.h>
# endif
#endif
+#include <stddef.h>
+
+#include "sockaddr_conv.h"
#include "multicast.h"
+#include "sendrecvmsg.h"
ZEND_DECLARE_MODULE_GLOBALS(sockets)
-static PHP_GINIT_FUNCTION(sockets);
#ifndef MSG_WAITALL
#ifdef LINUX
@@ -112,16 +91,6 @@ static PHP_GINIT_FUNCTION(sockets);
#define PF_INET AF_INET
#endif
-static char *php_strerror(int error TSRMLS_DC);
-
-#define PHP_SOCKET_ERROR(socket, msg, errn) \
- do { \
- int _err = (errn); /* save value to avoid repeated calls to WSAGetLastError() on Windows */ \
- (socket)->error = _err; \
- SOCKETS_G(last_error) = _err; \
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s [%d]: %s", msg, _err, php_strerror(_err TSRMLS_CC)); \
- } while (0)
-
#define PHP_NORMAL_READ 0x0001
#define PHP_BINARY_READ 0x0002
@@ -277,15 +246,34 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_clear_error, 0, 0, 0)
ZEND_ARG_INFO(0, socket)
ZEND_END_ARG_INFO()
-
+
ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_import_stream, 0, 0, 1)
ZEND_ARG_INFO(0, stream)
ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_sendmsg, 0, 0, 3)
+ ZEND_ARG_INFO(0, socket)
+ ZEND_ARG_INFO(0, msghdr)
+ ZEND_ARG_INFO(0, flags)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_recvmsg, 0, 0, 3)
+ ZEND_ARG_INFO(0, socket)
+ ZEND_ARG_INFO(1, msghdr)
+ ZEND_ARG_INFO(0, flags)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_socket_cmsg_space, 0, 0, 2)
+ ZEND_ARG_INFO(0, level)
+ ZEND_ARG_INFO(0, type)
+ZEND_END_ARG_INFO()
/* }}} */
-PHP_MINIT_FUNCTION(sockets);
-PHP_MINFO_FUNCTION(sockets);
-PHP_RSHUTDOWN_FUNCTION(sockets);
+static PHP_GINIT_FUNCTION(sockets);
+static PHP_MINIT_FUNCTION(sockets);
+static PHP_MSHUTDOWN_FUNCTION(sockets);
+static PHP_MINFO_FUNCTION(sockets);
+static PHP_RSHUTDOWN_FUNCTION(sockets);
PHP_FUNCTION(socket_select);
PHP_FUNCTION(socket_create_listen);
@@ -351,6 +339,9 @@ const zend_function_entry sockets_functions[] = {
PHP_FE(socket_last_error, arginfo_socket_last_error)
PHP_FE(socket_clear_error, arginfo_socket_clear_error)
PHP_FE(socket_import_stream, arginfo_socket_import_stream)
+ PHP_FE(socket_sendmsg, arginfo_socket_sendmsg)
+ PHP_FE(socket_recvmsg, arginfo_socket_recvmsg)
+ PHP_FE(socket_cmsg_space, arginfo_socket_cmsg_space)
/* for downwards compatibility */
PHP_FALIAS(socket_getopt, socket_get_option, arginfo_socket_get_option)
@@ -365,7 +356,7 @@ zend_module_entry sockets_module_entry = {
"sockets",
sockets_functions,
PHP_MINIT(sockets),
- NULL,
+ PHP_MSHUTDOWN(sockets),
NULL,
PHP_RSHUTDOWN(sockets),
PHP_MINFO(sockets),
@@ -396,13 +387,13 @@ PHP_SOCKETS_API int php_sockets_le_socket(void) /* {{{ */
static php_socket *php_create_socket(void) /* {{{ */
{
php_socket *php_sock = emalloc(sizeof *php_sock);
-
+
php_sock->bsd_socket = -1; /* invalid socket */
php_sock->type = PF_UNSPEC;
php_sock->error = 0;
php_sock->blocking = 1;
php_sock->zstream = NULL;
-
+
return php_sock;
}
/* }}} */
@@ -559,7 +550,7 @@ static int php_read(php_socket *sock, void *buf, size_t maxlen, int flags)
}
/* }}} */
-static char *php_strerror(int error TSRMLS_DC) /* {{{ */
+char *sockets_strerror(int error TSRMLS_DC) /* {{{ */
{
const char *buf;
@@ -606,213 +597,6 @@ static char *php_strerror(int error TSRMLS_DC) /* {{{ */
}
/* }}} */
-#if HAVE_IPV6
-static int php_get_if_index_from_string(const char *val, unsigned *out TSRMLS_DC);
-
-/* Sets addr by hostname, or by ip in string form (AF_INET6) */
-static int php_set_inet6_addr(struct sockaddr_in6 *sin6, char *string, php_socket *php_sock TSRMLS_DC) /* {{{ */
-{
- struct in6_addr tmp;
-#if HAVE_GETADDRINFO
- struct addrinfo hints;
- struct addrinfo *addrinfo = NULL;
-#endif
- char *scope = strchr(string, '%');
-
- if (inet_pton(AF_INET6, string, &tmp)) {
- memcpy(&(sin6->sin6_addr.s6_addr), &(tmp.s6_addr), sizeof(struct in6_addr));
- } else {
-#if HAVE_GETADDRINFO
-
- memset(&hints, 0, sizeof(struct addrinfo));
- hints.ai_family = PF_INET6;
- getaddrinfo(string, NULL, &hints, &addrinfo);
- if (!addrinfo) {
-#ifdef PHP_WIN32
- PHP_SOCKET_ERROR(php_sock, "Host lookup failed", WSAGetLastError());
-#else
- PHP_SOCKET_ERROR(php_sock, "Host lookup failed", (-10000 - h_errno));
-#endif
- return 0;
- }
- if (addrinfo->ai_family != PF_INET6 || addrinfo->ai_addrlen != sizeof(struct sockaddr_in6)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Host lookup failed: Non AF_INET6 domain returned on AF_INET6 socket");
- freeaddrinfo(addrinfo);
- return 0;
- }
-
- memcpy(&(sin6->sin6_addr.s6_addr), ((struct sockaddr_in6*)(addrinfo->ai_addr))->sin6_addr.s6_addr, sizeof(struct in6_addr));
- freeaddrinfo(addrinfo);
-
-#else
- /* No IPv6 specific hostname resolution is available on this system? */
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Host lookup failed: getaddrinfo() not available on this system");
- return 0;
-#endif
-
- }
-
- if (scope++) {
- long lval = 0;
- double dval = 0;
- unsigned scope_id = 0;
-
- if (IS_LONG == is_numeric_string(scope, strlen(scope), &lval, &dval, 0)) {
- if (lval > 0 && lval <= UINT_MAX) {
- scope_id = lval;
- }
- } else {
- php_get_if_index_from_string(scope, &scope_id TSRMLS_CC);
- }
-
- sin6->sin6_scope_id = scope_id;
- }
-
- return 1;
-}
-/* }}} */
-#endif
-
-/* Sets addr by hostname, or by ip in string form (AF_INET) */
-static int php_set_inet_addr(struct sockaddr_in *sin, char *string, php_socket *php_sock TSRMLS_DC) /* {{{ */
-{
- struct in_addr tmp;
- struct hostent *host_entry;
-
- if (inet_aton(string, &tmp)) {
- sin->sin_addr.s_addr = tmp.s_addr;
- } else {
- if (! (host_entry = gethostbyname(string))) {
- /* Note: < -10000 indicates a host lookup error */
-#ifdef PHP_WIN32
- PHP_SOCKET_ERROR(php_sock, "Host lookup failed", WSAGetLastError());
-#else
- PHP_SOCKET_ERROR(php_sock, "Host lookup failed", (-10000 - h_errno));
-#endif
- return 0;
- }
- if (host_entry->h_addrtype != AF_INET) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Host lookup failed: Non AF_INET domain returned on AF_INET socket");
- return 0;
- }
- memcpy(&(sin->sin_addr.s_addr), host_entry->h_addr_list[0], host_entry->h_length);
- }
-
- return 1;
-}
-/* }}} */
-
-/* Sets addr by hostname or by ip in string form (AF_INET or AF_INET6,
- * depending on the socket) */
-static int php_set_inet46_addr(php_sockaddr_storage *ss, socklen_t *ss_len, char *string, php_socket *php_sock TSRMLS_DC) /* {{{ */
-{
- if (php_sock->type == AF_INET) {
- struct sockaddr_in t = {0};
- if (php_set_inet_addr(&t, string, php_sock TSRMLS_CC)) {
- memcpy(ss, &t, sizeof t);
- ss->ss_family = AF_INET;
- *ss_len = sizeof(t);
- return 1;
- }
- }
-#if HAVE_IPV6
- else if (php_sock->type == AF_INET6) {
- struct sockaddr_in6 t = {0};
- if (php_set_inet6_addr(&t, string, php_sock TSRMLS_CC)) {
- memcpy(ss, &t, sizeof t);
- ss->ss_family = AF_INET6;
- *ss_len = sizeof(t);
- return 1;
- }
- }
-#endif
- else {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
- "IP address used in the context of an unexpected type of socket");
- }
- return 0;
-}
-
-static int php_get_if_index_from_string(const char *val, unsigned *out TSRMLS_DC)
-{
-#if HAVE_IF_NAMETOINDEX
- unsigned int ind;
-
- ind = if_nametoindex(val);
- if (ind == 0) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
- "no interface with name \"%s\" could be found", val);
- return FAILURE;
- } else {
- *out = ind;
- return SUCCESS;
- }
-#else
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
- "this platform does not support looking up an interface by "
- "name, an integer interface index must be supplied instead");
- return FAILURE;
-#endif
-}
-
-static int php_get_if_index_from_zval(zval *val, unsigned *out TSRMLS_DC)
-{
- int ret;
-
- if (Z_TYPE_P(val) == IS_LONG) {
- if (Z_LVAL_P(val) < 0 || Z_LVAL_P(val) > UINT_MAX) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
- "the interface index cannot be negative or larger than %u;"
- " given %ld", UINT_MAX, Z_LVAL_P(val));
- ret = FAILURE;
- } else {
- *out = Z_LVAL_P(val);
- ret = SUCCESS;
- }
- } else {
- zval_add_ref(&val);
- convert_to_string_ex(&val);
- ret = php_get_if_index_from_string(Z_STRVAL_P(val), out TSRMLS_CC);
- zval_ptr_dtor(&val);
- }
-
- return ret;
-}
-
-static int php_get_if_index_from_array(const HashTable *ht, const char *key,
- php_socket *sock, unsigned int *if_index TSRMLS_DC)
-{
- zval **val;
-
- if (zend_hash_find(ht, key, strlen(key) + 1, (void **)&val) == FAILURE) {
- *if_index = 0; /* default: 0 */
- return SUCCESS;
- }
-
- return php_get_if_index_from_zval(*val, if_index TSRMLS_CC);
-}
-
-static int php_get_address_from_array(const HashTable *ht, const char *key,
- php_socket *sock, php_sockaddr_storage *ss, socklen_t *ss_len TSRMLS_DC)
-{
- zval **val,
- *valcp;
-
- if (zend_hash_find(ht, key, strlen(key) + 1, (void **)&val) == FAILURE) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "no key \"%s\" passed in optval", key);
- return FAILURE;
- }
- valcp = *val;
- zval_add_ref(&valcp);
- convert_to_string_ex(val);
- if (!php_set_inet46_addr(ss, ss_len, Z_STRVAL_P(valcp), sock TSRMLS_CC)) {
- zval_ptr_dtor(&valcp);
- return FAILURE;
- }
- zval_ptr_dtor(&valcp);
- return SUCCESS;
-}
-
/* {{{ PHP_GINIT_FUNCTION */
static PHP_GINIT_FUNCTION(sockets)
{
@@ -823,7 +607,7 @@ static PHP_GINIT_FUNCTION(sockets)
/* {{{ PHP_MINIT_FUNCTION
*/
-PHP_MINIT_FUNCTION(sockets)
+static PHP_MINIT_FUNCTION(sockets)
{
le_socket = zend_register_list_destructors_ex(php_destroy_socket, NULL, le_socket_name, module_number);
@@ -837,11 +621,11 @@ PHP_MINIT_FUNCTION(sockets)
REGISTER_LONG_CONSTANT("SOCK_RAW", SOCK_RAW, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SOCK_SEQPACKET",SOCK_SEQPACKET, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SOCK_RDM", SOCK_RDM, CONST_CS | CONST_PERSISTENT);
+
REGISTER_LONG_CONSTANT("MSG_OOB", MSG_OOB, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("MSG_WAITALL", MSG_WAITALL, CONST_CS | CONST_PERSISTENT);
-#ifdef MSG_DONTWAIT
- REGISTER_LONG_CONSTANT("MSG_DONTWAIT", MSG_DONTWAIT, CONST_CS | CONST_PERSISTENT);
-#endif
+ REGISTER_LONG_CONSTANT("MSG_CTRUNC", MSG_CTRUNC, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("MSG_TRUNC", MSG_TRUNC, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("MSG_PEEK", MSG_PEEK, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("MSG_DONTROUTE", MSG_DONTROUTE, CONST_CS | CONST_PERSISTENT);
#ifdef MSG_EOR
@@ -850,6 +634,29 @@ PHP_MINIT_FUNCTION(sockets)
#ifdef MSG_EOF
REGISTER_LONG_CONSTANT("MSG_EOF", MSG_EOF, CONST_CS | CONST_PERSISTENT);
#endif
+
+#ifdef MSG_CONFIRM
+ REGISTER_LONG_CONSTANT("MSG_CONFIRM", MSG_CONFIRM, CONST_CS | CONST_PERSISTENT);
+#endif
+#ifdef MSG_ERRQUEUE
+ REGISTER_LONG_CONSTANT("MSG_ERRQUEUE", MSG_ERRQUEUE, CONST_CS | CONST_PERSISTENT);
+#endif
+#ifdef MSG_NOSIGNAL
+ REGISTER_LONG_CONSTANT("MSG_NOSIGNAL", MSG_NOSIGNAL, CONST_CS | CONST_PERSISTENT);
+#endif
+#ifdef MSG_DONTWAIT
+ REGISTER_LONG_CONSTANT("MSG_DONTWAIT", MSG_DONTWAIT, CONST_CS | CONST_PERSISTENT);
+#endif
+#ifdef MSG_MORE
+ REGISTER_LONG_CONSTANT("MSG_MORE", MSG_MORE, CONST_CS | CONST_PERSISTENT);
+#endif
+#ifdef MSG_WAITFORONE
+ REGISTER_LONG_CONSTANT("MSG_WAITFORONE",MSG_WAITFORONE, CONST_CS | CONST_PERSISTENT);
+#endif
+#ifdef MSG_CMSG_CLOEXEC
+ REGISTER_LONG_CONSTANT("MSG_CMSG_CLOEXEC",MSG_CMSG_CLOEXEC,CONST_CS | CONST_PERSISTENT);
+#endif
+
REGISTER_LONG_CONSTANT("SO_DEBUG", SO_DEBUG, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SO_REUSEADDR", SO_REUSEADDR, CONST_CS | CONST_PERSISTENT);
#ifdef SO_REUSEPORT
@@ -867,6 +674,9 @@ PHP_MINIT_FUNCTION(sockets)
REGISTER_LONG_CONSTANT("SO_SNDTIMEO", SO_SNDTIMEO, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SO_RCVTIMEO", SO_RCVTIMEO, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SO_TYPE", SO_TYPE, CONST_CS | CONST_PERSISTENT);
+#ifdef SO_FAMILY
+ REGISTER_LONG_CONSTANT("SO_FAMILY", SO_FAMILY, CONST_CS | CONST_PERSISTENT);
+#endif
REGISTER_LONG_CONSTANT("SO_ERROR", SO_ERROR, CONST_CS | CONST_PERSISTENT);
#ifdef SO_BINDTODEVICE
REGISTER_LONG_CONSTANT("SO_BINDTODEVICE", SO_BINDTODEVICE, CONST_CS | CONST_PERSISTENT);
@@ -879,24 +689,13 @@ PHP_MINIT_FUNCTION(sockets)
REGISTER_LONG_CONSTANT("PHP_NORMAL_READ", PHP_NORMAL_READ, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("PHP_BINARY_READ", PHP_BINARY_READ, CONST_CS | CONST_PERSISTENT);
-#ifndef RFC3678_API
-#define MCAST_JOIN_GROUP IP_ADD_MEMBERSHIP
-#define MCAST_LEAVE_GROUP IP_DROP_MEMBERSHIP
+ REGISTER_LONG_CONSTANT("MCAST_JOIN_GROUP", PHP_MCAST_JOIN_GROUP, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("MCAST_LEAVE_GROUP", PHP_MCAST_LEAVE_GROUP, CONST_CS | CONST_PERSISTENT);
#ifdef HAS_MCAST_EXT
-#define MCAST_BLOCK_SOURCE IP_BLOCK_SOURCE
-#define MCAST_UNBLOCK_SOURCE IP_UNBLOCK_SOURCE
-#define MCAST_JOIN_SOURCE_GROUP IP_ADD_SOURCE_MEMBERSHIP
-#define MCAST_LEAVE_SOURCE_GROUP IP_DROP_SOURCE_MEMBERSHIP
-#endif
-#endif
-
- REGISTER_LONG_CONSTANT("MCAST_JOIN_GROUP", MCAST_JOIN_GROUP, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("MCAST_LEAVE_GROUP", MCAST_LEAVE_GROUP, CONST_CS | CONST_PERSISTENT);
-#ifdef HAS_MCAST_EXT
- REGISTER_LONG_CONSTANT("MCAST_BLOCK_SOURCE", MCAST_BLOCK_SOURCE, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("MCAST_UNBLOCK_SOURCE", MCAST_UNBLOCK_SOURCE, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("MCAST_JOIN_SOURCE_GROUP", MCAST_JOIN_SOURCE_GROUP, CONST_CS | CONST_PERSISTENT);
- REGISTER_LONG_CONSTANT("MCAST_LEAVE_SOURCE_GROUP", MCAST_LEAVE_SOURCE_GROUP, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("MCAST_BLOCK_SOURCE", PHP_MCAST_BLOCK_SOURCE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("MCAST_UNBLOCK_SOURCE", PHP_MCAST_UNBLOCK_SOURCE, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("MCAST_JOIN_SOURCE_GROUP", PHP_MCAST_JOIN_SOURCE_GROUP, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("MCAST_LEAVE_SOURCE_GROUP", PHP_MCAST_LEAVE_SOURCE_GROUP, CONST_CS | CONST_PERSISTENT);
#endif
REGISTER_LONG_CONSTANT("IP_MULTICAST_IF", IP_MULTICAST_IF, CONST_CS | CONST_PERSISTENT);
@@ -922,13 +721,29 @@ PHP_MINIT_FUNCTION(sockets)
REGISTER_LONG_CONSTANT("SOL_TCP", IPPROTO_TCP, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SOL_UDP", IPPROTO_UDP, CONST_CS | CONST_PERSISTENT);
+#if HAVE_IPV6
+ REGISTER_LONG_CONSTANT("IPV6_UNICAST_HOPS", IPV6_UNICAST_HOPS, CONST_CS | CONST_PERSISTENT);
+#endif
+
+ php_socket_sendrecvmsg_init(INIT_FUNC_ARGS_PASSTHRU);
+
+ return SUCCESS;
+}
+/* }}} */
+
+/* {{{ PHP_MSHUTDOWN_FUNCTION
+ */
+static PHP_MSHUTDOWN_FUNCTION(sockets)
+{
+ php_socket_sendrecvmsg_shutdown(SHUTDOWN_FUNC_ARGS_PASSTHRU);
+
return SUCCESS;
}
/* }}} */
/* {{{ PHP_MINFO_FUNCTION
*/
-PHP_MINFO_FUNCTION(sockets)
+static PHP_MINFO_FUNCTION(sockets)
{
php_info_print_table_start();
php_info_print_table_row(2, "Sockets Support", "enabled");
@@ -937,7 +752,7 @@ PHP_MINFO_FUNCTION(sockets)
/* }}} */
/* {{{ PHP_RSHUTDOWN_FUNCTION */
-PHP_RSHUTDOWN_FUNCTION(sockets)
+static PHP_RSHUTDOWN_FUNCTION(sockets)
{
if (SOCKETS_G(strerror_buf)) {
efree(SOCKETS_G(strerror_buf));
@@ -1084,7 +899,7 @@ PHP_FUNCTION(socket_select)
if (retval == -1) {
SOCKETS_G(last_error) = errno;
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to select [%d]: %s", errno, php_strerror(errno TSRMLS_CC));
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to select [%d]: %s", errno, sockets_strerror(errno TSRMLS_CC));
RETURN_FALSE;
}
@@ -1153,7 +968,7 @@ PHP_FUNCTION(socket_set_nonblock)
}
ZEND_FETCH_RESOURCE(php_sock, php_socket *, &arg1, -1, le_socket_name, le_socket);
-
+
if (php_sock->zstream != NULL) {
php_stream *stream;
/* omit notice if resource doesn't exist anymore */
@@ -1190,7 +1005,7 @@ PHP_FUNCTION(socket_set_block)
}
ZEND_FETCH_RESOURCE(php_sock, php_socket *, &arg1, -1, le_socket_name, le_socket);
-
+
/* if socket was created from a stream, give the stream a chance to take
* care of the operation itself, thereby allowing it to update its internal
* state */
@@ -1544,7 +1359,7 @@ PHP_FUNCTION(socket_create)
if (IS_INVALID_SOCKET(php_sock)) {
SOCKETS_G(last_error) = errno;
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create socket [%d]: %s", errno, php_strerror(errno TSRMLS_CC));
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create socket [%d]: %s", errno, sockets_strerror(errno TSRMLS_CC));
efree(php_sock);
RETURN_FALSE;
}
@@ -1577,7 +1392,7 @@ PHP_FUNCTION(socket_connect)
#if HAVE_IPV6
case AF_INET6: {
struct sockaddr_in6 sin6 = {0};
-
+
if (argc != 3) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Socket of type AF_INET6 requires 3 arguments");
RETURN_FALSE;
@@ -1598,7 +1413,7 @@ PHP_FUNCTION(socket_connect)
#endif
case AF_INET: {
struct sockaddr_in sin = {0};
-
+
if (argc != 3) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Socket of type AF_INET requires 3 arguments");
RETURN_FALSE;
@@ -1617,7 +1432,7 @@ PHP_FUNCTION(socket_connect)
case AF_UNIX: {
struct sockaddr_un s_un = {0};
-
+
if (addr_len >= sizeof(s_un.sun_path)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Path too long");
RETURN_FALSE;
@@ -1654,7 +1469,7 @@ PHP_FUNCTION(socket_strerror)
return;
}
- RETURN_STRING(php_strerror(arg1 TSRMLS_CC), 1);
+ RETURN_STRING(sockets_strerror(arg1 TSRMLS_CC), 1);
}
/* }}} */
@@ -1663,7 +1478,7 @@ PHP_FUNCTION(socket_strerror)
PHP_FUNCTION(socket_bind)
{
zval *arg1;
- php_sockaddr_storage sa_storage;
+ php_sockaddr_storage sa_storage = {0};
struct sockaddr *sock_type = (struct sockaddr*) &sa_storage;
php_socket *php_sock;
char *addr;
@@ -1681,10 +1496,19 @@ PHP_FUNCTION(socket_bind)
case AF_UNIX:
{
struct sockaddr_un *sa = (struct sockaddr_un *) sock_type;
- memset(sa, 0, sizeof(sa_storage));
+
sa->sun_family = AF_UNIX;
- snprintf(sa->sun_path, 108, "%s", addr);
- retval = bind(php_sock->bsd_socket, (struct sockaddr *) sa, SUN_LEN(sa));
+
+ if (addr_len >= sizeof(sa->sun_path)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,
+ "Invalid path: too long (maximum size is %d)",
+ (int)sizeof(sa->sun_path) - 1);
+ RETURN_FALSE;
+ }
+ memcpy(&sa->sun_path, addr, addr_len);
+
+ retval = bind(php_sock->bsd_socket, (struct sockaddr *) sa,
+ offsetof(struct sockaddr_un, sun_path) + addr_len);
break;
}
@@ -1692,8 +1516,6 @@ PHP_FUNCTION(socket_bind)
{
struct sockaddr_in *sa = (struct sockaddr_in *) sock_type;
- memset(sa, 0, sizeof(sa_storage)); /* Apparently, Mac OSX needs this */
-
sa->sin_family = AF_INET;
sa->sin_port = htons((unsigned short) port);
@@ -1709,8 +1531,6 @@ PHP_FUNCTION(socket_bind)
{
struct sockaddr_in6 *sa = (struct sockaddr_in6 *) sock_type;
- memset(sa, 0, sizeof(sa_storage)); /* Apparently, Mac OSX needs this */
-
sa->sin6_family = AF_INET6;
sa->sin6_port = htons((unsigned short) port);
@@ -2046,7 +1866,17 @@ PHP_FUNCTION(socket_get_option)
}
}
}
-
+#if HAVE_IPV6
+ else if (level == IPPROTO_IPV6) {
+ int ret = php_do_getsockopt_ipv6_rfc3542(php_sock, level, optname, return_value TSRMLS_CC);
+ if (ret == SUCCESS) {
+ return;
+ } else if (ret == FAILURE) {
+ RETURN_FALSE;
+ } /* else continue */
+ }
+#endif
+
/* sol_socket options and general case */
switch(optname) {
case SO_LINGER:
@@ -2088,7 +1918,7 @@ PHP_FUNCTION(socket_get_option)
add_assoc_long(return_value, "sec", tv.tv_sec);
add_assoc_long(return_value, "usec", tv.tv_usec);
break;
-
+
default:
optlen = sizeof(other_val);
@@ -2105,102 +1935,6 @@ PHP_FUNCTION(socket_get_option)
}
/* }}} */
-static int php_do_mcast_opt(php_socket *php_sock, int level, int optname, zval **arg4 TSRMLS_DC)
-{
- HashTable *opt_ht;
- unsigned int if_index;
- int retval;
- int (*mcast_req_fun)(php_socket *, int, struct sockaddr *, socklen_t,
- unsigned TSRMLS_DC);
-#ifdef HAS_MCAST_EXT
- int (*mcast_sreq_fun)(php_socket *, int, struct sockaddr *, socklen_t,
- struct sockaddr *, socklen_t, unsigned TSRMLS_DC);
-#endif
-
- switch (optname) {
- case MCAST_JOIN_GROUP:
- mcast_req_fun = &php_mcast_join;
- goto mcast_req_fun;
- case MCAST_LEAVE_GROUP:
- {
- php_sockaddr_storage group = {0};
- socklen_t glen;
-
- mcast_req_fun = &php_mcast_leave;
-mcast_req_fun:
- convert_to_array_ex(arg4);
- opt_ht = HASH_OF(*arg4);
-
- if (php_get_address_from_array(opt_ht, "group", php_sock, &group,
- &glen TSRMLS_CC) == FAILURE) {
- return FAILURE;
- }
- if (php_get_if_index_from_array(opt_ht, "interface", php_sock,
- &if_index TSRMLS_CC) == FAILURE) {
- return FAILURE;
- }
-
- retval = mcast_req_fun(php_sock, level, (struct sockaddr*)&group,
- glen, if_index TSRMLS_CC);
- break;
- }
-
-#ifdef HAS_MCAST_EXT
- case MCAST_BLOCK_SOURCE:
- mcast_sreq_fun = &php_mcast_block_source;
- goto mcast_sreq_fun;
- case MCAST_UNBLOCK_SOURCE:
- mcast_sreq_fun = &php_mcast_unblock_source;
- goto mcast_sreq_fun;
- case MCAST_JOIN_SOURCE_GROUP:
- mcast_sreq_fun = &php_mcast_join_source;
- goto mcast_sreq_fun;
- case MCAST_LEAVE_SOURCE_GROUP:
- {
- php_sockaddr_storage group = {0},
- source = {0};
- socklen_t glen,
- slen;
-
- mcast_sreq_fun = &php_mcast_leave_source;
- mcast_sreq_fun:
- convert_to_array_ex(arg4);
- opt_ht = HASH_OF(*arg4);
-
- if (php_get_address_from_array(opt_ht, "group", php_sock, &group,
- &glen TSRMLS_CC) == FAILURE) {
- return FAILURE;
- }
- if (php_get_address_from_array(opt_ht, "source", php_sock, &source,
- &slen TSRMLS_CC) == FAILURE) {
- return FAILURE;
- }
- if (php_get_if_index_from_array(opt_ht, "interface", php_sock,
- &if_index TSRMLS_CC) == FAILURE) {
- return FAILURE;
- }
-
- retval = mcast_sreq_fun(php_sock, level, (struct sockaddr*)&group,
- glen, (struct sockaddr*)&source, slen, if_index TSRMLS_CC);
- break;
- }
-#endif
- default:
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
- "unexpected option in php_do_mcast_opt (level %d, option %d). "
- "This is a bug.", level, optname);
- return FAILURE;
- }
-
- if (retval != 0) {
- if (retval != -2) { /* error, but message already emitted */
- PHP_SOCKET_ERROR(php_sock, "unable to set socket option", errno);
- }
- return FAILURE;
- }
- return SUCCESS;
-}
-
/* {{{ proto bool socket_set_option(resource socket, int level, int optname, int|array optval)
Sets socket options for the socket */
PHP_FUNCTION(socket_set_option)
@@ -2219,12 +1953,8 @@ PHP_FUNCTION(socket_set_option)
HashTable *opt_ht;
zval **l_onoff, **l_linger;
zval **sec, **usec;
-
- /* Multicast */
- unsigned int if_index;
- struct in_addr if_addr;
- unsigned char ipv4_mcast_ttl_lback;
-
+
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rllZ", &arg1, &level, &optname, &arg4) == FAILURE) {
return;
}
@@ -2233,94 +1963,26 @@ PHP_FUNCTION(socket_set_option)
set_errno(0);
- if (level == IPPROTO_IP) {
- switch (optname) {
- case MCAST_JOIN_GROUP:
- case MCAST_LEAVE_GROUP:
-#ifdef HAS_MCAST_EXT
- case MCAST_BLOCK_SOURCE:
- case MCAST_UNBLOCK_SOURCE:
- case MCAST_JOIN_SOURCE_GROUP:
- case MCAST_LEAVE_SOURCE_GROUP:
-#endif
- if (php_do_mcast_opt(php_sock, level, optname, arg4 TSRMLS_CC) == FAILURE) {
- RETURN_FALSE;
- } else {
- RETURN_TRUE;
- }
+#define HANDLE_SUBCALL(res) \
+ do { \
+ if (res == 1) { goto default_case; } \
+ else if (res == SUCCESS) { RETURN_TRUE; } \
+ else { RETURN_FALSE; } \
+ } while (0)
- case IP_MULTICAST_IF:
- if (php_get_if_index_from_zval(*arg4, &if_index TSRMLS_CC) == FAILURE) {
- RETURN_FALSE;
- }
- if (php_if_index_to_addr4(if_index, php_sock, &if_addr TSRMLS_CC) == FAILURE) {
- RETURN_FALSE;
- }
- opt_ptr = &if_addr;
- optlen = sizeof(if_addr);
- goto dosockopt;
-
- case IP_MULTICAST_LOOP:
- convert_to_boolean_ex(arg4);
- goto ipv4_loop_ttl;
- case IP_MULTICAST_TTL:
- convert_to_long_ex(arg4);
- if (Z_LVAL_PP(arg4) < 0L || Z_LVAL_PP(arg4) > 255L) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
- "Expected a value between 0 and 255");
- RETURN_FALSE;
- }
-ipv4_loop_ttl:
- ipv4_mcast_ttl_lback = (unsigned char) Z_LVAL_PP(arg4);
- opt_ptr = &ipv4_mcast_ttl_lback;
- optlen = sizeof(ipv4_mcast_ttl_lback);
- goto dosockopt;
- }
+ if (level == IPPROTO_IP) {
+ int res = php_do_setsockopt_ip_mcast(php_sock, level, optname, arg4 TSRMLS_CC);
+ HANDLE_SUBCALL(res);
}
#if HAVE_IPV6
else if (level == IPPROTO_IPV6) {
- switch (optname) {
- case MCAST_JOIN_GROUP:
- case MCAST_LEAVE_GROUP:
-#ifdef HAS_MCAST_EXT
- case MCAST_BLOCK_SOURCE:
- case MCAST_UNBLOCK_SOURCE:
- case MCAST_JOIN_SOURCE_GROUP:
- case MCAST_LEAVE_SOURCE_GROUP:
-#endif
- if (php_do_mcast_opt(php_sock, level, optname, arg4 TSRMLS_CC) == FAILURE) {
- RETURN_FALSE;
- } else {
- RETURN_TRUE;
- }
-
- case IPV6_MULTICAST_IF:
- if (php_get_if_index_from_zval(*arg4, &if_index TSRMLS_CC) == FAILURE) {
- RETURN_FALSE;
- }
-
- opt_ptr = &if_index;
- optlen = sizeof(if_index);
- goto dosockopt;
-
- case IPV6_MULTICAST_LOOP:
- convert_to_boolean_ex(arg4);
- goto ipv6_loop_hops;
- case IPV6_MULTICAST_HOPS:
- convert_to_long_ex(arg4);
- if (Z_LVAL_PP(arg4) < -1L || Z_LVAL_PP(arg4) > 255L) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING,
- "Expected a value between -1 and 255");
- RETURN_FALSE;
- }
-ipv6_loop_hops:
- ov = (int) Z_LVAL_PP(arg4);
- opt_ptr = &ov;
- optlen = sizeof(ov);
- goto dosockopt;
+ int res = php_do_setsockopt_ipv6_mcast(php_sock, level, optname, arg4 TSRMLS_CC);
+ if (res == 1) {
+ res = php_do_setsockopt_ipv6_rfc3542(php_sock, level, optname, arg4 TSRMLS_CC);
}
+ HANDLE_SUBCALL(res);
}
#endif
@@ -2397,6 +2059,7 @@ ipv6_loop_hops:
#endif
default:
+default_case:
convert_to_long_ex(arg4);
ov = Z_LVAL_PP(arg4);
@@ -2405,12 +2068,9 @@ ipv6_loop_hops:
break;
}
-dosockopt:
retval = setsockopt(php_sock->bsd_socket, level, optname, opt_ptr, optlen);
if (retval != 0) {
- if (retval != -2) { /* error, but message already emitted */
- PHP_SOCKET_ERROR(php_sock, "unable to set socket option", errno);
- }
+ PHP_SOCKET_ERROR(php_sock, "unable to set socket option", errno);
RETURN_FALSE;
}
@@ -2451,7 +2111,7 @@ PHP_FUNCTION(socket_create_pair)
if (socketpair(domain, type, protocol, fds_array) != 0) {
SOCKETS_G(last_error) = errno;
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to create socket pair [%d]: %s", errno, php_strerror(errno TSRMLS_CC));
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to create socket pair [%d]: %s", errno, sockets_strerror(errno TSRMLS_CC));
efree(php_sock[0]);
efree(php_sock[1]);
RETURN_FALSE;
@@ -2550,6 +2210,53 @@ PHP_FUNCTION(socket_clear_error)
}
/* }}} */
+php_socket *socket_import_file_descriptor(PHP_SOCKET socket TSRMLS_DC)
+{
+#ifdef SO_DOMAIN
+ int type;
+ socklen_t type_len = sizeof(type);
+#endif
+ php_socket *retsock;
+ php_sockaddr_storage addr;
+ socklen_t addr_len = sizeof(addr);
+#ifndef PHP_WIN32
+ int t;
+#endif
+
+ retsock = php_create_socket();
+ retsock->bsd_socket = socket;
+
+ /* determine family */
+#ifdef SO_DOMAIN
+ if (getsockopt(socket, SOL_SOCKET, SO_DOMAIN, &type, &type_len) == 0) {
+ retsock->type = type;
+ } else
+#endif
+ if (getsockname(socket, (struct sockaddr*)&addr, &addr_len) == 0) {
+ retsock->type = addr.ss_family;
+ } else {
+ PHP_SOCKET_ERROR(retsock, "unable to obtain socket family", errno);
+ goto error;
+ }
+
+ /* determine blocking mode */
+#ifndef PHP_WIN32
+ t = fcntl(socket, F_GETFL);
+ if (t == -1) {
+ PHP_SOCKET_ERROR(retsock, "unable to obtain blocking state", errno);
+ goto error;
+ } else {
+ retsock->blocking = !(t & O_NONBLOCK);
+ }
+#endif
+
+ return retsock;
+
+error:
+ efree(retsock);
+ return NULL;
+}
+
/* {{{ proto void socket_import_stream(resource stream)
Imports a stream that encapsulates a socket into a socket extension resource. */
PHP_FUNCTION(socket_import_stream)
@@ -2558,44 +2265,23 @@ PHP_FUNCTION(socket_import_stream)
php_stream *stream;
php_socket *retsock = NULL;
PHP_SOCKET socket; /* fd */
- php_sockaddr_storage addr;
- socklen_t addr_len = sizeof(addr);
-#ifndef PHP_WIN32
- int t;
-#endif
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zstream) == FAILURE) {
return;
}
php_stream_from_zval(stream, &zstream);
-
+
if (php_stream_cast(stream, PHP_STREAM_AS_SOCKETD, (void**)&socket, 1)) {
/* error supposedly already shown */
RETURN_FALSE;
}
-
- retsock = php_create_socket();
-
- retsock->bsd_socket = socket;
-
- /* determine family */
- if (getsockname(socket, (struct sockaddr*)&addr, &addr_len) == 0) {
- retsock->type = addr.ss_family;
- } else {
- PHP_SOCKET_ERROR(retsock, "unable to obtain socket family", errno);
- goto error;
- }
-
- /* determine blocking mode */
-#ifndef PHP_WIN32
- t = fcntl(socket, F_GETFL);
- if(t == -1) {
- PHP_SOCKET_ERROR(retsock, "unable to obtain blocking state", errno);
- goto error;
- } else {
- retsock->blocking = !(t & O_NONBLOCK);
+
+ retsock = socket_import_file_descriptor(socket TSRMLS_CC);
+ if (retsock == NULL) {
+ RETURN_FALSE;
}
-#else
+
+#ifdef PHP_WIN32
/* on windows, check if the stream is a socket stream and read its
* private data; otherwise assume it's in non-blocking mode */
if (php_stream_is(stream, PHP_STREAM_IS_SOCKET)) {
@@ -2605,7 +2291,7 @@ PHP_FUNCTION(socket_import_stream)
retsock->blocking = 1;
}
#endif
-
+
/* hold a zval reference to the stream (holding a php_stream* directly could
* also be done, but this might be slightly better if in the future we want
* to provide a socket_export_stream) */
@@ -2614,21 +2300,14 @@ PHP_FUNCTION(socket_import_stream)
zval_copy_ctor(retsock->zstream);
Z_UNSET_ISREF_P(retsock->zstream);
Z_SET_REFCOUNT_P(retsock->zstream, 1);
-
+
php_stream_set_option(stream, PHP_STREAM_OPTION_READ_BUFFER,
PHP_STREAM_BUFFER_NONE, NULL);
-
+
ZEND_REGISTER_RESOURCE(return_value, retsock, le_socket);
- return;
-error:
- if (retsock != NULL)
- efree(retsock);
- RETURN_FALSE;
}
/* }}} */
-#endif
-
/*
* Local variables:
* tab-width: 4
diff --git a/ext/sockets/tests/mcast_ipv6_send.phpt b/ext/sockets/tests/mcast_ipv6_send.phpt
index b8d38bf68f..f75bb09903 100644
--- a/ext/sockets/tests/mcast_ipv6_send.phpt
+++ b/ext/sockets/tests/mcast_ipv6_send.phpt
@@ -9,8 +9,8 @@ if (!defined('IPPROTO_IPV6')) {
die('skip IPv6 not available.');
}
$level = IPPROTO_IPV6;
-$s = socket_create($domain, SOCK_DGRAM, SOL_UDP) or die("skip Can not create socket");
-if (socket_set_option($s, $level, IP_MULTICAST_IF, 1) === false) {
+$s = socket_create(AF_INET6, SOCK_DGRAM, SOL_UDP) or die("skip Can not create socket");
+if (socket_set_option($s, $level, IPV6_MULTICAST_IF, 1) === false) {
die("skip interface 1 either doesn't exist or has no ipv6 address");
}
--FILE--
diff --git a/ext/sockets/tests/socket_abstract_path.phpt b/ext/sockets/tests/socket_abstract_path.phpt
new file mode 100644
index 0000000000..816e5c11bb
--- /dev/null
+++ b/ext/sockets/tests/socket_abstract_path.phpt
@@ -0,0 +1,44 @@
+--TEST--
+Support for paths in the abstract namespace (bind, connect)
+--SKIPIF--
+<?php
+if (!extension_loaded('sockets'))
+ die('skip sockets extension not available.');
+
+if (PHP_OS != 'Linux') {
+ die('skip For Linux only');
+}
+?>
+--FILE--
+<?php
+include __DIR__."/mcast_helpers.php.inc";
+
+$path = "\x00/foo_bar";
+
+echo "creating server socket\n";
+$servers = socket_create(AF_UNIX, SOCK_STREAM, 0) or die("err");
+socket_bind($servers, $path) or die("Could not bind");
+socket_listen($servers) or die("Could not listen");
+socket_set_nonblock($servers) or die("Could not put in non-blocking mode");
+
+echo "creating client socket\n";
+$clients = socket_create(AF_UNIX, SOCK_STREAM, 0) or die("err");
+socket_connect($clients, $path) or die("Error connecting");
+
+$conns = socket_accept($servers) or die("Could not accept connection");
+
+$r = socket_sendmsg($clients, [
+ //"name" => [ "addr" => $path, ],
+ "iov" => ["test ", "thing", "\n"],
+], 0);
+var_dump($r);
+checktimeout($conns, 500);
+
+if (!socket_recv($conns, $buf, 20, 0)) die("recv");
+print_r($buf);
+?>
+--EXPECTF--
+creating server socket
+creating client socket
+int(11)
+test thing
diff --git a/ext/sockets/tests/socket_abstract_path_sendmsg.phpt b/ext/sockets/tests/socket_abstract_path_sendmsg.phpt
new file mode 100644
index 0000000000..5a9275a26b
--- /dev/null
+++ b/ext/sockets/tests/socket_abstract_path_sendmsg.phpt
@@ -0,0 +1,40 @@
+--TEST--
+Support for paths in the abstract namespace (bind, sendmsg, recvmsg)
+--SKIPIF--
+<?php
+if (!extension_loaded('sockets'))
+ die('skip sockets extension not available.');
+
+if (PHP_OS != 'Linux') {
+ die('skip For Linux only');
+}
+?>
+--FILE--
+<?php
+include __DIR__."/mcast_helpers.php.inc";
+
+$path = "\x00/bar_foo";
+
+echo "creating send socket\n";
+$sends1 = socket_create(AF_UNIX, SOCK_DGRAM, 0) or die("err");
+socket_set_nonblock($sends1) or die("Could not put in non-blocking mode");
+
+echo "creating receive socket\n";
+$s = socket_create(AF_UNIX, SOCK_DGRAM, 0) or die("err");
+socket_bind($s, $path) or die("err");
+
+$r = socket_sendmsg($sends1, [
+ "name" => [ "path" => $path],
+ "iov" => ["test ", "thing", "\n"],
+], 0);
+var_dump($r);
+checktimeout($s, 500);
+
+if (!socket_recv($s, $buf, 20, 0)) die("recv");
+print_r($buf);
+?>
+--EXPECTF--
+creating send socket
+creating receive socket
+int(11)
+test thing
diff --git a/ext/sockets/tests/socket_cmsg_credentials.phpt b/ext/sockets/tests/socket_cmsg_credentials.phpt
new file mode 100644
index 0000000000..6a1c23fa8c
--- /dev/null
+++ b/ext/sockets/tests/socket_cmsg_credentials.phpt
@@ -0,0 +1,89 @@
+--TEST--
+recvmsg(): receive SCM_CREDENTIALS messages
+--SKIPIF--
+<?php
+if (!extension_loaded('sockets')) {
+die('skip sockets extension not available.');
+}
+if (strtolower(substr(PHP_OS, 0, 3)) == 'win') {
+die('skip not for Microsoft Windows');
+}
+--CLEAN--
+<?php
+$path = __DIR__ . "/unix_sock";
+@unlink($path);
+
+--FILE--
+<?php
+include __DIR__."/mcast_helpers.php.inc";
+$path = __DIR__ . "/unix_sock";
+
+@unlink($path);
+
+echo "creating send socket\n";
+$sends1 = socket_create(AF_UNIX, SOCK_DGRAM, 0) or die("err");
+var_dump($sends1);
+socket_set_nonblock($sends1) or die("Could not put in non-blocking mode");
+
+echo "creating receive socket\n";
+$s = socket_create(AF_UNIX, SOCK_DGRAM, 0) or die("err");
+var_dump($s);
+$br = socket_bind($s, $path) or die("err");
+var_dump($br);
+socket_set_nonblock($sends1) or die("Could not put in non-blocking mode");
+socket_set_option($s, SOL_SOCKET, SO_PASSCRED, 1) or die("could not set SO_PASSCRED");
+
+
+//$r = socket_sendmsg($sends1, [
+// "iov" => ["test ", "thing", "\n"],
+//], 0);
+$r = socket_sendto($sends1, $msg = "dread", strlen($msg), 0, $path);
+var_dump($r);
+checktimeout($s, 500);
+
+$data = [
+ "name" => [],
+ "buffer_size" => 2000,
+ "controllen" => socket_cmsg_space(SOL_SOCKET, SCM_CREDENTIALS)
+];
+if (!socket_recvmsg($s, $data, 0)) die("recvmsg");
+print_r($data);
+
+$pid = getmypid();
+var_dump($data['control'][0]['data']['pid'] === $pid);
+
+--EXPECTF--
+creating send socket
+resource(%d) of type (Socket)
+creating receive socket
+resource(%d) of type (Socket)
+bool(true)
+int(5)
+Array
+(
+ [name] =>
+ [control] => Array
+ (
+ [0] => Array
+ (
+ [level] => %d
+ [type] => %d
+ [data] => Array
+ (
+ [pid] => %d
+ [uid] => %d
+ [gid] => %d
+ )
+
+ )
+
+ )
+
+ [iov] => Array
+ (
+ [0] => dread
+ )
+
+ [flags] => 0
+)
+bool(true)
diff --git a/ext/sockets/tests/socket_cmsg_rights.phpt b/ext/sockets/tests/socket_cmsg_rights.phpt
new file mode 100644
index 0000000000..8c1734a568
--- /dev/null
+++ b/ext/sockets/tests/socket_cmsg_rights.phpt
@@ -0,0 +1,101 @@
+--TEST--
+recvmsg(): receive SCM_CREDENTIALS messages
+--SKIPIF--
+<?php
+if (!extension_loaded('sockets')) {
+die('skip sockets extension not available.');
+}
+if (strtolower(substr(PHP_OS, 0, 3)) == 'win') {
+die('skip not for Microsoft Windows');
+}
+--CLEAN--
+<?php
+$path = __DIR__ . "/unix_sock";
+@unlink($path);
+
+--FILE--
+<?php
+include __DIR__."/mcast_helpers.php.inc";
+$path = __DIR__ . "/unix_sock";
+
+@unlink($path);
+
+echo "creating send socket\n";
+$sends1 = socket_create(AF_UNIX, SOCK_DGRAM, 0) or die("err");
+var_dump($sends1);
+socket_set_nonblock($sends1) or die("Could not put in non-blocking mode");
+
+echo "creating receive socket\n";
+$s = socket_create(AF_UNIX, SOCK_DGRAM, 0) or die("err");
+var_dump($s);
+$br = socket_bind($s, $path) or die("err");
+var_dump($br);
+socket_set_nonblock($s) or die("Could not put in non-blocking mode");
+
+$r = socket_sendmsg($sends1, [
+ "name" => [ "path" => $path ],
+ "iov" => ["test ", "thing", "\n"],
+ "control" => [
+ [
+ "level" => SOL_SOCKET,
+ "type" => SCM_RIGHTS,
+ "data" => [$sends1, STDIN, STDOUT, STDERR],
+ ]
+ ]
+], 0);
+var_dump($r);
+checktimeout($s, 500);
+
+$data = [
+ "name" => [],
+ "buffer_size" => 2000,
+ "controllen" => socket_cmsg_space(SOL_SOCKET, SCM_RIGHTS, 3)
+];
+var_dump($data);
+if (!socket_recvmsg($s, $data, 0)) die("recvmsg");
+print_r($data);
+--EXPECTF--
+creating send socket
+resource(%d) of type (Socket)
+creating receive socket
+resource(%d) of type (Socket)
+bool(true)
+int(11)
+array(3) {
+ ["name"]=>
+ array(0) {
+ }
+ ["buffer_size"]=>
+ int(2000)
+ ["controllen"]=>
+ int(32)
+}
+Array
+(
+ [name] =>
+ [control] => Array
+ (
+ [0] => Array
+ (
+ [level] => %d
+ [type] => %d
+ [data] => Array
+ (
+ [0] => Resource id #%d
+ [1] => Resource id #%d
+ [2] => Resource id #%d
+ [3] => Resource id #%d
+ )
+
+ )
+
+ )
+
+ [iov] => Array
+ (
+ [0] => test thing
+
+ )
+
+ [flags] => 0
+)
diff --git a/ext/sockets/tests/socket_recvmsg.phpt b/ext/sockets/tests/socket_recvmsg.phpt
new file mode 100644
index 0000000000..a2204112b3
--- /dev/null
+++ b/ext/sockets/tests/socket_recvmsg.phpt
@@ -0,0 +1,92 @@
+--TEST--
+recvmsg(): basic test
+--SKIPIF--
+<?php
+if (!extension_loaded('sockets')) {
+ die('skip sockets extension not available.');
+}
+
+require 'ipv6_skipif.inc';
+
+if (!defined('IPPROTO_IPV6')) {
+ die('skip IPv6 not available.');
+}
+if (!defined('IPV6_RECVPKTINFO')) {
+ die('skip IPV6_RECVPKTINFO not available.');
+}
+?>
+--FILE--
+<?php
+include __DIR__."/mcast_helpers.php.inc";
+$addr = '::1';
+
+echo "creating send socket\n";
+$sends1 = socket_create(AF_INET6, SOCK_DGRAM, SOL_UDP) or die("err");
+var_dump($sends1);
+$br = socket_bind($sends1, '::', 7001) or die("err");
+var_dump($br);
+socket_set_nonblock($sends1) or die("Could not put in non-blocking mode");
+
+echo "creating receive socket\n";
+$s = socket_create(AF_INET6, SOCK_DGRAM, SOL_UDP) or die("err");
+var_dump($s);
+$br = socket_bind($s, '::0', 3000) or die("err");
+var_dump($br);
+
+socket_set_option($s, IPPROTO_IPV6, IPV6_RECVPKTINFO, 1) or die("err");
+
+$r = socket_sendto($sends1, $m = "testing packet", strlen($m), 0, $addr, 3000);
+var_dump($r);
+if ($r < 12) die;
+checktimeout($s, 500);
+
+$data = [
+ "name" => ["family" => AF_INET6, "addr" => "::1"],
+ "buffer_size" => 2000,
+ "controllen" => socket_cmsg_space(IPPROTO_IPV6, IPV6_PKTINFO),
+];
+if (!socket_recvmsg($s, $data, 0)) die("recvmsg");
+print_r($data);
+
+--EXPECTF--
+creating send socket
+resource(%d) of type (Socket)
+bool(true)
+creating receive socket
+resource(%d) of type (Socket)
+bool(true)
+int(14)
+Array
+(
+ [name] => Array
+ (
+ [family] => %d
+ [addr] => ::1
+ [port] => 7001
+ [flowinfo] => 0
+ [scope_id] => 0
+ )
+
+ [control] => Array
+ (
+ [0] => Array
+ (
+ [level] => %d
+ [type] => %d
+ [data] => Array
+ (
+ [addr] => ::1
+ [ifindex] => %d
+ )
+
+ )
+
+ )
+
+ [iov] => Array
+ (
+ [0] => testing packet
+ )
+
+ [flags] => 0
+)
diff --git a/ext/sockets/tests/socket_sendrecvmsg_multi_msg-win32.phpt b/ext/sockets/tests/socket_sendrecvmsg_multi_msg-win32.phpt
new file mode 100644
index 0000000000..3aba012726
--- /dev/null
+++ b/ext/sockets/tests/socket_sendrecvmsg_multi_msg-win32.phpt
@@ -0,0 +1,110 @@
+--TEST--
+sendmsg()/recvmsg(): test ability to receive multiple messages (WIN32)
+--SKIPIF--
+<?php
+if (!extension_loaded('sockets'))
+ die('skip sockets extension not available.');
+if (!defined('IPPROTO_IPV6'))
+ die('skip IPv6 not available.');
+if (substr(PHP_OS, 0, 3) != 'WIN')
+ die('skip Only for Windows!');
+/* Windows supports IPV6_RECVTCLASS and is able to receive the tclass via
+ * WSARecvMsg (though only the top 6 bits seem to reported), but WSASendMsg
+ * does not accept IPV6_TCLASS messages. We still test that sendmsg() works
+ * corectly by sending an IPV6_PKTINFO message that will have no effect */
+
+--FILE--
+<?php
+include __DIR__."/mcast_helpers.php.inc";
+$addr = '::1';
+
+echo "creating send socket\n";
+$sends1 = socket_create(AF_INET6, SOCK_DGRAM, SOL_UDP) or die("err");
+var_dump($sends1);
+$br = socket_bind($sends1, '::', 7001) or die("err");
+var_dump($br);
+socket_set_nonblock($sends1) or die("Could not put in non-blocking mode");
+
+echo "creating receive socket\n";
+$s = socket_create(AF_INET6, SOCK_DGRAM, SOL_UDP) or die("err");
+var_dump($s);
+$br = socket_bind($s, '::0', 3000) or die("err");
+var_dump($br);
+
+socket_set_option($s, IPPROTO_IPV6, IPV6_RECVPKTINFO, 1) or die("err");
+socket_set_option($s, IPPROTO_IPV6, IPV6_RECVTCLASS, 1) or die("err");
+
+$r = socket_sendmsg($sends1, [
+ "name" => [ "addr" => "::1", "port" => 3000],
+ "iov" => ["test ", "thing", "\n"],
+ "control" => [[
+ "level" => IPPROTO_IPV6,
+ "type" => IPV6_PKTINFO,
+ "data" => [
+ 'addr' => '::1',
+ 'ifindex' => 1 /* we're assuming loopback is 1. Is this a safe assumption? */
+ ],
+ ]]
+], 0);
+var_dump($r);
+checktimeout($s, 500);
+
+$data = [
+ "name" => ["family" => AF_INET6, "addr" => "::1"],
+ "buffer_size" => 2000,
+ "controllen" => socket_cmsg_space(IPPROTO_IPV6, IPV6_PKTINFO) +
+ socket_cmsg_space(IPPROTO_IPV6, IPV6_TCLASS),
+];
+if (!socket_recvmsg($s, $data, 0)) die("recvmsg");
+print_r($data);
+
+--EXPECTF--
+creating send socket
+resource(5) of type (Socket)
+bool(true)
+creating receive socket
+resource(6) of type (Socket)
+bool(true)
+int(11)
+Array
+(
+ [name] => Array
+ (
+ [family] => %d
+ [addr] => ::1
+ [port] => 7001
+ [flowinfo] => 0
+ [scope_id] => 0
+ )
+
+ [control] => Array
+ (
+ [0] => Array
+ (
+ [level] => %d
+ [type] => %d
+ [data] => Array
+ (
+ [addr] => ::1
+ [ifindex] => %d
+ )
+
+ )
+
+ [1] => Array
+ (
+ [level] => %d
+ [type] => %d
+ [data] => 0
+ )
+
+ )
+
+ [iov] => Array
+ (
+ [0] => test thing
+
+ )
+
+ [flags] => 0
+)
diff --git a/ext/sockets/tests/socket_sendrecvmsg_multi_msg.phpt b/ext/sockets/tests/socket_sendrecvmsg_multi_msg.phpt
new file mode 100644
index 0000000000..6b46f33715
--- /dev/null
+++ b/ext/sockets/tests/socket_sendrecvmsg_multi_msg.phpt
@@ -0,0 +1,113 @@
+--TEST--
+sendmsg()/recvmsg(): test ability to receive multiple messages
+--SKIPIF--
+<?php
+if (!extension_loaded('sockets'))
+ die('skip sockets extension not available.');
+
+require 'ipv6_skipif.inc';
+
+if (!defined('IPPROTO_IPV6'))
+ die('skip IPv6 not available.');
+if (substr(PHP_OS, 0, 3) == 'WIN')
+ die('skip Not for the Windows!');
+/* Windows supports IPV6_RECVTCLASS and is able to receive the tclass via
+ * WSARecvMsg (though only the top 6 bits seem to reported), but WSASendMsg
+ * does not accept IPV6_TCLASS messages */
+
+if (!defined('IPV6_RECVPKTINFO')) {
+ die('skip IPV6_RECVPKTINFO not available.');
+}
+?>
+--FILE--
+<?php
+include __DIR__."/mcast_helpers.php.inc";
+$addr = '::1';
+
+echo "creating send socket\n";
+$sends1 = socket_create(AF_INET6, SOCK_DGRAM, SOL_UDP) or die("err");
+var_dump($sends1);
+$br = socket_bind($sends1, '::', 7001) or die("err");
+var_dump($br);
+socket_set_nonblock($sends1) or die("Could not put in non-blocking mode");
+
+echo "creating receive socket\n";
+$s = socket_create(AF_INET6, SOCK_DGRAM, SOL_UDP) or die("err");
+var_dump($s);
+$br = socket_bind($s, '::0', 3000) or die("err");
+var_dump($br);
+
+socket_set_option($s, IPPROTO_IPV6, IPV6_RECVPKTINFO, 1) or die("err");
+socket_set_option($s, IPPROTO_IPV6, IPV6_RECVTCLASS, 1) or die("err");
+
+$r = socket_sendmsg($sends1, [
+ "name" => [ "addr" => "::1", "port" => 3000],
+ "iov" => ["test ", "thing", "\n"],
+ "control" => [[
+ "level" => IPPROTO_IPV6,
+ "type" => IPV6_TCLASS,
+ "data" => 40,
+ ]]
+], 0);
+var_dump($r);
+checktimeout($s, 500);
+
+$data = [
+ "name" => ["family" => AF_INET6, "addr" => "::1"],
+ "buffer_size" => 2000,
+ "controllen" => socket_cmsg_space(IPPROTO_IPV6, IPV6_PKTINFO) +
+ socket_cmsg_space(IPPROTO_IPV6, IPV6_TCLASS),
+];
+if (!socket_recvmsg($s, $data, 0)) die("recvmsg");
+print_r($data);
+
+--EXPECTF--
+creating send socket
+resource(5) of type (Socket)
+bool(true)
+creating receive socket
+resource(6) of type (Socket)
+bool(true)
+int(11)
+Array
+(
+ [name] => Array
+ (
+ [family] => %d
+ [addr] => ::1
+ [port] => 7001
+ [flowinfo] => 0
+ [scope_id] => 0
+ )
+
+ [control] => Array
+ (
+ [0] => Array
+ (
+ [level] => %d
+ [type] => %d
+ [data] => Array
+ (
+ [addr] => ::1
+ [ifindex] => %d
+ )
+
+ )
+
+ [1] => Array
+ (
+ [level] => %d
+ [type] => %d
+ [data] => 40
+ )
+
+ )
+
+ [iov] => Array
+ (
+ [0] => test thing
+
+ )
+
+ [flags] => 0
+)
diff --git a/ext/sockets/tests/socket_sentto_recvfrom_ipv4_udp.phpt b/ext/sockets/tests/socket_sentto_recvfrom_ipv4_udp.phpt
index bf95044d48..5aeaa0824f 100644
--- a/ext/sockets/tests/socket_sentto_recvfrom_ipv4_udp.phpt
+++ b/ext/sockets/tests/socket_sentto_recvfrom_ipv4_udp.phpt
@@ -14,12 +14,14 @@ if (!extension_loaded('sockets')) {
if (!socket_set_nonblock($socket)) {
die('Unable to set nonblocking mode for socket');
}
- socket_recvfrom($socket, $buf, 12, 0, $from, $port); // cause warning
+
$address = '127.0.0.1';
socket_sendto($socket, '', 1, 0, $address); // cause warning
if (!socket_bind($socket, $address, 1223)) {
die("Unable to bind to $address:1223");
}
+
+ var_dump(socket_recvfrom($socket, $buf, 12, 0, $from, $port)); //false (EAGAIN - no warning)
$msg = "Ping!";
$len = strlen($msg);
@@ -44,9 +46,9 @@ if (!extension_loaded('sockets')) {
socket_close($socket);
--EXPECTF--
-Warning: socket_recvfrom(): unable to recvfrom [%d]: %a in %s on line %d
Warning: Wrong parameter count for socket_sendto() in %s on line %d
+bool(false)
Warning: socket_recvfrom() expects at least 5 parameters, 4 given in %s on line %d
diff --git a/ext/sockets/tests/socket_sentto_recvfrom_ipv6_udp.phpt b/ext/sockets/tests/socket_sentto_recvfrom_ipv6_udp.phpt
index 2beb8080cd..bd07904277 100644
--- a/ext/sockets/tests/socket_sentto_recvfrom_ipv6_udp.phpt
+++ b/ext/sockets/tests/socket_sentto_recvfrom_ipv6_udp.phpt
@@ -18,7 +18,7 @@ require 'ipv6_skipif.inc';
if (!socket_set_nonblock($socket)) {
die('Unable to set nonblocking mode for socket');
}
- socket_recvfrom($socket, $buf, 12, 0, $from, $port); // cause warning
+ var_dump(socket_recvfrom($socket, $buf, 12, 0, $from, $port)); // false (EAGAIN, no warning)
$address = '::1';
socket_sendto($socket, '', 1, 0, $address); // cause warning
if (!socket_bind($socket, $address, 1223)) {
@@ -48,7 +48,7 @@ require 'ipv6_skipif.inc';
socket_close($socket);
--EXPECTF--
-Warning: socket_recvfrom(): unable to recvfrom [11]: Resource temporarily unavailable in %s on line %d
+bool(false)
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 55ad75c65e..e25bf4df1a 100644
--- a/ext/sockets/tests/socket_sentto_recvfrom_unix.phpt
+++ b/ext/sockets/tests/socket_sentto_recvfrom_unix.phpt
@@ -18,7 +18,7 @@ if (!extension_loaded('sockets')) {
if (!socket_set_nonblock($socket)) {
die('Unable to set nonblocking mode for socket');
}
- socket_recvfrom($socket, $buf, 12, 0, $from, $port); // cause warning
+ var_dump(socket_recvfrom($socket, $buf, 12, 0, $from, $port)); //false (EAGAIN, no warning)
$address = sprintf("/tmp/%s.sock", uniqid());
if (!socket_bind($socket, $address)) {
die("Unable to bind to $address");
@@ -53,8 +53,7 @@ if (!extension_loaded('sockets')) {
?>
--EXPECTF--
Warning: socket_create(): Unable to create socket [%d]: Protocol not supported in %s on line %d
-
-Warning: socket_recvfrom(): unable to recvfrom [%d]: Resource temporarily unavailable in %s on line %d
+bool(false)
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_option_error_socket_option.phpt b/ext/sockets/tests/socket_set_option_error_socket_option.phpt
index eaa0e64faf..ea3b36d99f 100644
--- a/ext/sockets/tests/socket_set_option_error_socket_option.phpt
+++ b/ext/sockets/tests/socket_set_option_error_socket_option.phpt
@@ -3,7 +3,10 @@ Test if socket_set_option() returns 'unable to set socket option' failure for in
--SKIPIF--
<?php
if (!extension_loaded('sockets')) {
- die('SKIP sockets extension not available.');
+ die('SKIP sockets extension not available.');
+}
+if (PHP_OS == 'Darwin') {
+ die('skip Not for OSX');
}
$filename = dirname(__FILE__) . '/006_root_check.tmp';
$fp = fopen($filename, 'w');
diff --git a/ext/sockets/tests/socket_set_option_in6_pktinfo.phpt b/ext/sockets/tests/socket_set_option_in6_pktinfo.phpt
new file mode 100644
index 0000000000..75019cafac
--- /dev/null
+++ b/ext/sockets/tests/socket_set_option_in6_pktinfo.phpt
@@ -0,0 +1,38 @@
+--TEST--
+socket_set_option() with IPV6_PKTINFO
+--SKIPIF--
+<?php
+if (!extension_loaded('sockets')) {
+ die('skip sockets extension not available.');
+}
+
+require 'ipv6_skipif.inc';
+
+if (!defined('IPPROTO_IPV6')) {
+ die('skip IPv6 not available.');
+}
+if (substr(PHP_OS, 0, 3) == 'WIN') {
+ die('skip Not for Windows!');
+}
+if (!defined('IPV6_PKTINFO')) {
+ die('skip IPV6_PKTINFO not available.');
+}
+--FILE--
+<?php
+
+$s = socket_create(AF_INET6, SOCK_DGRAM, SOL_UDP) or die("err");
+var_dump(socket_set_option($s, IPPROTO_IPV6, IPV6_PKTINFO, []));
+var_dump(socket_set_option($s, IPPROTO_IPV6, IPV6_PKTINFO, [
+ "addr" => '::1',
+ "ifindex" => 0
+]));
+//Oddly, Linux does not support IPV6_PKTINFO in sockgetopt().
+//See do_ipv6_getsockopt() on the kernel sources
+//A work-around with is sort-of possible (with IPV6_2292PKTOPTIONS),
+//but not worth it
+//var_dump(socket_get_option($s, IPPROTO_IPV6, IPV6_PKTINFO));
+
+--EXPECTF--
+Warning: socket_set_option(): error converting user data (path: in6_pktinfo): The key 'addr' is required in %s on line %d
+bool(false)
+bool(true)
diff --git a/ext/sockets/windows_common.h b/ext/sockets/windows_common.h
new file mode 100644
index 0000000000..3a9cb59129
--- /dev/null
+++ b/ext/sockets/windows_common.h
@@ -0,0 +1,120 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2012 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. |
+ +----------------------------------------------------------------------+
+ */
+#ifndef WINDOWS_COMMON_H
+#define WINDOWS_COMMON_H
+
+#include <Winsock2.h>
+#define NTDDI_XP NTDDI_WINXP /* bug in SDK */
+#include <IPHlpApi.h> /* conflicting definition of CMSG_DATA */
+#undef NTDDI_XP
+
+#define HAVE_IF_NAMETOINDEX 1
+
+#define IS_INVALID_SOCKET(a) (a->bsd_socket == INVALID_SOCKET)
+
+#ifdef errno
+# undef errno
+#endif
+#define errno WSAGetLastError()
+#define h_errno WSAGetLastError()
+#define set_errno(a) WSASetLastError(a)
+#define close(a) closesocket(a)
+
+#ifdef ENETUNREACH /* errno.h probably included */
+# undef EWOULDBLOCK
+# undef EINPROGRESS
+# undef EALREADY
+# undef ENOTSOCK
+# undef EDESTADDRREQ
+# undef EMSGSIZE
+# undef EPROTOTYPE
+# undef ENOPROTOOPT
+# undef EPROTONOSUPPORT
+# undef ESOCKTNOSUPPORT
+# undef EOPNOTSUPP
+# undef EPFNOSUPPORT
+# undef EAFNOSUPPORT
+# undef EADDRINUSE
+# undef EADDRNOTAVAIL
+# undef ENETDOWN
+# undef ENETUNREACH
+# undef ENETRESET
+# undef ECONNABORTED
+# undef ECONNRESET
+# undef ENOBUFS
+# undef EISCONN
+# undef ENOTCONN
+# undef ESHUTDOWN
+# undef ETOOMANYREFS
+# undef ETIMEDOUT
+# undef ECONNREFUSED
+# undef ELOOP
+# undef ENAMETOOLONG
+# undef EHOSTDOWN
+# undef EHOSTUNREACH
+# undef ENOTEMPTY
+# undef EPROCLIM
+# undef EUSERS
+# undef EDQUOT
+# undef ESTALE
+# undef EREMOTE
+
+# undef EAGAIN
+#endif
+
+/* section disabled in WinSock2.h */
+#define EWOULDBLOCK WSAEWOULDBLOCK
+#define EINPROGRESS WSAEINPROGRESS
+#define EALREADY WSAEALREADY
+#define ENOTSOCK WSAENOTSOCK
+#define EDESTADDRREQ WSAEDESTADDRREQ
+#define EMSGSIZE WSAEMSGSIZE
+#define EPROTOTYPE WSAEPROTOTYPE
+#define ENOPROTOOPT WSAENOPROTOOPT
+#define EPROTONOSUPPORT WSAEPROTONOSUPPORT
+#define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
+#define EOPNOTSUPP WSAEOPNOTSUPP
+#define EPFNOSUPPORT WSAEPFNOSUPPORT
+#define EAFNOSUPPORT WSAEAFNOSUPPORT
+#define EADDRINUSE WSAEADDRINUSE
+#define EADDRNOTAVAIL WSAEADDRNOTAVAIL
+#define ENETDOWN WSAENETDOWN
+#define ENETUNREACH WSAENETUNREACH
+#define ENETRESET WSAENETRESET
+#define ECONNABORTED WSAECONNABORTED
+#define ECONNRESET WSAECONNRESET
+#define ENOBUFS WSAENOBUFS
+#define EISCONN WSAEISCONN
+#define ENOTCONN WSAENOTCONN
+#define ESHUTDOWN WSAESHUTDOWN
+#define ETOOMANYREFS WSAETOOMANYREFS
+#define ETIMEDOUT WSAETIMEDOUT
+#define ECONNREFUSED WSAECONNREFUSED
+#define ELOOP WSAELOOP
+#define ENAMETOOLONG WSAENAMETOOLONG
+#define EHOSTDOWN WSAEHOSTDOWN
+#define EHOSTUNREACH WSAEHOSTUNREACH
+#define ENOTEMPTY WSAENOTEMPTY
+#define EPROCLIM WSAEPROCLIM
+#define EUSERS WSAEUSERS
+#define EDQUOT WSAEDQUOT
+#define ESTALE WSAESTALE
+#define EREMOTE WSAEREMOTE
+
+/* and an extra one */
+#define EAGAIN WSAEWOULDBLOCK
+
+#endif
diff --git a/ext/spl/doxygen.cfg b/ext/spl/doxygen.cfg
index 4b71787238..5c7025a9ad 100755
--- a/ext/spl/doxygen.cfg
+++ b/ext/spl/doxygen.cfg
@@ -111,7 +111,7 @@ HTML_STYLESHEET =
HTML_ALIGN_MEMBERS = YES
GENERATE_HTMLHELP = YES
CHM_FILE = ../spl.chm
-HHC_LOCATION = hhc.exe
+#HHC_LOCATION = hhc.exe
GENERATE_CHI = NO
BINARY_TOC = NO
TOC_EXPAND = NO
@@ -210,7 +210,7 @@ MAX_DOT_GRAPH_WIDTH = 1200
MAX_DOT_GRAPH_HEIGHT = 1024
MAX_DOT_GRAPH_DEPTH = 0
GENERATE_LEGEND = YES
-DOT_CLEANUP = YES
+DOT_CLEANUP = NO
#---------------------------------------------------------------------------
# Configuration::additions related to the search engine
#---------------------------------------------------------------------------
diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c
index a37a453c8c..5927e05562 100644
--- a/ext/spl/php_spl.c
+++ b/ext/spl/php_spl.c
@@ -743,8 +743,17 @@ PHP_FUNCTION(spl_autoload_functions)
}
add_next_index_string(tmp, alfi->func_ptr->common.function_name, 1);
add_next_index_zval(return_value, tmp);
- } else
- add_next_index_string(return_value, alfi->func_ptr->common.function_name, 1);
+ } else {
+ if (strncmp(alfi->func_ptr->common.function_name, "__lambda_func", sizeof("__lambda_func") - 1)) {
+ add_next_index_string(return_value, alfi->func_ptr->common.function_name, 1);
+ } else {
+ char *key;
+ uint len;
+ long dummy;
+ zend_hash_get_current_key_ex(SPL_G(autoload_functions), &key, &len, &dummy, 0, &function_pos);
+ add_next_index_stringl(return_value, key, len - 1, 1);
+ }
+ }
zend_hash_move_forward_ex(SPL_G(autoload_functions), &function_pos);
}
@@ -791,7 +800,7 @@ PHPAPI void php_spl_object_hash(zval *obj, char *result TSRMLS_DC) /* {{{*/
hash_handle = SPL_G(hash_mask_handle)^(intptr_t)Z_OBJ_HANDLE_P(obj);
hash_handlers = SPL_G(hash_mask_handlers)^(intptr_t)Z_OBJ_HT_P(obj);
- spprintf(&hex, 32, "%016x%016x", hash_handle, hash_handlers);
+ spprintf(&hex, 32, "%016lx%016lx", hash_handle, hash_handlers);
strlcpy(result, hex, 33);
efree(hex);
diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c
index 68727d1367..f41d0fb9cd 100644
--- a/ext/spl/spl_array.c
+++ b/ext/spl/spl_array.c
@@ -309,7 +309,7 @@ static zval **spl_array_get_dimension_ptr_ptr(int check_inherited, zval *object,
if (!offset) {
return &EG(uninitialized_zval_ptr);
}
-
+
if ((type == BP_VAR_W || type == BP_VAR_RW) && (ht->nApplyCount > 0)) {
zend_error(E_WARNING, "Modification of ArrayObject during sorting is prohibited");
return &EG(error_zval_ptr);;
@@ -341,8 +341,8 @@ static zval **spl_array_get_dimension_ptr_ptr(int check_inherited, zval *object,
case IS_RESOURCE:
zend_error(E_STRICT, "Resource ID#%ld used as offset, casting to integer (%ld)", Z_LVAL_P(offset), Z_LVAL_P(offset));
case IS_DOUBLE:
- case IS_BOOL:
- case IS_LONG:
+ case IS_BOOL:
+ case IS_LONG:
if (offset->type == IS_DOUBLE) {
index = (long)Z_DVAL_P(offset);
} else {
@@ -386,7 +386,7 @@ static zval *spl_array_read_dimension_ex(int check_inherited, zval *object, zval
} else {
SEPARATE_ARG_IF_REF(offset);
}
- zend_call_method_with_1_params(&object, Z_OBJCE_P(object), &intern->fptr_offset_get, "offsetGet", &rv, offset);
+ zend_call_method_with_1_params(&object, Z_OBJCE_P(object), &intern->fptr_offset_get, "offsetGet", &rv, offset);
zval_ptr_dtor(&offset);
if (rv) {
zval_ptr_dtor(&intern->retval);
@@ -444,7 +444,7 @@ static void spl_array_write_dimension_ex(int check_inherited, zval *object, zval
zval_ptr_dtor(&offset);
return;
}
-
+
if (!offset) {
ht = spl_array_get_hash_table(intern, 0 TSRMLS_CC);
if (ht->nApplyCount > 0) {
@@ -467,8 +467,8 @@ static void spl_array_write_dimension_ex(int check_inherited, zval *object, zval
return;
case IS_DOUBLE:
case IS_RESOURCE:
- case IS_BOOL:
- case IS_LONG:
+ case IS_BOOL:
+ case IS_LONG:
ht = spl_array_get_hash_table(intern, 0 TSRMLS_CC);
if (ht->nApplyCount > 0) {
zend_error(E_WARNING, "Modification of ArrayObject during sorting is prohibited");
@@ -556,13 +556,13 @@ static void spl_array_unset_dimension_ex(int check_inherited, zval *object, zval
obj->std.properties_table[property_info->offset] = NULL;
}
}
- }
+ }
}
break;
case IS_DOUBLE:
case IS_RESOURCE:
- case IS_BOOL:
- case IS_LONG:
+ case IS_BOOL:
+ case IS_LONG:
if (offset->type == IS_DOUBLE) {
index = (long)Z_DVAL_P(offset);
} else {
@@ -608,7 +608,7 @@ static int spl_array_has_dimension_ex(int check_inherited, zval *object, zval *o
}
return 0;
}
-
+
switch(Z_TYPE_P(offset)) {
case IS_STRING:
{
@@ -627,9 +627,9 @@ static int spl_array_has_dimension_ex(int check_inherited, zval *object, zval *o
return 0;
case IS_DOUBLE:
case IS_RESOURCE:
- case IS_BOOL:
+ case IS_BOOL:
case IS_LONG:
- {
+ {
HashTable *ht = spl_array_get_hash_table(intern, 0 TSRMLS_CC);
if (offset->type == IS_DOUBLE) {
index = (long)Z_DVAL_P(offset);
@@ -727,7 +727,7 @@ void spl_array_iterator_append(zval *object, zval *append_value TSRMLS_DC) /* {{
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Array was modified outside object and is no longer an array");
return;
}
-
+
if (Z_TYPE_P(intern->array) == IS_OBJECT) {
php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "Cannot append properties to objects, use %s::offsetSet() instead", Z_OBJCE_P(object)->name);
return;
@@ -771,7 +771,7 @@ SPL_METHOD(Array, getArrayCopy)
{
zval *object = getThis(), *tmp;
spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
-
+
array_init(return_value);
zend_hash_copy(HASH_OF(return_value), spl_array_get_hash_table(intern, 0 TSRMLS_CC), (copy_ctor_func_t) zval_add_ref, &tmp, sizeof(zval*));
} /* }}} */
@@ -854,15 +854,15 @@ static void spl_array_write_property(zval *object, zval *member, zval *value, co
std_object_handlers.write_property(object, member, value, key TSRMLS_CC);
} /* }}} */
-static zval **spl_array_get_property_ptr_ptr(zval *object, zval *member, const zend_literal *key TSRMLS_DC) /* {{{ */
+static zval **spl_array_get_property_ptr_ptr(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */
{
spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
if ((intern->ar_flags & SPL_ARRAY_ARRAY_AS_PROPS) != 0
&& !std_object_handlers.has_property(object, member, 2, key TSRMLS_CC)) {
- return spl_array_get_dimension_ptr_ptr(1, object, member, BP_VAR_RW TSRMLS_CC);
+ return spl_array_get_dimension_ptr_ptr(1, object, member, type TSRMLS_CC);
}
- return std_object_handlers.get_property_ptr_ptr(object, member, key TSRMLS_CC);
+ return std_object_handlers.get_property_ptr_ptr(object, member, type, key TSRMLS_CC);
} /* }}} */
static int spl_array_has_property(zval *object, zval *member, int has_set_exists, const zend_literal *key TSRMLS_DC) /* {{{ */
@@ -983,7 +983,7 @@ static void spl_array_it_dtor(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
efree(iterator);
}
/* }}} */
-
+
static int spl_array_it_valid(zend_object_iterator *iter TSRMLS_DC) /* {{{ */
{
spl_array_it *iterator = (spl_array_it *)iter;
@@ -1018,20 +1018,20 @@ static void spl_array_it_get_current_data(zend_object_iterator *iter, zval ***da
}
/* }}} */
-static int spl_array_it_get_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) /* {{{ */
+static void spl_array_it_get_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC) /* {{{ */
{
spl_array_it *iterator = (spl_array_it *)iter;
spl_array_object *object = iterator->object;
HashTable *aht = spl_array_get_hash_table(object, 0 TSRMLS_CC);
if (object->ar_flags & SPL_ARRAY_OVERLOADED_KEY) {
- return zend_user_it_get_current_key(iter, str_key, str_key_len, int_key TSRMLS_CC);
+ zend_user_it_get_current_key(iter, key TSRMLS_CC);
} else {
if (spl_array_object_verify_pos_ex(object, aht, "ArrayIterator::current(): " TSRMLS_CC) == FAILURE) {
- return HASH_KEY_NON_EXISTANT;
+ ZVAL_NULL(key);
+ } else {
+ zend_hash_get_current_key_zval_ex(aht, key, &object->pos);
}
-
- return zend_hash_get_current_key_ex(aht, str_key, str_key_len, int_key, 1, &object->pos);
}
}
/* }}} */
@@ -1050,7 +1050,7 @@ static void spl_array_it_move_forward(zend_object_iterator *iter TSRMLS_DC) /* {
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "ArrayIterator::current(): Array was modified outside object and is no longer an array");
return;
}
-
+
if ((object->ar_flags & SPL_ARRAY_IS_REF) && spl_hash_verify_pos_ex(object, aht TSRMLS_CC) == FAILURE) {
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "ArrayIterator::next(): Array was modified outside object and internal position is no longer valid");
} else {
@@ -1108,7 +1108,7 @@ static void spl_array_set_array(zval *object, spl_array_object *intern, zval **a
if (just_array) {
spl_array_object *other = (spl_array_object*)zend_object_store_get_object(*array TSRMLS_CC);
ar_flags = other->ar_flags & ~SPL_ARRAY_INT_MASK;
- }
+ }
ar_flags |= SPL_ARRAY_USE_OTHER;
intern->array = *array;
} else {
@@ -1166,7 +1166,7 @@ zend_object_iterator *spl_array_get_iterator(zend_class_entry *ce, zval *object,
iterator->intern.ce = ce;
iterator->intern.value = NULL;
iterator->object = array_object;
-
+
return (zend_object_iterator*)iterator;
}
/* }}} */
@@ -1231,7 +1231,7 @@ SPL_METHOD(Array, getIteratorClass)
{
zval *object = getThis();
spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
-
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
@@ -1246,11 +1246,11 @@ SPL_METHOD(Array, getFlags)
{
zval *object = getThis();
spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
-
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
-
+
RETURN_LONG(intern->ar_flags & ~SPL_ARRAY_INT_MASK);
}
/* }}} */
@@ -1266,7 +1266,7 @@ SPL_METHOD(Array, setFlags)
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &ar_flags) == FAILURE) {
return;
}
-
+
intern->ar_flags = (intern->ar_flags & SPL_ARRAY_INT_MASK) | (ar_flags & ~SPL_ARRAY_INT_MASK);
}
/* }}} */
@@ -1280,7 +1280,7 @@ SPL_METHOD(Array, exchangeArray)
array_init(return_value);
zend_hash_copy(HASH_OF(return_value), spl_array_get_hash_table(intern, 0 TSRMLS_CC), (copy_ctor_func_t) zval_add_ref, &tmp, sizeof(zval*));
-
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &array) == FAILURE) {
return;
}
@@ -1298,7 +1298,7 @@ SPL_METHOD(Array, getIterator)
spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
spl_array_object *iterator;
HashTable *aht = spl_array_get_hash_table(intern, 0 TSRMLS_CC);
-
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
@@ -1321,7 +1321,7 @@ SPL_METHOD(Array, rewind)
{
zval *object = getThis();
spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
-
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
@@ -1354,9 +1354,9 @@ SPL_METHOD(Array, seek)
if (position >= 0) { /* negative values are not supported */
spl_array_rewind(intern TSRMLS_CC);
result = SUCCESS;
-
+
while (position-- > 0 && (result = spl_array_next(intern TSRMLS_CC)) == SUCCESS);
-
+
if (result == SUCCESS && zend_hash_has_more_elements_ex(aht, &intern->pos) == SUCCESS) {
return; /* ok */
}
@@ -1376,7 +1376,7 @@ int static spl_array_object_count_elements_helper(spl_array_object *intern, long
}
if (Z_TYPE_P(intern->array) == IS_OBJECT) {
- /* We need to store the 'pos' since we'll modify it in the functions
+ /* We need to store the 'pos' since we'll modify it in the functions
* we're going to call and which do not support 'pos' as parameter. */
pos = intern->pos;
*count = 0;
@@ -1420,7 +1420,7 @@ SPL_METHOD(Array, count)
{
long count;
spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
-
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
@@ -1436,11 +1436,11 @@ static void spl_array_method(INTERNAL_FUNCTION_PARAMETERS, char *fname, int fnam
HashTable *aht = spl_array_get_hash_table(intern, 0 TSRMLS_CC);
zval *tmp, *arg = NULL;
zval *retval_ptr = NULL;
-
+
MAKE_STD_ZVAL(tmp);
Z_TYPE_P(tmp) = IS_ARRAY;
Z_ARRVAL_P(tmp) = aht;
-
+
if (!use_arg) {
aht->nApplyCount++;
zend_call_method(NULL, NULL, NULL, fname, fname_len, &retval_ptr, 1, tmp, NULL TSRMLS_CC);
@@ -1517,7 +1517,7 @@ SPL_METHOD(Array, current)
spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
zval **entry;
HashTable *aht = spl_array_get_hash_table(intern, 0 TSRMLS_CC);
-
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
@@ -1540,32 +1540,20 @@ SPL_METHOD(Array, key)
if (zend_parse_parameters_none() == FAILURE) {
return;
}
-
+
spl_array_iterator_key(getThis(), return_value TSRMLS_CC);
} /* }}} */
void spl_array_iterator_key(zval *object, zval *return_value TSRMLS_DC) /* {{{ */
{
spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
- char *string_key;
- uint string_length;
- ulong num_key;
HashTable *aht = spl_array_get_hash_table(intern, 0 TSRMLS_CC);
if (spl_array_object_verify_pos(intern, aht TSRMLS_CC) == FAILURE) {
return;
}
- switch (zend_hash_get_current_key_ex(aht, &string_key, &string_length, &num_key, 1, &intern->pos)) {
- case HASH_KEY_IS_STRING:
- RETVAL_STRINGL(string_key, string_length - 1, 0);
- break;
- case HASH_KEY_IS_LONG:
- RETVAL_LONG(num_key);
- break;
- case HASH_KEY_NON_EXISTANT:
- return;
- }
+ zend_hash_get_current_key_zval_ex(aht, return_value, &intern->pos);
}
/* }}} */
@@ -1587,7 +1575,7 @@ SPL_METHOD(Array, next)
spl_array_next_no_verify(intern, aht TSRMLS_CC);
}
-/* }}} */
+/* }}} */
/* {{{ proto bool ArrayIterator::valid()
Check whether array contains more entries */
@@ -1616,7 +1604,7 @@ SPL_METHOD(Array, hasChildren)
zval *object = getThis(), **entry;
spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
HashTable *aht = spl_array_get_hash_table(intern, 0 TSRMLS_CC);
-
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
@@ -1640,7 +1628,7 @@ SPL_METHOD(Array, getChildren)
zval *object = getThis(), **entry, *flags;
spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);
HashTable *aht = spl_array_get_hash_table(intern, 0 TSRMLS_CC);
-
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
@@ -1680,7 +1668,7 @@ SPL_METHOD(Array, serialize)
php_serialize_data_t var_hash;
smart_str buf = {0};
zval *flags;
-
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
@@ -1739,7 +1727,7 @@ SPL_METHOD(Array, unserialize)
php_unserialize_data_t var_hash;
zval *pmembers, *pflags = NULL;
long flags;
-
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &buf, &buf_len) == FAILURE) {
return;
}
@@ -1968,7 +1956,7 @@ PHP_MINIT_FUNCTION(spl_array)
REGISTER_SPL_IMPLEMENTS(ArrayIterator, Countable);
memcpy(&spl_handler_ArrayIterator, &spl_handler_ArrayObject, sizeof(zend_object_handlers));
spl_ce_ArrayIterator->get_iterator = spl_array_get_iterator;
-
+
REGISTER_SPL_SUB_CLASS_EX(RecursiveArrayIterator, ArrayIterator, spl_array_object_new, spl_funcs_RecursiveArrayIterator);
REGISTER_SPL_IMPLEMENTS(RecursiveArrayIterator, RecursiveIterator);
spl_ce_RecursiveArrayIterator->get_iterator = spl_array_get_iterator;
diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c
index 0762db6259..6e53c7a947 100644
--- a/ext/spl/spl_directory.c
+++ b/ext/spl/spl_directory.c
@@ -1629,7 +1629,7 @@ SPL_METHOD(GlobIterator, count)
static void spl_filesystem_dir_it_dtor(zend_object_iterator *iter TSRMLS_DC);
static int spl_filesystem_dir_it_valid(zend_object_iterator *iter TSRMLS_DC);
static void spl_filesystem_dir_it_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC);
-static int spl_filesystem_dir_it_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC);
+static void spl_filesystem_dir_it_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC);
static void spl_filesystem_dir_it_move_forward(zend_object_iterator *iter TSRMLS_DC);
static void spl_filesystem_dir_it_rewind(zend_object_iterator *iter TSRMLS_DC);
@@ -1706,12 +1706,11 @@ static void spl_filesystem_dir_it_current_data(zend_object_iterator *iter, zval
/* }}} */
/* {{{ spl_filesystem_dir_it_current_key */
-static int spl_filesystem_dir_it_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
+static void spl_filesystem_dir_it_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC)
{
spl_filesystem_object *object = spl_filesystem_iterator_to_object((spl_filesystem_iterator *)iter);
-
- *int_key = object->u.dir.index;
- return HASH_KEY_IS_LONG;
+
+ ZVAL_LONG(key, object->u.dir.index);
}
/* }}} */
@@ -1785,19 +1784,16 @@ static void spl_filesystem_tree_it_current_data(zend_object_iterator *iter, zval
/* }}} */
/* {{{ spl_filesystem_tree_it_current_key */
-static int spl_filesystem_tree_it_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
+static void spl_filesystem_tree_it_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC)
{
spl_filesystem_object *object = spl_filesystem_iterator_to_object((spl_filesystem_iterator *)iter);
-
+
if (SPL_FILE_DIR_KEY(object, SPL_FILE_DIR_KEY_AS_FILENAME)) {
- *str_key_len = strlen(object->u.dir.entry.d_name) + 1;
- *str_key = estrndup(object->u.dir.entry.d_name, *str_key_len - 1);
+ ZVAL_STRING(key, object->u.dir.entry.d_name, 1);
} else {
spl_filesystem_object_get_file_name(object TSRMLS_CC);
- *str_key_len = object->file_name_len + 1;
- *str_key = estrndup(object->file_name, object->file_name_len);
+ ZVAL_STRINGL(key, object->file_name, object->file_name_len, 1);
}
- return HASH_KEY_IS_STRING;
}
/* }}} */
@@ -2294,7 +2290,7 @@ SPL_METHOD(SplFileObject, __construct)
intern->u.file.open_mode = NULL;
intern->u.file.open_mode_len = 0;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|sbr",
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|sbr!",
&intern->file_name, &intern->file_name_len,
&intern->u.file.open_mode, &intern->u.file.open_mode_len,
&use_include_path, &intern->u.file.zcontext) == FAILURE) {
diff --git a/ext/spl/spl_dllist.c b/ext/spl/spl_dllist.c
index d9a72c1bb8..39a0733b9a 100644
--- a/ext/spl/spl_dllist.c
+++ b/ext/spl/spl_dllist.c
@@ -794,7 +794,7 @@ SPL_METHOD(SplDoublyLinkedList, offsetGet)
intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
index = spl_offset_convert_to_long(zindex TSRMLS_CC);
- if (index < 0 || index >= intern->llist->count) {
+ if (index < 0 || index >= intern->llist->count) {
zend_throw_exception(spl_ce_OutOfRangeException, "Offset invalid or out of range", 0 TSRMLS_CC);
return;
}
@@ -881,9 +881,9 @@ SPL_METHOD(SplDoublyLinkedList, offsetUnset)
intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
index = spl_offset_convert_to_long(zindex TSRMLS_CC);
- llist = intern->llist;
+ llist = intern->llist;
- if (index < 0 || index >= intern->llist->count) {
+ if (index < 0 || index >= intern->llist->count) {
zend_throw_exception(spl_ce_OutOfRangeException, "Offset out of range", 0 TSRMLS_CC);
return;
}
@@ -1023,12 +1023,11 @@ static void spl_dllist_it_get_current_data(zend_object_iterator *iter, zval ***d
}
/* }}} */
-static int spl_dllist_it_get_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) /* {{{ */
+static void spl_dllist_it_get_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC) /* {{{ */
{
spl_dllist_it *iterator = (spl_dllist_it *)iter;
- *int_key = (ulong) iterator->traverse_position;
- return HASH_KEY_IS_LONG;
+ ZVAL_LONG(key, iterator->traverse_position);
}
/* }}} */
@@ -1139,7 +1138,7 @@ SPL_METHOD(SplDoublyLinkedList, serialize)
spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
smart_str buf = {0};
spl_ptr_llist_element *current = intern->llist->head, *next;
- zval *flags;
+ zval *flags;
php_serialize_data_t var_hash;
if (zend_parse_parameters_none() == FAILURE) {
@@ -1235,6 +1234,61 @@ error:
} /* }}} */
+/* {{{ proto void SplDoublyLinkedList::add(mixed $index, mixed $newval) U
+ Inserts a new entry before the specified $index consisting of $newval. */
+SPL_METHOD(SplDoublyLinkedList, add)
+{
+ zval *zindex, *value;
+ spl_dllist_object *intern;
+ spl_ptr_llist_element *element;
+ long index;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zz", &zindex, &value) == FAILURE) {
+ return;
+ }
+
+ intern = (spl_dllist_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+ index = spl_offset_convert_to_long(zindex TSRMLS_CC);
+
+ if (index < 0 || index > intern->llist->count) {
+ zend_throw_exception(spl_ce_OutOfRangeException, "Offset invalid or out of range", 0 TSRMLS_CC);
+ return;
+ }
+
+ Z_ADDREF_P(value);
+ if (index == intern->llist->count) {
+ /* If index is the last entry+1 then we do a push because we're not inserting before any entry */
+ spl_ptr_llist_push(intern->llist, value TSRMLS_CC);
+ } else {
+ /* Create the new element we want to insert */
+ spl_ptr_llist_element *elem = emalloc(sizeof(spl_ptr_llist_element));
+
+ /* Get the element we want to insert before */
+ element = spl_ptr_llist_offset(intern->llist, index, intern->flags & SPL_DLLIST_IT_LIFO);
+
+ elem->data = value;
+ elem->rc = 1;
+ /* connect to the neighbours */
+ elem->next = element;
+ elem->prev = element->prev;
+
+ /* connect the neighbours to this new element */
+ if (elem->prev == NULL) {
+ intern->llist->head = elem;
+ } else {
+ element->prev->next = elem;
+ }
+ element->prev = elem;
+
+ intern->llist->count++;
+
+ if (intern->llist->ctor) {
+ intern->llist->ctor(elem TSRMLS_CC);
+ }
+ }
+} /* }}} */
+
+
/* iterator handler table */
zend_object_iterator_funcs spl_dllist_it_funcs = {
spl_dllist_it_dtor,
@@ -1322,6 +1376,9 @@ static const zend_function_entry spl_funcs_SplDoublyLinkedList[] = {
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, add, arginfo_dllist_offsetSet, ZEND_ACC_PUBLIC)
+
/* Iterator */
SPL_ME(SplDoublyLinkedList, rewind, arginfo_dllist_void, ZEND_ACC_PUBLIC)
SPL_ME(SplDoublyLinkedList, current, arginfo_dllist_void, ZEND_ACC_PUBLIC)
diff --git a/ext/spl/spl_fixedarray.c b/ext/spl/spl_fixedarray.c
index 2f5e8c670b..ca61b3bd97 100644
--- a/ext/spl/spl_fixedarray.c
+++ b/ext/spl/spl_fixedarray.c
@@ -948,18 +948,16 @@ static void spl_fixedarray_it_get_current_data(zend_object_iterator *iter, zval
}
/* }}} */
-static int spl_fixedarray_it_get_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) /* {{{ */
+static void spl_fixedarray_it_get_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC) /* {{{ */
{
spl_fixedarray_it *iterator = (spl_fixedarray_it *)iter;
spl_fixedarray_object *intern = iterator->object;
if (intern->flags & SPL_FIXEDARRAY_OVERLOADED_KEY) {
- return zend_user_it_get_current_key(iter, str_key, str_key_len, int_key TSRMLS_CC);
+ zend_user_it_get_current_key(iter, key TSRMLS_CC);
} else {
- *int_key = (ulong) iterator->object->current;
- return HASH_KEY_IS_LONG;
+ ZVAL_LONG(key, iterator->object->current);
}
-
}
/* }}} */
diff --git a/ext/spl/spl_heap.c b/ext/spl/spl_heap.c
index 7ec86b5e81..2bc1f5e3d5 100644
--- a/ext/spl/spl_heap.c
+++ b/ext/spl/spl_heap.c
@@ -949,12 +949,11 @@ static void spl_pqueue_it_get_current_data(zend_object_iterator *iter, zval ***d
}
/* }}} */
-static int spl_heap_it_get_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) /* {{{ */
+static void spl_heap_it_get_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC) /* {{{ */
{
spl_heap_it *iterator = (spl_heap_it *)iter;
- *int_key = (ulong) iterator->object->heap->count - 1;
- return HASH_KEY_IS_LONG;
+ ZVAL_LONG(key, iterator->object->heap->count - 1);
}
/* }}} */
diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c
index f3120b2013..2517366330 100644
--- a/ext/spl/spl_iterators.c
+++ b/ext/spl/spl_iterators.c
@@ -117,6 +117,7 @@ typedef struct _spl_recursive_it_object {
zend_function *nextElement;
zend_class_entry *ce;
smart_str prefix[6];
+ smart_str postfix[1];
} spl_recursive_it_object;
typedef struct _spl_recursive_it_iterator {
@@ -190,16 +191,15 @@ static void spl_recursive_it_get_current_data(zend_object_iterator *iter, zval *
sub_iter->funcs->get_current_data(sub_iter, data TSRMLS_CC);
}
-static int spl_recursive_it_get_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
+static void spl_recursive_it_get_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC)
{
spl_recursive_it_object *object = (spl_recursive_it_object*)iter->data;
zend_object_iterator *sub_iter = object->iterators[object->level].iterator;
if (sub_iter->funcs->get_current_key) {
- return sub_iter->funcs->get_current_key(sub_iter, str_key, str_key_len, int_key TSRMLS_CC);
+ sub_iter->funcs->get_current_key(sub_iter, key TSRMLS_CC);
} else {
- *int_key = iter->index;
- return HASH_KEY_IS_LONG;
+ ZVAL_LONG(key, iter->index);
}
}
@@ -230,7 +230,7 @@ next_step:
if (iterator->funcs->valid(iterator TSRMLS_CC) == FAILURE) {
break;
}
- object->iterators[object->level].state = RS_TEST;
+ object->iterators[object->level].state = RS_TEST;
/* break; */
case RS_TEST:
ce = object->iterators[object->level].ce;
@@ -617,20 +617,7 @@ SPL_METHOD(RecursiveIteratorIterator, key)
}
if (iterator->funcs->get_current_key) {
- char *str_key;
- uint str_key_len;
- ulong int_key;
-
- switch (iterator->funcs->get_current_key(iterator, &str_key, &str_key_len, &int_key TSRMLS_CC)) {
- case HASH_KEY_IS_LONG:
- RETURN_LONG(int_key);
- break;
- case HASH_KEY_IS_STRING:
- RETURN_STRINGL(str_key, str_key_len-1, 0);
- break;
- default:
- RETURN_NULL();
- }
+ iterator->funcs->get_current_key(iterator, return_value TSRMLS_CC);
} else {
RETURN_NULL();
}
@@ -900,6 +887,8 @@ static void spl_RecursiveIteratorIterator_free_storage(void *_object TSRMLS_DC)
smart_str_free(&object->prefix[4]);
smart_str_free(&object->prefix[5]);
+ smart_str_free(&object->postfix[0]);
+
efree(object);
}
/* }}} */
@@ -920,6 +909,8 @@ static zend_object_value spl_RecursiveIteratorIterator_new_ex(zend_class_entry *
smart_str_appendl(&intern->prefix[3], "|-", 2);
smart_str_appendl(&intern->prefix[4], "\\-", 2);
smart_str_appendl(&intern->prefix[5], "", 0);
+
+ smart_str_appendl(&intern->postfix[0], "", 0);
}
zend_object_std_init(&intern->std, class_type TSRMLS_CC);
@@ -1039,7 +1030,7 @@ static void spl_recursive_tree_iterator_get_entry(spl_recursive_it_object * obje
static void spl_recursive_tree_iterator_get_postfix(spl_recursive_it_object * object, zval * return_value TSRMLS_DC)
{
- RETVAL_STRINGL("", 0, 1);
+ RETVAL_STRINGL(object->postfix[0].c, object->postfix[0].len, 1);
}
/* {{{ proto void RecursiveTreeIterator::__construct(RecursiveIterator|IteratorAggregate it [, int flags = RTIT_BYPASS_KEY [, int cit_flags = CIT_CATCH_GET_CHILD [, mode = RIT_SELF_FIRST ]]]) throws InvalidArgumentException
@@ -1082,6 +1073,22 @@ SPL_METHOD(RecursiveTreeIterator, getPrefix)
spl_recursive_tree_iterator_get_prefix(object, return_value TSRMLS_CC);
} /* }}} */
+/* {{{ proto void RecursiveTreeIterator::setPostfix(string prefix)
+ Sets postfix as used in getPostfix() */
+SPL_METHOD(RecursiveTreeIterator, setPostfix)
+{
+ spl_recursive_it_object *object = (spl_recursive_it_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
+ char* postfix;
+ int postfix_len;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &postfix, &postfix_len) == FAILURE) {
+ return;
+ }
+
+ smart_str_free(&object->postfix[0]);
+ smart_str_appendl(&object->postfix[0], postfix, postfix_len);
+} /* }}} */
+
/* {{{ proto string RecursiveTreeIterator::getEntry()
Returns the string presentation built for current element */
SPL_METHOD(RecursiveTreeIterator, getEntry)
@@ -1178,20 +1185,7 @@ SPL_METHOD(RecursiveTreeIterator, key)
}
if (iterator->funcs->get_current_key) {
- char *str_key;
- uint str_key_len;
- ulong int_key;
-
- switch (iterator->funcs->get_current_key(iterator, &str_key, &str_key_len, &int_key TSRMLS_CC)) {
- case HASH_KEY_IS_LONG:
- ZVAL_LONG(&key, int_key);
- break;
- case HASH_KEY_IS_STRING:
- ZVAL_STRINGL(&key, str_key, str_key_len-1, 0);
- break;
- default:
- ZVAL_NULL(&key);
- }
+ iterator->funcs->get_current_key(iterator, &key TSRMLS_CC);
} else {
ZVAL_NULL(&key);
}
@@ -1262,6 +1256,7 @@ static const zend_function_entry spl_funcs_RecursiveTreeIterator[] = {
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, arginfo_recursive_it_void, ZEND_ACC_PUBLIC)
+ SPL_ME(RecursiveTreeIterator, setPostfix, arginfo_recursive_it_void, ZEND_ACC_PUBLIC)
SPL_ME(RecursiveTreeIterator, getPostfix, arginfo_recursive_it_void, ZEND_ACC_PUBLIC)
PHP_FE_END
};
@@ -1597,9 +1592,9 @@ static inline void spl_dual_it_free(spl_dual_it_object *intern TSRMLS_DC)
zval_ptr_dtor(&intern->current.data);
intern->current.data = NULL;
}
- if (intern->current.str_key) {
- efree(intern->current.str_key);
- intern->current.str_key = NULL;
+ if (intern->current.key) {
+ zval_ptr_dtor(&intern->current.key);
+ intern->current.key = NULL;
}
if (intern->dit_type == DIT_CachingIterator || intern->dit_type == DIT_RecursiveCachingIterator) {
if (intern->u.caching.zstr) {
@@ -1642,11 +1637,16 @@ static inline int spl_dual_it_fetch(spl_dual_it_object *intern, int check_more T
intern->current.data = *data;
Z_ADDREF_P(intern->current.data);
}
+
+ MAKE_STD_ZVAL(intern->current.key);
if (intern->inner.iterator->funcs->get_current_key) {
- intern->current.key_type = intern->inner.iterator->funcs->get_current_key(intern->inner.iterator, &intern->current.str_key, &intern->current.str_key_len, &intern->current.int_key TSRMLS_CC);
+ intern->inner.iterator->funcs->get_current_key(intern->inner.iterator, intern->current.key TSRMLS_CC);
+ if (EG(exception)) {
+ zval_ptr_dtor(&intern->current.key);
+ intern->current.key = NULL;
+ }
} else {
- intern->current.key_type = HASH_KEY_IS_LONG;
- intern->current.int_key = intern->current.pos;
+ ZVAL_LONG(intern->current.key, intern->current.pos);
}
return EG(exception) ? FAILURE : SUCCESS;
}
@@ -1718,12 +1718,8 @@ SPL_METHOD(dual_it, key)
SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis());
- if (intern->current.data) {
- if (intern->current.key_type == HASH_KEY_IS_STRING) {
- RETURN_STRINGL(intern->current.str_key, intern->current.str_key_len-1, 1);
- } else {
- RETURN_LONG(intern->current.int_key);
- }
+ if (intern->current.key) {
+ RETURN_ZVAL(intern->current.key, 1, 0);
}
RETURN_NULL();
} /* }}} */
@@ -1934,27 +1930,18 @@ SPL_METHOD(CallbackFilterIterator, accept)
zend_fcall_info *fci = &intern->u.cbfilter->fci;
zend_fcall_info_cache *fcc = &intern->u.cbfilter->fcc;
zval **params[3];
- zval zkey;
- zval *zkey_p = &zkey;
zval *result;
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- if (intern->current.data == NULL) {
+ if (intern->current.data == NULL || intern->current.key == NULL) {
RETURN_FALSE;
}
-
- INIT_PZVAL(&zkey);
- if (intern->current.key_type == HASH_KEY_IS_LONG) {
- ZVAL_LONG(&zkey, intern->current.int_key);
- } else {
- ZVAL_STRINGL(&zkey, intern->current.str_key, intern->current.str_key_len-1, 0);
- }
params[0] = &intern->current.data;
- params[1] = &zkey_p;
+ params[1] = &intern->current.key;
params[2] = &intern->inner.zobject;
fci->retval_ptr_ptr = &result;
@@ -1978,9 +1965,9 @@ SPL_METHOD(CallbackFilterIterator, accept)
SPL_METHOD(RegexIterator, accept)
{
spl_dual_it_object *intern;
- char *subject, tmp[32], *result;
+ char *subject, *result;
int subject_len, use_copy, count = 0, result_len;
- zval subject_copy, zcount, *replacement, tmp_replacement;
+ zval *subject_ptr, subject_copy, zcount, *replacement, tmp_replacement;
if (zend_parse_parameters_none() == FAILURE) {
return;
@@ -1993,24 +1980,18 @@ SPL_METHOD(RegexIterator, accept)
}
if (intern->u.regex.flags & REGIT_USE_KEY) {
- if (intern->current.key_type == HASH_KEY_IS_LONG) {
- subject_len = slprintf(tmp, sizeof(tmp), "%ld", intern->current.int_key);
- subject = &tmp[0];
- use_copy = 0;
- } else {
- subject_len = intern->current.str_key_len - 1;
- subject = estrndup(intern->current.str_key, subject_len);
- use_copy = 1;
- }
+ subject_ptr = intern->current.key;
} else {
- zend_make_printable_zval(intern->current.data, &subject_copy, &use_copy);
- if (use_copy) {
- subject = Z_STRVAL(subject_copy);
- subject_len = Z_STRLEN(subject_copy);
- } else {
- subject = Z_STRVAL_P(intern->current.data);
- subject_len = Z_STRLEN_P(intern->current.data);
- }
+ subject_ptr = intern->current.data;
+ }
+
+ zend_make_printable_zval(subject_ptr, &subject_copy, &use_copy);
+ if (use_copy) {
+ subject = Z_STRVAL(subject_copy);
+ subject_len = Z_STRLEN(subject_copy);
+ } else {
+ subject = Z_STRVAL_P(subject_ptr);
+ subject_len = Z_STRLEN_P(subject_ptr);
}
switch (intern->u.regex.mode)
@@ -2058,12 +2039,9 @@ SPL_METHOD(RegexIterator, accept)
result = php_pcre_replace_impl(intern->u.regex.pce, subject, subject_len, replacement, 0, &result_len, -1, &count TSRMLS_CC);
if (intern->u.regex.flags & REGIT_USE_KEY) {
- if (intern->current.key_type != HASH_KEY_IS_LONG) {
- efree(intern->current.str_key);
- }
- intern->current.key_type = HASH_KEY_IS_STRING;
- intern->current.str_key = result;
- intern->current.str_key_len = result_len + 1;
+ zval_ptr_dtor(&intern->current.key);
+ MAKE_STD_ZVAL(intern->current.key);
+ ZVAL_STRINGL(intern->current.key, result, result_len, 0);
} else {
zval_ptr_dtor(&intern->current.data);
MAKE_STD_ZVAL(intern->current.data);
@@ -2597,14 +2575,14 @@ static inline void spl_caching_it_next(spl_dual_it_object *intern TSRMLS_DC)
/* Full cache ? */
if (intern->u.caching.flags & CIT_FULL_CACHE) {
zval *zcacheval;
+ zval *key = intern->current.key;
MAKE_STD_ZVAL(zcacheval);
ZVAL_ZVAL(zcacheval, intern->current.data, 1, 0);
- if (intern->current.key_type == HASH_KEY_IS_LONG) {
- add_index_zval(intern->u.caching.zcache, intern->current.int_key, zcacheval);
- } else {
- zend_symtable_update(HASH_OF(intern->u.caching.zcache), intern->current.str_key, intern->current.str_key_len, &zcacheval, sizeof(void*), NULL);
- }
+
+ array_set_zval_key(HASH_OF(intern->u.caching.zcache), key, zcacheval);
+
+ zval_ptr_dtor(&zcacheval);
}
/* Recursion ? */
if (intern->dit_type == DIT_RecursiveCachingIterator) {
@@ -2762,13 +2740,9 @@ SPL_METHOD(CachingIterator, __toString)
return;
}
if (intern->u.caching.flags & CIT_TOSTRING_USE_KEY) {
- if (intern->current.key_type == HASH_KEY_IS_STRING) {
- RETURN_STRINGL(intern->current.str_key, intern->current.str_key_len-1, 1);
- } else {
- RETVAL_LONG(intern->current.int_key);
- convert_to_string(return_value);
- return;
- }
+ MAKE_COPY_ZVAL(&intern->current.key, return_value);
+ convert_to_string(return_value);
+ return;
} else if (intern->u.caching.flags & CIT_TOSTRING_USE_CURRENT) {
MAKE_COPY_ZVAL(&intern->current.data, return_value);
convert_to_string(return_value);
@@ -3130,19 +3104,7 @@ SPL_METHOD(NoRewindIterator, key)
SPL_FETCH_AND_CHECK_DUAL_IT(intern, getThis());
if (intern->inner.iterator->funcs->get_current_key) {
- char *str_key;
- uint str_key_len;
- ulong int_key;
- switch (intern->inner.iterator->funcs->get_current_key(intern->inner.iterator, &str_key, &str_key_len, &int_key TSRMLS_CC)) {
- case HASH_KEY_IS_LONG:
- RETURN_LONG(int_key);
- break;
- case HASH_KEY_IS_STRING:
- RETURN_STRINGL(str_key, str_key_len-1, 0);
- break;
- default:
- RETURN_NULL();
- }
+ intern->inner.iterator->funcs->get_current_key(intern->inner.iterator, return_value TSRMLS_CC);
} else {
RETURN_NULL();
}
@@ -3509,11 +3471,7 @@ done:
static int spl_iterator_to_array_apply(zend_object_iterator *iter, void *puser TSRMLS_DC) /* {{{ */
{
- zval **data, *return_value = (zval*)puser;
- char *str_key;
- uint str_key_len;
- ulong int_key;
- int key_type;
+ zval **data, *return_value = (zval*)puser;
iter->funcs->get_current_data(iter, &data TSRMLS_CC);
if (EG(exception)) {
@@ -3523,20 +3481,13 @@ static int spl_iterator_to_array_apply(zend_object_iterator *iter, void *puser T
return ZEND_HASH_APPLY_STOP;
}
if (iter->funcs->get_current_key) {
- key_type = iter->funcs->get_current_key(iter, &str_key, &str_key_len, &int_key TSRMLS_CC);
+ zval key;
+ iter->funcs->get_current_key(iter, &key TSRMLS_CC);
if (EG(exception)) {
return ZEND_HASH_APPLY_STOP;
}
- Z_ADDREF_PP(data);
- switch(key_type) {
- case HASH_KEY_IS_STRING:
- add_assoc_zval_ex(return_value, str_key, str_key_len, *data);
- efree(str_key);
- break;
- case HASH_KEY_IS_LONG:
- add_index_zval(return_value, int_key, *data);
- break;
- }
+ array_set_zval_key(Z_ARRVAL_P(return_value), &key, *data);
+ zval_dtor(&key);
} else {
Z_ADDREF_PP(data);
add_next_index_zval(return_value, *data);
diff --git a/ext/spl/spl_iterators.h b/ext/spl/spl_iterators.h
index fdb4d69ac0..3991ddad33 100644
--- a/ext/spl/spl_iterators.h
+++ b/ext/spl/spl_iterators.h
@@ -133,10 +133,7 @@ typedef struct _spl_dual_it_object {
} inner;
struct {
zval *data;
- char *str_key;
- uint str_key_len;
- ulong int_key;
- int key_type; /* HASH_KEY_IS_STRING or HASH_KEY_IS_LONG */
+ zval *key;
int pos;
} current;
dual_it_type dit_type;
diff --git a/ext/spl/tests/SplDoublyLinkedList_add_invalid_offset.phpt b/ext/spl/tests/SplDoublyLinkedList_add_invalid_offset.phpt
new file mode 100644
index 0000000000..b94b067f4d
--- /dev/null
+++ b/ext/spl/tests/SplDoublyLinkedList_add_invalid_offset.phpt
@@ -0,0 +1,13 @@
+--TEST--
+Check that SplDoublyLinkedList::add throws an exception with an invalid offset argument
+--FILE--
+<?php
+try {
+ $dll = new SplDoublyLinkedList();
+ var_dump($dll->add(12,'Offset 12 should not exist'));
+} catch (OutOfRangeException $e) {
+ echo "Exception: ".$e->getMessage()."\n";
+}
+?>
+--EXPECTF--
+Exception: Offset invalid or out of range
diff --git a/ext/spl/tests/SplDoublyLinkedList_add_missing_parameter1.phpt b/ext/spl/tests/SplDoublyLinkedList_add_missing_parameter1.phpt
new file mode 100644
index 0000000000..12cfe40008
--- /dev/null
+++ b/ext/spl/tests/SplDoublyLinkedList_add_missing_parameter1.phpt
@@ -0,0 +1,11 @@
+--TEST--
+Check that SplDoublyLinkedList::add generate a warning and returns a NULL with missing arguments
+--FILE--
+<?php
+$dll = new SplDoublyLinkedList();
+var_dump($dll->add());
+?>
+--EXPECTF--
+Warning: SplDoublyLinkedList::add() expects exactly 2 parameters, 0 given in %s on line %d
+NULL
+
diff --git a/ext/spl/tests/SplDoublyLinkedList_add_missing_parameter2.phpt b/ext/spl/tests/SplDoublyLinkedList_add_missing_parameter2.phpt
new file mode 100644
index 0000000000..c9c319316f
--- /dev/null
+++ b/ext/spl/tests/SplDoublyLinkedList_add_missing_parameter2.phpt
@@ -0,0 +1,11 @@
+--TEST--
+Check that SplDoublyLinkedList::add generate a warning and returns a NULL with a missing value argument
+--FILE--
+<?php
+$dll = new SplDoublyLinkedList();
+var_dump($dll->add(2));
+?>
+--EXPECTF--
+Warning: SplDoublyLinkedList::add() expects exactly 2 parameters, 1 given in %s on line %d
+NULL
+
diff --git a/ext/spl/tests/SplDoublyLinkedList_add_null_offset.phpt b/ext/spl/tests/SplDoublyLinkedList_add_null_offset.phpt
new file mode 100644
index 0000000000..396f89b491
--- /dev/null
+++ b/ext/spl/tests/SplDoublyLinkedList_add_null_offset.phpt
@@ -0,0 +1,13 @@
+--TEST--
+Check that SplDoublyLinkedList::add throws an exception with an invalid offset argument
+--FILE--
+<?php
+try {
+ $dll = new SplDoublyLinkedList();
+ var_dump($dll->add(NULL,2));
+} catch (OutOfRangeException $e) {
+ echo "Exception: ".$e->getMessage()."\n";
+}
+?>
+--EXPECTF--
+Exception: Offset invalid or out of range
diff --git a/ext/spl/tests/bug61697.phpt b/ext/spl/tests/bug61697.phpt
new file mode 100644
index 0000000000..064aaa2e2b
--- /dev/null
+++ b/ext/spl/tests/bug61697.phpt
@@ -0,0 +1,24 @@
+--TEST--
+Bug #61697 (spl_autoload_functions returns lambda functions incorrectly)
+--FILE--
+<?php
+
+function f1($class) { echo "f1: [[$class]]\n"; }
+function f2($class) { echo "f2: [[$class]]\n"; }
+
+spl_autoload_register('f1');
+spl_autoload_register('f2');
+spl_autoload_register(create_function('$class', 'echo "cf1: [[$class]]\n";'));
+spl_autoload_register(create_function('$class', 'echo "cf2: [[$class]]\n";'));
+
+foreach (spl_autoload_functions() AS $func)
+{
+ spl_autoload_unregister($func);
+}
+
+print_r(spl_autoload_functions());
+?>
+--EXPECTF--
+Array
+(
+)
diff --git a/ext/spl/tests/bug64782.phpt b/ext/spl/tests/bug64782.phpt
new file mode 100644
index 0000000000..ac5d08d7d1
--- /dev/null
+++ b/ext/spl/tests/bug64782.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Bug #64782: SplFileObject constructor make $context optional / give it a default value
+--FILE--
+<?php
+
+var_dump(new SplFileObject(__FILE__, "r", false, null));
+
+?>
+--EXPECTF--
+object(SplFileObject)#1 (%d) {
+ ["pathName":"SplFileInfo":private]=>
+ string(%d) "%s/bug64782.php"
+ ["fileName":"SplFileInfo":private]=>
+ string(12) "bug64782.php"
+ ["openMode":"SplFileObject":private]=>
+ string(1) "r"
+ ["delimiter":"SplFileObject":private]=>
+ string(1) ","
+ ["enclosure":"SplFileObject":private]=>
+ string(1) """
+}
diff --git a/ext/spl/tests/dllist_013.phpt b/ext/spl/tests/dllist_013.phpt
new file mode 100644
index 0000000000..b60f063924
--- /dev/null
+++ b/ext/spl/tests/dllist_013.phpt
@@ -0,0 +1,45 @@
+--TEST--
+SPL: DoublyLinkedList: insert operations
+--FILE--
+<?php
+$dll = new SplDoublyLinkedList();
+// errors
+try {
+ $dll->add(2,5);
+} catch (OutOfRangeException $e) {
+ echo "Exception: ".$e->getMessage()."\n";
+}
+
+$dll->add(0,6); // 6
+$dll->add(0,3); // 3 6
+// Insert in the middle of the DLL
+$dll->add(1,4); // 3 4 6
+$dll->add(2,5); // 3 4 5 6
+$dll->unshift(2); // 2 3 5 4 6
+// Insert at the beginning and end of the DLL
+$dll->add(0,1); // 1 2 3 4 5 6
+$dll->add(6,7); // 1 2 3 4 5 6 7
+
+echo count($dll)."\n";
+
+echo $dll->pop()."\n";
+echo $dll->pop()."\n";
+echo $dll->pop()."\n";
+echo $dll->pop()."\n";
+echo $dll->pop()."\n";
+echo $dll->pop()."\n";
+echo $dll->pop()."\n";
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECTF--
+Exception: Offset invalid or out of range
+7
+7
+6
+5
+4
+3
+2
+1
+===DONE===
diff --git a/ext/spl/tests/iterator_to_array_nonscalar_keys.phpt b/ext/spl/tests/iterator_to_array_nonscalar_keys.phpt
new file mode 100644
index 0000000000..4ca9485faf
--- /dev/null
+++ b/ext/spl/tests/iterator_to_array_nonscalar_keys.phpt
@@ -0,0 +1,31 @@
+--TEST--
+Tests iterator_to_array() with non-scalar keys
+--FILE--
+<?php
+
+function gen() {
+ yield "foo" => 0;
+ yield 1 => 1;
+ yield 2.5 => 2;
+ yield null => 3;
+ yield [] => 4;
+ yield new stdClass => 5;
+}
+
+var_dump(iterator_to_array(gen()));
+
+?>
+--EXPECTF--
+Warning: Illegal offset type in %s on line %d
+
+Warning: Illegal offset type in %s on line %d
+array(4) {
+ ["foo"]=>
+ int(0)
+ [1]=>
+ int(1)
+ [2]=>
+ int(2)
+ [""]=>
+ int(3)
+}
diff --git a/ext/spl/tests/multiple_iterator_001.phpt b/ext/spl/tests/multiple_iterator_001.phpt
index edd03f5040..eb77f79371 100644
--- a/ext/spl/tests/multiple_iterator_001.phpt
+++ b/ext/spl/tests/multiple_iterator_001.phpt
@@ -23,8 +23,8 @@ echo "-- Default flags, MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_K
var_dump($m->getFlags() === (MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_NUMERIC));
-foreach($m as $value) {
- var_dump($m->key(), $value);
+foreach($m as $key => $value) {
+ var_dump($key, $value);
}
try {
$m->current();
@@ -42,8 +42,8 @@ echo "-- Flags = MultipleIterator::MIT_NEED_ANY | MultipleIterator::MIT_KEYS_NUM
$m->setFlags(MultipleIterator::MIT_NEED_ANY | MultipleIterator::MIT_KEYS_NUMERIC);
var_dump($m->getFlags() === (MultipleIterator::MIT_NEED_ANY | MultipleIterator::MIT_KEYS_NUMERIC));
-foreach($m as $value) {
- var_dump($m->key(), $value);
+foreach($m as $key => $value) {
+ var_dump($key, $value);
}
echo "-- Default flags, added element --\n";
@@ -51,8 +51,8 @@ echo "-- Default flags, added element --\n";
$m->setFlags(MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_NUMERIC);
$iter2[] = 3;
-foreach($m as $value) {
- var_dump($m->key(), $value);
+foreach($m as $key => $value) {
+ var_dump($key, $value);
}
echo "-- Flags |= MultipleIterator::MIT_KEYS_ASSOC, with iterator associated with NULL --\n";
@@ -71,8 +71,8 @@ $m->attachIterator($iter1, "iter1");
$m->attachIterator($iter2, b"iter2");
$m->attachIterator($iter3, 3);
-foreach($m as $value) {
- var_dump($m->key(), $value);
+foreach($m as $key => $value) {
+ var_dump($key, $value);
}
echo "-- Associate with invalid value --\n";
@@ -98,8 +98,8 @@ var_dump($m->containsIterator($iter2));
var_dump($m->detachIterator($iter2));
var_dump($m->countIterators());
var_dump($m->containsIterator($iter2));
-foreach($m as $value) {
- var_dump($m->key(), $value);
+foreach($m as $key => $value) {
+ var_dump($key, $value);
}
?>
diff --git a/ext/spl/tests/recursive_tree_iterator_setpostfix.phpt b/ext/spl/tests/recursive_tree_iterator_setpostfix.phpt
new file mode 100644
index 0000000000..d59e278fd6
--- /dev/null
+++ b/ext/spl/tests/recursive_tree_iterator_setpostfix.phpt
@@ -0,0 +1,88 @@
+--TEST--
+SPL: RecursiveTreeIterator::setPostfix()
+--CREDITS--
+Joshua Thijssen (jthijssen@noxlogic.nl)
+--FILE--
+<?php
+
+$arr = array(
+ 0 => array(
+ "a",
+ 1,
+ ),
+ "a" => array(
+ 2,
+ "b",
+ 3 => array(
+ 4,
+ "c",
+ ),
+ "3" => array(
+ 4,
+ "c",
+ ),
+ ),
+);
+
+$it = new RecursiveArrayIterator($arr);
+$it = new RecursiveTreeIterator($it);
+
+echo "----\n";
+echo $it->getPostfix();
+echo "\n\n";
+
+echo "----\n";
+$it->setPostfix("POSTFIX");
+echo $it->getPostfix();
+echo "\n\n";
+
+echo "----\n";
+foreach($it as $k => $v) {
+ echo "[$k] => $v\n";
+}
+
+echo "----\n";
+$it->setPostfix("");
+echo $it->getPostfix();
+echo "\n\n";
+
+echo "----\n";
+foreach($it as $k => $v) {
+ echo "[$k] => $v\n";
+}
+
+
+
+?>
+===DONE===
+--EXPECTF--
+----
+
+
+----
+POSTFIX
+
+----
+[0] => |-ArrayPOSTFIX
+[0] => | |-aPOSTFIX
+[1] => | \-1POSTFIX
+[a] => \-ArrayPOSTFIX
+[0] => |-2POSTFIX
+[1] => |-bPOSTFIX
+[3] => \-ArrayPOSTFIX
+[0] => |-4POSTFIX
+[1] => \-cPOSTFIX
+----
+
+
+----
+[0] => |-Array
+[0] => | |-a
+[1] => | \-1
+[a] => \-Array
+[0] => |-2
+[1] => |-b
+[3] => \-Array
+[0] => |-4
+[1] => \-c
+===DONE===
diff --git a/ext/sqlite3/config0.m4 b/ext/sqlite3/config0.m4
index 1365def033..6959a6f916 100644
--- a/ext/sqlite3/config0.m4
+++ b/ext/sqlite3/config0.m4
@@ -3,7 +3,7 @@ dnl config.m4 for extension sqlite3
dnl vim:et:ts=2:sw=2
PHP_ARG_WITH(sqlite3, whether to enable the SQLite3 extension,
-[ --without-sqlite3[=DIR] Do not include SQLite3 support. DIR is the prefix to
+[ --without-sqlite3[=DIR] Do not include SQLite3 support. DIR is the prefix to
SQLite3 installation directory.], yes)
if test $PHP_SQLITE3 != "no"; then
diff --git a/ext/sqlite3/libsqlite/sqlite3.c b/ext/sqlite3/libsqlite/sqlite3.c
index 3d71ebb18d..6d013b6751 100644
--- a/ext/sqlite3/libsqlite/sqlite3.c
+++ b/ext/sqlite3/libsqlite/sqlite3.c
@@ -18139,7 +18139,7 @@ SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){
sqlite3_int64 priorLimit;
sqlite3_int64 excess;
#ifndef SQLITE_OMIT_AUTOINIT
- sqlite3_initialize();
+ if( sqlite3_initialize() ) return 0;
#endif
sqlite3_mutex_enter(mem0.mutex);
priorLimit = mem0.alarmThreshold;
diff --git a/ext/sqlite3/php_sqlite3.h b/ext/sqlite3/php_sqlite3.h
index 5961e4401b..2c19b9d9c4 100644
--- a/ext/sqlite3/php_sqlite3.h
+++ b/ext/sqlite3/php_sqlite3.h
@@ -21,7 +21,7 @@
#ifndef PHP_SQLITE3_H
#define PHP_SQLITE3_H
-#define PHP_SQLITE3_VERSION "0.7"
+#define PHP_SQLITE3_VERSION "0.7-dev"
extern zend_module_entry sqlite3_module_entry;
#define phpext_sqlite3_ptr &sqlite3_module_entry
diff --git a/ext/sqlite3/tests/bug53463.phpt b/ext/sqlite3/tests/bug53463.phpt
index 744a214612..dcfc13d5ba 100644
--- a/ext/sqlite3/tests/bug53463.phpt
+++ b/ext/sqlite3/tests/bug53463.phpt
@@ -27,4 +27,4 @@ echo "Done\n";
--EXPECT--
string(8) "whatever"
bool(false)
-Done
+Done \ No newline at end of file
diff --git a/ext/standard/Makefile.frag b/ext/standard/Makefile.frag
index 4e94962183..8b6e3e233a 100644
--- a/ext/standard/Makefile.frag
+++ b/ext/standard/Makefile.frag
@@ -1,9 +1,9 @@
$(srcdir)/var_unserializer.c: $(srcdir)/var_unserializer.re
- @(cd $(top_srcdir); $(RE2C) -b -o ext/standard/var_unserializer.c ext/standard/var_unserializer.re)
+ @(cd $(top_srcdir); $(RE2C) --no-generation-date -b -o ext/standard/var_unserializer.c ext/standard/var_unserializer.re)
$(srcdir)/url_scanner_ex.c: $(srcdir)/url_scanner_ex.re
- @(cd $(top_srcdir); $(RE2C) -b -o ext/standard/url_scanner_ex.c ext/standard/url_scanner_ex.re)
+ @(cd $(top_srcdir); $(RE2C) --no-generation-date -b -o ext/standard/url_scanner_ex.c ext/standard/url_scanner_ex.re)
$(builddir)/info.lo: $(builddir)/../../main/build-defs.h
diff --git a/ext/standard/array.c b/ext/standard/array.c
index c2efca58fc..1a29afa6dc 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -927,24 +927,12 @@ PHP_FUNCTION(current)
PHP_FUNCTION(key)
{
HashTable *array;
- char *string_key;
- uint string_length;
- ulong num_key;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "H", &array) == FAILURE) {
return;
}
- switch (zend_hash_get_current_key_ex(array, &string_key, &string_length, &num_key, 0, NULL)) {
- case HASH_KEY_IS_STRING:
- RETVAL_STRINGL(string_key, string_length - 1, 1);
- break;
- case HASH_KEY_IS_LONG:
- RETVAL_LONG(num_key);
- break;
- case HASH_KEY_NON_EXISTANT:
- return;
- }
+ zend_hash_get_current_key_zval(array, return_value);
}
/* }}} */
@@ -1055,9 +1043,6 @@ static int php_array_walk(HashTable *target_hash, zval *userdata, int recursive
zval **args[3], /* Arguments to userland function */
*retval_ptr = NULL, /* Return value - unused */
*key=NULL; /* Entry key */
- char *string_key;
- uint string_key_len;
- ulong num_key;
/* Set up known arguments */
args[1] = &key;
@@ -1103,17 +1088,7 @@ static int php_array_walk(HashTable *target_hash, zval *userdata, int recursive
} else {
/* Allocate space for key */
MAKE_STD_ZVAL(key);
-
- /* Set up the key */
- switch (zend_hash_get_current_key_ex(target_hash, &string_key, &string_key_len, &num_key, 0, NULL)) {
- case HASH_KEY_IS_LONG:
- Z_TYPE_P(key) = IS_LONG;
- Z_LVAL_P(key) = num_key;
- break;
- case HASH_KEY_IS_STRING:
- ZVAL_STRINGL(key, string_key, string_key_len - 1, 1);
- break;
- }
+ zend_hash_get_current_key_zval(target_hash, key);
/* Call the userland function */
if (zend_call_function(&BG(array_walk_fci), &BG(array_walk_fci_cache) TSRMLS_CC) == SUCCESS) {
@@ -1205,9 +1180,6 @@ static void php_search_array(INTERNAL_FUNCTION_PARAMETERS, int behavior) /* {{{
res; /* comparison result */
HashPosition pos; /* hash iterator */
zend_bool strict = 0; /* strict comparison or not */
- ulong num_key;
- uint str_key_len;
- char *string_key;
int (*is_equal_func)(zval *, zval *, zval * TSRMLS_DC) = is_equal_function;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "za|b", &value, &array, &strict) == FAILURE) {
@@ -1225,15 +1197,8 @@ static void php_search_array(INTERNAL_FUNCTION_PARAMETERS, int behavior) /* {{{
if (behavior == 0) {
RETURN_TRUE;
} else {
- /* Return current key */
- switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(array), &string_key, &str_key_len, &num_key, 0, &pos)) {
- case HASH_KEY_IS_STRING:
- RETURN_STRINGL(string_key, str_key_len - 1, 1);
- break;
- case HASH_KEY_IS_LONG:
- RETURN_LONG(num_key);
- break;
- }
+ zend_hash_get_current_key_zval_ex(Z_ARRVAL_P(array), return_value, &pos);
+ return;
}
}
zend_hash_move_forward_ex(Z_ARRVAL_P(array), &pos);
@@ -2257,13 +2222,14 @@ PHPAPI int php_array_merge(HashTable *dest, HashTable *src, int recursive TSRMLS
case HASH_KEY_IS_STRING:
if (recursive && zend_hash_find(dest, string_key, string_key_len, (void **)&dest_entry) == SUCCESS) {
HashTable *thash = Z_TYPE_PP(dest_entry) == IS_ARRAY ? Z_ARRVAL_PP(dest_entry) : NULL;
+ zval *src_zval;
+ zval *tmp = NULL;
if ((thash && thash->nApplyCount > 1) || (*src_entry == *dest_entry && Z_ISREF_PP(dest_entry) && (Z_REFCOUNT_PP(dest_entry) % 2))) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected");
return 0;
}
SEPARATE_ZVAL(dest_entry);
- SEPARATE_ZVAL(src_entry);
if (Z_TYPE_PP(dest_entry) == IS_NULL) {
convert_to_array_ex(dest_entry);
@@ -2271,23 +2237,34 @@ PHPAPI int php_array_merge(HashTable *dest, HashTable *src, int recursive TSRMLS
} else {
convert_to_array_ex(dest_entry);
}
- if (Z_TYPE_PP(src_entry) == IS_NULL) {
- convert_to_array_ex(src_entry);
- add_next_index_null(*src_entry);
+ if (Z_TYPE_PP(src_entry) == IS_OBJECT) {
+ ALLOC_ZVAL(src_zval);
+ INIT_PZVAL_COPY(src_zval, *src_entry);
+ zval_copy_ctor(src_zval);
+ convert_to_array(src_zval);
+ tmp = src_zval;
} else {
- convert_to_array_ex(src_entry);
+ src_zval = *src_entry;
}
- if (thash) {
- thash->nApplyCount++;
- }
- if (!php_array_merge(Z_ARRVAL_PP(dest_entry), Z_ARRVAL_PP(src_entry), recursive TSRMLS_CC)) {
+ if (Z_TYPE_P(src_zval) == IS_ARRAY) {
+ if (thash) {
+ thash->nApplyCount++;
+ }
+ if (!php_array_merge(Z_ARRVAL_PP(dest_entry), Z_ARRVAL_P(src_zval), recursive TSRMLS_CC)) {
+ if (thash) {
+ thash->nApplyCount--;
+ }
+ return 0;
+ }
if (thash) {
thash->nApplyCount--;
}
- return 0;
+ } else {
+ Z_ADDREF_PP(src_entry);
+ zend_hash_next_index_insert(Z_ARRVAL_PP(dest_entry), &src_zval, sizeof(zval *), NULL);
}
- if (thash) {
- thash->nApplyCount--;
+ if (tmp) {
+ zval_ptr_dtor(&tmp);
}
} else {
Z_ADDREF_PP(src_entry);
@@ -2391,7 +2368,6 @@ 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 */
@@ -2447,9 +2423,6 @@ PHP_FUNCTION(array_keys)
res, /* Result of comparison */
*new_val; /* New value */
int add_key; /* Flag to indicate whether a key should be added */
- char *string_key; /* String key */
- uint string_key_len;
- ulong num_key; /* Numeric key */
zend_bool strict = 0; /* do strict comparison */
HashPosition pos;
int (*is_equal_func)(zval *, zval *, zval * TSRMLS_DC) = is_equal_function;
@@ -2480,19 +2453,8 @@ PHP_FUNCTION(array_keys)
if (add_key) {
MAKE_STD_ZVAL(new_val);
-
- switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &string_key, &string_key_len, &num_key, 1, &pos)) {
- case HASH_KEY_IS_STRING:
- ZVAL_STRINGL(new_val, string_key, string_key_len - 1, 0);
- zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &new_val, sizeof(zval *), NULL);
- break;
-
- case HASH_KEY_IS_LONG:
- Z_TYPE_P(new_val) = IS_LONG;
- Z_LVAL_P(new_val) = num_key;
- zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &new_val, sizeof(zval *), NULL);
- break;
- }
+ zend_hash_get_current_key_zval_ex(Z_ARRVAL_P(input), new_val, &pos);
+ zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &new_val, sizeof(zval *), NULL);
}
zend_hash_move_forward_ex(Z_ARRVAL_P(input), &pos);
@@ -2573,6 +2535,100 @@ PHP_FUNCTION(array_count_values)
}
/* }}} */
+/* {{{ array_column_param_helper
+ * Specialized conversion rules for array_column() function
+ */
+static inline
+zend_bool array_column_param_helper(zval **param,
+ const char *name TSRMLS_DC) {
+ switch (Z_TYPE_PP(param)) {
+ case IS_DOUBLE:
+ convert_to_long_ex(param);
+ /* fallthrough */
+ case IS_LONG:
+ return 1;
+
+ case IS_OBJECT:
+ convert_to_string_ex(param);
+ /* fallthrough */
+ case IS_STRING:
+ return 1;
+
+ default:
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "The %s key should be either a string or an integer", name);
+ return 0;
+ }
+}
+
+/* {{{ proto array array_column(array input, mixed column_key[, mixed index_key])
+ Return the values from a single column in the input array, identified by the
+ value_key and optionally indexed by the index_key */
+PHP_FUNCTION(array_column)
+{
+ zval **zcolumn = NULL, **zkey = NULL, **data;
+ HashTable *arr_hash;
+ HashPosition pointer;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "hZ!|Z!", &arr_hash, &zcolumn, &zkey) == FAILURE) {
+ return;
+ }
+
+ if ((zcolumn && !array_column_param_helper(zcolumn, "column" TSRMLS_CC)) ||
+ (zkey && !array_column_param_helper(zkey, "index" TSRMLS_CC))) {
+ RETURN_FALSE;
+ }
+
+ array_init(return_value);
+ for (zend_hash_internal_pointer_reset_ex(arr_hash, &pointer);
+ zend_hash_get_current_data_ex(arr_hash, (void**)&data, &pointer) == SUCCESS;
+ zend_hash_move_forward_ex(arr_hash, &pointer)) {
+ zval **zcolval, **zkeyval = NULL;
+ HashTable *ht;
+
+ if (Z_TYPE_PP(data) != IS_ARRAY) {
+ /* Skip elemens which are not sub-arrays */
+ continue;
+ }
+ ht = Z_ARRVAL_PP(data);
+
+ if (!zcolumn) {
+ /* NULL column ID means use entire subarray as data */
+ zcolval = data;
+
+ /* Otherwise, skip if the value doesn't exist in our subarray */
+ } else if ((Z_TYPE_PP(zcolumn) == IS_STRING) &&
+ (zend_hash_find(ht, Z_STRVAL_PP(zcolumn), Z_STRLEN_PP(zcolumn) + 1, (void**)&zcolval) == FAILURE)) {
+ continue;
+ } else if ((Z_TYPE_PP(zcolumn) == IS_LONG) &&
+ (zend_hash_index_find(ht, Z_LVAL_PP(zcolumn), (void**)&zcolval) == FAILURE)) {
+ continue;
+ }
+
+ /* Failure will leave zkeyval alone which will land us on the final else block below
+ * which is to append the value as next_index
+ */
+ if (zkey && (Z_TYPE_PP(zkey) == IS_STRING)) {
+ zend_hash_find(ht, Z_STRVAL_PP(zkey), Z_STRLEN_PP(zkey) + 1, (void**)&zkeyval);
+ } else if (zkey && (Z_TYPE_PP(zkey) == IS_LONG)) {
+ zend_hash_index_find(ht, Z_LVAL_PP(zkey), (void**)&zkeyval);
+ }
+
+ Z_ADDREF_PP(zcolval);
+ if (zkeyval && Z_TYPE_PP(zkeyval) == IS_STRING) {
+ add_assoc_zval(return_value, Z_STRVAL_PP(zkeyval), *zcolval);
+ } else if (zkeyval && Z_TYPE_PP(zkeyval) == IS_LONG) {
+ add_index_zval(return_value, Z_LVAL_PP(zkeyval), *zcolval);
+ } else if (zkeyval && Z_TYPE_PP(zkeyval) == IS_OBJECT) {
+ SEPARATE_ZVAL(zkeyval);
+ convert_to_string(*zkeyval);
+ add_assoc_zval(return_value, Z_STRVAL_PP(zkeyval), *zcolval);
+ } else {
+ add_next_index_zval(return_value, *zcolval);
+ }
+ }
+}
+/* }}} */
+
/* {{{ proto array array_reverse(array input [, bool preserve keys])
Return input as a new array with the order of the entries reversed */
PHP_FUNCTION(array_reverse)
@@ -2691,9 +2747,6 @@ PHP_FUNCTION(array_pad)
PHP_FUNCTION(array_flip)
{
zval *array, **entry, *data;
- char *string_key;
- uint str_key_len;
- ulong num_key;
HashPosition pos;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) {
@@ -2705,15 +2758,7 @@ PHP_FUNCTION(array_flip)
zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(array), &pos);
while (zend_hash_get_current_data_ex(Z_ARRVAL_P(array), (void **)&entry, &pos) == SUCCESS) {
MAKE_STD_ZVAL(data);
- switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(array), &string_key, &str_key_len, &num_key, 1, &pos)) {
- case HASH_KEY_IS_STRING:
- ZVAL_STRINGL(data, string_key, str_key_len - 1, 0);
- break;
- case HASH_KEY_IS_LONG:
- Z_TYPE_P(data) = IS_LONG;
- Z_LVAL_P(data) = num_key;
- break;
- }
+ zend_hash_get_current_key_zval_ex(Z_ARRVAL_P(array), data, &pos);
if (Z_TYPE_PP(entry) == IS_LONG) {
zend_hash_index_update(Z_ARRVAL_P(return_value), Z_LVAL_PP(entry), &data, sizeof(data), NULL);
@@ -3983,7 +4028,7 @@ PHP_FUNCTION(array_rand)
/* We can't use zend_hash_index_find() because the array may have string keys or gaps. */
zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(input), &pos);
- while (num_req && (key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &string_key, &string_key_len, &num_key, 0, &pos)) != HASH_KEY_NON_EXISTANT) {
+ while (num_req && (key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &string_key, &string_key_len, &num_key, 0, &pos)) != HASH_KEY_NON_EXISTENT) {
randval = php_rand(TSRMLS_C);
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c
index c01365589e..e22725bdb0 100644
--- a/ext/standard/basic_functions.c
+++ b/ext/standard/basic_functions.c
@@ -128,6 +128,8 @@ typedef struct _user_tick_function_entry {
static void user_shutdown_function_dtor(php_shutdown_function_entry *shutdown_function_entry);
static void user_tick_function_dtor(user_tick_function_entry *tick_function_entry);
+static HashTable basic_submodules;
+
#undef sprintf
/* {{{ arginfo */
@@ -434,6 +436,12 @@ ZEND_BEGIN_ARG_INFO(arginfo_array_count_values, 0)
ZEND_ARG_INFO(0, arg) /* ARRAY_INFO(0, arg, 0) */
ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO_EX(arginfo_array_column, 0, 0, 2)
+ ZEND_ARG_INFO(0, arg) /* ARRAY_INFO(0, arg, 0) */
+ ZEND_ARG_INFO(0, column_key)
+ ZEND_ARG_INFO(0, index_key)
+ZEND_END_ARG_INFO()
+
ZEND_BEGIN_ARG_INFO_EX(arginfo_array_reverse, 0, 0, 1)
ZEND_ARG_INFO(0, input) /* ARRAY_INFO(0, arg, 0) */
ZEND_ARG_INFO(0, preserve_keys)
@@ -1548,18 +1556,6 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_phpcredits, 0, 0, 0)
ZEND_ARG_INFO(0, flag)
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_INFO(arginfo_php_logo_guid, 0)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO(arginfo_php_real_logo_guid, 0)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO(arginfo_php_egg_logo_guid, 0)
-ZEND_END_ARG_INFO()
-
-ZEND_BEGIN_ARG_INFO(arginfo_zend_logo_guid, 0)
-ZEND_END_ARG_INFO()
-
ZEND_BEGIN_ARG_INFO(arginfo_php_sapi_name, 0)
ZEND_END_ARG_INFO()
@@ -1793,8 +1789,8 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_number_format, 0, 0, 1)
ZEND_ARG_INFO(0, number)
ZEND_ARG_INFO(0, num_decimal_places)
- ZEND_ARG_INFO(0, dec_seperator)
- ZEND_ARG_INFO(0, thousands_seperator)
+ ZEND_ARG_INFO(0, dec_separator)
+ ZEND_ARG_INFO(0, thousands_separator)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_fmod, 0)
@@ -1864,6 +1860,25 @@ ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO(arginfo_getlastmod, 0)
ZEND_END_ARG_INFO()
/* }}} */
+/* {{{ password.c */
+ZEND_BEGIN_ARG_INFO_EX(arginfo_password_hash, 0, 0, 2)
+ ZEND_ARG_INFO(0, password)
+ ZEND_ARG_INFO(0, algo)
+ ZEND_ARG_INFO(0, options)
+ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO_EX(arginfo_password_get_info, 0, 0, 1)
+ ZEND_ARG_INFO(0, hash)
+ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO_EX(arginfo_password_needs_rehash, 0, 0, 2)
+ ZEND_ARG_INFO(0, hash)
+ ZEND_ARG_INFO(0, algo)
+ ZEND_ARG_INFO(0, options)
+ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO_EX(arginfo_password_verify, 0, 0, 2)
+ ZEND_ARG_INFO(0, password)
+ ZEND_ARG_INFO(0, hash)
+ZEND_END_ARG_INFO()
+/* }}} */
/* {{{ proc_open.c */
#ifdef PHP_CAN_SUPPORT_PROC_OPEN
ZEND_BEGIN_ARG_INFO_EX(arginfo_proc_terminate, 0, 0, 1)
@@ -2520,6 +2535,10 @@ ZEND_BEGIN_ARG_INFO(arginfo_strval, 0)
ZEND_ARG_INFO(0, var)
ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO(arginfo_boolval, 0)
+ ZEND_ARG_INFO(0, var)
+ZEND_END_ARG_INFO()
+
ZEND_BEGIN_ARG_INFO(arginfo_is_null, 0)
ZEND_ARG_INFO(0, var)
ZEND_END_ARG_INFO()
@@ -2717,10 +2736,6 @@ const zend_function_entry basic_functions[] = { /* {{{ */
PHP_FE(phpinfo, arginfo_phpinfo)
PHP_FE(phpversion, arginfo_phpversion)
PHP_FE(phpcredits, arginfo_phpcredits)
- PHP_FE(php_logo_guid, arginfo_php_logo_guid)
- PHP_FE(php_real_logo_guid, arginfo_php_real_logo_guid)
- PHP_FE(php_egg_logo_guid, arginfo_php_egg_logo_guid)
- PHP_FE(zend_logo_guid, arginfo_zend_logo_guid)
PHP_FE(php_sapi_name, arginfo_php_sapi_name)
PHP_FE(php_uname, arginfo_php_uname)
PHP_FE(php_ini_scanned_files, arginfo_php_ini_scanned_files)
@@ -2874,6 +2889,10 @@ const zend_function_entry basic_functions[] = { /* {{{ */
PHP_FE(base64_decode, arginfo_base64_decode)
PHP_FE(base64_encode, arginfo_base64_encode)
+ PHP_FE(password_hash, arginfo_password_hash)
+ PHP_FE(password_get_info, arginfo_password_get_info)
+ PHP_FE(password_needs_rehash, arginfo_password_needs_rehash)
+ PHP_FE(password_verify, arginfo_password_verify)
PHP_FE(convert_uuencode, arginfo_convert_uuencode)
PHP_FE(convert_uudecode, arginfo_convert_uudecode)
@@ -3043,6 +3062,7 @@ const zend_function_entry basic_functions[] = { /* {{{ */
PHP_FE(floatval, arginfo_floatval)
PHP_FALIAS(doubleval, floatval, arginfo_floatval)
PHP_FE(strval, arginfo_strval)
+ PHP_FE(boolval, arginfo_boolval)
PHP_FE(gettype, arginfo_gettype)
PHP_FE(settype, arginfo_settype)
PHP_FE(is_null, arginfo_is_null)
@@ -3309,6 +3329,7 @@ const zend_function_entry basic_functions[] = { /* {{{ */
PHP_FE(array_keys, arginfo_array_keys)
PHP_FE(array_values, arginfo_array_values)
PHP_FE(array_count_values, arginfo_array_count_values)
+ PHP_FE(array_column, arginfo_array_column)
PHP_FE(array_reverse, arginfo_array_reverse)
PHP_FE(array_reduce, arginfo_array_reduce)
PHP_FE(array_pad, arginfo_array_pad)
@@ -3513,6 +3534,34 @@ PHPAPI double php_get_inf(void) /* {{{ */
}
/* }}} */
+#define BASIC_MINIT_SUBMODULE(module) \
+ if (PHP_MINIT(module)(INIT_FUNC_ARGS_PASSTHRU) == SUCCESS) {\
+ BASIC_ADD_SUBMODULE(module); \
+ }
+
+#define BASIC_ADD_SUBMODULE(module) \
+ zend_hash_add_empty_element(&basic_submodules, #module, strlen(#module));
+
+#define BASIC_RINIT_SUBMODULE(module) \
+ if (zend_hash_exists(&basic_submodules, #module, strlen(#module))) { \
+ PHP_RINIT(module)(INIT_FUNC_ARGS_PASSTHRU); \
+ }
+
+#define BASIC_MINFO_SUBMODULE(module) \
+ if (zend_hash_exists(&basic_submodules, #module, strlen(#module))) { \
+ PHP_MINFO(module)(ZEND_MODULE_INFO_FUNC_ARGS_PASSTHRU); \
+ }
+
+#define BASIC_RSHUTDOWN_SUBMODULE(module) \
+ if (zend_hash_exists(&basic_submodules, #module, strlen(#module))) { \
+ PHP_RSHUTDOWN(module)(SHUTDOWN_FUNC_ARGS_PASSTHRU); \
+ }
+
+#define BASIC_MSHUTDOWN_SUBMODULE(module) \
+ if (zend_hash_exists(&basic_submodules, #module, strlen(#module))) { \
+ PHP_MSHUTDOWN(module)(SHUTDOWN_FUNC_ARGS_PASSTHRU); \
+ }
+
PHP_MINIT_FUNCTION(basic) /* {{{ */
{
#ifdef ZTS
@@ -3527,6 +3576,8 @@ PHP_MINIT_FUNCTION(basic) /* {{{ */
#endif
#endif
+ zend_hash_init(&basic_submodules, 0, NULL, NULL, 1);
+
BG(incomplete_class) = incomplete_class_entry = php_create_incomplete_class(TSRMLS_C);
REGISTER_LONG_CONSTANT("CONNECTION_ABORTED", PHP_CONNECTION_ABORTED, CONST_CS | CONST_PERSISTENT);
@@ -3586,39 +3637,43 @@ PHP_MINIT_FUNCTION(basic) /* {{{ */
register_html_constants(INIT_FUNC_ARGS_PASSTHRU);
register_string_constants(INIT_FUNC_ARGS_PASSTHRU);
- PHP_MINIT(file)(INIT_FUNC_ARGS_PASSTHRU);
- PHP_MINIT(pack)(INIT_FUNC_ARGS_PASSTHRU);
- PHP_MINIT(browscap)(INIT_FUNC_ARGS_PASSTHRU);
- PHP_MINIT(standard_filters)(INIT_FUNC_ARGS_PASSTHRU);
- PHP_MINIT(user_filters)(INIT_FUNC_ARGS_PASSTHRU);
+ BASIC_ADD_SUBMODULE(dl)
+ BASIC_ADD_SUBMODULE(mail)
+ BASIC_ADD_SUBMODULE(streams)
+ BASIC_MINIT_SUBMODULE(file)
+ BASIC_MINIT_SUBMODULE(pack)
+ BASIC_MINIT_SUBMODULE(browscap)
+ BASIC_MINIT_SUBMODULE(standard_filters)
+ BASIC_MINIT_SUBMODULE(user_filters)
+ BASIC_MINIT_SUBMODULE(password)
#if defined(HAVE_LOCALECONV) && defined(ZTS)
- PHP_MINIT(localeconv)(INIT_FUNC_ARGS_PASSTHRU);
+ BASIC_MINIT_SUBMODULE(localeconv)
#endif
#if defined(HAVE_NL_LANGINFO)
- PHP_MINIT(nl_langinfo)(INIT_FUNC_ARGS_PASSTHRU);
+ BASIC_MINIT_SUBMODULE(nl_langinfo)
#endif
#if HAVE_CRYPT
- PHP_MINIT(crypt)(INIT_FUNC_ARGS_PASSTHRU);
+ BASIC_MINIT_SUBMODULE(crypt)
#endif
- PHP_MINIT(lcg)(INIT_FUNC_ARGS_PASSTHRU);
+ BASIC_MINIT_SUBMODULE(lcg)
- PHP_MINIT(dir)(INIT_FUNC_ARGS_PASSTHRU);
+ BASIC_MINIT_SUBMODULE(dir)
#ifdef HAVE_SYSLOG_H
- PHP_MINIT(syslog)(INIT_FUNC_ARGS_PASSTHRU);
+ BASIC_MINIT_SUBMODULE(syslog)
#endif
- PHP_MINIT(array)(INIT_FUNC_ARGS_PASSTHRU);
- PHP_MINIT(assert)(INIT_FUNC_ARGS_PASSTHRU);
- PHP_MINIT(url_scanner_ex)(INIT_FUNC_ARGS_PASSTHRU);
+ BASIC_MINIT_SUBMODULE(array)
+ BASIC_MINIT_SUBMODULE(assert)
+ BASIC_MINIT_SUBMODULE(url_scanner_ex)
#ifdef PHP_CAN_SUPPORT_PROC_OPEN
- PHP_MINIT(proc_open)(INIT_FUNC_ARGS_PASSTHRU);
+ BASIC_MINIT_SUBMODULE(proc_open)
#endif
- PHP_MINIT(user_streams)(INIT_FUNC_ARGS_PASSTHRU);
- PHP_MINIT(imagetypes)(INIT_FUNC_ARGS_PASSTHRU);
+ BASIC_MINIT_SUBMODULE(user_streams)
+ BASIC_MINIT_SUBMODULE(imagetypes)
php_register_url_stream_wrapper("php", &php_stream_php_wrapper TSRMLS_CC);
php_register_url_stream_wrapper("file", &php_plain_files_wrapper TSRMLS_CC);
@@ -3626,14 +3681,12 @@ PHP_MINIT_FUNCTION(basic) /* {{{ */
php_register_url_stream_wrapper("glob", &php_glob_stream_wrapper TSRMLS_CC);
#endif
php_register_url_stream_wrapper("data", &php_stream_rfc2397_wrapper TSRMLS_CC);
-#ifndef PHP_CURL_URL_WRAPPERS
php_register_url_stream_wrapper("http", &php_stream_http_wrapper TSRMLS_CC);
php_register_url_stream_wrapper("ftp", &php_stream_ftp_wrapper TSRMLS_CC);
-#endif
#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);
+ BASIC_MINIT_SUBMODULE(dns)
# endif
#endif
@@ -3659,24 +3712,23 @@ PHP_MSHUTDOWN_FUNCTION(basic) /* {{{ */
#endif
php_unregister_url_stream_wrapper("php" TSRMLS_CC);
-#ifndef PHP_CURL_URL_WRAPPERS
php_unregister_url_stream_wrapper("http" TSRMLS_CC);
php_unregister_url_stream_wrapper("ftp" TSRMLS_CC);
-#endif
- PHP_MSHUTDOWN(browscap)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
- PHP_MSHUTDOWN(array)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
- PHP_MSHUTDOWN(assert)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
- PHP_MSHUTDOWN(url_scanner_ex)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
- PHP_MSHUTDOWN(file)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
- PHP_MSHUTDOWN(standard_filters)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
+ BASIC_MSHUTDOWN_SUBMODULE(browscap)
+ BASIC_MSHUTDOWN_SUBMODULE(array)
+ BASIC_MSHUTDOWN_SUBMODULE(assert)
+ BASIC_MSHUTDOWN_SUBMODULE(url_scanner_ex)
+ BASIC_MSHUTDOWN_SUBMODULE(file)
+ BASIC_MSHUTDOWN_SUBMODULE(standard_filters)
#if defined(HAVE_LOCALECONV) && defined(ZTS)
- PHP_MSHUTDOWN(localeconv)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
+ BASIC_MSHUTDOWN_SUBMODULE(localeconv)
#endif
#if HAVE_CRYPT
- PHP_MSHUTDOWN(crypt)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
+ BASIC_MSHUTDOWN_SUBMODULE(crypt)
#endif
+ zend_hash_destroy(&basic_submodules);
return SUCCESS;
}
/* }}} */
@@ -3710,10 +3762,10 @@ PHP_RINIT_FUNCTION(basic) /* {{{ */
PHP_RINIT(filestat)(INIT_FUNC_ARGS_PASSTHRU);
#ifdef HAVE_SYSLOG_H
- PHP_RINIT(syslog)(INIT_FUNC_ARGS_PASSTHRU);
+ BASIC_RINIT_SUBMODULE(syslog)
#endif
- PHP_RINIT(dir)(INIT_FUNC_ARGS_PASSTHRU);
- PHP_RINIT(url_scanner_ex)(INIT_FUNC_ARGS_PASSTHRU);
+ BASIC_RINIT_SUBMODULE(dir)
+ BASIC_RINIT_SUBMODULE(url_scanner_ex)
/* Setup default context */
FG(default_context) = NULL;
@@ -3759,14 +3811,14 @@ PHP_RSHUTDOWN_FUNCTION(basic) /* {{{ */
PHP_RSHUTDOWN(filestat)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
#ifdef HAVE_SYSLOG_H
#ifdef PHP_WIN32
- PHP_RSHUTDOWN(syslog)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
+ BASIC_RSHUTDOWN_SUBMODULE(syslog)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
#endif
#endif
- PHP_RSHUTDOWN(assert)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
- PHP_RSHUTDOWN(url_scanner_ex)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
- PHP_RSHUTDOWN(streams)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
+ BASIC_RSHUTDOWN_SUBMODULE(assert)
+ BASIC_RSHUTDOWN_SUBMODULE(url_scanner_ex)
+ BASIC_RSHUTDOWN_SUBMODULE(streams)
#ifdef PHP_WIN32
- PHP_RSHUTDOWN(win32_core_globals)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
+ BASIC_RSHUTDOWN_SUBMODULE(win32_core_globals)
#endif
if (BG(user_tick_functions)) {
@@ -3775,8 +3827,8 @@ PHP_RSHUTDOWN_FUNCTION(basic) /* {{{ */
BG(user_tick_functions) = NULL;
}
- PHP_RSHUTDOWN(user_filters)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
- PHP_RSHUTDOWN(browscap)(SHUTDOWN_FUNC_ARGS_PASSTHRU);
+ BASIC_RSHUTDOWN_SUBMODULE(user_filters)
+ BASIC_RSHUTDOWN_SUBMODULE(browscap)
BG(page_uid) = -1;
BG(page_gid) = -1;
@@ -3787,10 +3839,10 @@ PHP_RSHUTDOWN_FUNCTION(basic) /* {{{ */
PHP_MINFO_FUNCTION(basic) /* {{{ */
{
php_info_print_table_start();
- PHP_MINFO(dl)(ZEND_MODULE_INFO_FUNC_ARGS_PASSTHRU);
- PHP_MINFO(mail)(ZEND_MODULE_INFO_FUNC_ARGS_PASSTHRU);
+ BASIC_MINFO_SUBMODULE(dl)
+ BASIC_MINFO_SUBMODULE(mail)
php_info_print_table_end();
- PHP_MINFO(assert)(ZEND_MODULE_INFO_FUNC_ARGS_PASSTHRU);
+ BASIC_MINFO_SUBMODULE(assert)
}
/* }}} */
@@ -5056,12 +5108,12 @@ void php_free_shutdown_functions(TSRMLS_D) /* {{{ */
}
/* }}} */
-/* {{{ proto void register_shutdown_function(string function_name) U
+/* {{{ proto void register_shutdown_function(callback function) U
Register a user-level function to be called on request termination */
PHP_FUNCTION(register_shutdown_function)
{
php_shutdown_function_entry shutdown_function_entry;
- char *function_name = NULL;
+ char *callback_name = NULL;
int i;
shutdown_function_entry.arg_count = ZEND_NUM_ARGS();
@@ -5078,8 +5130,8 @@ PHP_FUNCTION(register_shutdown_function)
}
/* Prevent entering of anything but valid callback (syntax check only!) */
- if (!zend_is_callable(shutdown_function_entry.arguments[0], 0, &function_name TSRMLS_CC)) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid shutdown callback '%s' passed", function_name);
+ if (!zend_is_callable(shutdown_function_entry.arguments[0], 0, &callback_name TSRMLS_CC)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid shutdown callback '%s' passed", callback_name);
efree(shutdown_function_entry.arguments);
RETVAL_FALSE;
} else {
@@ -5093,8 +5145,8 @@ PHP_FUNCTION(register_shutdown_function)
}
zend_hash_next_index_insert(BG(user_shutdown_function_names), &shutdown_function_entry, sizeof(php_shutdown_function_entry), NULL);
}
- if (function_name) {
- efree(function_name);
+ if (callback_name) {
+ efree(callback_name);
}
}
/* }}} */
diff --git a/ext/standard/config.m4 b/ext/standard/config.m4
index c1f5aff7c2..3d00d88dda 100644
--- a/ext/standard/config.m4
+++ b/ext/standard/config.m4
@@ -182,12 +182,12 @@ AC_TRY_RUN([
main() {
#if HAVE_CRYPT
- char salt[30], answer[80];
-
- salt[0]='$'; salt[1]='6'; salt[2]='$'; salt[3]='$'; salt[4]='b'; salt[5]='a'; salt[6]='r'; salt[7]='\0';
+ char salt[21], answer[21+86];
+
+ strcpy(salt,"\$6\$rasmuslerdorf\$");
strcpy(answer, salt);
- strcpy(&answer[29],"$6$$QMXjqd7rHQZPQ1yHsXkQqC1FBzDiVfTHXL.LaeDAeVV.IzMaV9VU4MQ8kPuZa2SOP1A0RPm772EaFYjpEJtdu.");
- exit (strcmp((char *)crypt("foo",salt),answer));
+ strcat(answer, "EeHCRjm0bljalWuALHSTs1NB9ipEiLEXLhYeXdOpx22gmlmVejnVXFhd84cEKbYxCo.XuUTrW.RLraeEnsvWs/");
+ exit (strcmp((char *)crypt("rasmuslerdorf",salt),answer));
#else
exit(0);
#endif
@@ -211,12 +211,13 @@ AC_TRY_RUN([
main() {
#if HAVE_CRYPT
- char salt[30], answer[80];
- salt[0]='$'; salt[1]='5'; salt[2]='$'; salt[3]='$'; salt[4]='s'; salt[5]='a'; salt[6]='l'; salt[7]='t'; salt[8]='s'; salt[9]='t'; salt[10]='r'; salt[11]='i'; salt[12]='n'; salt[13]='g'; salt[14]='\0';
- strcat(salt,"");
+ char salt[21], answer[21+43];
+
+ strcpy(salt,"\$5\$rasmuslerdorf\$");
strcpy(answer, salt);
- strcpy(&answer[29], "$5$saltstring$5B8vYYiY.CVt1RlTTf8KbXBH3hsxY/GNooZaBBGWEc5");
- exit (strcmp((char *)crypt("foo",salt),answer));
+ strcat(answer, "cFAm2puLCujQ9t.0CxiFIIvFi4JyQx5UncCt/xRIX23");
+ exit (strcmp((char *)crypt("rasmuslerdorf",salt),answer));
+
#else
exit(0);
#endif
@@ -602,7 +603,7 @@ PHP_NEW_EXTENSION(standard, array.c base64.c basic_functions.c browscap.c crc32.
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 \
- filters.c proc_open.c streamsfuncs.c http.c)
+ filters.c proc_open.c streamsfuncs.c http.c password.c)
PHP_ADD_MAKEFILE_FRAGMENT
PHP_INSTALL_HEADERS([ext/standard/])
diff --git a/ext/standard/config.w32 b/ext/standard/config.w32
index d14b859e9d..5f24641b4d 100644
--- a/ext/standard/config.w32
+++ b/ext/standard/config.w32
@@ -19,7 +19,7 @@ EXTENSION("standard", "array.c base64.c basic_functions.c browscap.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 filters.c proc_open.c \
+ user_filters.c uuencode.c filters.c proc_open.c password.c \
streamsfuncs.c http.c flock_compat.c", false /* never shared */);
PHP_INSTALL_HEADERS("", "ext/standard");
if (PHP_MBREGEX != "no") {
diff --git a/ext/standard/credits.c b/ext/standard/credits.c
index 0e9f3989ae..006c2d4c1a 100644
--- a/ext/standard/credits.c
+++ b/ext/standard/credits.c
@@ -105,7 +105,7 @@ PHPAPI void php_print_credits(int flag TSRMLS_DC) /* {{{ */
if (flag & PHP_CREDITS_QA) {
php_info_print_table_start();
php_info_print_table_header(1, "PHP Quality Assurance Team");
- php_info_print_table_row(1, "Ilia Alshanetsky, Joerg Behrens, Antony Dovgal, Stefan Esser, Moriyoshi Koizumi, Magnus Maatta, Sebastian Nohn, Derick Rethans, Melvyn Sopacua, Jani Taskinen, Pierre-Alain Joye, Dmitry Stogov, Felipe Pena");
+ php_info_print_table_row(1, "Ilia Alshanetsky, Joerg Behrens, Antony Dovgal, Stefan Esser, Moriyoshi Koizumi, Magnus Maatta, Sebastian Nohn, Derick Rethans, Melvyn Sopacua, Jani Taskinen, Pierre-Alain Joye, Dmitry Stogov, Felipe Pena, David Soria Parra");
php_info_print_table_end();
}
diff --git a/ext/standard/credits_ext.h b/ext/standard/credits_ext.h
index 7bdb41e608..1d652857eb 100644
--- a/ext/standard/credits_ext.h
+++ b/ext/standard/credits_ext.h
@@ -41,13 +41,13 @@ CREDIT_LINE("mcrypt", "Sascha Schumann, Derick Rethans");
CREDIT_LINE("MS SQL", "Frank M. Kromann");
CREDIT_LINE("Multibyte String Functions", "Tsukada Takuya, Rui Hirokawa");
CREDIT_LINE("MySQL driver for PDO", "George Schlossnagle, Wez Furlong, Ilia Alshanetsky, Johannes Schlueter");
-CREDIT_LINE("MySQL", "Zeev Suraski, Zak Greant, Georg Richter");
+CREDIT_LINE("MySQL", "Zeev Suraski, Zak Greant, Georg Richter, Andrey Hristov");
CREDIT_LINE("MySQLi", "Zak Greant, Georg Richter, Andrey Hristov, Ulf Wendel");
-CREDIT_LINE("MySQLnd", "Andrey Hristov, Ulf Wendel, Georg Richter");
+CREDIT_LINE("MySQLnd", "Andrey Hristov, Ulf Wendel, Georg Richter, Johannes Schlüter");
CREDIT_LINE("OCI8", "Stig Bakken, Thies C. Arntzen, Andy Sautins, David Benson, Maxim Maletsky, Harald Radi, Antony Dovgal, Andi Gutmans, Wez Furlong, Christopher Jones, Oracle Corporation");
CREDIT_LINE("ODBC driver for PDO", "Wez Furlong");
CREDIT_LINE("ODBC", "Stig Bakken, Andreas Karajannis, Frank M. Kromann, Daniel R. Kalowsky");
-CREDIT_LINE("OpenSSL", "Stig Venaas, Wez Furlong, Sascha Kettler");
+CREDIT_LINE("OpenSSL", "Stig Venaas, Wez Furlong, Sascha Kettler, Scott MacVicar");
CREDIT_LINE("Oracle (OCI) driver for PDO", "Wez Furlong");
CREDIT_LINE("pcntl", "Jason Greene, Arnaud Le Blanc");
CREDIT_LINE("Perl Compatible Regexps", "Andrei Zmievski");
diff --git a/ext/standard/crypt.c b/ext/standard/crypt.c
index b0d17153f2..8750378b53 100644
--- a/ext/standard/crypt.c
+++ b/ext/standard/crypt.c
@@ -145,44 +145,9 @@ static void php_to64(char *s, long v, int n) /* {{{ */
}
/* }}} */
-/* {{{ proto string crypt(string str [, string salt])
- Hash a string */
-PHP_FUNCTION(crypt)
+PHPAPI int php_crypt(const char *password, const int pass_len, const char *salt, int salt_len, char **result)
{
- char salt[PHP_MAX_SALT_LEN + 1];
- char *str, *salt_in = NULL;
- int str_len, salt_in_len = 0;
char *crypt_res;
- salt[0] = salt[PHP_MAX_SALT_LEN] = '\0';
-
- /* This will produce suitable results if people depend on DES-encryption
- * available (passing always 2-character salt). At least for glibc6.1 */
- memset(&salt[1], '$', PHP_MAX_SALT_LEN - 1);
-
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &str, &str_len, &salt_in, &salt_in_len) == FAILURE) {
- return;
- }
-
- if (salt_in) {
- memcpy(salt, salt_in, MIN(PHP_MAX_SALT_LEN, salt_in_len));
- }
-
- /* The automatic salt generation covers standard DES, md5-crypt and Blowfish (simple) */
- if (!*salt) {
-#if PHP_MD5_CRYPT
- strncpy(salt, "$1$", PHP_MAX_SALT_LEN);
- php_to64(&salt[3], PHP_CRYPT_RAND, 4);
- php_to64(&salt[7], PHP_CRYPT_RAND, 4);
- strncpy(&salt[11], "$", PHP_MAX_SALT_LEN - 11);
-#elif PHP_STD_DES_CRYPT
- php_to64(&salt[0], PHP_CRYPT_RAND, 2);
- salt[2] = '\0';
-#endif
- salt_in_len = strlen(salt);
- } else {
- salt_in_len = MIN(PHP_MAX_SALT_LEN, salt_in_len);
- }
-
/* Windows (win32/crypt) has a stripped down version of libxcrypt and
a CryptoApi md5_crypt implementation */
#if PHP_USE_PHP_CRYPT_R
@@ -190,55 +155,44 @@ PHP_FUNCTION(crypt)
struct php_crypt_extended_data buffer;
if (salt[0]=='$' && salt[1]=='1' && salt[2]=='$') {
- char output[MD5_HASH_MAX_LEN];
+ char output[MD5_HASH_MAX_LEN], *out;
- RETURN_STRING(php_md5_crypt_r(str, salt, output), 1);
+ out = php_md5_crypt_r(password, salt, output);
+ if (out) {
+ *result = estrdup(out);
+ return SUCCESS;
+ }
+ return FAILURE;
} else if (salt[0]=='$' && salt[1]=='6' && salt[2]=='$') {
- const char sha512_salt_prefix[] = "$6$";
- const char sha512_rounds_prefix[] = "rounds=";
char *output;
- int needed = (sizeof(sha512_salt_prefix) - 1
- + sizeof(sha512_rounds_prefix) + 9 + 1
- + salt_in_len + 1 + 86 + 1);
- output = emalloc(needed);
- salt[salt_in_len] = '\0';
+ output = emalloc(PHP_MAX_SALT_LEN);
- crypt_res = php_sha512_crypt_r(str, salt, output, needed);
+ crypt_res = php_sha512_crypt_r(password, salt, output, PHP_MAX_SALT_LEN);
if (!crypt_res) {
- if (salt[0]=='*' && salt[1]=='0') {
- RETVAL_STRING("*1", 1);
- } else {
- RETVAL_STRING("*0", 1);
- }
+ memset(output, 0, PHP_MAX_SALT_LEN);
+ efree(output);
+ return FAILURE;
} else {
- RETVAL_STRING(output, 1);
+ *result = estrdup(output);
+ memset(output, 0, PHP_MAX_SALT_LEN);
+ efree(output);
+ return SUCCESS;
}
-
- memset(output, 0, needed);
- efree(output);
} else if (salt[0]=='$' && salt[1]=='5' && salt[2]=='$') {
- const char sha256_salt_prefix[] = "$5$";
- const char sha256_rounds_prefix[] = "rounds=";
char *output;
- int needed = (sizeof(sha256_salt_prefix) - 1
- + sizeof(sha256_rounds_prefix) + 9 + 1
- + salt_in_len + 1 + 43 + 1);
- output = emalloc(needed);
- salt[salt_in_len] = '\0';
+ output = emalloc(PHP_MAX_SALT_LEN);
- crypt_res = php_sha256_crypt_r(str, salt, output, needed);
+ crypt_res = php_sha256_crypt_r(password, salt, output, PHP_MAX_SALT_LEN);
if (!crypt_res) {
- if (salt[0]=='*' && salt[1]=='0') {
- RETVAL_STRING("*1", 1);
- } else {
- RETVAL_STRING("*0", 1);
- }
+ memset(output, 0, PHP_MAX_SALT_LEN);
+ efree(output);
+ return FAILURE;
} else {
- RETVAL_STRING(output, 1);
+ *result = estrdup(output);
+ memset(output, 0, PHP_MAX_SALT_LEN);
+ efree(output);
+ return SUCCESS;
}
-
- memset(output, 0, needed);
- efree(output);
} else if (
salt[0] == '$' &&
salt[1] == '2' &&
@@ -251,31 +205,25 @@ PHP_FUNCTION(crypt)
memset(output, 0, PHP_MAX_SALT_LEN + 1);
- crypt_res = php_crypt_blowfish_rn(str, salt, output, sizeof(output));
+ crypt_res = php_crypt_blowfish_rn(password, salt, output, sizeof(output));
if (!crypt_res) {
- if (salt[0]=='*' && salt[1]=='0') {
- RETVAL_STRING("*1", 1);
- } else {
- RETVAL_STRING("*0", 1);
- }
+ memset(output, 0, PHP_MAX_SALT_LEN + 1);
+ return FAILURE;
} else {
- RETVAL_STRING(output, 1);
+ *result = estrdup(output);
+ memset(output, 0, PHP_MAX_SALT_LEN + 1);
+ return SUCCESS;
}
-
- memset(output, 0, PHP_MAX_SALT_LEN + 1);
} else {
memset(&buffer, 0, sizeof(buffer));
_crypt_extended_init_r();
- crypt_res = _crypt_extended_r(str, salt, &buffer);
+ crypt_res = _crypt_extended_r(password, salt, &buffer);
if (!crypt_res) {
- if (salt[0]=='*' && salt[1]=='0') {
- RETURN_STRING("*1", 1);
- } else {
- RETURN_STRING("*0", 1);
- }
+ return FAILURE;
} else {
- RETURN_STRING(crypt_res, 1);
+ *result = estrdup(crypt_res);
+ return SUCCESS;
}
}
}
@@ -291,21 +239,68 @@ PHP_FUNCTION(crypt)
# else
# error Data struct used by crypt_r() is unknown. Please report.
# endif
- crypt_res = crypt_r(str, salt, &buffer);
+ crypt_res = crypt_r(password, salt, &buffer);
if (!crypt_res) {
- if (salt[0]=='*' && salt[1]=='0') {
- RETURN_STRING("*1", 1);
- } else {
- RETURN_STRING("*0", 1);
- }
+ return FAILURE;
} else {
- RETURN_STRING(crypt_res, 1);
+ *result = estrdup(crypt_res);
+ return SUCCESS;
}
}
# endif
#endif
}
/* }}} */
+
+
+/* {{{ proto string crypt(string str [, string salt])
+ Hash a string */
+PHP_FUNCTION(crypt)
+{
+ char salt[PHP_MAX_SALT_LEN + 1];
+ char *str, *salt_in = NULL, *result = NULL;
+ int str_len, salt_in_len = 0;
+ salt[0] = salt[PHP_MAX_SALT_LEN] = '\0';
+
+ /* This will produce suitable results if people depend on DES-encryption
+ * available (passing always 2-character salt). At least for glibc6.1 */
+ memset(&salt[1], '$', PHP_MAX_SALT_LEN - 1);
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &str, &str_len, &salt_in, &salt_in_len) == FAILURE) {
+ return;
+ }
+
+ if (salt_in) {
+ memcpy(salt, salt_in, MIN(PHP_MAX_SALT_LEN, salt_in_len));
+ }
+
+ /* The automatic salt generation covers standard DES, md5-crypt and Blowfish (simple) */
+ if (!*salt) {
+#if PHP_MD5_CRYPT
+ strncpy(salt, "$1$", PHP_MAX_SALT_LEN);
+ php_to64(&salt[3], PHP_CRYPT_RAND, 4);
+ php_to64(&salt[7], PHP_CRYPT_RAND, 4);
+ strncpy(&salt[11], "$", PHP_MAX_SALT_LEN - 11);
+#elif PHP_STD_DES_CRYPT
+ php_to64(&salt[0], PHP_CRYPT_RAND, 2);
+ salt[2] = '\0';
+#endif
+ salt_in_len = strlen(salt);
+ } else {
+ salt_in_len = MIN(PHP_MAX_SALT_LEN, salt_in_len);
+ }
+ salt[salt_in_len] = '\0';
+
+ if (php_crypt(str, str_len, salt, salt_in_len, &result) == FAILURE) {
+ if (salt[0] == '*' && salt[1] == '0') {
+ RETURN_STRING("*1", 1);
+ } else {
+ RETURN_STRING("*0", 1);
+ }
+ }
+ RETURN_STRING(result, 0);
+}
+/* }}} */
#endif
/*
diff --git a/ext/standard/dl.c b/ext/standard/dl.c
index 9bf3e443c9..012592381b 100644
--- a/ext/standard/dl.c
+++ b/ext/standard/dl.c
@@ -97,9 +97,9 @@ PHPAPI PHP_FUNCTION(dl)
#define USING_ZTS 0
#endif
-/* {{{ php_dl
+/* {{{ php_load_extension
*/
-PHPAPI int php_load_extension(char *filename, int type, int start_now TSRMLS_DC) /* {{{ */
+PHPAPI int php_load_extension(char *filename, int type, int start_now TSRMLS_DC)
{
void *handle;
char *libpath;
@@ -171,6 +171,11 @@ PHPAPI int php_load_extension(char *filename, int type, int start_now TSRMLS_DC)
}
if (!get_module) {
+ if (DL_FETCH_SYMBOL(handle, "zend_extension_entry") || DL_FETCH_SYMBOL(handle, "_zend_extension_entry")) {
+ DL_UNLOAD(handle);
+ php_error_docref(NULL TSRMLS_CC, error_type, "Invalid library (appears to be a Zend Extension, try loading using zend_extension=%s from php.ini)", filename);
+ return FAILURE;
+ }
DL_UNLOAD(handle);
php_error_docref(NULL TSRMLS_CC, error_type, "Invalid library (maybe not a PHP library) '%s'", filename);
return FAILURE;
diff --git a/ext/standard/file.c b/ext/standard/file.c
index c17e1f38e1..cae5428363 100644
--- a/ext/standard/file.c
+++ b/ext/standard/file.c
@@ -159,6 +159,7 @@ static ZEND_RSRC_DTOR_FUNC(file_context_dtor)
static void file_globals_ctor(php_file_globals *file_globals_p TSRMLS_DC)
{
FG(pclose_ret) = 0;
+ FG(pclose_wait) = 0;
FG(user_stream_current_filename) = NULL;
FG(def_chunk_size) = PHP_SOCK_CHUNK_SIZE;
FG(wrapper_errors) = NULL;
@@ -817,7 +818,7 @@ PHP_FUNCTION(tempnam)
if (p_len > 64) {
p[63] = '\0';
}
-
+
RETVAL_FALSE;
if ((fd = php_open_temporary_fd_ex(dir, p, &opened_path, 1 TSRMLS_CC)) >= 0) {
@@ -960,7 +961,9 @@ PHP_FUNCTION(pclose)
PHP_STREAM_TO_ZVAL(stream, &arg1);
+ FG(pclose_wait) = 1;
zend_list_delete(stream->rsrc_id);
+ FG(pclose_wait) = 0;
RETURN_LONG(FG(pclose_ret));
}
/* }}} */
@@ -1377,13 +1380,13 @@ PHP_FUNCTION(umask)
{
long arg1 = 0;
int oldumask;
-
+
oldumask = umask(077);
if (BG(umask) == -1) {
BG(umask) = oldumask;
}
-
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &arg1) == FAILURE) {
RETURN_FALSE;
}
@@ -1796,22 +1799,23 @@ quit_loop:
#define FPUTCSV_FLD_CHK(c) memchr(Z_STRVAL(field), c, Z_STRLEN(field))
-/* {{{ proto int fputcsv(resource fp, array fields [, string delimiter [, string enclosure]])
+/* {{{ proto int fputcsv(resource fp, array fields [, string delimiter [, string enclosure [, string escape_char]]])
Format line as CSV and write to file pointer */
PHP_FUNCTION(fputcsv)
{
- char delimiter = ','; /* allow this to be set as parameter */
- char enclosure = '"'; /* allow this to be set as parameter */
- const char escape_char = '\\';
+ char delimiter = ','; /* allow this to be set as parameter */
+ char enclosure = '"'; /* allow this to be set as parameter */
+ char escape_char = '\\'; /* allow this to be set as parameter */
php_stream *stream;
zval *fp = NULL, *fields = NULL;
int ret;
- char *delimiter_str = NULL, *enclosure_str = NULL;
- int delimiter_str_len = 0, enclosure_str_len = 0;
+ char *delimiter_str = NULL, *enclosure_str = NULL, *escape_str = NULL;
+ int delimiter_str_len = 0, enclosure_str_len = 0, escape_str_len = 0;
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra|ss",
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ra|sss",
&fp, &fields, &delimiter_str, &delimiter_str_len,
- &enclosure_str, &enclosure_str_len) == FAILURE) {
+ &enclosure_str, &enclosure_str_len,
+ &escape_str, &escape_str_len) == FAILURE) {
return;
}
@@ -1839,6 +1843,17 @@ PHP_FUNCTION(fputcsv)
enclosure = *enclosure_str;
}
+ if (escape_str != NULL) {
+ if (escape_str_len < 1) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "escape must be a character");
+ RETURN_FALSE;
+ } else if (escape_str_len > 1) {
+ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "escape must be a single character");
+ }
+ /* use first character from string */
+ escape_char = *escape_str;
+ }
+
PHP_STREAM_TO_ZVAL(stream, &fp);
ret = php_fputcsv(stream, fields, delimiter, enclosure, escape_char TSRMLS_CC);
@@ -2054,11 +2069,11 @@ PHPAPI void php_fgetcsv(php_stream *stream, char delimiter, char enclosure, char
char *tmp = bptr;
while ((*tmp != delimiter) && isspace((int)*(unsigned char *)tmp)) {
tmp++;
- }
+ }
if (*tmp == enclosure) {
bptr = tmp;
}
- }
+ }
if (first_field && bptr == line_end) {
add_next_index_null(return_value);
@@ -2445,7 +2460,7 @@ PHP_FUNCTION(sys_get_temp_dir)
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- RETURN_STRING((char *)php_get_temporary_directory(), 1);
+ RETURN_STRING((char *)php_get_temporary_directory(TSRMLS_C), 1);
}
/* }}} */
diff --git a/ext/standard/file.h b/ext/standard/file.h
index 933d49479c..d2b20bf928 100644
--- a/ext/standard/file.h
+++ b/ext/standard/file.h
@@ -115,7 +115,7 @@ typedef struct _php_meta_tags_data {
php_meta_tags_token php_next_meta_token(php_meta_tags_data * TSRMLS_DC);
typedef struct {
- int pclose_ret;
+ int pclose_ret;
size_t def_chunk_size;
long auto_detect_line_endings;
long default_socket_timeout;
@@ -126,6 +126,7 @@ typedef struct {
HashTable *stream_wrappers; /* per-request copy of url_stream_wrappers_hash */
HashTable *stream_filters; /* per-request copy of stream_filters_hash */
HashTable *wrapper_errors; /* key: wrapper address; value: linked list of char* */
+ int pclose_wait;
} php_file_globals;
#ifdef ZTS
diff --git a/ext/standard/filestat.c b/ext/standard/filestat.c
index 565888f312..3a95a9f9a4 100644
--- a/ext/standard/filestat.c
+++ b/ext/standard/filestat.c
@@ -803,7 +803,7 @@ PHP_FUNCTION(touch)
PHPAPI void php_clear_stat_cache(zend_bool clear_realpath_cache, const char *filename, int filename_len TSRMLS_DC)
{
/* always clear CurrentStatFile and CurrentLStatFile even if filename is not NULL
- * as it may contains outdated data (e.g. "nlink" for a directory when deleting a file
+ * as it may contain outdated data (e.g. "nlink" for a directory when deleting a file
* in this directory, as shown by lstat_stat_variation9.phpt) */
if (BG(CurrentStatFile)) {
efree(BG(CurrentStatFile));
diff --git a/ext/standard/head.c b/ext/standard/head.c
index ae64099fa1..eca032a97b 100644
--- a/ext/standard/head.c
+++ b/ext/standard/head.c
@@ -40,11 +40,11 @@ PHP_FUNCTION(header)
{
zend_bool rep = 1;
sapi_header_line ctr = {0};
-
+
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line,
&ctr.line_len, &rep, &ctr.response_code) == FAILURE)
return;
-
+
sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC);
}
/* }}} */
@@ -80,7 +80,7 @@ PHPAPI int php_setcookie(char *name, int name_len, char *value, int value_len, t
char *dt;
sapi_header_line ctr = {0};
int result;
-
+
if (name && strpbrk(name, "=,; \t\r\n\013\014") != NULL) { /* man isspace for \013 and \014 */
zend_error( E_WARNING, "Cookie names cannot contain any of the following '=,; \\t\\r\\n\\013\\014'" );
return FAILURE;
@@ -111,18 +111,19 @@ PHPAPI int php_setcookie(char *name, int name_len, char *value, int value_len, t
cookie = emalloc(len + 100);
if (value && value_len == 0) {
- /*
+ /*
* MSIE doesn't delete a cookie when you set it to a null value
* so in order to force cookies to be deleted, even on MSIE, we
* pick an expiry date in the past
*/
dt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, 1, 0 TSRMLS_CC);
- snprintf(cookie, len + 100, "Set-Cookie: %s=deleted; expires=%s", name, dt);
+ snprintf(cookie, len + 100, "Set-Cookie: %s=deleted; expires=%s; Max-Age=0", name, dt);
efree(dt);
} else {
snprintf(cookie, len + 100, "Set-Cookie: %s=%s", name, value ? encoded_value : "");
if (expires > 0) {
const char *p;
+ char tsdelta[13];
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 */
@@ -136,6 +137,10 @@ PHPAPI int php_setcookie(char *name, int name_len, char *value, int value_len, t
}
strlcat(cookie, dt, len + 100);
efree(dt);
+
+ snprintf(tsdelta, sizeof(tsdelta), "%li", (long) difftime(expires, time(NULL)));
+ strlcat(cookie, "; Max-Age=", len + 100);
+ strlcat(cookie, tsdelta, len + 100);
}
}
@@ -237,11 +242,11 @@ PHP_FUNCTION(headers_sent)
ZVAL_LONG(arg2, line);
case 1:
zval_dtor(arg1);
- if (file) {
+ if (file) {
ZVAL_STRING(arg1, file, 1);
} else {
ZVAL_STRING(arg1, "", 1);
- }
+ }
break;
}
diff --git a/ext/standard/http.c b/ext/standard/http.c
index 0b5aea314b..2b1c1390bd 100644
--- a/ext/standard/http.c
+++ b/ext/standard/http.c
@@ -56,7 +56,7 @@ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr,
arg_sep_len = strlen(arg_sep);
for (zend_hash_internal_pointer_reset(ht);
- (key_type = zend_hash_get_current_key_ex(ht, &key, &key_len, &idx, 0, NULL)) != HASH_KEY_NON_EXISTANT;
+ (key_type = zend_hash_get_current_key_ex(ht, &key, &key_len, &idx, 0, NULL)) != HASH_KEY_NON_EXISTENT;
zend_hash_move_forward(ht)
) {
if (key_type == HASH_KEY_IS_STRING && key_len && key[key_len-1] == '\0') {
@@ -69,12 +69,11 @@ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr,
const char *tmp;
zend_object *zobj = zend_objects_get_address(type TSRMLS_CC);
- if (zend_check_property_access(zobj, key, key_len-1 TSRMLS_CC) != SUCCESS) {
+ if (zend_check_property_access(zobj, key, key_len TSRMLS_CC) != SUCCESS) {
/* private or protected property access outside of the class */
continue;
}
- zend_unmangle_property_name(key, key_len-1, &tmp, (const char**)&key);
- key_len = strlen(key);
+ zend_unmangle_property_name_ex(key, key_len, &tmp, (const char**)&key, &key_len);
}
if (zend_hash_get_current_data_ex(ht, (void **)&zdata, NULL) == FAILURE || !zdata || !(*zdata)) {
diff --git a/ext/standard/incomplete_class.c b/ext/standard/incomplete_class.c
index 1816ac4605..968a5e2ebd 100644
--- a/ext/standard/incomplete_class.c
+++ b/ext/standard/incomplete_class.c
@@ -40,12 +40,12 @@ static void incomplete_class_message(zval *object, int error_type TSRMLS_DC)
zend_bool class_name_alloced = 1;
class_name = php_lookup_class_name(object, NULL);
-
+
if (!class_name) {
class_name_alloced = 0;
class_name = "unknown";
}
-
+
php_error_docref(NULL TSRMLS_CC, error_type, INCOMPLETE_CLASS_MSG, class_name);
if (class_name_alloced) {
@@ -57,7 +57,7 @@ static void incomplete_class_message(zval *object, int error_type TSRMLS_DC)
static zval *incomplete_class_get_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */
{
incomplete_class_message(object, E_NOTICE TSRMLS_CC);
-
+
if (type == BP_VAR_W || type == BP_VAR_RW) {
return EG(error_zval_ptr);
} else {
@@ -71,8 +71,8 @@ static void incomplete_class_write_property(zval *object, zval *member, zval *va
incomplete_class_message(object, E_NOTICE TSRMLS_CC);
}
/* }}} */
-
-static zval **incomplete_class_get_property_ptr_ptr(zval *object, zval *member, const zend_literal *key TSRMLS_DC) /* {{{ */
+
+static zval **incomplete_class_get_property_ptr_ptr(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */
{
incomplete_class_message(object, E_NOTICE TSRMLS_CC);
return &EG(error_zval_ptr);
@@ -105,12 +105,12 @@ static zend_object_value php_create_incomplete_object(zend_class_entry *class_ty
{
zend_object *object;
zend_object_value value;
-
+
value = zend_objects_new(&object, class_type TSRMLS_CC);
value.handlers = &php_incomplete_object_handlers;
-
+
object_properties_init(object, class_type);
-
+
return value;
}
@@ -128,7 +128,7 @@ PHPAPI zend_class_entry *php_create_incomplete_class(TSRMLS_D)
php_incomplete_object_handlers.write_property = incomplete_class_write_property;
php_incomplete_object_handlers.get_property_ptr_ptr = incomplete_class_get_property_ptr_ptr;
php_incomplete_object_handlers.get_method = incomplete_class_get_method;
-
+
return zend_register_internal_class(&incomplete_class TSRMLS_CC);
}
/* }}} */
diff --git a/ext/standard/info.c b/ext/standard/info.c
index 70b2e2f617..a4996b6bfc 100644
--- a/ext/standard/info.c
+++ b/ext/standard/info.c
@@ -92,14 +92,6 @@ static int php_info_printf(const char *fmt, ...) /* {{{ */
}
/* }}} */
-static void php_info_print_request_uri(TSRMLS_D) /* {{{ */
-{
- if (SG(request_info).request_uri) {
- php_info_print_html_esc(SG(request_info).request_uri, strlen(SG(request_info).request_uri));
- }
-}
-/* }}} */
-
static int php_info_print(const char *str) /* {{{ */
{
TSRMLS_FETCH();
@@ -328,7 +320,7 @@ char* php_get_windows_name()
}
if (VER_PLATFORM_WIN32_NT==osvi.dwPlatformId && osvi.dwMajorVersion > 4 ) {
- if (osvi.dwMajorVersion == 6) {
+ if (osvi.dwMajorVersion == 6) {
if( osvi.dwMinorVersion == 0 ) {
if( osvi.wProductType == VER_NT_WORKSTATION ) {
major = "Windows Vista";
@@ -342,6 +334,12 @@ char* php_get_windows_name()
} else {
major = "Windows Server 2008 R2";
}
+ } else if ( osvi.dwMinorVersion == 2 ) {
+ if( osvi.wProductType == VER_NT_WORKSTATION ) {
+ major = "Windows 8";
+ } else {
+ major = "Windows Server 2012";
+ }
} else {
major = "Unknown Windows version";
}
@@ -664,7 +662,6 @@ PHPAPI void php_print_info(int flag TSRMLS_DC)
{
char **env, *tmp1, *tmp2;
char *php_uname;
- int expose_php = INI_INT("expose_php");
if (!sapi_module.phpinfo_as_text) {
php_print_info_htmlhead(TSRMLS_C);
@@ -675,7 +672,6 @@ PHPAPI void php_print_info(int flag TSRMLS_DC)
if (flag & PHP_INFO_GENERAL) {
char *zend_version = get_zend_version();
char temp_api[10];
- char *logo_guid;
php_uname = php_get_uname('a');
@@ -683,14 +679,19 @@ PHPAPI void php_print_info(int flag TSRMLS_DC)
php_info_print_box_start(1);
}
- if (expose_php && !sapi_module.phpinfo_as_text) {
- php_info_print("<a href=\"http://www.php.net/\"><img border=\"0\" src=\"");
- php_info_print_request_uri(TSRMLS_C);
- php_info_print("?=");
- logo_guid = php_logo_guid();
- php_info_print(logo_guid);
- efree(logo_guid);
- php_info_print("\" alt=\"PHP Logo\" /></a>");
+ if (!sapi_module.phpinfo_as_text) {
+ time_t the_time;
+ struct tm *ta, tmbuf;
+
+ the_time = time(NULL);
+ ta = php_localtime_r(&the_time, &tmbuf);
+
+ php_info_print("<a href=\"http://www.php.net/\"><img border=\"0\" src=\"");
+ if (ta && (ta->tm_mon==3) && (ta->tm_mday==1)) {
+ php_info_print(PHP_EGG_LOGO_DATA_URI "\" alt=\"PHP logo\" /></a>");
+ } else {
+ php_info_print(PHP_LOGO_DATA_URI "\" alt=\"PHP logo\" /></a>");
+ }
}
if (!sapi_module.phpinfo_as_text) {
@@ -791,10 +792,9 @@ PHPAPI void php_print_info(int flag TSRMLS_DC)
/* Zend Engine */
php_info_print_box_start(0);
- if (expose_php && !sapi_module.phpinfo_as_text) {
+ if (!sapi_module.phpinfo_as_text) {
php_info_print("<a href=\"http://www.zend.com/\"><img border=\"0\" src=\"");
- php_info_print_request_uri(TSRMLS_C);
- php_info_print("?="ZEND_LOGO_GUID"\" alt=\"Zend logo\" /></a>\n");
+ php_info_print(ZEND_LOGO_DATA_URI "\" alt=\"Zend logo\" /></a>\n");
}
php_info_print("This program makes use of the Zend Scripting Language Engine:");
php_info_print(!sapi_module.phpinfo_as_text?"<br />":"\n");
@@ -807,15 +807,6 @@ PHPAPI void php_print_info(int flag TSRMLS_DC)
efree(php_uname);
}
- if ((flag & PHP_INFO_CREDITS) && expose_php && !sapi_module.phpinfo_as_text) {
- php_info_print_hr();
- php_info_print("<h1><a href=\"");
- php_info_print_request_uri(TSRMLS_C);
- php_info_print("?=PHPB8B5F2A0-3C92-11d3-A3A9-4C7B08C10000\">");
- php_info_print("PHP Credits");
- php_info_print("</a></h1>\n");
- }
-
zend_ini_sort_entries(TSRMLS_C);
if (flag & PHP_INFO_CONFIGURATION) {
@@ -897,6 +888,12 @@ PHPAPI void php_print_info(int flag TSRMLS_DC)
php_info_print_table_end();
}
+
+ if ((flag & PHP_INFO_CREDITS) && !sapi_module.phpinfo_as_text) {
+ php_info_print_hr();
+ php_print_credits(PHP_CREDITS_ALL & ~PHP_CREDITS_FULLPAGE TSRMLS_CC);
+ }
+
if (flag & PHP_INFO_LICENSE) {
if (!sapi_module.phpinfo_as_text) {
SECTION("PHP License");
@@ -930,6 +927,7 @@ PHPAPI void php_print_info(int flag TSRMLS_DC)
php_info_print("questions about PHP licensing, please contact license@php.net.\n");
}
}
+
if (!sapi_module.phpinfo_as_text) {
php_info_print("</div></body></html>");
}
@@ -1195,77 +1193,6 @@ PHP_FUNCTION(phpcredits)
}
/* }}} */
-/* {{{ php_logo_guid
- */
-PHPAPI char *php_logo_guid(void)
-{
- char *logo_guid;
-
- time_t the_time;
- struct tm *ta, tmbuf;
-
- the_time = time(NULL);
- ta = php_localtime_r(&the_time, &tmbuf);
-
- if (ta && (ta->tm_mon==3) && (ta->tm_mday==1)) {
- logo_guid = PHP_EGG_LOGO_GUID;
- } else {
- logo_guid = PHP_LOGO_GUID;
- }
-
- return estrdup(logo_guid);
-
-}
-/* }}} */
-
-/* {{{ proto string php_logo_guid(void)
- Return the special ID used to request the PHP logo in phpinfo screens*/
-PHP_FUNCTION(php_logo_guid)
-{
- if (zend_parse_parameters_none() == FAILURE) {
- return;
- }
-
- RETURN_STRING(php_logo_guid(), 0);
-}
-/* }}} */
-
-/* {{{ proto string php_real_logo_guid(void)
- Return the special ID used to request the PHP logo in phpinfo screens*/
-PHP_FUNCTION(php_real_logo_guid)
-{
- if (zend_parse_parameters_none() == FAILURE) {
- return;
- }
-
- RETURN_STRINGL(PHP_LOGO_GUID, sizeof(PHP_LOGO_GUID)-1, 1);
-}
-/* }}} */
-
-/* {{{ proto string php_egg_logo_guid(void)
- Return the special ID used to request the PHP logo in phpinfo screens*/
-PHP_FUNCTION(php_egg_logo_guid)
-{
- if (zend_parse_parameters_none() == FAILURE) {
- return;
- }
-
- RETURN_STRINGL(PHP_EGG_LOGO_GUID, sizeof(PHP_EGG_LOGO_GUID)-1, 1);
-}
-/* }}} */
-
-/* {{{ proto string zend_logo_guid(void)
- Return the special ID used to request the Zend logo in phpinfo screens*/
-PHP_FUNCTION(zend_logo_guid)
-{
- if (zend_parse_parameters_none() == FAILURE) {
- return;
- }
-
- RETURN_STRINGL(ZEND_LOGO_GUID, sizeof(ZEND_LOGO_GUID)-1, 1);
-}
-/* }}} */
-
/* {{{ proto string php_sapi_name(void)
Return the current SAPI module name */
PHP_FUNCTION(php_sapi_name)
diff --git a/ext/standard/info.h b/ext/standard/info.h
index 871542d3dc..631eb049f1 100644
--- a/ext/standard/info.h
+++ b/ext/standard/info.h
@@ -50,19 +50,14 @@
#endif /* HAVE_CREDITS_DEFS */
-#define PHP_LOGO_GUID "PHPE9568F34-D428-11d2-A769-00AA001ACF42"
-#define PHP_EGG_LOGO_GUID "PHPE9568F36-D428-11d2-A769-00AA001ACF42"
-#define ZEND_LOGO_GUID "PHPE9568F35-D428-11d2-A769-00AA001ACF42"
-#define PHP_CREDITS_GUID "PHPB8B5F2A0-3C92-11d3-A3A9-4C7B08C10000"
+#define PHP_LOGO_DATA_URI "data:image/gif;base64,R0lGODlheABDAOZqAH+CuDk3RyglKszN4qGky9PV57K01ENCWIOGuYKDs1JScpCSwsLE3qqs0ExLY1tcg93e7Ds4PG5xpWptnWFjjXV5sXt+teXm8JmcxoyNwbm62Wtrkk5Oa3F0qXp6o4iLvXJ0o3RzmI6QwVpbfuLj73t9raSl0G1wonJ2rJWWyLu92XR4roWIu5KVw9jZ6pKSxGRmkmtun6WozpSWxS4rL1NRaLO012xqjFxbdoqNv2ZolmhqmpyfyDEuOa6w05yczVVWeJ6hypaZxYGCr2dplz89ULy+2l5giZiZyIyOv4mKuldYfLa319XX6CIeIGxvns7Q5L/A3Hd7tHZ4p19efZmZzG5vmHN3riIeH////5COj1lWV8fGx+7u9dXU1fb2+oKAgayqq3Ryc/Hw8Z6cnePi40tISbm4uWdkZYmJtgD/AEdGX9/g7ZuczGlrnG9zp4yMuri52bi615qbzKeqz9vc65qcyWZkhGhniaeo0m5woIuLucbH4MfJ4WlsnJeYyyH5BAEAAGoALAAAAAB4AEMAAAf/gGqCg4SFhoeIiYqLjI2Oj5CRkpOUlZaXlm0/bXOYnp+gP3l5Nj4acUwaGkwGPj4NMgRBPBhCLQtJIjkfGTkiLymgwqENGgx9TQVQUAN9fAxRUSpyrK90sbNCMy26HwgAFhYVVyglFgkZwcPrjCZxfC5sbBAQdS7JA9QysyIf/iwAEQgEQLDgN4LhpKxA8UbCCT87nkwZkoSdRTVBbAxgQ+KCRxIk8jUQskCKyZMoU6pceXJcBwkTduiAQeEIBStDRFzEFIQJFI4eL7gwQqcFy6NIk6K88iYGjCNHHoxYcsSDzp2Qfmh0AYEjBCMEWCgdSzbplRM6HiwBokDBiCkz/7AuMqGhQBMXdQoYSFK2r1+kHWAsUcCBgwM8CeQayhNlAJQCA3zk+LtyAYbLmDF8oJz0DQUFDtasUeBBsZo8Rvj0GcBkBueVH7JwmU2bS5fXSt0sWXPggIMQO91FYcCgAQLcKzFwwcK8uZnbyJN22F2kyJrSw374kGNEBQ8L0VeqINO8uZgC4ZVeeXAgQAAOcECZMMBEDgEA6VcWEFOeORkV+Sn1hgLu9XAHJnPQ4YMBMhwXoEpdmNEfFlwQ8KBSMazRQw8H7FHJDzI00EBJF6YEQBYTYpHFZiUm9UAAGwInSRsE7ONgiycpN6EZX+ColB9F0EADFZHYEQQBM4CH1P8HmTXZJItHqRDGhGJc0CSJLDHp5Jb4jYWCAzQIUMMjSGAQBJRHffBFFmy26eabWXRRQANdolQAGBOSAWebFwxg4UkL7Ckom10M0IBSQAgggAONzCAEBmIpRcByKVZqBhhcfAEgSl1sUWmKNGyhRRldkGjAlJ9OuAUYXnRxKFIjCOAEo4psI8SNSY2X6qdbeAFBlyfu+ikYY2AgxQB4CqtqGQMkNYITTuCQSAoitIBmUhDwp2yKYUBgEgZebJsiGrdd4Km45dHgRbNIrQEtdoX84ctkZX0hIbr9eQGglPjm2wCK/TZHQxl/HhWAEwIsYEg/9JIVW8DlbdHjnRAzp8X/BeFWjIUY0B3VgaxjEpICAh/UOdakO8I5xhnaTugFAZ1OyMWbY3CBRopaZIFqxHCWcca5E5aBJUsKQJsGId7gOpau/YnhLUoLNNAFeRNqwQDA/a2IEgYNfBFB1VloUTW7gBrwRbL9hWGAUjTMOsgfACCgZFnZ5rmpiVl83XQWGZfH40oQAN1czoIzd8baKn0wBs53H7UEtAqrIYIFJpNlr8wFpxS4qjpT+XRKMfd3RhY0BG3sSqGXp0XjLHUA7Q2CsJBQXw9POMa1J23eHxpZoN3cfyoFG3QZE9KQxVGpD846S0W4rUY4c5OFcn8R9MjS5f0RjrlK4BafxRmqXnAU/9blAa8UB070IEgFlDFdHhqfp1R72uQ3d7tK/Pa3Rdhjs4QB8dtTCgWgJYgVUKZu2VueSQwAvqD1rTnV04/vmAOGLBQOC4djCQOo1p/7CZCAKbgC+/yCvfJUiCXJY04EOre7+J0khVgIA+lMtxIAeG1C5CLLAJ0gCBQYsC/C6yDujkWp7PWuassLYnm8AMB0HU8/HCxPGBS4kh0KogMoGCFZdES9J6LkAwXwQun6Q4MxfOGCJ0xJ9yb0vfBxDwJinFD1KncUK6phIVpcWhSZQy4V+FEFEOjCGLQwRtENoH7M8SBK8sczsWWvC38EZBfK4EiZUXEl6FPf8zpwhb7sR/9VWghlKMVwrxSJ4QsEeKAKvWinCWKhghcUlSi1QMphia8szaPVB97Qgb5ESGNo+MICToVDF5rEXBOSYSEDdsqhSed1gkiBBN7wQ6UosV/NPJYrrbYSRGKBiRoDgzD78jgnRO55EujlWNbYLxqcYZxSQGZ/uPCqramSOW0MWATOcAFnss15gnjBCSTQSaUwUlxmIMMYBlCnGXbQn8TUH//wZQYZMoCOSSmaE45GiCGc4A1joZj+ZjlLMnBhDIVCU6BIGkpWnkQFXGDp6C4oBpaG0qQoZcAQpQMyQ6TgBCdQJ1JgyIUL0IMeBfgjAfxpEkAe9aiZA9QAnkqPQy6TOV7/MOpRk+pHAux0LAdL2CGSEIMToAAp10wkU30khQU0sTxZwChy3OUEeBkiAWUtaHLuuUK2sqQBDYxYx/JTTmkpogR5ZclB+WhMv0qBAZVsDhjQE6By0moRiDWrBKvGAMeqRHdSvCRlNHpZRpRgAjHoQB6lQNR6etYkeXPZ6aLTgQNAq7SNSABqJaDFtGJhDGv10QIWx0a5+oUIPYCWYSOhhCdMQLNS+N8Wpktd3r3WntSlLhgG+xoFyEoAMprEC0DghxjwFgAFoCo9EHddKaBXvRBwLWWIcDAnRICjlkiAG1D7htW2168nsK1yQfGCKfgBtar9r19RwAFZOaEI+AWF/xL04IYD91fBJTrBGhzcg/CygwUUPrAEzorh8BzhAIoSQA9gpxgWgGAHbnBDDKhZYsr4gQMBCJMAAsBi0wgiCSUgwg5gPAEa1zgpEyBQD4QkJrv6eBApSIAedEAEIbshqP7F8BuOgOMNLbkIeHjBkxfxAinr4Mxn3sFHSXzdHRxBAe2B0YYOcAMPjfkRL0DAFIgAgz77mQh++KhQ8zMBIjwANNVxj6JxEAI735kSIhjCnilA6UpT+gh9rnCg38BpTkvg058GKlCJcGm2iKY3B6hOEQJwABxsIDGPFkYKPlACEFgBKlB5gK53PZUlrAUIbGkLYQpjmNCcujdFUAAVbjgwBDHHWjEpUAICPOCBDWwgLb4GdrDbQmzDcIAKIxiBFaxQgmY/+9yLEEEaEHAVdLv73fCOd7wDAQA7AA=="
+#define PHP_EGG_LOGO_DATA_URI "data:image/gif;base64,R0lGODlheABDAOf/ABIZISAeIhwhLA8jRwYlVSUoLyIpNSkoKwkvbR4tRBUwVDMuNysxOx87Yg89gDo3RTI5SgBCkDg6PDY7RyBCcTxBQz9BVD9ETxxPkQ9SoktIYkROVkpNWDJSeilVhkxObEZTZQVevgBfxVZQZRxcn1BUYFNTc1FXWRZht1ZYVQBm0ghlzBhksVVafyNlqSpkn1hcZwBr2EVfhABs0lRdcF5adRJpyWBcaVlgYl5dh15efh5q0gdw3iFsxhBy2Rtxxhhx0Ttsn2BkigB45SxwtDFwq0dslGNoc1pqfRtz6GRmkypzwFZuiQl772psaWlpiiF25Ax94zB10BB+3iV44BR96yN71TJ5vit7zih73GluoDt6tk53nix66QOG+nBwl0l7r3F2cjOAzSKB9guI9SKC8HF1lW90pm93jTCC3SaE6zWC12F8knR6fHV5gzaC5SmH6ESC3y6H9kGGyiqJ8UuDzXx5oWV9v1aA0nl6qWmAnXl6tHJ8tV6AyVGGuS6K/EyHwyKO/D6J5T+K2SGQ9zqL3ziN9jaP6jmP8WaHwYGCsHqIkC6U/C2V9naFv0GS50mS2IGFuYeHnEWU4iyZ/16P2ISIr1iSz4mLiF2SxV+TvImLlmiSsnqPrIeLvzmc/kOa9Uaa74aNtHWRyXiSvk+a6YyNvIGQwo6OsImTnFib3lKd5l2d2kKi/WSd0k2h9zeo/1Gi8ZSUw5GVyn+czE2m/46bsY2ZyHugwUmr/12n8GCn6pieoGWn5Hekzpueq26n25yby1ms/ICk25ejrlGy/56iymav+V2y+2yv7Wex9KaopWG2/1e5/5Wu2H216265/HW3/qus0aavxWe+/66wvYy33YC4+Hi7+bO0uHPB/aq3wa6112vF/4e/9pfA27u31YDF/XnK/5PG77y/25TI/MDBxYbN/qvH7LfH2qPP+47V/57T/cPN2abT9c3M5Jna/77S7LrU57HV+KLg/7zd+tbb3dbb6a7l/sbh99Hi+Lrp++Pm7+Hx/P3//P///yH5BAEKAP8ALAAAAAB4AEMAAAj+AP8JHEiwoMGDCBMqXMiwocOHECNKnEixosWLFoNpDIaxo8ePwaRJ4yaNHDhw5EySFCnNmEtjt2TJMmXKk01PpmbN+sgTZEly7+7de0eUaMqj4FaKfBlzps1IkfZI3cMnzx5Fnnb23MrQGLig/PgJHTvUZEtjNZ9CXcu2bVSpfPicOaOlrpY8ikxx3fvPGLd3YQOHfUdOWkw+jkaNEjVtquPHkCNLnVtXieUcSr7k5YvRK2DB9wrLctSnUi9dxYpRo6atEy/JsGM7pqskh+0WLXLY0csZYrC/QsOGNubplrNkxWq1Wp6rObNu53y5kU2dupbaLUxob5FHVu+Fxsj+kb3HzdTUc/TonWtWrLnqXMWaiQvnC031+7LPKMn+4YOGJ4p8Z1BJRA0ljSeQ1XMOPOt00wx7xYhDjWrinDNOEFzQwgd+HEamnwkahGiCHQL+QyBR4MgSWzjw0CNOM+4xKN868FhjhB/PqIMON844c8spp6zlSSSexIXYUx06pkULGlhggQZfcObVUdK8FRs70NCzDnvNUeNgN+vQ4w4XfvSizDHIQAMNM8LooosyaWqDDTbhhOPNnc9g88www/RIHH5nMOmkBiT2FNJRxuBXjzAMTghLK/IVAyY843TgAhaHIKIpIXDQgUgjhwjySCijllLKKrqssssuqaqaTDL+e57CYQ4WPPDAB7x15BdKxlgp2zi9JBPLOetQkwsssBTTYDPwwMMOBSRYgQghdMhRxrVl0AHHG9xuO0UWghRSyCOlTCJuIZNAoq4qwMh63xkm2LrAExiFNFKV96GzyyOICPNIOfRQs9wnucCjTTf07OMOBREAQQcZZXhRxcTYUmExFVFEkUUWaXTscRqhlDuIGGJA0ssoHGqhwQILWJCrRPZKo+J9z5xpCBnUNtrKJwTjc4426bHTQQQzVHFtFU00AUUXEw8BxRBUDBHFtnAIksYUVpOLzDGpTjLIIJA40mEOD7AcJczGtORrbJ48E8orn8jhhRyv4AMPMrBQAkv+M14ijI/QRHeBLdJdMA3F0jzwAIUPb2iKCBwbTwHHI6PqEoub6c6xYcoWHHCADhEF49LM1UWyCyigEMIIIYY0EY56xeycCzO5NAP0PoDPEDG2XSR9eBeHQ8GDD3CUk4862AgD+cZZwAHHIY/EEssqkGjeIR8aeD7CQ6L/eZ8jlWg6hxVkQFxFi8bunOze4tCDzzgNOFB0E9c2UcUYSRd++BA++JCFPm5wwjLKcQjnZcEHQJjcuB6BKl2oQmwdMoHnNNAQWdyiV/iJRB2yoAY1vOEFVbBWFegBD3HkYjmtaI+X4PG++PmgfnKIobXKEDWnDWF4abgHBwzgBG/AQXL+kANCGg6RBitYAQtrgMQqVgFBDrXgAAGgoEJkcou1xeYWdZjCFKKghiqQQAr4o0N61hG7T+gtF+IQBz7wYQ0FEG0M12IEz0DBM001QlNU8EEa2nEBA7QBG5ATxLeAgMRChGINP0jkD7AghkQ08T4tCEAAapCQWZhCFgi6zyjWIAhr2MIFQ5DaD4bQBUS4Dx7NeJQZYQGdfdDjGQOIQAzo14h5yCMf+ahHPfIhj3ZsQx7QgMMg2jEBAbQBecd4xSOIuIZmkguJWFDkJWiRJA1IslAFmQVOMkmdSFxiDYfQhz/8gYQodMFpwAsFPlzZjJ0xohVoPMc+4OEKAkSACnL+IMQxsnGBC3DgnyXgwAYusIFslGMV1SjmAU6AAzfwIh3YCMUkelEKcj0CXWuI5hzmYA0ryuYBATiAdwqSlvvwQRVYyMI8xumPVKTBaEgrwzHWCI/YMeKdxdBG+9jBBQJkoAqBQAQ2NlECGJSABjCgwVEDygBzeGMTEyiAAUrQTwYUIAzeCIUtiPGNZ+jCVI9Iww/EcAlX+OIWHDoDFLdHkFkQyaORuURKB5GCaoxTD4gog7WaMAZvjJE9rUjWg9JTKQKggAyMaEQ53FDUauAyl/r4RQkY0AZ+HOECASBGNX7BWAEAYBGlYAJBcRAGTGBiG8oQK1kzwQpSbK46JpD+5MuGBFfI3AELQKBCEAxQgHbYwwWNKB+22JEeF7WHldQIEzy8kQAEZOETO5sHDU5Qgm08QxiNgEMhzFGCAlTgHiWYgATycad52KKYJ3gGCATAgA1woJ8GwEQpevCDQQACEHMwqzPuA0Up/sOttX0MH3oAhBn4wAPTOAANNpEFMuyVfuxoETy6cSxJSXgdroglHGbXCnnQwA1HSIcyJhaFQqSjuwzYBgcYcIRywCENkPhFAQBwAmJ+Nh7TIAYaeAsMIPRADHPwwxKuAAhXkOIUpJNMJAMwUvMEeCoDtsEKVjADEhQgAAIggRrIUIXCNYEM7KARPNIHC3Gs48zhkIH+YUEhDIGlgwM3cIMtjlEFKrzhEe1Y8QIka4BFxEINgngGGjy7iGp4Fhe64Fo8DAAATkyhB1iYQxBcsAQiXGELW8iENcwjmTNIkl7/ePJUPLEEKatABTsAAgUSgAE43OxavVMDO85h5mZANxfJPbM3GoCANLyiGMyAxDQ4AINNWEMYhEDEIdTxiwsU4AhouIAAqoEINWTBGRAAAAC2MWgGJEOZj7hEAgDAhTSgAAtXeIELWMBuEpCACJl2RqIiY4EoCsSkgOjBCmIQgx34GwiF4CAhhHutRqwjjetABnRhQawzZ2IAGXiFMNqjilT8MxvooAYzoMGObBxhAgywBxL++oiODmahE4xmQDuyvQFtvCIUhfCDZzlxiB8sYQ5bIAG7WeBuF5CgCGDwAy6SLJUPBGAB967OKbBggx3wIAYq4PcOfBAFOljdwVXwAjPCcY5uSCgXyulGs8rRAQLUgRlsyoU30MCBEpjjHubYBjGcQGwIpOIeMJjABp5BBzVYAQmePcI0ZkwMbQgjFpDoxKHhIIYrXKEIL3gBEdTtbgz8HNOcgIwSJCmQ18LGE3MAwgpUwIMh8LvfPqBCsgcOMTLQ6WDnmBB75lOODDsgFhpnRivmAYK2X4AGE7hA8IvqhnhUY8Vt8IYa6FAHC2h7G0gAwAbkMQ49pYMGAJAAKwT+MYgrECEIHog8vOHt7hcUYQuZf8zmA/Df6owCC1OOOg/KUIWnx2AIjYCbIT5BBkNwHRoVcg7MkFPUcA7eUHZigAy0Iwy5IA8QAGdHAGJHAAMw4AbbMA+PIAkcMAG8UA5UoAaJwGgXkA7ZJgG8cIK8AAOYlQrmMgiWFgQyAAZbQAQu4AKRB35BEARbgAvqx3n/EBeyUQdSIAKoFgM+MARkoAZPFwWH8AqtMC37Bw3noCZmdg51Uid+AHG6gAwMWAu5sA0TcAMlwA+5VA/zEA/qcAyIUArtQAzEcA/XQAVwgAsW0Ge2IAEAwADvBVAX0AbPUAhgA29GgAZ2wARgAHn+JPACYLAhlsAFXOAr6ycQZ+B5kDEKPzADoxcDw/OBZaAGqfcKyAAKzNEKwhAOycMiB5cM4QAMCuAAk6ANtOOF0PALxOYG/XAMn9B3VmcI1vYK0VAO0QAKQwAH4xAP98APSMBb9rANqbAIbpAK1gU9I+MCWyADViEVXAAGL+ABMiAKsBGJP0iJjnEKYtB0UcdvPEAFj1MGQ6AGsRAO0KANasIMyKAM2nAMUpgMu6AKl0ABCPADCrgzlNAKi1UCJbAJ/SAMhlAG+1M+VJAtjUAIVMADnggEVkAKHCAAOOANwrAL3lAOyhAKhyAujQdvLeAYkZAJWwAGRgAGcGV0SPf+D3twBrBBCz+wbzvQb5rYjocACogQCsKgDcmgDXUiDtCADLrQC7twCYDgARRAAAhgA8sBC59wU69QDzTQdsSQD7kgQkNQBWRAB1FTOFUwAxTpAzbQA53AAABADNAACj8EB8o2koUwB5dABGBwkpDhB2DABeIoFfUmRZ4wF5FhCnNgAyIweudYenCgBqUQC6FwDMpwCZcQDuIgj/QoBhjgAAiAABGAAoeAQq1ACYxACbnQD8SQCr/AD+wACnJgOF0gB0l4Q1BABTuAhFQABGswaAXwDcIACm8ABEAgOWmALqswB98nBJEBhJ32aQIxC3MhjqfwAzbgA5mYOFDzBnD+AIqxIAzQoApqgg0AGA7FgJRr0ANWIIrKwTNVeVOtcA7lwA7qUA6toFdlADwhlIRwIDw8MAO46QOq4EvtgA1PSAVU9i1TAIjdRwQyQJMdsmQjJZOE+RiJgJgr4G85eYRcBAehoAxvogtzIJnHsHU/U570CAqUMJDtGQgsGghyEAipwQgLKTiFwwP0Y3VUUAVQwG/0wz9AEAq6IAwF6gMxMAPDmQZYMDLw9gFJsgf91VZa4KCOIQYhMGX+dkOpJwiv0ITSswu9sAXKoAxrwnVT2Aq0U5Us6gVj4AV/4AVuOgayWQZKMzFQwJD2Uwaf0nemN0sMOQPVyYSgoAZRMAT+MzADWWBESep9QWACSRJbAfAy/6AIUeoYjrAEISACiTkDVAAFHVQ1QJoqqpAJXHAJpRCPxGKFDLgzaKqmY7Cmc+OirZo099llWVcGhNAIPlkFQ5CTE8MDK2ADUfAKjaAGX9mffmoDRyQGRFAEMpAkahUAbAWlkyoVpmCpU9ZviVMFzgMKoTA9quAHIAABMgAJukAnVmh4yqGqjOCmavoHbeqmMeQFhuAFSUM/clAFt5o6N6QCsUkGUGCkbNYKXMY/MxACBktfiiql+AFSInUQplAXm3MLV2ChM8BvnKpsoCA9q8AKIBB8MNAJvYCU0BAOsEg7N0WagcCmf7CmcqP+pl4AMU3AA0nQBHNDBqCAq4SgBjwKMTxgA3Bws2QQCOwIBDZgsCGAAijAAkSgBNV0TQkhqVowFXOgb5m4A3KIOofQravgCv2EBlFxCqzwJtigDfIopGj6B4HgroHACHLQpoaAPxGTOE0gm4QgiohQBToLBS/bBf0JBy5KCOzoA/SFAkeLtCwQBEmyZJSkEHlQF1LhCjeZiUaoBoggCC9WCKWgCRNgBo7BB6OwC8rAdfLoTmzrru46BmjLqknjBUkws0GLq69QbVRQNLLZBLs6BNlSBVNjBT2AtL7LAi7AtE4kSf7FuHWRB7TAdIrJb4VKdVlwCLqgCRcQGZ+rU/D+eEJoOgaBsKauCqdkUK/1ijOgkAtwmUcvVD4xW3p0ADxRAASYerRLkAEZcLgRRLwP0bhaUK02UKinJzwW8wbQK72SMQracK4Tdyw8Q7ot6qJyUK9dVgafAAqxCwdRcIQvS69OYzQ8oAJWWqg2sAQukAFXcI3VcQb1Zm8QIamKMLGYuJMTmXocmgycML2S8QxXCA0a1x7tWQvIgAyyA13r6gVlkITQlSkV/JDcGzx1+nSh5KOEdAUukAj4oQQLIEmLGxGm8AWQ0AP7u2+lJ4eI8AqSKcCScQrnYIXUIAxww6JoGwitADe31go3VZVPyK2QY2CqI1zAMwR0QH+h9IH+U1CckxBk3ghbUHQAZzMRwcAKkXuhBna1r/AmmUDDNUyy2oAMuVCVbfsHhCAHhvAHMbS2awu7W3oIUmADWYAIrdAImlwGjdAIgWAIA2d1zyNRG8uD1KEEIBUAEgCpEjEOa4CJ+5Z6VysM9QgMG/CXUvEM2kANOCwMtcAIaXtT0iw3oMyilEAwuRAKoVBEaTC+ckzNN5VPrEctcNAIo7IKyYDLsKEFJzxJHjEIUubFX6nKbaIMwEADlgAbySMMbCIM0tyiN+WibhrL7vnGsaAMkDAIsXAMwgCUzQE30izN5UMHyQYqDJQMvgAbfPABUBQALvMRqmAFhXqbH6jKDo3+DL2ABJIgGXygDasskC1qCIbwogu8ttCVQuWpDZegCvdYCkRZtlXpYMJl0VGgbJfTC8DwGKjAByrz0QuQyB6RDGlQqM2rBuf8CpezC5xwBPy8xmRwzS4a0HLzou7phWhXjy/ACspQCshAlOGgxmgaCLOJt3J4CKai1L5CK55zAPPCFX/opzPgb1RXy6WwC5oAA9z0GL0Qzg7WtgtsCGlr0+8kDJYdJx6wBazQCw7NDNpQC+tJCSwqm4aAMbU8CaowCuahBR/wAH39AKC2F5NAtBc6dVQXBYJwKq4AA5bwl6uQOgHNrnJQzaBs1gMZ0bmgDcrQAAPgAZcgppg5MIb+cFMQcy1yuAZ9cAd7oAXxsgB9PQLYxBeQUGAVW7H9EwVTcNjAUAJfYBdS6gmlgAhBG7RuSgij3bY2nc21wIC58ArQoAsNoAAYAAbQIJ7Q0B7qKt9VkAXYLRc50Nos490W8ARa8R2qQJ3XqpPEk9DJgARmYBkgXheTeAd9sAZxoAbWPDdqet9yBE8nlAv/TQEUcAWqMLbNDM2fQDl4kN3bnQMmUCtlwzIT7su9AbnzvLw+MAXKgA3JwAZu4FZ5AOJSrgQifgYk3gd4YOLc4jgRLJqX45R2yQp8MgqOsCHX4eNNAuS28gA18AVEXiLleKmJqQIGlgXlus4wQBCmoAjAUT7lII4ZVO7eczHohG4X13EZ2hEiTrLotWIBbR4gJaIQl0C4mBp/SV4KSQkMOIAQ2pQHefAFthHqop4DuIEb2nHq2tEf/REirM7oJqADAFLhkc4QlI6pdH6kupAMu+0QlhQJdmAHX/AF2JEdqJ7qqq4BH6ADuBHseCHrs/4QkEu4iJlqFrkGk8AKrrABPEETkfDmz94RgEC4IWCkVpAG4eKlmiAB377uFeEKS4ACNvADQpQG5LILwMAE7J7vAhEQADs="
+#define ZEND_LOGO_DATA_URI "data:image/gif;base64,R0lGODlhcQBIANUAAA0NDgEDBgIFCS5EXhUdJwUPGgQKER0rOgABAgkZKiZpqxhDbQ0kOwobLQkZKSNgnSBXjh1PghpGchQ2Vx1NfAoaKiJYjQoYJgsaKQECAzdQaS0/UTE1OQUPGAkaKh5ViiFclRpJdQocLSBZjh5UhhpIcw8qQxc+YwwgMwcVIQkaKQgXIwcZJTM6PwIEBRkaGjEyMv9mAP///8zMzMfHx7+/v6urq5KSknNzc1VVVTw8PDc3NyYmJgcHBwMDAwAAACwAAAAAcQBIAAAG/8CZcEgsGo/IpHJ5/DGf0KiU+Ks6p9Kr0KrFer9GbReM7IrJ6O95Zt262durUy5uD8/rtL58h7vlf3+AcHlsdoR7iU12eIhzbXVVfpOTgGOKiWNrkpKUhZ99iJijl4d5kFSdXKmdb6OvsFOXsbS1oba4ubq7vL1DNjg6ODW+xVg3OTw/AisCOMbQSsA6AD8FDAsjIwwv0d5DNcnLIhMU2uclPzbf3jwC2Ofx585MwTfssD8n8vwjKDpLcggo8OMZPkw8GPSTN6HKCxg5hhHJ8WOCv4IHFeEwsDAeiQULJjBYUQXGM4oWtTU0mDGNjR/mOi48gcJKynMrW+oBcFNmP/8SJnri/JFDJ5kaL0T4XLqwYVGjWGy8MFCCqVWGRKFKsQGgAImrYIc+1bqEq9ewaEc0vEc2CdKzacOmY9vWxjoiMAx81Sajr9+/MhaE2Iu2hAAexPraJUbGxo3HkB/f/XKjCgBhwH5kOwcYsAoU5dKSMIBYSN8cOSZvxRGjtevXOnREZDwFhogSE1AYqKIwXl8VBlKoUNHXgAEUJwhfJVGgtGkZsek+Afa6uvUY0bFUjEdhgnJtIUwwmLDAb4cU3tM2pz2jb/YnN67Lr/4eSuWYPkmEGDyiL4MODITgm1+CkdBZgSh00xkMOkiHRHzWxSahDvNJyN4SG6HV1wSfJcf/GWAMdObfCQv8IOILDUoj34QTrhgbS0zAgEJYfqGgQnp8yXACA8N9NkFfHQRX4wl+6cADDH2h6KBdz7jIYosRShjFdmD5B6CAH/JIHkgh9JUCeuXJAOBpPDTYF4MO4mDCAU5KmMMNxNDAWpSx2QdTlTJwiNxeIhbYnwzDZeMlcTLAAAOc7qVIxAsVsrjkdRNCkeFVNd5ImIgqmCDgbyoICiihZd5gQ189KDoDDTcYcN1lE+JAgxE2QCrlEzLi+V+Af+4XpnHCafpnoL8SWugNOwD5gqg4oMbDCtahkAGD9RUBIX2xjbUElUyJ6BcDJoQJ2AldfuppoCJe0IEOB5hw/wIEKFRQnQgesJrDhUTI+iJ8d2arbXGdjhDub6BxOm6nJvzVwMEMSCDBAw+AwIAHr3kgQgdl5vAqEjXYq4NqSeAgAFjd2djjyL7qJ9JwDCQXnq/+mqBpCQXsWIEHKVPwQcMgOOyAaw4k0EAKGCmhsbVKVLbCBFUtte+GC+ylH5df6cffCFIbKAMJJ5A4GARcdz2BA2CH3YAIDABA7y8aO1g0NeOEttDSgLJMowwuh9D13VwDFTbYCZjQMEBIDO3FNACY0NFvwY3M72ZoLWCACRTgLfnXYTPwAQgKmFAUDjjQ1SbHtfXWz29gggSSSHKHRcIKJkAAguR4R/C1CJFD8P+AAiykABoCQrQJoxc4FHC4uPLod+DUfxI4mF8O/AhYgXj/JdjNEUSgwAMY1ECDxjpcDEZl330IrDzapvyViCn7FUD5yXXdWcqXg3D7CdPCNqHaWNSA7YDPIw+kkH1BTo3OA6QA9UUAIvhfCoZEAgj0ZUdhA03tRvAAEvhuDzpQCj8wJTcvgamAVgqYDIQTpgIkcIQfFFOAHCgDBjTPdFvj2gPaRDQy4CBf5JMBr4bTQeINinTe+U0BCiYDBzSgL2BbAAtT4IA+xbBrIODe2cDwghltEIVb8p8PPyWwPxlAAERsgAeQ6AAlklFEDtAUFKNIp9iADlXJQs2bbuA9Jdz/ED/i69eHwgUsTvkFPVb7QQUk0BcPNLGIZWRhEsPFqzTazXUzbKOphBCrNnaujkUwS/jgFqItkqszCKDdGRFpRlJa7VuDiaQliVBJ7t0LVl0JX/K0ZYAuCuyUfrEGBUaZREUmEgL/KiJoIqBKagljCPUz5pN+N4MaxLIj4RmZNINSN/BUE2s86gsADBABEJSgbit7ZDjzFgKRgC1lEJgPdiw2g2Ta70lvOkINeACXhTzNdPgUDAX24zR+asN4MjiSAS73AX5WjZxPhMA9Q/ABdbYGVY1aJuiGsBFZxqUjhhFGDlwgP4aN4HWwC2nXLOjQiLJIInbUy0Wt4pQa2IUH/ydQwARmKr8RiDSkJW3T/TCJMXpadKX/ZEBWKEqAFgDgBjCYgAJAetO75VSZjuKpEuYpgKQBlR8lYqZdhsCBhTG1qSR96pMkREcvUNWq/CBPXOixBA5QIGdN5dpTsTPWBkk1CmftR0N+YACkhUUEgJOGD0jwVa7l7LCvy2ld33TXKeQ1HiuxQQ5eUIUVoEBdS5kAAJ7gghM84G45Y9jtSgCCCHjAA2PzwGHqOqF4KuKxagkaJTmngxcIzycU+AH+iFADFCwVtCAgTwRQEIALQEAEIlBBB15QJtbKZrdpqAEMqhrbGiIThx0pgHWJgAMJ/NawDxhADzj3DBioSwQGAIfADpyLUloIpCbbHQJPlsIAGCxhBxa4HcM6at865qCcRFlsWXORA5MwIYMyWQADBBBfIdzgBRpAwVtvpzkjhCM1lHQMZKb4DY/xozsiEMAPeNDeJNDAMT/YwAkkwICJcpgsL9mMgglyGRxMlAmiAoCN2zIFeoZ4xK6NLo+nYIMX3XjISNZKEAAAOw=="
BEGIN_EXTERN_C()
PHP_FUNCTION(phpversion);
PHP_FUNCTION(phpinfo);
PHP_FUNCTION(phpcredits);
-PHP_FUNCTION(php_logo_guid);
-PHP_FUNCTION(php_real_logo_guid);
-PHP_FUNCTION(zend_logo_guid);
-PHP_FUNCTION(php_egg_logo_guid);
PHP_FUNCTION(php_sapi_name);
PHP_FUNCTION(php_uname);
PHP_FUNCTION(php_ini_scanned_files);
@@ -83,7 +78,6 @@ PHPAPI void php_info_print_box_start(int bg);
PHPAPI void php_info_print_box_end(void);
PHPAPI void php_info_print_hr(void);
PHPAPI void php_info_print_module(zend_module_entry *module TSRMLS_DC);
-PHPAPI char *php_logo_guid(void);
PHPAPI char *php_get_uname(char mode);
void register_phpinfo_constants(INIT_FUNC_ARGS);
diff --git a/ext/standard/mail.c b/ext/standard/mail.c
index 43adfeef71..bfbcef6ceb 100644
--- a/ext/standard/mail.c
+++ b/ext/standard/mail.c
@@ -21,10 +21,12 @@
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
+#include <time.h>
#include "php.h"
#include "ext/standard/info.h"
#include "ext/standard/php_string.h"
#include "ext/standard/basic_functions.h"
+#include "ext/date/php_date.h"
#if HAVE_SYSEXITS_H
#include <sysexits.h>
@@ -246,8 +248,16 @@ PHPAPI int php_mail(char *to, char *subject, char *message, char *headers, char
return val; \
if (mail_log && *mail_log) {
- char *tmp;
- int l = spprintf(&tmp, 0, "mail() on [%s:%d]: To: %s -- Headers: %s\n", zend_get_executed_filename(TSRMLS_C), zend_get_executed_lineno(TSRMLS_C), to, hdr ? hdr : "");
+ char *tmp, *date_str;
+ time_t curtime;
+ int l;
+
+ time(&curtime);
+ date_str = php_format_date("d-M-Y H:i:s e", 13, curtime, 1 TSRMLS_CC);
+
+ l = spprintf(&tmp, 0, "[%s] mail() on [%s:%d]: To: %s -- Headers: %s\n", date_str, zend_get_executed_filename(TSRMLS_C), zend_get_executed_lineno(TSRMLS_C), to, hdr ? hdr : "");
+
+ efree(date_str);
if (hdr) {
php_mail_log_crlf_to_spaces(tmp);
diff --git a/ext/standard/math.c b/ext/standard/math.c
index 72f6d51c6f..2be049f200 100644
--- a/ext/standard/math.c
+++ b/ext/standard/math.c
@@ -1226,7 +1226,7 @@ PHPAPI char *_php_math_number_format_ex(double d, int dec, char *dec_point,
}
/* }}} */
-/* {{{ proto string number_format(float number [, int num_decimal_places [, string dec_seperator, string thousands_seperator]])
+/* {{{ proto string number_format(float number [, int num_decimal_places [, string dec_separator, string thousands_separator]])
Formats a number with grouped thousands */
PHP_FUNCTION(number_format)
{
diff --git a/ext/standard/pack.c b/ext/standard/pack.c
index d133e66d98..16a30668dc 100644
--- a/ext/standard/pack.c
+++ b/ext/standard/pack.c
@@ -99,7 +99,7 @@ static void php_pack(zval **val, int size, int *map, char *output)
/* }}} */
/* pack() idea stolen from Perl (implemented formats behave the same as there)
- * Implemented formats are A, a, h, H, c, C, s, S, i, I, l, L, n, N, f, d, x, X, @.
+ * Implemented formats are Z, A, a, h, H, c, C, s, S, i, I, l, L, n, N, f, d, x, X, @.
*/
/* {{{ proto string pack(string format, mixed arg1 [, mixed arg2 [, mixed ...]])
Takes one or more arguments and packs them into a binary string according to the format argument */
@@ -170,6 +170,7 @@ PHP_FUNCTION(pack)
/* Always uses one arg */
case 'a':
case 'A':
+ case 'Z':
case 'h':
case 'H':
if (currentarg >= num_args) {
@@ -186,6 +187,12 @@ PHP_FUNCTION(pack)
}
convert_to_string_ex(argv[currentarg]);
arg = Z_STRLEN_PP(argv[currentarg]);
+ if (code == 'Z') {
+ /* add one because Z is always NUL-terminated:
+ * pack("Z*", "aa") === "aa\0"
+ * pack("Z2", "aa") === "a\0" */
+ arg++;
+ }
}
currentarg++;
@@ -250,6 +257,7 @@ PHP_FUNCTION(pack)
case 'a':
case 'A':
+ case 'Z':
case 'c':
case 'C':
case 'x':
@@ -315,16 +323,19 @@ PHP_FUNCTION(pack)
switch ((int) code) {
case 'a':
case 'A':
- memset(&output[outputpos], (code == 'a') ? '\0' : ' ', arg);
+ case 'Z': {
+ int arg_cp = (code != 'Z') ? arg : MAX(0, arg - 1);
+ memset(&output[outputpos], (code == 'a' || code == 'Z') ? '\0' : ' ', arg);
val = argv[currentarg++];
if (Z_ISREF_PP(val)) {
SEPARATE_ZVAL(val);
}
convert_to_string_ex(val);
memcpy(&output[outputpos], Z_STRVAL_PP(val),
- (Z_STRLEN_PP(val) < arg) ? Z_STRLEN_PP(val) : arg);
+ (Z_STRLEN_PP(val) < arg_cp) ? Z_STRLEN_PP(val) : arg_cp);
outputpos += arg;
break;
+ }
case 'h':
case 'H': {
@@ -511,7 +522,7 @@ static long php_unpack(char *data, int size, int issigned, int *map)
* chars1, chars2, and ints.
* Numeric pack types will return numbers, a and A will return strings,
* f and d will return doubles.
- * Implemented formats are A, a, h, H, c, C, s, S, i, I, l, L, n, N, f, d, x, X, @.
+ * Implemented formats are Z, A, a, h, H, c, C, s, S, i, I, l, L, n, N, f, d, x, X, @.
*/
/* {{{ proto array unpack(string format, string input)
Unpack binary string into named array elements according to format argument */
@@ -586,6 +597,7 @@ PHP_FUNCTION(unpack)
case 'a':
case 'A':
+ case 'Z':
size = arg;
arg = 1;
break;
@@ -662,9 +674,23 @@ PHP_FUNCTION(unpack)
if ((inputpos + size) <= inputlen) {
switch ((int) type) {
- case 'a':
+ case 'a': {
+ /* a will not strip any trailing whitespace or null padding */
+ int len = inputlen - inputpos; /* Remaining string */
+
+ /* If size was given take minimum of len and size */
+ if ((size >= 0) && (len > size)) {
+ len = size;
+ }
+
+ size = len;
+
+ add_assoc_stringl(return_value, n, &input[inputpos], len, 1);
+ break;
+ }
case 'A': {
- char pad = (type == 'a') ? '\0' : ' ';
+ /* A will strip any trailing whitespace */
+ char padn = '\0'; char pads = ' '; char padt = '\t'; char padc = '\r'; char padl = '\n';
int len = inputlen - inputpos; /* Remaining string */
/* If size was given take minimum of len and size */
@@ -674,15 +700,45 @@ PHP_FUNCTION(unpack)
size = len;
- /* Remove padding chars from unpacked data */
+ /* Remove trailing white space and nulls chars from unpacked data */
while (--len >= 0) {
- if (input[inputpos + len] != pad)
+ if (input[inputpos + len] != padn
+ && input[inputpos + len] != pads
+ && input[inputpos + len] != padt
+ && input[inputpos + len] != padc
+ && input[inputpos + len] != padl
+ )
break;
}
add_assoc_stringl(return_value, n, &input[inputpos], len + 1, 1);
break;
}
+ /* New option added for Z to remain in-line with the Perl implementation */
+ case 'Z': {
+ /* Z will strip everything after the first null character */
+ char pad = '\0';
+ int s,
+ len = inputlen - inputpos; /* Remaining string */
+
+ /* If size was given take minimum of len and size */
+ if ((size >= 0) && (len > size)) {
+ len = size;
+ }
+
+ size = len;
+
+ /* Remove everything after the first null */
+ for (s=0 ; s < len ; s++) {
+ if (input[inputpos + s] == pad)
+ break;
+ }
+ len = s;
+
+ add_assoc_stringl(return_value, n, &input[inputpos], len, 1);
+ break;
+ }
+
case 'h':
case 'H': {
diff --git a/ext/standard/password.c b/ext/standard/password.c
new file mode 100644
index 0000000000..ae405096fa
--- /dev/null
+++ b/ext/standard/password.c
@@ -0,0 +1,460 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2014 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: Anthony Ferrara <ircmaxell@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#include <stdlib.h>
+
+#include "php.h"
+#if HAVE_CRYPT
+
+#include "fcntl.h"
+#include "php_password.h"
+#include "php_rand.h"
+#include "php_crypt.h"
+#include "base64.h"
+#include "zend_interfaces.h"
+#include "info.h"
+
+#if PHP_WIN32
+#include "win32/winutil.h"
+#endif
+
+PHP_MINIT_FUNCTION(password) /* {{{ */
+{
+ REGISTER_LONG_CONSTANT("PASSWORD_DEFAULT", PHP_PASSWORD_DEFAULT, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("PASSWORD_BCRYPT", PHP_PASSWORD_BCRYPT, CONST_CS | CONST_PERSISTENT);
+
+ REGISTER_LONG_CONSTANT("PASSWORD_BCRYPT_DEFAULT_COST", PHP_PASSWORD_BCRYPT_COST, CONST_CS | CONST_PERSISTENT);
+
+ return SUCCESS;
+}
+/* }}} */
+
+static char* php_password_get_algo_name(const php_password_algo algo)
+{
+ switch (algo) {
+ case PHP_PASSWORD_BCRYPT:
+ return "bcrypt";
+ case PHP_PASSWORD_UNKNOWN:
+ default:
+ return "unknown";
+ }
+}
+
+static php_password_algo php_password_determine_algo(const char *hash, const size_t len)
+{
+ if (len > 3 && hash[0] == '$' && hash[1] == '2' && hash[2] == 'y' && len == 60) {
+ return PHP_PASSWORD_BCRYPT;
+ }
+
+ return PHP_PASSWORD_UNKNOWN;
+}
+
+static int php_password_salt_is_alphabet(const char *str, const size_t len) /* {{{ */
+{
+ size_t i = 0;
+
+ for (i = 0; i < len; i++) {
+ if (!((str[i] >= 'A' && str[i] <= 'Z') || (str[i] >= 'a' && str[i] <= 'z') || (str[i] >= '0' && str[i] <= '9') || str[i] == '.' || str[i] == '/')) {
+ return FAILURE;
+ }
+ }
+ return SUCCESS;
+}
+/* }}} */
+
+static int php_password_salt_to64(const char *str, const size_t str_len, const size_t out_len, char *ret) /* {{{ */
+{
+ size_t pos = 0;
+ size_t ret_len = 0;
+ unsigned char *buffer;
+ if ((int) str_len < 0) {
+ return FAILURE;
+ }
+ buffer = php_base64_encode((unsigned char*) str, (int) str_len, (int*) &ret_len);
+ if (ret_len < out_len) {
+ /* Too short of an encoded string generated */
+ efree(buffer);
+ return FAILURE;
+ }
+ for (pos = 0; pos < out_len; pos++) {
+ if (buffer[pos] == '+') {
+ ret[pos] = '.';
+ } else if (buffer[pos] == '=') {
+ efree(buffer);
+ return FAILURE;
+ } else {
+ ret[pos] = buffer[pos];
+ }
+ }
+ efree(buffer);
+ return SUCCESS;
+}
+/* }}} */
+
+static int php_password_make_salt(size_t length, char *ret TSRMLS_DC) /* {{{ */
+{
+ int buffer_valid = 0;
+ size_t i, raw_length;
+ char *buffer;
+ char *result;
+
+ if (length > (INT_MAX / 3)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Length is too large to safely generate");
+ return FAILURE;
+ }
+
+ raw_length = length * 3 / 4 + 1;
+
+ buffer = (char *) safe_emalloc(raw_length, 1, 1);
+
+#if PHP_WIN32
+ {
+ BYTE *iv_b = (BYTE *) buffer;
+ if (php_win32_get_random_bytes(iv_b, raw_length) == SUCCESS) {
+ buffer_valid = 1;
+ }
+ }
+#else
+ {
+ int fd, n;
+ size_t read_bytes = 0;
+ fd = open("/dev/urandom", O_RDONLY);
+ if (fd >= 0) {
+ while (read_bytes < raw_length) {
+ n = read(fd, buffer + read_bytes, raw_length - read_bytes);
+ if (n < 0) {
+ break;
+ }
+ read_bytes += (size_t) n;
+ }
+ close(fd);
+ }
+ if (read_bytes >= raw_length) {
+ buffer_valid = 1;
+ }
+ }
+#endif
+ if (!buffer_valid) {
+ for (i = 0; i < raw_length; i++) {
+ buffer[i] ^= (char) (255.0 * php_rand(TSRMLS_C) / RAND_MAX);
+ }
+ }
+
+ result = safe_emalloc(length, 1, 1);
+ if (php_password_salt_to64(buffer, raw_length, length, result) == FAILURE) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Generated salt too short");
+ efree(buffer);
+ efree(result);
+ return FAILURE;
+ }
+ memcpy(ret, result, (int) length);
+ efree(result);
+ efree(buffer);
+ ret[length] = 0;
+ return SUCCESS;
+}
+/* }}} */
+
+PHP_FUNCTION(password_get_info)
+{
+ php_password_algo algo;
+ int hash_len;
+ char *hash, *algo_name;
+ zval *options;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &hash, &hash_len) == FAILURE) {
+ return;
+ }
+
+ if (hash_len < 0 || (size_t) hash_len < 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Supplied password hash too long to safely identify");
+ RETURN_FALSE;
+ }
+
+ ALLOC_INIT_ZVAL(options);
+ array_init(options);
+
+ algo = php_password_determine_algo(hash, (size_t) hash_len);
+ algo_name = php_password_get_algo_name(algo);
+
+ switch (algo) {
+ case PHP_PASSWORD_BCRYPT:
+ {
+ long cost = PHP_PASSWORD_BCRYPT_COST;
+ sscanf(hash, "$2y$%ld$", &cost);
+ add_assoc_long(options, "cost", cost);
+ }
+ break;
+ case PHP_PASSWORD_UNKNOWN:
+ default:
+ break;
+ }
+
+ array_init(return_value);
+
+ add_assoc_long(return_value, "algo", algo);
+ add_assoc_string(return_value, "algoName", algo_name, 1);
+ add_assoc_zval(return_value, "options", options);
+}
+
+PHP_FUNCTION(password_needs_rehash)
+{
+ long new_algo = 0;
+ php_password_algo algo;
+ int hash_len;
+ char *hash;
+ HashTable *options = 0;
+ zval **option_buffer;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|H", &hash, &hash_len, &new_algo, &options) == FAILURE) {
+ return;
+ }
+
+ if (hash_len < 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Supplied password hash too long to safely identify");
+ RETURN_FALSE;
+ }
+
+ algo = php_password_determine_algo(hash, (size_t) hash_len);
+
+ if (algo != new_algo) {
+ RETURN_TRUE;
+ }
+
+ switch (algo) {
+ case PHP_PASSWORD_BCRYPT:
+ {
+ long new_cost = PHP_PASSWORD_BCRYPT_COST, cost = 0;
+
+ if (options && zend_symtable_find(options, "cost", sizeof("cost"), (void **) &option_buffer) == SUCCESS) {
+ if (Z_TYPE_PP(option_buffer) != IS_LONG) {
+ zval cast_option_buffer;
+ MAKE_COPY_ZVAL(option_buffer, &cast_option_buffer);
+ convert_to_long(&cast_option_buffer);
+ new_cost = Z_LVAL(cast_option_buffer);
+ zval_dtor(&cast_option_buffer);
+ } else {
+ new_cost = Z_LVAL_PP(option_buffer);
+ }
+ }
+
+ sscanf(hash, "$2y$%ld$", &cost);
+ if (cost != new_cost) {
+ RETURN_TRUE;
+ }
+ }
+ break;
+ case PHP_PASSWORD_UNKNOWN:
+ default:
+ break;
+ }
+ RETURN_FALSE;
+}
+
+/* {{{ proto boolean password_make_salt(string password, string hash)
+Verify a hash created using crypt() or password_hash() */
+PHP_FUNCTION(password_verify)
+{
+ int status = 0, i;
+ int password_len, hash_len;
+ char *ret, *password, *hash;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &password, &password_len, &hash, &hash_len) == FAILURE) {
+ RETURN_FALSE;
+ }
+ if (php_crypt(password, password_len, hash, hash_len, &ret) == FAILURE) {
+ RETURN_FALSE;
+ }
+
+ if (strlen(ret) != hash_len || hash_len < 13) {
+ efree(ret);
+ RETURN_FALSE;
+ }
+
+ /* We're using this method instead of == in order to provide
+ * resistence towards timing attacks. This is a constant time
+ * equality check that will always check every byte of both
+ * values. */
+ for (i = 0; i < hash_len; i++) {
+ status |= (ret[i] ^ hash[i]);
+ }
+
+ efree(ret);
+
+ RETURN_BOOL(status == 0);
+
+}
+/* }}} */
+
+/* {{{ proto string password_hash(string password, int algo, array options = array())
+Hash a password */
+PHP_FUNCTION(password_hash)
+{
+ char *hash_format, *hash, *salt, *password, *result;
+ long algo = 0;
+ int password_len = 0, hash_len;
+ size_t salt_len = 0, required_salt_len = 0, hash_format_len;
+ HashTable *options = 0;
+ zval **option_buffer;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|H", &password, &password_len, &algo, &options) == FAILURE) {
+ return;
+ }
+
+ switch (algo) {
+ case PHP_PASSWORD_BCRYPT:
+ {
+ long cost = PHP_PASSWORD_BCRYPT_COST;
+
+ if (options && zend_symtable_find(options, "cost", 5, (void **) &option_buffer) == SUCCESS) {
+ if (Z_TYPE_PP(option_buffer) != IS_LONG) {
+ zval cast_option_buffer;
+ MAKE_COPY_ZVAL(option_buffer, &cast_option_buffer);
+ convert_to_long(&cast_option_buffer);
+ cost = Z_LVAL(cast_option_buffer);
+ zval_dtor(&cast_option_buffer);
+ } else {
+ cost = Z_LVAL_PP(option_buffer);
+ }
+ }
+
+ if (cost < 4 || cost > 31) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid bcrypt cost parameter specified: %ld", cost);
+ RETURN_NULL();
+ }
+
+ required_salt_len = 22;
+ hash_format = emalloc(8);
+ sprintf(hash_format, "$2y$%02ld$", cost);
+ hash_format_len = 7;
+ }
+ break;
+ case PHP_PASSWORD_UNKNOWN:
+ default:
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown password hashing algorithm: %ld", algo);
+ RETURN_NULL();
+ }
+
+ if (options && zend_symtable_find(options, "salt", 5, (void**) &option_buffer) == SUCCESS) {
+ char *buffer;
+ int buffer_len_int = 0;
+ size_t buffer_len;
+ switch (Z_TYPE_PP(option_buffer)) {
+ case IS_STRING:
+ buffer = estrndup(Z_STRVAL_PP(option_buffer), Z_STRLEN_PP(option_buffer));
+ buffer_len_int = Z_STRLEN_PP(option_buffer);
+ break;
+ case IS_LONG:
+ case IS_DOUBLE:
+ case IS_OBJECT: {
+ zval cast_option_buffer;
+ MAKE_COPY_ZVAL(option_buffer, &cast_option_buffer);
+ convert_to_string(&cast_option_buffer);
+ if (Z_TYPE(cast_option_buffer) == IS_STRING) {
+ buffer = estrndup(Z_STRVAL(cast_option_buffer), Z_STRLEN(cast_option_buffer));
+ buffer_len_int = Z_STRLEN(cast_option_buffer);
+ zval_dtor(&cast_option_buffer);
+ break;
+ }
+ zval_dtor(&cast_option_buffer);
+ }
+ case IS_BOOL:
+ case IS_NULL:
+ case IS_RESOURCE:
+ case IS_ARRAY:
+ default:
+ efree(hash_format);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Non-string salt parameter supplied");
+ RETURN_NULL();
+ }
+ if (buffer_len_int < 0) {
+ efree(hash_format);
+ efree(buffer);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Supplied salt is too long");
+ }
+ buffer_len = (size_t) buffer_len_int;
+ if (buffer_len < required_salt_len) {
+ efree(hash_format);
+ efree(buffer);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Provided salt is too short: %lu expecting %lu", (unsigned long) buffer_len, (unsigned long) required_salt_len);
+ RETURN_NULL();
+ } else if (php_password_salt_is_alphabet(buffer, buffer_len) == FAILURE) {
+ salt = safe_emalloc(required_salt_len, 1, 1);
+ if (php_password_salt_to64(buffer, buffer_len, required_salt_len, salt) == FAILURE) {
+ efree(hash_format);
+ efree(buffer);
+ efree(salt);
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Provided salt is too short: %lu", (unsigned long) buffer_len);
+ RETURN_NULL();
+ }
+ salt_len = required_salt_len;
+ } else {
+ salt = safe_emalloc(required_salt_len, 1, 1);
+ memcpy(salt, buffer, (int) required_salt_len);
+ salt_len = required_salt_len;
+ }
+ efree(buffer);
+ } else {
+ salt = safe_emalloc(required_salt_len, 1, 1);
+ if (php_password_make_salt(required_salt_len, salt TSRMLS_CC) == FAILURE) {
+ efree(hash_format);
+ efree(salt);
+ RETURN_FALSE;
+ }
+ salt_len = required_salt_len;
+ }
+
+ salt[salt_len] = 0;
+
+ hash = safe_emalloc(salt_len + hash_format_len, 1, 1);
+ sprintf(hash, "%s%s", hash_format, salt);
+ hash[hash_format_len + salt_len] = 0;
+
+ efree(hash_format);
+ efree(salt);
+
+ /* This cast is safe, since both values are defined here in code and cannot overflow */
+ hash_len = (int) (hash_format_len + salt_len);
+
+ if (php_crypt(password, password_len, hash, hash_len, &result) == FAILURE) {
+ efree(hash);
+ RETURN_FALSE;
+ }
+
+ efree(hash);
+
+ if (strlen(result) < 13) {
+ efree(result);
+ RETURN_FALSE;
+ }
+
+ RETURN_STRING(result, 0);
+}
+/* }}} */
+
+#endif /* HAVE_CRYPT */
+/*
+ * 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/php_array.h b/ext/standard/php_array.h
index 3c8e224e09..e2af3310d0 100644
--- a/ext/standard/php_array.h
+++ b/ext/standard/php_array.h
@@ -71,6 +71,7 @@ PHP_FUNCTION(array_replace_recursive);
PHP_FUNCTION(array_keys);
PHP_FUNCTION(array_values);
PHP_FUNCTION(array_count_values);
+PHP_FUNCTION(array_column);
PHP_FUNCTION(array_reverse);
PHP_FUNCTION(array_reduce);
PHP_FUNCTION(array_pad);
diff --git a/ext/standard/php_crypt.h b/ext/standard/php_crypt.h
index 0664a9f438..f0b96010bc 100644
--- a/ext/standard/php_crypt.h
+++ b/ext/standard/php_crypt.h
@@ -23,6 +23,7 @@
#ifndef PHP_CRYPT_H
#define PHP_CRYPT_H
+PHPAPI int php_crypt(const char *password, const int pass_len, const char *salt, int salt_len, char **result);
PHP_FUNCTION(crypt);
#if HAVE_CRYPT
PHP_MINIT_FUNCTION(crypt);
diff --git a/ext/standard/php_password.h b/ext/standard/php_password.h
new file mode 100644
index 0000000000..a38af97626
--- /dev/null
+++ b/ext/standard/php_password.h
@@ -0,0 +1,48 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2014 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: Anthony Ferrara <ircmaxell@php.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef PHP_PASSWORD_H
+#define PHP_PASSWORD_H
+
+PHP_FUNCTION(password_hash);
+PHP_FUNCTION(password_verify);
+PHP_FUNCTION(password_needs_rehash);
+PHP_FUNCTION(password_get_info);
+
+PHP_MINIT_FUNCTION(password);
+
+#define PHP_PASSWORD_DEFAULT PHP_PASSWORD_BCRYPT
+
+#define PHP_PASSWORD_BCRYPT_COST 10
+
+typedef enum {
+ PHP_PASSWORD_UNKNOWN,
+ PHP_PASSWORD_BCRYPT
+} php_password_algo;
+
+#endif
+
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/ext/standard/php_standard.h b/ext/standard/php_standard.h
index 3c8f55321e..d7476cb397 100644
--- a/ext/standard/php_standard.h
+++ b/ext/standard/php_standard.h
@@ -58,6 +58,7 @@
#include "php_versioning.h"
#include "php_ftok.h"
#include "php_type.h"
+#include "php_password.h"
#define phpext_standard_ptr basic_functions_module_ptr
PHP_MINIT_FUNCTION(standard_filters);
diff --git a/ext/standard/php_type.h b/ext/standard/php_type.h
index 75bb13b39c..8b71f87e5e 100644
--- a/ext/standard/php_type.h
+++ b/ext/standard/php_type.h
@@ -24,6 +24,7 @@
PHP_FUNCTION(intval);
PHP_FUNCTION(floatval);
PHP_FUNCTION(strval);
+PHP_FUNCTION(boolval);
PHP_FUNCTION(gettype);
PHP_FUNCTION(settype);
PHP_FUNCTION(is_null);
diff --git a/ext/standard/proc_open.c b/ext/standard/proc_open.c
index b22877c7ab..1e37e64563 100644
--- a/ext/standard/proc_open.c
+++ b/ext/standard/proc_open.c
@@ -172,7 +172,7 @@ static php_process_env_t _php_array_to_envp(zval *environment, int is_persistent
#endif
p += el_len + 1;
break;
- case HASH_KEY_NON_EXISTANT:
+ case HASH_KEY_NON_EXISTENT:
break;
}
}
@@ -208,6 +208,7 @@ static void proc_open_rsrc_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
DWORD wstatus;
#elif HAVE_SYS_WAIT_H
int wstatus;
+ int waitpid_options = 0;
pid_t wait_pid;
#endif
@@ -220,18 +221,27 @@ static void proc_open_rsrc_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
}
#ifdef PHP_WIN32
- WaitForSingleObject(proc->childHandle, INFINITE);
+ if (FG(pclose_wait)) {
+ WaitForSingleObject(proc->childHandle, INFINITE);
+ }
GetExitCodeProcess(proc->childHandle, &wstatus);
- FG(pclose_ret) = wstatus;
+ if (wstatus == STILL_ACTIVE) {
+ FG(pclose_ret) = -1;
+ } else {
+ FG(pclose_ret) = wstatus;
+ }
CloseHandle(proc->childHandle);
#elif HAVE_SYS_WAIT_H
+ if (!FG(pclose_wait)) {
+ waitpid_options = WNOHANG;
+ }
do {
- wait_pid = waitpid(proc->child, &wstatus, 0);
+ wait_pid = waitpid(proc->child, &wstatus, waitpid_options);
} while (wait_pid == -1 && errno == EINTR);
- if (wait_pid == -1) {
+ if (wait_pid <= 0) {
FG(pclose_ret) = -1;
} else {
if (WIFEXITED(wstatus))
@@ -300,7 +310,9 @@ PHP_FUNCTION(proc_close)
ZEND_FETCH_RESOURCE(proc, struct php_process_handle *, &zproc, -1, "process", le_proc_open);
+ FG(pclose_wait) = 1;
zend_list_delete(Z_LVAL_P(zproc));
+ FG(pclose_wait) = 0;
RETURN_LONG(FG(pclose_ret));
}
/* }}} */
@@ -438,6 +450,7 @@ PHP_FUNCTION(proc_open)
DWORD dwCreateFlags = 0;
char *command_with_cmd;
UINT old_error_mode;
+ char cur_cwd[MAXPATHLEN];
#endif
#ifdef NETWARE
char** child_argv = NULL;
@@ -676,13 +689,13 @@ PHP_FUNCTION(proc_open)
#ifdef PHP_WIN32
if (cwd == NULL) {
- char cur_cwd[MAXPATHLEN];
char *getcwd_result;
getcwd_result = VCWD_GETCWD(cur_cwd, MAXPATHLEN);
if (!getcwd_result) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot get current directory");
goto exit_fail;
}
+ cwd = cur_cwd;
}
memset(&si, 0, sizeof(si));
diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c
index bdb05ec9b8..b623447651 100644
--- a/ext/standard/streamsfuncs.c
+++ b/ext/standard/streamsfuncs.c
@@ -583,7 +583,7 @@ PHP_FUNCTION(stream_get_wrappers)
HashPosition pos;
array_init(return_value);
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;
+ (key_flags = zend_hash_get_current_key_ex(url_stream_wrappers_hash, &stream_protocol, &stream_protocol_len, &num_key, 0, &pos)) != HASH_KEY_NON_EXISTENT;
zend_hash_move_forward_ex(url_stream_wrappers_hash, &pos)) {
if (key_flags == HASH_KEY_IS_STRING) {
add_next_index_stringl(return_value, stream_protocol, stream_protocol_len - 1, 1);
@@ -668,7 +668,7 @@ static int stream_array_from_fd_set(zval *stream_array, fd_set *fds TSRMLS_DC)
type = zend_hash_get_current_key_ex(Z_ARRVAL_P(stream_array),
&key, &key_len, &num_ind, 0, NULL);
- if (type == HASH_KEY_NON_EXISTANT ||
+ if (type == HASH_KEY_NON_EXISTENT ||
zend_hash_get_current_data(Z_ARRVAL_P(stream_array), (void **) &elem) == FAILURE) {
continue; /* should not happen */
}
diff --git a/ext/standard/string.c b/ext/standard/string.c
index c4e77f2f29..009479b191 100644
--- a/ext/standard/string.c
+++ b/ext/standard/string.c
@@ -280,6 +280,7 @@ PHP_FUNCTION(hex2bin)
result = php_hex2bin((unsigned char *)data, datalen, &newlen);
if (!result) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Input string must be hexadecimal string");
RETURN_FALSE;
}
@@ -2864,7 +2865,7 @@ static inline void php_strtr_populate_shift(PATNREPL *patterns, int patnum, int
}
/* }}} */
/* {{{ php_strtr_compare_hash_suffix */
-static int php_strtr_compare_hash_suffix(const void *a, const void *b, void *ctx_g)
+static int php_strtr_compare_hash_suffix(const void *a, const void *b TSRMLS_DC, void *ctx_g)
{
const PPRES *res = ctx_g;
const PATNREPL *pnr_a = a,
@@ -2890,62 +2891,6 @@ static int php_strtr_compare_hash_suffix(const void *a, const void *b, void *ctx
}
}
/* }}} */
-/* {{{ Sorting (no zend_qsort_r in this PHP version) */
-#define HS_LEFT(i) ((i) * 2 + 1)
-#define HS_RIGHT(i) ((i) * 2 + 2)
-#define HS_PARENT(i) (((i) - 1) / 2);
-#define HS_OFF(data, i) ((void *)(&((data)->arr)[i]))
-#define HS_CMP_CALL(data, i1, i2) \
- (php_strtr_compare_hash_suffix(HS_OFF((data), (i1)), HS_OFF((data), (i2)), (data)->res))
-struct hs_data {
- PATNREPL *arr;
- size_t nel;
- size_t heapel;
- PPRES *res;
-};
-static inline void php_strtr_swap(PATNREPL *a, PATNREPL *b)
-{
- PATNREPL tmp = *a;
- *a = *b;
- *b = tmp;
-}
-static inline void php_strtr_fix_heap(struct hs_data *data, size_t i)
-{
- size_t li = HS_LEFT(i),
- ri = HS_RIGHT(i),
- largei;
- if (li < data->heapel && HS_CMP_CALL(data, li, i) > 0) {
- largei = li;
- } else {
- largei = i;
- }
- if (ri < data->heapel && HS_CMP_CALL(data, ri, largei) > 0) {
- largei = ri;
- }
- if (largei != i) {
- php_strtr_swap(HS_OFF(data, i), HS_OFF(data, largei));
- php_strtr_fix_heap(data, largei);
- }
-}
-static inline void php_strtr_build_heap(struct hs_data *data)
-{
- size_t i;
- for (i = data->nel / 2; i > 0; i--) {
- php_strtr_fix_heap(data, i - 1);
- }
-}
-static inline void php_strtr_heapsort(PATNREPL *arr, size_t nel, PPRES *res)
-{
- struct hs_data data = { arr, nel, nel, res };
- size_t i;
- php_strtr_build_heap(&data);
- for (i = nel; i > 1; i--) {
- php_strtr_swap(arr, HS_OFF(&data, i - 1));
- data.heapel--;
- php_strtr_fix_heap(&data, 0);
- }
-}
-/* }}} */
/* {{{ php_strtr_free_strp */
static void php_strtr_free_strp(void *strp)
{
@@ -3043,7 +2988,13 @@ static PPRES *php_strtr_array_prepare(STR *text, PATNREPL *patterns, int patnum,
res->patterns = safe_emalloc(patnum, sizeof(*res->patterns), 0);
memcpy(res->patterns, patterns, sizeof(*patterns) * patnum);
- php_strtr_heapsort(res->patterns, patnum, res);
+#ifdef ZTS
+ zend_qsort_r(res->patterns, patnum, sizeof(*res->patterns),
+ php_strtr_compare_hash_suffix, res, NULL); /* tsrmls not needed */
+#else
+ zend_qsort_r(res->patterns, patnum, sizeof(*res->patterns),
+ php_strtr_compare_hash_suffix, res);
+#endif
res->prefix = safe_emalloc(patnum, sizeof(*res->prefix), 0);
for (i = 0; i < patnum; i++) {
@@ -5665,7 +5616,7 @@ PHP_FUNCTION(substr_compare)
if (!cs) {
RETURN_LONG(zend_binary_strncmp(s1 + offset, (s1_len - offset), s2, s2_len, cmp_len));
} else {
- RETURN_LONG(zend_binary_strncasecmp(s1 + offset, (s1_len - offset), s2, s2_len, cmp_len));
+ RETURN_LONG(zend_binary_strncasecmp_l(s1 + offset, (s1_len - offset), s2, s2_len, cmp_len));
}
}
/* }}} */
diff --git a/ext/standard/tests/array/array_column_basic.phpt b/ext/standard/tests/array/array_column_basic.phpt
new file mode 100644
index 0000000000..418f373872
--- /dev/null
+++ b/ext/standard/tests/array/array_column_basic.phpt
@@ -0,0 +1,327 @@
+--TEST--
+Test array_column() function: basic functionality
+--FILE--
+<?php
+/* Prototype:
+ * array array_column(array $input, mixed $column_key[, mixed $index_key]);
+ * Description:
+ * Returns an array containing all the values from
+ * the specified "column" in a two-dimensional array.
+ */
+
+echo "*** Testing array_column() : basic functionality ***\n";
+/* Array representing a possible record set returned from a database */
+$records = array(
+ array(
+ 'id' => 1,
+ 'first_name' => 'John',
+ 'last_name' => 'Doe'
+ ),
+ array(
+ 'id' => 2,
+ 'first_name' => 'Sally',
+ 'last_name' => 'Smith'
+ ),
+ array(
+ 'id' => 3,
+ 'first_name' => 'Jane',
+ 'last_name' => 'Jones'
+ )
+);
+
+echo "-- first_name column from recordset --\n";
+var_dump(array_column($records, 'first_name'));
+
+echo "-- id column from recordset --\n";
+var_dump(array_column($records, 'id'));
+
+echo "-- last_name column from recordset, keyed by value from id column --\n";
+var_dump(array_column($records, 'last_name', 'id'));
+
+echo "-- last_name column from recordset, keyed by value from first_name column --\n";
+var_dump(array_column($records, 'last_name', 'first_name'));
+
+echo "\n*** Testing multiple data types ***\n";
+$fh = fopen(__FILE__, 'r', true);
+$values = array(
+ array(
+ 'id' => 1,
+ 'value' => new stdClass
+ ),
+ array(
+ 'id' => 2,
+ 'value' => 34.2345
+ ),
+ array(
+ 'id' => 3,
+ 'value' => true
+ ),
+ array(
+ 'id' => 4,
+ 'value' => false
+ ),
+ array(
+ 'id' => 5,
+ 'value' => null
+ ),
+ array(
+ 'id' => 6,
+ 'value' => 1234
+ ),
+ array(
+ 'id' => 7,
+ 'value' => 'Foo'
+ ),
+ array(
+ 'id' => 8,
+ 'value' => $fh
+ )
+);
+var_dump(array_column($values, 'value'));
+var_dump(array_column($values, 'value', 'id'));
+
+echo "\n*** Testing numeric column keys ***\n";
+$numericCols = array(
+ array('aaa', '111'),
+ array('bbb', '222'),
+ array('ccc', '333', -1 => 'ddd')
+);
+var_dump(array_column($numericCols, 1));
+var_dump(array_column($numericCols, 1, 0));
+var_dump(array_column($numericCols, 1, 0.123));
+var_dump(array_column($numericCols, 1, -1));
+
+echo "\n*** Testing failure to find specified column ***\n";
+var_dump(array_column($numericCols, 2));
+var_dump(array_column($numericCols, 'foo'));
+var_dump(array_column($numericCols, 0, 'foo'));
+var_dump(array_column($numericCols, 3.14));
+
+echo "\n*** Testing single dimensional array ***\n";
+$singleDimension = array('foo', 'bar', 'baz');
+var_dump(array_column($singleDimension, 1));
+
+echo "\n*** Testing columns not present in all rows ***\n";
+$mismatchedColumns = array(
+ array('a' => 'foo', 'b' => 'bar', 'e' => 'bbb'),
+ array('a' => 'baz', 'c' => 'qux', 'd' => 'aaa'),
+ array('a' => 'eee', 'b' => 'fff', 'e' => 'ggg'),
+);
+var_dump(array_column($mismatchedColumns, 'c'));
+var_dump(array_column($mismatchedColumns, 'c', 'a'));
+var_dump(array_column($mismatchedColumns, 'a', 'd'));
+var_dump(array_column($mismatchedColumns, 'a', 'e'));
+var_dump(array_column($mismatchedColumns, 'b'));
+var_dump(array_column($mismatchedColumns, 'b', 'a'));
+
+echo "\n*** Testing use of object converted to string ***\n";
+class Foo
+{
+ public function __toString()
+ {
+ return 'last_name';
+ }
+}
+class Bar
+{
+ public function __toString()
+ {
+ return 'first_name';
+ }
+}
+$f = new Foo();
+$b = new Bar();
+var_dump(array_column($records, $f));
+var_dump(array_column($records, $f, $b));
+
+echo "Done\n";
+?>
+--EXPECTF--
+*** Testing array_column() : basic functionality ***
+-- first_name column from recordset --
+array(3) {
+ [0]=>
+ string(4) "John"
+ [1]=>
+ string(5) "Sally"
+ [2]=>
+ string(4) "Jane"
+}
+-- id column from recordset --
+array(3) {
+ [0]=>
+ int(1)
+ [1]=>
+ int(2)
+ [2]=>
+ int(3)
+}
+-- last_name column from recordset, keyed by value from id column --
+array(3) {
+ [1]=>
+ string(3) "Doe"
+ [2]=>
+ string(5) "Smith"
+ [3]=>
+ string(5) "Jones"
+}
+-- last_name column from recordset, keyed by value from first_name column --
+array(3) {
+ ["John"]=>
+ string(3) "Doe"
+ ["Sally"]=>
+ string(5) "Smith"
+ ["Jane"]=>
+ string(5) "Jones"
+}
+
+*** Testing multiple data types ***
+array(8) {
+ [0]=>
+ object(stdClass)#%d (0) {
+ }
+ [1]=>
+ float(34.2345)
+ [2]=>
+ bool(true)
+ [3]=>
+ bool(false)
+ [4]=>
+ NULL
+ [5]=>
+ int(1234)
+ [6]=>
+ string(3) "Foo"
+ [7]=>
+ resource(%d) of type (stream)
+}
+array(8) {
+ [1]=>
+ object(stdClass)#%d (0) {
+ }
+ [2]=>
+ float(34.2345)
+ [3]=>
+ bool(true)
+ [4]=>
+ bool(false)
+ [5]=>
+ NULL
+ [6]=>
+ int(1234)
+ [7]=>
+ string(3) "Foo"
+ [8]=>
+ resource(%d) of type (stream)
+}
+
+*** Testing numeric column keys ***
+array(3) {
+ [0]=>
+ string(3) "111"
+ [1]=>
+ string(3) "222"
+ [2]=>
+ string(3) "333"
+}
+array(3) {
+ ["aaa"]=>
+ string(3) "111"
+ ["bbb"]=>
+ string(3) "222"
+ ["ccc"]=>
+ string(3) "333"
+}
+array(3) {
+ ["aaa"]=>
+ string(3) "111"
+ ["bbb"]=>
+ string(3) "222"
+ ["ccc"]=>
+ string(3) "333"
+}
+array(3) {
+ [0]=>
+ string(3) "111"
+ [1]=>
+ string(3) "222"
+ ["ddd"]=>
+ string(3) "333"
+}
+
+*** Testing failure to find specified column ***
+array(0) {
+}
+array(0) {
+}
+array(3) {
+ [0]=>
+ string(3) "aaa"
+ [1]=>
+ string(3) "bbb"
+ [2]=>
+ string(3) "ccc"
+}
+array(0) {
+}
+
+*** Testing single dimensional array ***
+array(0) {
+}
+
+*** Testing columns not present in all rows ***
+array(1) {
+ [0]=>
+ string(3) "qux"
+}
+array(1) {
+ ["baz"]=>
+ string(3) "qux"
+}
+array(3) {
+ [0]=>
+ string(3) "foo"
+ ["aaa"]=>
+ string(3) "baz"
+ [1]=>
+ string(3) "eee"
+}
+array(3) {
+ ["bbb"]=>
+ string(3) "foo"
+ [0]=>
+ string(3) "baz"
+ ["ggg"]=>
+ string(3) "eee"
+}
+array(2) {
+ [0]=>
+ string(3) "bar"
+ [1]=>
+ string(3) "fff"
+}
+array(2) {
+ ["foo"]=>
+ string(3) "bar"
+ ["eee"]=>
+ string(3) "fff"
+}
+
+*** Testing use of object converted to string ***
+array(3) {
+ [0]=>
+ string(3) "Doe"
+ [1]=>
+ string(5) "Smith"
+ [2]=>
+ string(5) "Jones"
+}
+array(3) {
+ ["John"]=>
+ string(3) "Doe"
+ ["Sally"]=>
+ string(5) "Smith"
+ ["Jane"]=>
+ string(5) "Jones"
+}
+Done
diff --git a/ext/standard/tests/array/array_column_error.phpt b/ext/standard/tests/array/array_column_error.phpt
new file mode 100644
index 0000000000..bdcbec0062
--- /dev/null
+++ b/ext/standard/tests/array/array_column_error.phpt
@@ -0,0 +1,82 @@
+--TEST--
+Test array_column() function: error conditions
+--FILE--
+<?php
+/* Prototype:
+ * array array_column(array $input, mixed $column_key[, mixed $index_key]);
+ * Description:
+ * Returns an array containing all the values from
+ * the specified "column" in a two-dimensional array.
+ */
+
+echo "*** Testing array_column() : error conditions ***\n";
+
+echo "\n-- Testing array_column() function with Zero arguments --\n";
+var_dump(array_column());
+
+echo "\n-- Testing array_column() function with One argument --\n";
+var_dump(array_column(array()));
+
+echo "\n-- Testing array_column() function with string as first parameter --\n";
+var_dump(array_column('foo', 0));
+
+echo "\n-- Testing array_column() function with int as first parameter --\n";
+var_dump(array_column(1, 'foo'));
+
+echo "\n-- Testing array_column() column key parameter should be a string or an integer (testing bool) --\n";
+var_dump(array_column(array(), true));
+
+echo "\n-- Testing array_column() column key parameter should be a string or integer (testing array) --\n";
+var_dump(array_column(array(), array()));
+
+echo "\n-- Testing array_column() index key parameter should be a string or an integer (testing bool) --\n";
+var_dump(array_column(array(), 'foo', true));
+
+echo "\n-- Testing array_column() index key parameter should be a string or integer (testing array) --\n";
+var_dump(array_column(array(), 'foo', array()));
+
+echo "Done\n";
+?>
+--EXPECTF--
+*** Testing array_column() : error conditions ***
+
+-- Testing array_column() function with Zero arguments --
+
+Warning: array_column() expects at least 2 parameters, 0 given in %s on line %d
+NULL
+
+-- Testing array_column() function with One argument --
+
+Warning: array_column() expects at least 2 parameters, 1 given in %s on line %d
+NULL
+
+-- Testing array_column() function with string as first parameter --
+
+Warning: array_column() expects parameter 1 to be array, string given in %s on line %d
+NULL
+
+-- Testing array_column() function with int as first parameter --
+
+Warning: array_column() expects parameter 1 to be array, integer given in %s on line %d
+NULL
+
+-- Testing array_column() column key parameter should be a string or an integer (testing bool) --
+
+Warning: array_column(): The column key should be either a string or an integer in %s on line %d
+bool(false)
+
+-- Testing array_column() column key parameter should be a string or integer (testing array) --
+
+Warning: array_column(): The column key should be either a string or an integer in %s on line %d
+bool(false)
+
+-- Testing array_column() index key parameter should be a string or an integer (testing bool) --
+
+Warning: array_column(): The index key should be either a string or an integer in %s on line %d
+bool(false)
+
+-- Testing array_column() index key parameter should be a string or integer (testing array) --
+
+Warning: array_column(): The index key should be either a string or an integer in %s on line %d
+bool(false)
+Done
diff --git a/ext/standard/tests/array/array_column_object_cast.phpt b/ext/standard/tests/array/array_column_object_cast.phpt
new file mode 100644
index 0000000000..762aaa81f4
--- /dev/null
+++ b/ext/standard/tests/array/array_column_object_cast.phpt
@@ -0,0 +1,52 @@
+--TEST--
+Test array_column() function: basic functionality
+--FILE--
+<?php
+class ColumnKeyClass {
+ function __toString() { return 'first_name'; }
+}
+
+class IndexKeyClass {
+ function __toString() { return 'id'; }
+}
+
+class ValueClass {
+ function __toString() { return '2135'; }
+}
+
+
+$column_key = new ColumnKeyClass();
+$index_key = new IndexKeyClass();
+$value = new ValueClass();
+
+
+// Array representing a possible record set returned from a database
+$records = array(
+ array(
+ 'id' => $value,
+ 'first_name' => 'John',
+ 'last_name' => 'XXX'
+ ),
+ array(
+ 'id' => 3245,
+ 'first_name' => 'Sally',
+ 'last_name' => 'Smith'
+ ),
+);
+$firstNames = array_column($records, $column_key, $index_key);
+print_r($firstNames);
+var_dump($column_key);
+var_dump($index_key);
+var_dump($value);
+--EXPECTF--
+Array
+(
+ [2135] => John
+ [3245] => Sally
+)
+object(ColumnKeyClass)#%d (0) {
+}
+object(IndexKeyClass)#%d (0) {
+}
+object(ValueClass)#%d (0) {
+}
diff --git a/ext/standard/tests/array/array_column_variant.phpt b/ext/standard/tests/array/array_column_variant.phpt
new file mode 100644
index 0000000000..0af0869497
--- /dev/null
+++ b/ext/standard/tests/array/array_column_variant.phpt
@@ -0,0 +1,85 @@
+--TEST--
+Test array_column() function: variant functionality
+--FILE--
+<?php
+/* Array from Bug Request #64493 test script */
+$rows = array(
+ 456 => array('id' => '3', 'title' => 'Foo', 'date' => '2013-03-25'),
+ 457 => array('id' => '5', 'title' => 'Bar', 'date' => '2012-05-20'),
+);
+
+echo "-- pass null as second parameter to get back all columns indexed by third parameter --\n";
+var_dump(array_column($rows, null, 'id'));
+
+echo "-- pass null as second parameter and bogus third param to get back zero-indexed array of all columns --\n";
+var_dump(array_column($rows, null, 'foo'));
+
+echo "-- pass null as second parameter and no third param to get back array_values(input) --\n";
+var_dump(array_column($rows, null));
+
+echo "Done\n";
+--EXPECTF--
+-- pass null as second parameter to get back all columns indexed by third parameter --
+array(2) {
+ [3]=>
+ array(3) {
+ ["id"]=>
+ string(1) "3"
+ ["title"]=>
+ string(3) "Foo"
+ ["date"]=>
+ string(10) "2013-03-25"
+ }
+ [5]=>
+ array(3) {
+ ["id"]=>
+ string(1) "5"
+ ["title"]=>
+ string(3) "Bar"
+ ["date"]=>
+ string(10) "2012-05-20"
+ }
+}
+-- pass null as second parameter and bogus third param to get back zero-indexed array of all columns --
+array(2) {
+ [0]=>
+ array(3) {
+ ["id"]=>
+ string(1) "3"
+ ["title"]=>
+ string(3) "Foo"
+ ["date"]=>
+ string(10) "2013-03-25"
+ }
+ [1]=>
+ array(3) {
+ ["id"]=>
+ string(1) "5"
+ ["title"]=>
+ string(3) "Bar"
+ ["date"]=>
+ string(10) "2012-05-20"
+ }
+}
+-- pass null as second parameter and no third param to get back array_values(input) --
+array(2) {
+ [0]=>
+ array(3) {
+ ["id"]=>
+ string(1) "3"
+ ["title"]=>
+ string(3) "Foo"
+ ["date"]=>
+ string(10) "2013-03-25"
+ }
+ [1]=>
+ array(3) {
+ ["id"]=>
+ string(1) "5"
+ ["title"]=>
+ string(3) "Bar"
+ ["date"]=>
+ string(10) "2012-05-20"
+ }
+}
+Done
diff --git a/ext/standard/tests/array/compact.phpt b/ext/standard/tests/array/compact.phpt
index 4b4bfbb732..02df44ebd8 100644
--- a/ext/standard/tests/array/compact.phpt
+++ b/ext/standard/tests/array/compact.phpt
@@ -1,8 +1,5 @@
--TEST--
compact()
---INI--
-unicode.script_encoding=UTF-8
-unicode.output_encoding=UTF-8
--FILE--
<?php
diff --git a/ext/standard/tests/array/each.phpt b/ext/standard/tests/array/each.phpt
index 19ee728fd2..974808c08c 100644
--- a/ext/standard/tests/array/each.phpt
+++ b/ext/standard/tests/array/each.phpt
Binary files differ
diff --git a/ext/standard/tests/array/locale_sort.phpt b/ext/standard/tests/array/locale_sort.phpt
index 1db96042e8..c2f66c01df 100644
--- a/ext/standard/tests/array/locale_sort.phpt
+++ b/ext/standard/tests/array/locale_sort.phpt
@@ -9,9 +9,6 @@ if (false == setlocale(LC_CTYPE, "fr_FR.ISO8859-1", "fr_FR")) {
die("skip setlocale() failed\n");
}
?>
---INI--
-unicode.script_encoding=ISO8859-1
-unicode.output_encoding=ISO8859-1
--FILE--
<?php
setlocale(LC_ALL, 'fr_FR.ISO8859-1', 'fr_FR');
diff --git a/ext/standard/tests/array/uasort_variation9.phpt b/ext/standard/tests/array/uasort_variation9.phpt
index 486042e5e7..85578b0207 100644
--- a/ext/standard/tests/array/uasort_variation9.phpt
+++ b/ext/standard/tests/array/uasort_variation9.phpt
@@ -14,7 +14,7 @@ echo "*** Testing uasort() : 'cmp_function' with reference arguments ***\n";
// comparison function
/* Prototype : int cmp(mixed &$value1, mixed &$value2)
- * Parameters : $value1 and $value2 - values recieved by reference
+ * Parameters : $value1 and $value2 - values received by reference
* Return value : 0 - if both values are same
* 1 - if value1 is greater than value2
* -1 - if value1 is less than value2
diff --git a/ext/standard/tests/bug64370_var1.phpt b/ext/standard/tests/bug64370_var1.phpt
index ff64d61616..aca46a594d 100644
--- a/ext/standard/tests/bug64370_var1.phpt
+++ b/ext/standard/tests/bug64370_var1.phpt
@@ -1,10 +1,5 @@
--TEST--
Test bug #64370 microtime(true) less than $_SERVER['REQUEST_TIME_FLOAT']
---SKIPIF--
-<?php
- if (PHP_MAJOR_VERSION < 5 || (PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 4)) {
- die('skip PHP 5.4+ only');
- }
--FILE--
<?php
echo "\$_SERVER['REQUEST_TIME']: {$_SERVER['REQUEST_TIME']}\n";
diff --git a/ext/standard/tests/dir/dir_variation1-win32.phpt b/ext/standard/tests/dir/dir_variation1-win32.phpt
deleted file mode 100644
index 1f7f4a2cf3..0000000000
--- a/ext/standard/tests/dir/dir_variation1-win32.phpt
+++ /dev/null
@@ -1,170 +0,0 @@
---TEST--
-Test dir() function : usage variations - unexpected value for 'dir' argument
---SKIPIF--
-<?php
-if (substr(PHP_OS, 0, 3) != 'WIN') {
- die("skip Valid only on Windows");
-}
-?>
---FILE--
-<?php
-/*
- * Prototype : object dir(string $directory[, resource $context])
- * Description: Directory class with properties, handle and class and methods read, rewind and close
- * Source code: ext/standard/dir.c
- */
-
-/*
- * Passing non string values to 'directory' argument of dir() and see
- * that the function outputs proper warning messages wherever expected.
- */
-
-echo "*** Testing dir() : unexpected values for \$directory argument ***\n";
-
-// get an unset variable
-$unset_var = 10;
-unset($unset_var);
-
-class A
-{
- public $var;
- public function init() {
- $this->var = 10;
- }
-}
-
-// get a resource variable
-$fp = fopen(__FILE__, "r"); // get a file handle
-$dfp = opendir( dirname(__FILE__) ); // get a dir handle
-
-// unexpected values to be passed to $directory argument
-$unexpected_values = array (
-
- // array data
-/*1*/ array(),
- array(0),
- array(1),
- array(1, 2),
- array('color' => 'red', 'item' => 'pen'),
-
- // null data
-/*6*/ NULL,
- null,
-
- // boolean data
-/*8*/ true,
- false,
- TRUE,
- FALSE,
-
- // empty data
-/*12*/ "",
- '',
-
- // undefined data
-/*14*/ @$undefined_var,
-
- // unset data
-/*15*/ @$unset_var,
-
- // resource variable(dir and file handle)
-/*16*/ $fp,
- $dfp,
-
- // object data
-/*18*/ new A()
-);
-
-// loop through various elements of $unexpected_values to check the behavior of dir()
-$iterator = 1;
-foreach( $unexpected_values as $unexpected_value ) {
- echo "\n-- Iteration $iterator --\n";
- var_dump( dir($unexpected_value) );
- $iterator++;
-}
-
-fclose($fp);
-closedir($dfp);
-echo "Done";
-?>
---EXPECTF--
-*** Testing dir() : unexpected values for $directory argument ***
-
--- Iteration 1 --
-
-Warning: dir() expects parameter 1 to be string, array given in %s on line %d
-NULL
-
--- Iteration 2 --
-
-Warning: dir() expects parameter 1 to be string, array given in %s on line %d
-NULL
-
--- Iteration 3 --
-
-Warning: dir() expects parameter 1 to be string, array given in %s on line %d
-NULL
-
--- Iteration 4 --
-
-Warning: dir() expects parameter 1 to be string, array given in %s on line %d
-NULL
-
--- Iteration 5 --
-
-Warning: dir() expects parameter 1 to be string, array given in %s on line %d
-NULL
-
--- Iteration 6 --
-bool(false)
-
--- Iteration 7 --
-bool(false)
-
--- Iteration 8 --
-
-Warning: dir(1,1): The system cannot find the file specified. (code: 2) in %s on line %d
-
-Warning: dir(1): failed to open dir: %s in %s on line %d
-bool(false)
-
--- Iteration 9 --
-bool(false)
-
--- Iteration 10 --
-
-Warning: dir(1,1): The system cannot find the file specified. (code: 2) in %s on line %d
-
-Warning: dir(1): failed to open dir: %s in %s on line %d
-bool(false)
-
--- Iteration 11 --
-bool(false)
-
--- Iteration 12 --
-bool(false)
-
--- Iteration 13 --
-bool(false)
-
--- Iteration 14 --
-bool(false)
-
--- Iteration 15 --
-bool(false)
-
--- Iteration 16 --
-
-Warning: dir() expects parameter 1 to be string, resource given in %s on line %d
-NULL
-
--- Iteration 17 --
-
-Warning: dir() expects parameter 1 to be string, resource given in %s on line %d
-NULL
-
--- Iteration 18 --
-
-Warning: dir() expects parameter 1 to be string, object given in %s on line %d
-NULL
-Done \ No newline at end of file
diff --git a/ext/standard/tests/dir/dir_variation5-win32.phpt b/ext/standard/tests/dir/dir_variation5-win32.phpt
deleted file mode 100644
index e70b9d3533..0000000000
--- a/ext/standard/tests/dir/dir_variation5-win32.phpt
+++ /dev/null
@@ -1,37 +0,0 @@
---TEST--
-Test dir() function : usage variations - open a file instead of directory
---SKIPIF--
-<?php
-if (substr(PHP_OS, 0, 3) != 'WIN') {
- die("skip Valid only on Windows");
-}
-?>
---FILE--
-<?php
-/*
- * Prototype : object dir(string $directory[, resource $context])
- * Description: Directory class with properties, handle and class and methods read, rewind and close
- * Source code: ext/standard/dir.c
- */
-
-/*
- * Passing a file as argument to dir() function instead of a directory
- * and checking if proper warning message is generated.
- */
-
-echo "*** Testing dir() : open a file instead of a directory ***\n";
-
-// open the file instead of directory
-$d = dir(__FILE__);
-var_dump( $d );
-
-echo "Done";
-?>
---EXPECTF--
-*** Testing dir() : open a file instead of a directory ***
-
-Warning: dir(%s): The directory name is invalid. (code: %d) in %s on line %d
-
-Warning: dir(%s): failed to open dir: %s in %s on line %d
-bool(false)
-Done
diff --git a/ext/standard/tests/dir/dir_variation6-win32.phpt b/ext/standard/tests/dir/dir_variation6-win32.phpt
deleted file mode 100644
index e0e4749809..0000000000
--- a/ext/standard/tests/dir/dir_variation6-win32.phpt
+++ /dev/null
@@ -1,61 +0,0 @@
---TEST--
-Test dir() function : usage variations - non-existent directory
---SKIPIF--
-<?php
-if (substr(PHP_OS, 0, 3) != 'WIN') {
- die("skip Valid only on Windows");
-}
-?>
---FILE--
-<?php
-/*
- * Prototype : object dir(string $directory[, resource $context])
- * Description: Directory class with properties, handle and class and methods read, rewind and close
- * Source code: ext/standard/dir.c
- */
-
-/*
- * Passing a non-existent directory as argument to dir() function
- * and checking to see if proper warning message is output.
- */
-echo "*** Testing dir() : open a non-existent directory ***\n";
-
-// create the temporary directory
-$file_path = dirname(__FILE__);
-$dir_path = $file_path."/dir_variation6";
-@mkdir($dir_path);
-
-// open existent directory
-$d = dir($dir_path);
-$d->close(); //close the dir
-
-// remove directory and try to open the same(non-existent) directory again
-rmdir($dir_path);
-clearstatcache();
-
-echo "-- opening previously removed directory --\n";
-var_dump( dir($dir_path) );
-
-// point to a non-existent directory
-$non_existent_dir = $file_path."/non_existent_dir";
-echo "-- opening non-existent directory --\n";
-$d = dir($non_existent_dir);
-var_dump( $d );
-
-echo "Done";
-?>
---EXPECTF--
-*** Testing dir() : open a non-existent directory ***
--- opening previously removed directory --
-
-Warning: dir(%s): The system cannot find the file specified. (code: %d) in %s on line %d
-
-Warning: dir(%s): failed to open dir: %s in %s on line %d
-bool(false)
--- opening non-existent directory --
-
-Warning: dir(%s): The system cannot find the file specified. (code: %d) in %s on line %d
-
-Warning: dir(%s): failed to open dir: %s in %s on line %d
-bool(false)
-Done
diff --git a/ext/standard/tests/dir/dir_variation8-win32.phpt b/ext/standard/tests/dir/dir_variation8-win32.phpt
deleted file mode 100644
index a56c98b880..0000000000
--- a/ext/standard/tests/dir/dir_variation8-win32.phpt
+++ /dev/null
@@ -1,68 +0,0 @@
---TEST--
-Test dir() function : usage variations - checking with wildcard characters
---SKIPIF--
-<?php
-if (substr(PHP_OS, 0, 3) != 'WIN') {
- die("skip Valid only on Windows");
-}
-?>
---FILE--
-<?php
-/*
- * Prototype : object dir(string $directory[, resource $context])
- * Description: Directory class with properties, handle and class and methods read, rewind and close
- * Source code: ext/standard/dir.c
- */
-
-/*
- * Create more than one temporary directory & subdirectory and check if dir() function can open
- * those directories when wildcard characters are used to refer to them.
- */
-
-echo "*** Testing dir() : checking with wildcard characters ***\n";
-
-// create the temporary directories
-$file_path = dirname(__FILE__);
-$dir_path = $file_path."/dir_variation81";
-$sub_dir_path = $dir_path."/sub_dir1";
-
-@mkdir($dir_path1);
-@mkdir($sub_dir_path);
-
-/* with different wildcard characters */
-
-echo "-- wildcard = '*' --\n";
-var_dump( dir($file_path."/dir_var*") );
-var_dump( dir($file_path."/*") );
-
-echo "-- wildcard = '?' --\n";
-var_dump( dir($dir_path."/sub_dir?") );
-var_dump( dir($dir_path."/sub?dir1") );
-
-echo "Done";
-?>
---EXPECTF--
-*** Testing dir() : checking with wildcard characters ***
--- wildcard = '*' --
-
-Warning: dir(%s/dir_var*,%s/dir_var*): %r(No such file or directory|The system cannot find the path specified. \(code: 3\))%r in %s on line %d
-
-Warning: dir(%s/dir_var*): failed to open dir: %s in %s on line %d
-bool(false)
-
-Warning: dir(%s/*,%s/*): %r(No such file or directory|The system cannot find the path specified. \(code: 3\))%r in %s on line %d
-
-Warning: dir(%s/*): failed to open dir: %s in %s on line %d
-bool(false)
--- wildcard = '?' --
-
-Warning: dir(%s/dir_variation81/sub_dir?,%s/dir_variation81/sub_dir?): %r(No such file or directory|The system cannot find the path specified. \(code: 3\))%r in %s on line %d
-
-Warning: dir(%s/dir_variation81/sub_dir?): failed to open dir: %s in %s on line %d
-bool(false)
-
-Warning: dir(%s/dir_variation81/sub?dir1,%s/dir_variation81/sub?dir1): %r(No such file or directory|The system cannot find the path specified. \(code: 3\))%r in %s on line %d
-
-Warning: dir(%s/dir_variation81/sub?dir1): failed to open dir: %s in %s on line %d
-bool(false)
-Done
diff --git a/ext/standard/tests/dir/dir_variation9-win32.phpt b/ext/standard/tests/dir/dir_variation9-win32.phpt
deleted file mode 100644
index 32b0bd946b..0000000000
--- a/ext/standard/tests/dir/dir_variation9-win32.phpt
+++ /dev/null
@@ -1,125 +0,0 @@
---TEST--
-Test dir() function : usage variations - relative valid and invalid paths
---SKIPIF--
-<?php
-if (substr(PHP_OS, 0, 3) != 'WIN') {
- die("skip Valid only on Windows");
-}
-?>
---FILE--
-<?php
-/*
- * Prototype : object dir(string $directory[, resource $context])
- * Description: Directory class with properties, handle and class and methods read, rewind and close
- * Source code: ext/standard/dir.c
- */
-
-/*
- * Checking the behavior of dir() function by passing directories which
- * have valid and invalid relative path.
- */
-
-echo "*** Testing dir() : checking with valid and invalid paths ***\n";
-
-/* create the temporary directories */
-
-$file_path = dirname(__FILE__);
-
-// directory dir_variation91 with one sub-directory sub_dir11 and sub-sub-directory sub_dir111
-$dir_path1 = $file_path."/dir_variation91";
-$sub_dir11 = $dir_path1."/sub_dir11";
-$sub_dir111 = $sub_dir11."/sub_dir111";
-
-// directory dir_variation92 with one sub-directory sub_dir21
-$dir_path2 = $file_path."/dir_variation92";
-$sub_dir21 = $dir_path2."/sub_dir21";
-
-@mkdir($dir_path1);
-@mkdir($dir_path2);
-@mkdir($sub_dir11);
-@mkdir($sub_dir111);
-@mkdir($sub_dir21);
-
-// open the directory with valid paths
-echo "\n-- With valid paths --\n";
-var_dump( dir("$dir_path1/sub_dir11/sub_dir111/..") );
-var_dump( dir("$dir_path2/sub_dir21/../../dir_variation91") );
-var_dump( dir("$dir_path2/sub_dir21/../../dir_variation91/sub_dir11/..") );
-var_dump( dir("$dir_path1/sub_dir11/sub_dir111/../../../dir_variation92/sub_dir21/..") );
-
-// open the directory with invalid path
-echo "\n-- With invalid paths --\n";
-var_dump( dir("$dir_path1/sub_dir12/sub_dir111/..") );
-var_dump( dir("$dir_path2/sub_dir21/../dir_variation91") );
-var_dump( dir("$dir_path2/sub_dir21/../../dir_variation91/sub_dir12/..") );
-var_dump( dir("$dir_path1/sub_dir11/sub_dir111/../../dir_variation92/sub_dir21/..") );
-
-echo "Done";
-?>
---CLEAN--
-<?php
-$file_path = dirname(__FILE__);
-
-$dir_path1 = $file_path."/dir_variation91";
-$sub_dir11 = $dir_path1."/sub_dir11";
-$sub_dir111 = $sub_dir11."/sub_dir111";
-$dir_path2 = $file_path."/dir_variation92";
-$sub_dir21 = $dir_path2."/sub_dir21";
-
-rmdir($sub_dir21);
-rmdir($sub_dir111);
-rmdir($sub_dir11);
-rmdir($dir_path1);
-rmdir($dir_path2);
-?>
---EXPECTF--
-*** Testing dir() : checking with valid and invalid paths ***
-
--- With valid paths --
-object(Directory)#%d (2) {
- ["path"]=>
- string(%d) "%s/dir_variation91/sub_dir11/sub_dir111/.."
- ["handle"]=>
- resource(%d) of type (stream)
-}
-object(Directory)#%d (2) {
- ["path"]=>
- string(%d) "%s/dir_variation92/sub_dir21/../../dir_variation91"
- ["handle"]=>
- resource(%d) of type (stream)
-}
-object(Directory)#%d (2) {
- ["path"]=>
- string(%d) "%s/dir_variation92/sub_dir21/../../dir_variation91/sub_dir11/.."
- ["handle"]=>
- resource(%d) of type (stream)
-}
-object(Directory)#%d (2) {
- ["path"]=>
- string(%d) "%s/dir_variation91/sub_dir11/sub_dir111/../../../dir_variation92/sub_dir21/.."
- ["handle"]=>
- resource(%d) of type (stream)
-}
-
--- With invalid paths --
-
-Warning: dir(%sdir_variation91/sub_dir12/sub_dir111/..,%sdir_variation91/sub_dir12/sub_dir111/..): The system cannot find the path specified. (code: 3) in %sdir_variation9-win32.php on line %d
-
-Warning: dir(%s/dir_variation91/sub_dir12/sub_dir111/..): failed to open dir: %s in %s on line %d
-bool(false)
-
-Warning: dir(%sdir_variation92/sub_dir21/../dir_variation91,%sdir_variation92/sub_dir21/../dir_variation91): The system cannot find the file specified. (code: 2) in %sdir_variation9-win32.php on line %d
-
-Warning: dir(%s/dir_variation92/sub_dir21/../dir_variation91): failed to open dir: %s in %s on line %d
-bool(false)
-
-Warning: dir(%sdir_variation92/sub_dir21/../../dir_variation91/sub_dir12/..,%sdir_variation92/sub_dir21/../../dir_variation91/sub_dir12/..): The system cannot find the file specified. (code: 2) in %sdir_variation9-win32.php on line %d
-
-Warning: dir(%s/dir_variation92/sub_dir21/../../dir_variation91/sub_dir12/..): failed to open dir: %s in %s on line %d
-bool(false)
-
-Warning: dir(%sdir_variation91/sub_dir11/sub_dir111/../../dir_variation92/sub_dir21/..,%sdir_variation91/sub_dir11/sub_dir111/../../dir_variation92/sub_dir21/..): The system cannot find the path specified. (code: 3) in %sdir_variation9-win32.php on line %d
-
-Warning: dir(%s/dir_variation91/sub_dir11/sub_dir111/../../dir_variation92/sub_dir21/..): failed to open dir: %s in %s on line %d
-bool(false)
-Done
diff --git a/ext/standard/tests/dir/opendir_error2-win32.phpt b/ext/standard/tests/dir/opendir_error2-win32.phpt
deleted file mode 100644
index c3ecd35349..0000000000
--- a/ext/standard/tests/dir/opendir_error2-win32.phpt
+++ /dev/null
@@ -1,47 +0,0 @@
---TEST--
-Test opendir() function : error conditions - Non-existent directory
---SKIPIF--
-<?php
-if (substr(PHP_OS, 0, 3) != 'WIN') {
- die("skip Valid only on Windows");
-}
-?>
---FILE--
-<?php
-/* Prototype : mixed opendir(string $path[, resource $context])
- * Description: Open a directory and return a dir_handle
- * Source code: ext/standard/dir.c
- */
-
-/*
- * Pass a non-existent directory as $path argument to opendir() to test behaviour
- */
-
-echo "*** Testing opendir() : error conditions ***\n";
-
-echo "\n-- Pass a non-existent absolute path: --\n";
-$path = dirname(__FILE__) . "/idonotexist";
-var_dump(opendir($path));
-
-echo "\n-- Pass a non-existent relative path: --\n";
-chdir(dirname(__FILE__));
-var_dump(opendir('idonotexist'));
-?>
-===DONE===
---EXPECTF--
-*** Testing opendir() : error conditions ***
-
--- Pass a non-existent absolute path: --
-
-Warning: opendir(%s/idonotexist,%s/idonotexist): The system cannot find the file specified. (code: %d) in %s on line %d
-
-Warning: opendir(%s/idonotexist): failed to open dir: %s in %s on line %d
-bool(false)
-
--- Pass a non-existent relative path: --
-
-Warning: opendir(idonotexist,idonotexist): The system cannot find the file specified. (code: %d) in %s on line %d
-
-Warning: opendir(idonotexist): failed to open dir: %s in %s on line %d
-bool(false)
-===DONE===
diff --git a/ext/standard/tests/dir/opendir_variation1-win32.phpt b/ext/standard/tests/dir/opendir_variation1-win32.phpt
deleted file mode 100644
index 9a75a5b6a7..0000000000
--- a/ext/standard/tests/dir/opendir_variation1-win32.phpt
+++ /dev/null
@@ -1,248 +0,0 @@
---TEST--
-Test opendir() function : usage variations - different data types as $path arg
---SKIPIF--
-<?php
-if (substr(PHP_OS, 0, 3) != 'WIN') {
- die("skip Valid only on Windows");
-}
-?>
---FILE--
-<?php
-/* Prototype : mixed opendir(string $path[, resource $context])
- * Description: Open a directory and return a dir_handle
- * Source code: ext/standard/dir.c
- */
-
-/*
- * Pass different data types as $path argument to opendir() to test behaviour
- * Where possible, an existing directory has been entered as a string value
- */
-
-echo "*** Testing opendir() : usage variations ***\n";
-
-// create directory to be passed as string value where possible
-$path = dirname(__FILE__) . "/opendir_variation1";
-mkdir($path);
-
-//get an unset variable
-$unset_var = 10;
-unset ($unset_var);
-
-// get a class
-class classA {
-
- var $path;
- function __construct($path) {
- $this->path = $path;
- }
- public function __toString() {
- return $this->path;
- }
-}
-
-// heredoc string
-$heredoc = <<<EOT
-$path
-EOT;
-
-// get a resource variable
-$fp = fopen(__FILE__, "r");
-
-// unexpected values to be passed to $path argument
-$inputs = array(
-
- // int data
-/*1*/ 0,
- 1,
- 12345,
- -2345,
-
- // float data
-/*5*/ 10.5,
- -10.5,
- 12.3456789000e10,
- 12.3456789000E-10,
- .5,
-
- // null data
-/*10*/ NULL,
- null,
-
- // boolean data
-/*12*/ true,
- false,
- TRUE,
- FALSE,
-
- // empty data
-/*16*/ "",
- '',
- array(),
-
- // string data
-/*19*/ "$path",
- 'string',
- $heredoc,
-
- // object data
-/*22*/ new classA($path),
-
- // undefined data
-/*23*/ @$undefined_var,
-
- // unset data
-/*24*/ @$unset_var,
-
- // resource variable
-/*25*/ $fp
-);
-
-// loop through each element of $inputs to check the behavior of opendir()
-$iterator = 1;
-foreach($inputs as $input) {
- echo "\n-- Iteration $iterator --\n";
- var_dump( $dh = opendir($input) );
- if ($dh) {
- closedir($dh);
- }
- $iterator++;
-};
-
-fclose($fp);
-?>
-===DONE===
---CLEAN--
-<?php
-$path = dirname(__FILE__) . "/opendir_variation1";
-rmdir($path);
-?>
---EXPECTF--
-*** Testing opendir() : usage variations ***
-
--- Iteration 1 --
-
-Warning: opendir(0,0): The system cannot find the file specified. (code: 2) in %s on line %d
-
-Warning: opendir(0): failed to open dir: %s in %s on line %d
-bool(false)
-
--- Iteration 2 --
-
-Warning: opendir(1,1): The system cannot find the file specified. (code: 2) in %s on line %d
-
-Warning: opendir(1): failed to open dir: %s in %s on line %d
-bool(false)
-
--- Iteration 3 --
-
-Warning: opendir(12345,12345): The system cannot find the file specified. (code: 2) in %s on line %d
-
-Warning: opendir(12345): failed to open dir: %s in %s on line %d
-bool(false)
-
--- Iteration 4 --
-
-Warning: opendir(-2345,-2345): The system cannot find the file specified. (code: 2) in %s on line %d
-
-Warning: opendir(-2345): failed to open dir: %s in %s on line %d
-bool(false)
-
--- Iteration 5 --
-
-Warning: opendir(10.5,10.5): The system cannot find the file specified. (code: 2) in %s on line %d
-
-Warning: opendir(10.5): failed to open dir: %s in %s on line %d
-bool(false)
-
--- Iteration 6 --
-
-Warning: opendir(-10.5,-10.5): The system cannot find the file specified. (code: 2) in %s on line %d
-
-Warning: opendir(-10.5): failed to open dir: %s in %s on line %d
-bool(false)
-
--- Iteration 7 --
-
-Warning: opendir(123456789000,123456789000): The system cannot find the file specified. (code: 2) in %s on line %d
-
-Warning: opendir(123456789000): failed to open dir: %s in %s on line %d
-bool(false)
-
--- Iteration 8 --
-
-Warning: opendir(1.23456789E-9,1.23456789E-9): The system cannot find the file specified. (code: 2) in %s on line %d
-
-Warning: opendir(1.23456789E-9): failed to open dir: %s in %s on line %d
-bool(false)
-
--- Iteration 9 --
-
-Warning: opendir(0.5,0.5): The system cannot find the file specified. (code: 2) in %s on line %d
-
-Warning: opendir(0.5): failed to open dir: %s in %s on line %d
-bool(false)
-
--- Iteration 10 --
-bool(false)
-
--- Iteration 11 --
-bool(false)
-
--- Iteration 12 --
-
-Warning: opendir(1,1): The system cannot find the file specified. (code: 2) in %s on line %d
-
-Warning: opendir(1): failed to open dir: %s in %s on line %d
-bool(false)
-
--- Iteration 13 --
-bool(false)
-
--- Iteration 14 --
-
-Warning: opendir(1,1): The system cannot find the file specified. (code: 2) in %s on line %d
-
-Warning: opendir(1): failed to open dir: %s in %s on line %d
-bool(false)
-
--- Iteration 15 --
-bool(false)
-
--- Iteration 16 --
-bool(false)
-
--- Iteration 17 --
-bool(false)
-
--- Iteration 18 --
-
-Warning: opendir() expects parameter 1 to be string, array given in %s on line %d
-NULL
-
--- Iteration 19 --
-resource(%d) of type (stream)
-
--- Iteration 20 --
-
-Warning: opendir(string,string): The system cannot find the file specified. (code: 2) in %s on line %d
-
-Warning: opendir(string): failed to open dir: %s in %s on line %d
-bool(false)
-
--- Iteration 21 --
-resource(%d) of type (stream)
-
--- Iteration 22 --
-resource(%d) of type (stream)
-
--- Iteration 23 --
-bool(false)
-
--- Iteration 24 --
-bool(false)
-
--- Iteration 25 --
-
-Warning: opendir() expects parameter 1 to be string, resource given in %s on line %d
-NULL
-===DONE===
diff --git a/ext/standard/tests/dir/scandir_error2-win32.phpt b/ext/standard/tests/dir/scandir_error2-win32.phpt
deleted file mode 100644
index 9920be747d..0000000000
--- a/ext/standard/tests/dir/scandir_error2-win32.phpt
+++ /dev/null
@@ -1,51 +0,0 @@
---TEST--
-Test scandir() function : error conditions - Non-existent directory
---SKIPIF--
-<?php
-if (substr(PHP_OS, 0, 3) != 'WIN') {
- die("skip Valid only on Windows");
-}
-?>
---FILE--
-<?php
-/* Prototype : array scandir(string $dir [, int $sorting_order [, resource $context]])
- * Description: List files & directories inside the specified path
- * Source code: ext/standard/dir.c
- */
-
-/*
- * Pass a directory that does not exist to scandir() to test error messages
- */
-
-echo "*** Testing scandir() : error conditions ***\n";
-
-$directory = dirname(__FILE__) . '/idonotexist';
-
-echo "\n-- Pass scandir() an absolute path that does not exist --\n";
-var_dump(scandir($directory));
-
-echo "\n-- Pass scandir() a relative path that does not exist --\n";
-var_dump(scandir('/idonotexist'));
-?>
-===DONE===
---EXPECTF--
-*** Testing scandir() : error conditions ***
-
--- Pass scandir() an absolute path that does not exist --
-
-Warning: scandir(%s/idonotexist,%s/idonotexist): The system cannot find the file specified. (code: 2) in %s on line %d
-
-Warning: scandir(%s/idonotexist): failed to open dir: %s in %s on line %d
-
-Warning: scandir(): (errno %d): %s in %s on line %d
-bool(false)
-
--- Pass scandir() a relative path that does not exist --
-
-Warning: scandir(/idonotexist,/idonotexist): The system cannot find the file specified. (code: 2) in %s on line %d
-
-Warning: scandir(/idonotexist): failed to open dir: %s in %s on line %d
-
-Warning: scandir(): (errno %d): %s in %s on line %d
-bool(false)
-===DONE===
diff --git a/ext/standard/tests/dir/scandir_variation1-win32.phpt b/ext/standard/tests/dir/scandir_variation1-win32.phpt
deleted file mode 100644
index a2b5bd4672..0000000000
--- a/ext/standard/tests/dir/scandir_variation1-win32.phpt
+++ /dev/null
@@ -1,289 +0,0 @@
---TEST--
-Test scandir() function : usage variations - different data types as $dir arg
---SKIPIF--
-<?php
-if (substr(PHP_OS, 0, 3) != 'WIN') {
- die("skip Valid only on Windows");
-}
-?>
---FILE--
-<?php
-/* Prototype : array scandir(string $dir [, int $sorting_order [, resource $context]])
- * Description: List files & directories inside the specified path
- * Source code: ext/standard/dir.c
- */
-
-/*
- * Pass different data types as $dir argument to test behaviour of scandir()
- */
-
-echo "*** Testing scandir() : usage variations ***\n";
-
-//get an unset variable
-$unset_var = 10;
-unset ($unset_var);
-
-// get a class
-class classA
-{
- public function __toString() {
- return "Class A object";
- }
-}
-
-// heredoc string
-$heredoc = <<<EOT
-hello world
-EOT;
-
-// get a resource variable
-$fp = fopen(__FILE__, "r");
-
-// unexpected values to be passed to $dir argument
-$inputs = array(
-
- // int data
-/*1*/ 0,
- 1,
- 12345,
- -2345,
-
- // float data
-/*5*/ 10.5,
- -10.5,
- 12.3456789000e10,
- 12.3456789000E-10,
- .5,
-
- // null data
-/*10*/ NULL,
- null,
-
- // boolean data
-/*12*/ true,
- false,
- TRUE,
- FALSE,
-
- // empty data
-/*16*/ "",
- '',
- array(),
-
- // string data
-/*19*/ "string",
- 'string',
- $heredoc,
-
- // object data
-/*22*/ new classA(),
-
- // undefined data
-/*23*/ @$undefined_var,
-
- // unset data
-/*24*/ @$unset_var,
-
- // resource variable
-/*25*/ $fp
-);
-
-// loop through each element of $inputs to check the behavior of scandir()
-$iterator = 1;
-foreach($inputs as $input) {
- echo "\n-- Iteration $iterator --\n";
- var_dump( scandir($input) );
- $iterator++;
-};
-
-fclose($fp);
-?>
-===DONE===
---EXPECTF--
-*** Testing scandir() : usage variations ***
-
--- Iteration 1 --
-
-Warning: scandir(0,0): The system cannot find the file specified. (code: 2) in %s on line %d
-
-Warning: scandir(0): failed to open dir: No such file or directory in %sscandir_variation1-win32.php on line %d
-
-Warning: scandir(): (errno %d): %s in %s on line %d
-bool(false)
-
--- Iteration 2 --
-
-Warning: scandir(1,1): The system cannot find the file specified. (code: 2) in %s on line %d
-
-Warning: scandir(1): failed to open dir: No such file or directory in %sscandir_variation1-win32.php on line %d
-
-Warning: scandir(): (errno %d): %s in %s on line %d
-bool(false)
-
--- Iteration 3 --
-
-Warning: scandir(12345,12345): The system cannot find the file specified. (code: 2) in %s on line %d
-
-Warning: scandir(12345): failed to open dir: No such file or directory in %sscandir_variation1-win32.php on line %d
-
-Warning: scandir(): (errno %d): %s in %s on line %d
-bool(false)
-
--- Iteration 4 --
-
-Warning: scandir(-2345,-2345): The system cannot find the file specified. (code: 2) in %s on line %d
-
-Warning: scandir(-2345): failed to open dir: No such file or directory in %sscandir_variation1-win32.php on line %d
-
-Warning: scandir(): (errno %d): %s in %s on line %d
-bool(false)
-
--- Iteration 5 --
-
-Warning: scandir(10.5,10.5): The system cannot find the file specified. (code: 2) in %s on line %d
-
-Warning: scandir(10.5): failed to open dir: No such file or directory in %sscandir_variation1-win32.php on line %d
-
-Warning: scandir(): (errno %d): %s in %s on line %d
-bool(false)
-
--- Iteration 6 --
-
-Warning: scandir(-10.5,-10.5): The system cannot find the file specified. (code: 2) in %s on line %d
-
-Warning: scandir(-10.5): failed to open dir: No such file or directory in %sscandir_variation1-win32.php on line %d
-
-Warning: scandir(): (errno %d): %s in %s on line %d
-bool(false)
-
--- Iteration 7 --
-
-Warning: scandir(123456789000,123456789000): The system cannot find the file specified. (code: 2) in %s on line %d
-
-Warning: scandir(123456789000): failed to open dir: No such file or directory in %sscandir_variation1-win32.php on line %d
-
-Warning: scandir(): (errno %d): %s in %s on line %d
-bool(false)
-
--- Iteration 8 --
-
-Warning: scandir(1.23456789E-9,1.23456789E-9): The system cannot find the file specified. (code: 2) in %s on line %d
-
-Warning: scandir(1.23456789E-9): failed to open dir: No such file or directory in %sscandir_variation1-win32.php on line %d
-
-Warning: scandir(): (errno %d): %s in %s on line %d
-bool(false)
-
--- Iteration 9 --
-
-Warning: scandir(0.5,0.5): The system cannot find the file specified. (code: 2) in %s on line %d
-
-Warning: scandir(0.5): failed to open dir: No such file or directory in %sscandir_variation1-win32.php on line %d
-
-Warning: scandir(): (errno %d): %s in %s on line %d
-bool(false)
-
--- Iteration 10 --
-
-Warning: scandir(): Directory name cannot be empty in %s on line %d
-bool(false)
-
--- Iteration 11 --
-
-Warning: scandir(): Directory name cannot be empty in %s on line %d
-bool(false)
-
--- Iteration 12 --
-
-Warning: scandir(1,1): The system cannot find the file specified. (code: 2) in %s on line %d
-
-Warning: scandir(1): failed to open dir: No such file or directory in %sscandir_variation1-win32.php on line %d
-
-Warning: scandir(): (errno %d): %s in %s on line %d
-bool(false)
-
--- Iteration 13 --
-
-Warning: scandir(): Directory name cannot be empty in %s on line %d
-bool(false)
-
--- Iteration 14 --
-
-Warning: scandir(1,1): The system cannot find the file specified. (code: 2) in %s on line %d
-
-Warning: scandir(1): failed to open dir: No such file or directory in %sscandir_variation1-win32.php on line %d
-
-Warning: scandir(): (errno %d): %s in %s on line %d
-bool(false)
-
--- Iteration 15 --
-
-Warning: scandir(): Directory name cannot be empty in %s on line %d
-bool(false)
-
--- Iteration 16 --
-
-Warning: scandir(): Directory name cannot be empty in %s on line %d
-bool(false)
-
--- Iteration 17 --
-
-Warning: scandir(): Directory name cannot be empty in %s on line %d
-bool(false)
-
--- Iteration 18 --
-
-Warning: scandir() expects parameter 1 to be a valid path, array given in %s on line %d
-NULL
-
--- Iteration 19 --
-
-Warning: scandir(string,string): The system cannot find the file specified. (code: 2) in %s on line %d
-
-Warning: scandir(string): failed to open dir: No such file or directory in %sscandir_variation1-win32.php on line %d
-
-Warning: scandir(): (errno %d): %s in %s on line %d
-bool(false)
-
--- Iteration 20 --
-
-Warning: scandir(string,string): The system cannot find the file specified. (code: 2) in %s on line %d
-
-Warning: scandir(string): failed to open dir: No such file or directory in %sscandir_variation1-win32.php on line %d
-
-Warning: scandir(): (errno %d): %s in %s on line %d
-bool(false)
-
--- Iteration 21 --
-
-Warning: scandir(hello world,hello world): The system cannot find the file specified. (code: 2) in %s on line %d
-
-Warning: scandir(hello world): failed to open dir: No such file or directory in %sscandir_variation1-win32.php on line %d
-
-Warning: scandir(): (errno %d): %s in %s on line %d
-bool(false)
-
--- Iteration 22 --
-
-Warning: scandir(Class A object,Class A object): The system cannot find the file specified. (code: 2) in %s on line %d
-
-Warning: scandir(Class A object): failed to open dir: No such file or directory in %sscandir_variation1-win32.php on line %d
-
-Warning: scandir(): (errno %d): %s in %s on line %d
-bool(false)
-
--- Iteration 23 --
-
-Warning: scandir(): Directory name cannot be empty in %s on line %d
-bool(false)
-
--- Iteration 24 --
-
-Warning: scandir(): Directory name cannot be empty in %s on line %d
-bool(false)
-
--- Iteration 25 --
-
-Warning: scandir() expects parameter 1 to be a valid path, resource given in %s on line %d
-NULL
-===DONE===
diff --git a/ext/standard/tests/dir/scandir_variation6-win32.phpt b/ext/standard/tests/dir/scandir_variation6-win32.phpt
deleted file mode 100644
index 040dc787cc..0000000000
--- a/ext/standard/tests/dir/scandir_variation6-win32.phpt
+++ /dev/null
@@ -1,84 +0,0 @@
---TEST--
-Test scandir() function : usage variations - Wildcards in directory path
---SKIPIF--
-<?php
-if (substr(PHP_OS, 0, 3) != 'WIN') {
- die("skip Valid only on Windows");
-}
-?>
---FILE--
-<?php
-/* Prototype : array scandir(string $dir [, int $sorting_order [, resource $context]])
- * Description: List files & directories inside the specified path
- * Source code: ext/standard/dir.c
- */
-
-/*
- * Pass a directory path using wildcards as $dir argument to test how scandir() behaves
- */
-
-echo "*** Testing scandir() : usage variations ***\n";
-
-// create the temporary directories
-$file_path = dirname(__FILE__);
-$dir_path = $file_path . "/scandir_variation6";
-$sub_dir_path = $dir_path . "/sub_dir1";
-
-mkdir($dir_path);
-mkdir($sub_dir_path);
-
-// with different wildcard characters
-
-echo "\n-- Wildcard = '*' --\n";
-var_dump( scandir($file_path . "/scandir_var*") );
-var_dump( scandir($file_path . "/*") );
-
-echo "\n-- Wildcard = '?' --\n";
-var_dump( scandir($dir_path . "/sub_dir?") );
-var_dump( scandir($dir_path . "/sub?dir1") );
-
-?>
-===DONE===
---CLEAN--
-<?php
-$dir_path = dirname(__FILE__) . "/scandir_variation6";
-$sub_dir_path = $dir_path . "/sub_dir1";
-
-rmdir($sub_dir_path);
-rmdir($dir_path);
-?>
---EXPECTF--
-*** Testing scandir() : usage variations ***
-
--- Wildcard = '*' --
-
-Warning: scandir(%s/scandir_var*,%s/scandir_var*): No such file or directory in %s on line %d
-
-Warning: scandir(%s/scandir_var*): failed to open dir: No such file or directory in %sscandir_variation6-win32.php on line %d
-
-Warning: scandir(): (errno %d): %s in %s on line %d
-bool(false)
-
-Warning: scandir(%s/*,%s/*): No such file or directory in %s on line %d
-
-Warning: scandir(%s/*): failed to open dir: No such file or directory in %sscandir_variation6-win32.php on line %d
-
-Warning: scandir(): (errno %d): %s in %s on line %d
-bool(false)
-
--- Wildcard = '?' --
-
-Warning: scandir(%s/scandir_variation6/sub_dir?,%s/scandir_variation6/sub_dir?): No such file or directory in %s on line %d
-
-Warning: scandir(%s/scandir_variation6/sub_dir?): failed to open dir: No such file or directory in %sscandir_variation6-win32.php on line %d
-
-Warning: scandir(): (errno %d): %s in %s on line %d
-bool(false)
-
-Warning: scandir(%s/scandir_variation6/sub?dir1,%s/scandir_variation6/sub?dir1): No such file or directory in %s on line %d
-
-Warning: scandir(%s/scandir_variation6/sub?dir1): failed to open dir: No such file or directory in %sscandir_variation6-win32.php on line %d
-
-Warning: scandir(): (errno %d): %s in %s on line %d
-bool(false)
-===DONE===
diff --git a/ext/standard/tests/file/007_error.phpt b/ext/standard/tests/file/007_error.phpt
index a369c9d977..112beb3059 100644
--- a/ext/standard/tests/file/007_error.phpt
+++ b/ext/standard/tests/file/007_error.phpt
@@ -76,7 +76,7 @@ bool(false)
Warning: fopen() expects at least 2 parameters, 0 given in %s on line %d
bool(false)
-Warning: fclose(): 5 is not a valid stream resource in %s on line %d
+Warning: fclose(): %d is not a valid stream resource in %s on line %d
bool(false)
Warning: fclose() expects parameter 1 to be resource, string given in %s on line %d
@@ -85,7 +85,7 @@ bool(false)
Warning: fclose() expects exactly 1 parameter, 0 given in %s on line %d
bool(false)
-Warning: feof(): 5 is not a valid stream resource in %s on line %d
+Warning: feof(): %d is not a valid stream resource in %s on line %d
bool(false)
Warning: feof() expects parameter 1 to be resource, string given in %s on line %d
diff --git a/ext/standard/tests/file/bug22414.phpt b/ext/standard/tests/file/bug22414.phpt
index 9538c8ede8..fcd85489f3 100644
--- a/ext/standard/tests/file/bug22414.phpt
+++ b/ext/standard/tests/file/bug22414.phpt
@@ -7,7 +7,7 @@ output_handler=
$php = getenv('TEST_PHP_EXECUTABLE');
$tmpfile = tempnam(__DIR__, 'phpt');
- $args = ' -n ';
+ $args = ' -n -dsafe_mode=off ';
/* Regular Data Test */
passthru($php . $args . ' -r " echo \"HELLO\"; "');
diff --git a/ext/standard/tests/file/disk_free_space_basic.phpt b/ext/standard/tests/file/disk_free_space_basic.phpt
index 9dc663ae16..200e92ab43 100644
--- a/ext/standard/tests/file/disk_free_space_basic.phpt
+++ b/ext/standard/tests/file/disk_free_space_basic.phpt
@@ -37,7 +37,7 @@ echo "\n Free Space after writing to a file\n";
$space2 = disk_free_space($file_path.$dir);
var_dump( $space2 );
-if( $space1 > $space2 )
+if($space1 > $space2 )
echo "\n Free Space Value Is Correct\n";
else
echo "\n Free Space Value Is Incorrect\n";
diff --git a/ext/standard/tests/file/fgetss_error.phpt b/ext/standard/tests/file/fgetss_error.phpt
index 3691e962e1..2b4ad68125 100644
--- a/ext/standard/tests/file/fgetss_error.phpt
+++ b/ext/standard/tests/file/fgetss_error.phpt
@@ -98,7 +98,7 @@ bool(false)
Warning: fgetss() expects parameter 1 to be resource, object given in %s on line %d
bool(false)
-- Testing fgetss() with closed/unset file handle --
-Warning: fgetss(): 5 is not a valid stream resource in %s on line %d
+Warning: fgetss(): %d is not a valid stream resource in %s on line %d
bool(false)
Warning: fgetss() expects parameter 1 to be resource, null given in %s on line %d
diff --git a/ext/standard/tests/file/fputcsv_error.phpt b/ext/standard/tests/file/fputcsv_error.phpt
index 9403cf446a..ebffd45425 100644
--- a/ext/standard/tests/file/fputcsv_error.phpt
+++ b/ext/standard/tests/file/fputcsv_error.phpt
@@ -48,7 +48,7 @@ Warning: fputcsv() expects at least 2 parameters, 0 given in %s on line %d
NULL
-- Testing fputcsv() with more than expected number of arguments --
-Warning: fputcsv() expects at most 4 parameters, 5 given in %s on line %d
+Warning: fputcsv() expects parameter 5 to be string, resource given in %s on line %d
NULL
-- Testing fputcsv() with invalid arguments --
-- Iteration 1 --
diff --git a/ext/standard/tests/file/fputcsv_variation15.phpt b/ext/standard/tests/file/fputcsv_variation15.phpt
new file mode 100755
index 0000000000..dc4a9e2dbd
--- /dev/null
+++ b/ext/standard/tests/file/fputcsv_variation15.phpt
@@ -0,0 +1,107 @@
+--TEST--
+various fputcsv() functionality tests
+--CREDITS--
+Lee Leathers <leeleathers@gmail.com>
+--FILE--
+<?php
+
+$list = array (
+ 0 => 'aaa,bbb',
+ 1 => 'aaa,"bbb"',
+ 2 => '"aaa","bbb"',
+ 3 => 'aaa,bbb',
+ 4 => '"aaa",bbb',
+ 5 => '"aaa", "bbb"',
+ 6 => ',',
+ 7 => 'aaa,',
+ 8 => ',"aaa"',
+ 9 => '"",""',
+ 10 => '"""""",',
+ 11 => '""""",aaa',
+ 12 => 'aaa,bbb ',
+ 13 => 'aaa,"bbb "',
+ 14 => 'aaa"aaa","bbb"bbb',
+ 15 => 'aaa"aaa""",bbb',
+ 16 => 'aaa,"/"bbb,ccc',
+ 17 => 'aaa"/"a","bbb"',
+ 18 => '"/"","aaa"',
+ 19 => '"/""",aaa',
+);
+
+$file = dirname(__FILE__) . 'fgetcsv.csv';
+@unlink($file);
+
+$fp = fopen($file, "w");
+foreach ($list as $v) {
+ fputcsv($fp, explode(',', $v), ',', '"', '/');
+}
+fclose($fp);
+
+$res = file($file);
+foreach($res as &$val)
+{
+ $val = substr($val, 0, -1);
+}
+echo '$list = ';var_export($res);echo ";\n";
+
+$fp = fopen($file, "r");
+$res = array();
+while($l=fgetcsv($fp, 0, ',', '"', '/'))
+{
+ $res[] = join(',',$l);
+}
+fclose($fp);
+
+echo '$list = ';var_export($res);echo ";\n";
+
+@unlink($file);
+
+?>
+===DONE===
+<?php exit(0); ?>
+--EXPECT--
+$list = array (
+ 0 => 'aaa,bbb',
+ 1 => 'aaa,"""bbb"""',
+ 2 => '"""aaa""","""bbb"""',
+ 3 => 'aaa,bbb',
+ 4 => '"""aaa""",bbb',
+ 5 => '"""aaa"""," ""bbb"""',
+ 6 => ',',
+ 7 => 'aaa,',
+ 8 => ',"""aaa"""',
+ 9 => '"""""",""""""',
+ 10 => '"""""""""""""",',
+ 11 => '"""""""""""",aaa',
+ 12 => 'aaa,"bbb "',
+ 13 => 'aaa,"""bbb """',
+ 14 => '"aaa""aaa""","""bbb""bbb"',
+ 15 => '"aaa""aaa""""""",bbb',
+ 16 => 'aaa,"""/"bbb",ccc',
+ 17 => '"aaa""/"a""","""bbb"""',
+ 18 => '"""/"""","""aaa"""',
+ 19 => '"""/"""""",aaa',
+);
+$list = array (
+ 0 => 'aaa,bbb',
+ 1 => 'aaa,"bbb"',
+ 2 => '"aaa","bbb"',
+ 3 => 'aaa,bbb',
+ 4 => '"aaa",bbb',
+ 5 => '"aaa", "bbb"',
+ 6 => ',',
+ 7 => 'aaa,',
+ 8 => ',"aaa"',
+ 9 => '"",""',
+ 10 => '"""""",',
+ 11 => '""""",aaa',
+ 12 => 'aaa,bbb ',
+ 13 => 'aaa,"bbb "',
+ 14 => 'aaa"aaa","bbb"bbb',
+ 15 => 'aaa"aaa""",bbb',
+ 16 => 'aaa,"/"bbb,ccc',
+ 17 => 'aaa"/"a","bbb"',
+ 18 => '"/"","aaa"',
+ 19 => '"/""",aaa',
+);
+===DONE===
diff --git a/ext/standard/tests/file/ftruncate_error.phpt b/ext/standard/tests/file/ftruncate_error.phpt
index a28095bc2d..254ad7688d 100644
--- a/ext/standard/tests/file/ftruncate_error.phpt
+++ b/ext/standard/tests/file/ftruncate_error.phpt
@@ -114,7 +114,7 @@ Warning: ftruncate() expects parameter 1 to be resource, object given in %s on l
bool(false)
-- Testing ftruncate() with closed/unset file handle --
-Warning: ftruncate(): 5 is not a valid stream resource in %s on line %d
+Warning: ftruncate(): %d is not a valid stream resource in %s on line %d
bool(false)
int(36)
diff --git a/ext/standard/tests/file/parse_ini_file.phpt b/ext/standard/tests/file/parse_ini_file.phpt
index dab07e56e7..db14c7a9b4 100644
--- a/ext/standard/tests/file/parse_ini_file.phpt
+++ b/ext/standard/tests/file/parse_ini_file.phpt
@@ -57,15 +57,15 @@ Non_alpha4 = %
Non_alpha5 = <>
Non_alpha6 = @
Non_alpha7 = #
-Non_alpha8 = ^
-Non_alpha9 = -
-Non_alpha10 = :
-Non_alpha11 = ?
-Non_alpha12 = /
-Non_alpha13 = \
+Non_alpha8 = -
+Non_alpha9 = :
+Non_alpha10 = ?
+Non_alpha11 = /
+Non_alpha12 = \
;These chars have a special meaning when used in the value,
; hence parser throws an error
-;Non_alpha14 = &
+;Non_alpha13 = &
+;Non_alpha14 = ^
;Non_alpha15 = {}
;Non_alpha16 = |
;Non_alpha17 = ~
@@ -249,12 +249,11 @@ Array
[Non_alpha5] => <>
[Non_alpha6] => @
[Non_alpha7] => #
- [Non_alpha8] => ^
- [Non_alpha9] => -
- [Non_alpha10] => :
- [Non_alpha11] => ?
- [Non_alpha12] => /
- [Non_alpha13] => \
+ [Non_alpha8] => -
+ [Non_alpha9] => :
+ [Non_alpha10] => ?
+ [Non_alpha11] => /
+ [Non_alpha12] => \
[Non_alpha1_quotes] => ;
[Non_alpha2_quotes] => +
[Non_alpha3_quotes] => *
@@ -385,12 +384,11 @@ Array
[Non_alpha5] => <>
[Non_alpha6] => @
[Non_alpha7] => #
- [Non_alpha8] => ^
- [Non_alpha9] => -
- [Non_alpha10] => :
- [Non_alpha11] => ?
- [Non_alpha12] => /
- [Non_alpha13] => \
+ [Non_alpha8] => -
+ [Non_alpha9] => :
+ [Non_alpha10] => ?
+ [Non_alpha11] => /
+ [Non_alpha12] => \
[Non_alpha1_quotes] => ;
[Non_alpha2_quotes] => +
[Non_alpha3_quotes] => *
diff --git a/ext/standard/tests/general_functions/boolval.phpt b/ext/standard/tests/general_functions/boolval.phpt
new file mode 100644
index 0000000000..9d0eac4ebd
--- /dev/null
+++ b/ext/standard/tests/general_functions/boolval.phpt
@@ -0,0 +1,29 @@
+--TEST--
+Testing boolval()
+--FILE--
+<?php
+ var_dump(boolval(false));
+ var_dump(boolval(NULL));
+ var_dump(boolval(""));
+ var_dump(boolval(0));
+ var_dump(boolval(array()));
+
+ var_dump(boolval(true));
+ var_dump(boolval("abc"));
+ var_dump(boolval(0.5));
+ var_dump(boolval(100));
+ var_dump(boolval(new stdClass()));
+ var_dump(boolval(STDIN));
+?>
+--EXPECTF--
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+bool(false)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
diff --git a/ext/standard/tests/general_functions/floatval.phpt b/ext/standard/tests/general_functions/floatval.phpt
index b427bda7d5..9b7a3281e4 100644
--- a/ext/standard/tests/general_functions/floatval.phpt
+++ b/ext/standard/tests/general_functions/floatval.phpt
@@ -157,8 +157,8 @@ float(-5000000)
*** Testing floatval() on non floating types ***
float(-2147483648)
float(2147483648)
-float(5)
-float(6)
+float(%d)
+float(%d)
float(0)
float(1)
float(-1300)
@@ -175,8 +175,8 @@ float(0)
*** Testing doubleval() on non floating types ***
float(-2147483648)
float(2147483648)
-float(5)
-float(6)
+float(%d)
+float(%d)
float(0)
float(1)
float(-1300)
diff --git a/ext/standard/tests/general_functions/gettype_settype_basic.phpt b/ext/standard/tests/general_functions/gettype_settype_basic.phpt
index d6fb0d495b..d1fd4095be 100644
--- a/ext/standard/tests/general_functions/gettype_settype_basic.phpt
+++ b/ext/standard/tests/general_functions/gettype_settype_basic.phpt
@@ -232,11 +232,11 @@ int(0)
string(7) "integer"
-- Iteration 12 --
bool(true)
-int(5)
+int(%d)
string(7) "integer"
-- Iteration 13 --
bool(true)
-int(6)
+int(%d)
string(7) "integer"
-- Iteration 14 --
8: Object of class point could not be converted to int
@@ -291,11 +291,11 @@ int(0)
string(7) "integer"
-- Iteration 12 --
bool(true)
-int(5)
+int(%d)
string(7) "integer"
-- Iteration 13 --
bool(true)
-int(6)
+int(%d)
string(7) "integer"
-- Iteration 14 --
8: Object of class point could not be converted to int
@@ -350,11 +350,11 @@ float(0)
string(6) "double"
-- Iteration 12 --
bool(true)
-float(5)
+float(%d)
string(6) "double"
-- Iteration 13 --
bool(true)
-float(6)
+float(%d)
string(6) "double"
-- Iteration 14 --
8: Object of class point could not be converted to double
@@ -409,11 +409,11 @@ float(0)
string(6) "double"
-- Iteration 12 --
bool(true)
-float(5)
+float(%d)
string(6) "double"
-- Iteration 13 --
bool(true)
-float(6)
+float(%d)
string(6) "double"
-- Iteration 14 --
8: Object of class point could not be converted to double
@@ -610,12 +610,12 @@ string(6) "string"
-- Iteration 12 --
2: settype(): Cannot convert to resource type
bool(false)
-resource(5) of type (stream)
+resource(%d) of type (stream)
string(8) "resource"
-- Iteration 13 --
2: settype(): Cannot convert to resource type
bool(false)
-resource(6) of type (stream)
+resource(%d) of type (stream)
string(8) "resource"
-- Iteration 14 --
2: settype(): Cannot convert to resource type
@@ -716,14 +716,14 @@ string(5) "array"
bool(true)
array(1) {
[0]=>
- resource(5) of type (stream)
+ resource(%d) of type (stream)
}
string(5) "array"
-- Iteration 13 --
bool(true)
array(1) {
[0]=>
- resource(6) of type (stream)
+ resource(%d) of type (stream)
}
string(5) "array"
-- Iteration 14 --
@@ -824,14 +824,14 @@ string(6) "object"
bool(true)
object(stdClass)#2 (1) {
["scalar"]=>
- resource(5) of type (stream)
+ resource(%d) of type (stream)
}
string(6) "object"
-- Iteration 13 --
bool(true)
object(stdClass)#2 (1) {
["scalar"]=>
- resource(6) of type (stream)
+ resource(%d) of type (stream)
}
string(6) "object"
-- Iteration 14 --
@@ -893,11 +893,11 @@ string(6) "string"
string(6) "string"
-- Iteration 12 --
bool(true)
-string(14) "Resource id #5"
+string(14) "Resource id #%d"
string(6) "string"
-- Iteration 13 --
bool(true)
-string(14) "Resource id #6"
+string(14) "Resource id #%d"
string(6) "string"
-- Iteration 14 --
bool(true)
diff --git a/ext/standard/tests/general_functions/parse_ini_string_001.phpt b/ext/standard/tests/general_functions/parse_ini_string_001.phpt
index e135210aa6..c5e70cb900 100644
--- a/ext/standard/tests/general_functions/parse_ini_string_001.phpt
+++ b/ext/standard/tests/general_functions/parse_ini_string_001.phpt
@@ -55,15 +55,15 @@ Non_alpha4 = %
Non_alpha5 = <>
Non_alpha6 = @
Non_alpha7 = #
-Non_alpha8 = ^
-Non_alpha9 = -
-Non_alpha10 = :
-Non_alpha11 = ?
-Non_alpha12 = /
-Non_alpha13 = \
+Non_alpha8 = -
+Non_alpha9 = :
+Non_alpha10 = ?
+Non_alpha11 = /
+Non_alpha12 = \
;These chars have a special meaning when used in the value,
; hence parser throws an error
-;Non_alpha14 = &
+;Non_alpha13 = &
+;Non_alpha14 = ^
;Non_alpha15 = {}
;Non_alpha16 = |
;Non_alpha17 = ~
@@ -239,12 +239,11 @@ Array
[Non_alpha5] => <>
[Non_alpha6] => @
[Non_alpha7] => #
- [Non_alpha8] => ^
- [Non_alpha9] => -
- [Non_alpha10] => :
- [Non_alpha11] => ?
- [Non_alpha12] => /
- [Non_alpha13] => \
+ [Non_alpha8] => -
+ [Non_alpha9] => :
+ [Non_alpha10] => ?
+ [Non_alpha11] => /
+ [Non_alpha12] => \
[Non_alpha1_quotes] => ;
[Non_alpha2_quotes] => +
[Non_alpha3_quotes] => *
@@ -375,12 +374,11 @@ Array
[Non_alpha5] => <>
[Non_alpha6] => @
[Non_alpha7] => #
- [Non_alpha8] => ^
- [Non_alpha9] => -
- [Non_alpha10] => :
- [Non_alpha11] => ?
- [Non_alpha12] => /
- [Non_alpha13] => \
+ [Non_alpha8] => -
+ [Non_alpha9] => :
+ [Non_alpha10] => ?
+ [Non_alpha11] => /
+ [Non_alpha12] => \
[Non_alpha1_quotes] => ;
[Non_alpha2_quotes] => +
[Non_alpha3_quotes] => *
diff --git a/ext/standard/tests/general_functions/print_r.phpt b/ext/standard/tests/general_functions/print_r.phpt
index 81a523ad0b..19e71fbfd7 100644
--- a/ext/standard/tests/general_functions/print_r.phpt
+++ b/ext/standard/tests/general_functions/print_r.phpt
@@ -1484,13 +1484,13 @@ object_class Object
*** Testing print_r() on resources ***
-- Iteration 1 --
-Resource id #5
-Resource id #5
-Resource id #5
+Resource id #%d
+Resource id #%d
+Resource id #%d
-- Iteration 2 --
-Resource id #6
-Resource id #6
-Resource id #6
+Resource id #%d
+Resource id #%d
+Resource id #%d
*** Testing print_r() on different combinations of scalar
and non-scalar variables ***
diff --git a/ext/standard/tests/general_functions/strval.phpt b/ext/standard/tests/general_functions/strval.phpt
index b92be41ef4..372ac6701e 100644
--- a/ext/standard/tests/general_functions/strval.phpt
+++ b/ext/standard/tests/general_functions/strval.phpt
@@ -279,9 +279,9 @@ string(0) ""
-- Iteration 1 --
string(6) "Object"
-- Iteration 2 --
-string(14) "Resource id #5"
+string(14) "Resource id #%d"
-- Iteration 3 --
-string(14) "Resource id #6"
+string(14) "Resource id #%d"
-- Iteration 4 --
Notice: Array to string conversion in %sstrval.php on line %d
diff --git a/ext/standard/tests/general_functions/type.phpt b/ext/standard/tests/general_functions/type.phpt
index 98eccbbda7..51654b1859 100644
--- a/ext/standard/tests/general_functions/type.phpt
+++ b/ext/standard/tests/general_functions/type.phpt
@@ -105,9 +105,9 @@ int(0)
bool(true)
int(0)
bool(true)
-int(5)
+int(%d)
bool(true)
-int(6)
+int(%d)
string(54) "Object of class stdClass could not be converted to int"
bool(true)
int(%d)
@@ -128,9 +128,9 @@ float(0)
bool(true)
float(0)
bool(true)
-float(5)
+float(%d)
bool(true)
-float(6)
+float(%d)
string(57) "Object of class stdClass could not be converted to double"
bool(true)
float(%d)
diff --git a/ext/standard/tests/general_functions/var_dump.phpt b/ext/standard/tests/general_functions/var_dump.phpt
index 09e9f3b99e..c47227141b 100644
--- a/ext/standard/tests/general_functions/var_dump.phpt
+++ b/ext/standard/tests/general_functions/var_dump.phpt
@@ -844,9 +844,9 @@ object(object_class)#13 (8) {
*** Testing var_dump() on resources ***
-- Iteration 1 --
-resource(5) of type (stream)
+resource(%d) of type (stream)
-- Iteration 2 --
-resource(6) of type (stream)
+resource(%d) of type (stream)
*** Testing var_dump() on different combinations of scalar
and non-scalar variables ***
@@ -1227,9 +1227,9 @@ array(4) {
}
array(2) {
[0]=>
- resource(5) of type (stream)
+ resource(%d) of type (stream)
[1]=>
- resource(6) of type (stream)
+ resource(%d) of type (stream)
}
array(9) {
[0]=>
diff --git a/ext/standard/tests/mail/bug51604.phpt b/ext/standard/tests/mail/bug51604.phpt
index a657021025..988849c4e1 100644
--- a/ext/standard/tests/mail/bug51604.phpt
+++ b/ext/standard/tests/mail/bug51604.phpt
@@ -11,7 +11,7 @@ if(substr(PHP_OS, 0, 3) == "WIN")
--FILE--
<?php
// Initialise all required variables
-$to = 'user@company.com';
+$to = 'user@example.com';
$subject = 'Test Subject';
$message = 'A Message';
$additional_headers = "KHeaders\n\n\n\n\n";
@@ -27,7 +27,7 @@ unlink($outFile);
===DONE===
--EXPECT--
bool(true)
-To: user@company.com
+To: user@example.com
Subject: Test Subject
KHeaders
diff --git a/ext/standard/tests/mail/mail_basic.phpt b/ext/standard/tests/mail/mail_basic.phpt
index fecb50f32c..70f32df40f 100644
--- a/ext/standard/tests/mail/mail_basic.phpt
+++ b/ext/standard/tests/mail/mail_basic.phpt
@@ -20,7 +20,7 @@ echo "*** Testing mail() : basic functionality ***\n";
// Initialise all required variables
-$to = 'user@company.com';
+$to = 'user@example.com';
$subject = 'Test Subject';
$message = 'A Message';
$additional_headers = 'KHeaders';
@@ -45,7 +45,7 @@ unlink($outFile);
*** Testing mail() : basic functionality ***
-- All Mail Content Parameters --
bool(true)
-To: user@company.com
+To: user@example.com
Subject: Test Subject
KHeaders
@@ -53,7 +53,7 @@ A Message
-- Mandatory Parameters --
bool(true)
-To: user@company.com
+To: user@example.com
Subject: Test Subject
A Message
diff --git a/ext/standard/tests/mail/mail_basic2.phpt b/ext/standard/tests/mail/mail_basic2.phpt
index 8967d18c4f..60ad009190 100644
--- a/ext/standard/tests/mail/mail_basic2.phpt
+++ b/ext/standard/tests/mail/mail_basic2.phpt
@@ -20,7 +20,7 @@ echo "*** Testing mail() : basic functionality ***\n";
// Initialise all required variables
-$to = 'user@company.com';
+$to = 'user@example.com';
$subject = 'Test Subject';
$message = 'A Message';
$additional_headers = 'KHeaders';
@@ -40,7 +40,7 @@ unlink($outFile);
*** Testing mail() : basic functionality ***
-- extra parameters --
bool(true)
-%w1%wTo: user@company.com
+%w1%wTo: user@example.com
%w2%wSubject: Test Subject
%w3%wKHeaders
%w4%w
diff --git a/ext/standard/tests/mail/mail_basic3.phpt b/ext/standard/tests/mail/mail_basic3.phpt
index 58eae0379e..3e648e5cac 100644
--- a/ext/standard/tests/mail/mail_basic3.phpt
+++ b/ext/standard/tests/mail/mail_basic3.phpt
@@ -19,7 +19,7 @@ echo "*** Testing mail() : basic functionality ***\n";
// Initialise all required variables
-$to = 'user@company.com';
+$to = 'user@example.com';
$subject = 'Test Subject';
$message = 'A Message';
diff --git a/ext/standard/tests/mail/mail_basic4.phpt b/ext/standard/tests/mail/mail_basic4.phpt
index 9ecc886aec..de2407a740 100644
--- a/ext/standard/tests/mail/mail_basic4.phpt
+++ b/ext/standard/tests/mail/mail_basic4.phpt
@@ -19,7 +19,7 @@ echo "*** Testing mail() : basic functionality ***\n";
// Initialise all required variables
-$to = 'user@company.com';
+$to = 'user@example.com';
$subject = 'Test Subject';
$message = 'A Message';
diff --git a/ext/standard/tests/mail/mail_basic5.phpt b/ext/standard/tests/mail/mail_basic5.phpt
index 7e42ccb833..8d755ebb86 100644
--- a/ext/standard/tests/mail/mail_basic5.phpt
+++ b/ext/standard/tests/mail/mail_basic5.phpt
@@ -19,7 +19,7 @@ echo "*** Testing mail() : basic functionality ***\n";
// Initialise all required variables
-$to = 'user@company.com';
+$to = 'user@example.com';
$subject = 'Test Subject';
$message = 'A Message';
diff --git a/ext/standard/tests/mail/mail_basic_alt1-win32.phpt b/ext/standard/tests/mail/mail_basic_alt1-win32.phpt
index 3c4dd88a5b..fc50498347 100644
--- a/ext/standard/tests/mail/mail_basic_alt1-win32.phpt
+++ b/ext/standard/tests/mail/mail_basic_alt1-win32.phpt
@@ -22,7 +22,7 @@ max_execution_time = 120
error_reporting(E_ALL & ~E_STRICT);
ini_set("SMTP", "localhost");
ini_set("smtp_port", 25);
-ini_set("sendmail_from", "user@company.com");
+ini_set("sendmail_from", "user@example.com");
echo "*** Testing mail() : basic functionality ***\n";
require_once(dirname(__FILE__).'/mail_include.inc');
diff --git a/ext/standard/tests/mail/mail_basic_alt2-win32.phpt b/ext/standard/tests/mail/mail_basic_alt2-win32.phpt
index d7bae62a0f..892d92391e 100644
--- a/ext/standard/tests/mail/mail_basic_alt2-win32.phpt
+++ b/ext/standard/tests/mail/mail_basic_alt2-win32.phpt
@@ -32,7 +32,7 @@ bool mail ( string \$to , string \$subject , string \$message [, string \$additi
Send an email message
HERE;
-$extra_headers = "from: user@company.com";
+$extra_headers = "from: user@example.com";
$res = mail($to, $subject, $message, $extra_headers);
diff --git a/ext/standard/tests/mail/mail_basic_alt3-win32.phpt b/ext/standard/tests/mail/mail_basic_alt3-win32.phpt
index 86b57eb813..1caa68c068 100644
--- a/ext/standard/tests/mail/mail_basic_alt3-win32.phpt
+++ b/ext/standard/tests/mail/mail_basic_alt3-win32.phpt
@@ -32,7 +32,7 @@ bool mail ( string \$to , string \$subject , string \$message [, string \$additi
Send an email message
HERE;
-$extra_headers = "FRom: user@company.com";
+$extra_headers = "FRom: user@example.com";
$res = mail($to, $subject, $message, $extra_headers);
diff --git a/ext/standard/tests/mail/mail_basic_alt4-win32.phpt b/ext/standard/tests/mail/mail_basic_alt4-win32.phpt
index f4a9d466bc..c8e45242e2 100644
--- a/ext/standard/tests/mail/mail_basic_alt4-win32.phpt
+++ b/ext/standard/tests/mail/mail_basic_alt4-win32.phpt
@@ -32,7 +32,7 @@ bool mail ( string \$to , string \$subject , string \$message [, string \$additi
Send an email message
HERE;
-$extra_headers = "from: user@company.com";
+$extra_headers = "from: user@example.com";
$extra_parameters = "addons"; // should be ignored
$res = mail($to, $subject, $message, $extra_headers, $extra_parameters);
diff --git a/ext/standard/tests/mail/mail_log.phpt b/ext/standard/tests/mail/mail_log.phpt
new file mode 100644
index 0000000000..86346ec307
--- /dev/null
+++ b/ext/standard/tests/mail/mail_log.phpt
@@ -0,0 +1,48 @@
+--TEST--
+Test mail() function : mail.log ini setting
+--INI--
+sendmail_path=tee /tmp/mail.out >/dev/null
+mail.log = /tmp/mail.log
+--SKIPIF--
+<?php
+if(substr(PHP_OS, 0, 3) == "WIN")
+ die("skip Won't run on Windows");
+?>
+--FILE--
+<?php
+date_default_timezone_set("UTC");
+
+$logfile = ini_get("mail.log");
+if (file_exists($logfile)) {
+ unlink($logfile);
+}
+touch($logfile);
+clearstatcache();
+
+$to = "test@example.com";
+$subject = "mail.log test";
+$message = "Testing mail.log";
+$headers = "X-Test: 1";
+
+var_dump(filesize($logfile) == 0);
+clearstatcache();
+
+var_dump(mail($to, $subject, $message, $headers));
+
+var_dump(filesize($logfile) > 0);
+clearstatcache();
+
+echo file_get_contents($logfile);
+?>
+Done
+--CLEAN--
+<?php
+unlink("/tmp/mail.log");
+unlink("/tmp/mail.out");
+?>
+--EXPECTF--
+bool(true)
+bool(true)
+bool(true)
+[%d-%s-%d %d:%d:%d UTC] mail() on [%smail_log.php:%d]: To: test@example.com -- Headers: X-Test: 1
+Done
diff --git a/ext/standard/tests/mail/mail_variation1.phpt b/ext/standard/tests/mail/mail_variation1.phpt
index bf37bf41e6..a8eb6bec79 100644
--- a/ext/standard/tests/mail/mail_variation1.phpt
+++ b/ext/standard/tests/mail/mail_variation1.phpt
@@ -18,7 +18,7 @@ if(substr(PHP_OS, 0, 3) == "WIN")
echo "*** Testing mail() : variation ***\n";
// Initialise all required variables
-$to = 'user@company.com';
+$to = 'user@example.com';
$subject = 'Test Subject';
$message = 'A Message';
var_dump( mail($to, $subject, $message) );
diff --git a/ext/standard/tests/mail/mail_variation2.phpt b/ext/standard/tests/mail/mail_variation2.phpt
index c16c2706a7..f0e44241b1 100644
--- a/ext/standard/tests/mail/mail_variation2.phpt
+++ b/ext/standard/tests/mail/mail_variation2.phpt
@@ -21,7 +21,7 @@ echo "*** Testing mail() : basic functionality ***\n";
// Initialise all required variables
-$to = 'user@company.com';
+$to = 'user@example.com';
$subject = 'Test Subject';
$message = 'A Message';
$outFile = "/tmp/php_test_mailVariation2.out";
@@ -36,7 +36,7 @@ unlink($outFile);
--EXPECTF--
*** Testing mail() : basic functionality ***
bool(true)
-%w1%wTo: user@company.com
+%w1%wTo: user@example.com
%w2%wSubject: Test Subject
%w3%w
%w4%wA Message
diff --git a/ext/standard/tests/mail/mail_variation_alt1-win32.phpt b/ext/standard/tests/mail/mail_variation_alt1-win32.phpt
index b81f3af9d2..dd7fd937e2 100644
--- a/ext/standard/tests/mail/mail_variation_alt1-win32.phpt
+++ b/ext/standard/tests/mail/mail_variation_alt1-win32.phpt
@@ -21,7 +21,7 @@ max_execution_time = 120
error_reporting(E_ALL & ~E_STRICT);
ini_set("SMTP", "localhost");
ini_set("smtp_port", 2525);
-ini_set("sendmail_from", "user@company.com");
+ini_set("sendmail_from", "user@example.com");
echo "*** Testing mail() : basic functionality ***\n";
require_once(dirname(__FILE__).'/mail_include.inc');
diff --git a/ext/standard/tests/mail/mail_variation_alt2-win32.phpt b/ext/standard/tests/mail/mail_variation_alt2-win32.phpt
index 6ae06bb202..817cc36af4 100644
--- a/ext/standard/tests/mail/mail_variation_alt2-win32.phpt
+++ b/ext/standard/tests/mail/mail_variation_alt2-win32.phpt
@@ -21,7 +21,7 @@ max_execution_time = 120
error_reporting(E_ALL & ~E_STRICT);
ini_set("SMTP", "localplace");
ini_set("smtp_port", 25);
-ini_set("sendmail_from", "user@company.com");
+ini_set("sendmail_from", "user@example.com");
echo "*** Testing mail() : basic functionality ***\n";
require_once(dirname(__FILE__).'/mail_include.inc');
diff --git a/ext/standard/tests/network/ip2long_variation1.phpt b/ext/standard/tests/network/ip2long_variation1.phpt
index f87282ae75..b228c9bd14 100644
--- a/ext/standard/tests/network/ip2long_variation1.phpt
+++ b/ext/standard/tests/network/ip2long_variation1.phpt
@@ -1,10 +1,5 @@
--TEST--
-Test ip2long() function : usage variation
---SKIPIF--
-<?php
-if(substr(PHP_OS, 0, 3) == "WIN")
- die("skip. Windows is more compliant (like 0 for localhost, etc.)");
-?>
+Test ip2long() function : usage variation 1
--FILE--
<?php
/* Prototype : int ip2long(string ip_address)
diff --git a/ext/standard/tests/network/ip2long_variation2.phpt b/ext/standard/tests/network/ip2long_variation2.phpt
new file mode 100644
index 0000000000..752956320c
--- /dev/null
+++ b/ext/standard/tests/network/ip2long_variation2.phpt
@@ -0,0 +1,39 @@
+--TEST--
+Test ip2long() function : usage variation 2, 32 bit
+--SKIPIF--
+<?php if(PHP_INT_SIZE != 4) {die('skip 32 bit only');} ?>
+--FILE--
+<?php
+/* Prototype : int ip2long(string ip_address)
+ * Description: Converts a string containing an (IPv4) Internet Protocol dotted address into a proper address
+ * Source code: ext/standard/basic_functions.c
+ * Alias to functions:
+ */
+
+$ips = array(
+ "1.1.011.011",
+ "127.0.0.1",
+ "1.1.071.071",
+ "0.0.0.0",
+ "1.1.081.081",
+ "192.168.0.0",
+ "256.0.0.1",
+ "192.168.0xa.5",
+);
+
+foreach($ips as $ip) {
+ var_dump(ip2long($ip));
+}
+
+?>
+===DONE===
+--EXPECT--
+bool(false)
+int(2130706433)
+bool(false)
+int(0)
+bool(false)
+int(-1062731776)
+bool(false)
+bool(false)
+===DONE===
diff --git a/ext/standard/tests/network/ip2long_variation2_x64.phpt b/ext/standard/tests/network/ip2long_variation2_x64.phpt
new file mode 100644
index 0000000000..a6fde5bdd9
--- /dev/null
+++ b/ext/standard/tests/network/ip2long_variation2_x64.phpt
@@ -0,0 +1,47 @@
+--TEST--
+Test ip2long() function : usage variation 2, 64 bit
+--SKIPIF--
+<?php
+/* from man inet_pton :
+ All numbers supplied as ``parts'' in a `.' notation may be decimal, octal, or hexadecimal, as specified
+ in the C language (i.e., a leading 0x or 0X implies hexadecimal; otherwise, a leading 0 implies octal;
+ otherwise, the number is interpreted as decimal).
+*/
+if(PHP_OS == 'Darwin') die("skip - inet_pton behaves differently on Darwin");
+if(PHP_INT_SIZE != 8) {die('skip 64 bit only');}
+?>
+--FILE--
+<?php
+/* Prototype : int ip2long(string ip_address)
+ * Description: Converts a string containing an (IPv4) Internet Protocol dotted address into a proper address
+ * Source code: ext/standard/basic_functions.c
+ * Alias to functions:
+ */
+
+$ips = array(
+ "1.1.011.011",
+ "127.0.0.1",
+ "1.1.071.071",
+ "0.0.0.0",
+ "1.1.081.081",
+ "192.168.0.0",
+ "256.0.0.1",
+ "192.168.0xa.5",
+);
+
+foreach($ips as $ip) {
+ var_dump(ip2long($ip));
+}
+
+?>
+===DONE===
+--EXPECT--
+bool(false)
+int(2130706433)
+bool(false)
+int(0)
+bool(false)
+int(3232235520)
+bool(false)
+bool(false)
+===DONE===
diff --git a/ext/standard/tests/network/setcookie.phpt b/ext/standard/tests/network/setcookie.phpt
new file mode 100644
index 0000000000..bf04ec78de
--- /dev/null
+++ b/ext/standard/tests/network/setcookie.phpt
@@ -0,0 +1,70 @@
+--TEST--
+setcookie() tests
+--DESCRIPTION--
+--INI--
+date.timezone=UTC
+--FILE--
+<?php
+setcookie('name');
+setcookie('name', 'value');
+setcookie('name', 'space value');
+setcookie('name', 'value', 0);
+setcookie('name', 'value', $tsp = time() + 5);
+setcookie('name', 'value', $tsn = time() - 6);
+setcookie('name', 'value', $tsc = time());
+setcookie('name', 'value', 0, '/path/');
+setcookie('name', 'value', 0, '', 'domain.tld');
+setcookie('name', 'value', 0, '', '', TRUE);
+setcookie('name', 'value', 0, '', '', FALSE, TRUE);
+
+
+$expected = array(
+ 'Set-Cookie: name=',
+ 'Set-Cookie: name=value',
+ 'Set-Cookie: name=space+value',
+ 'Set-Cookie: name=value',
+ 'Set-Cookie: name=value; expires='.date('D, d-M-Y H:i:s', $tsp).' GMT; Max-Age=5',
+ 'Set-Cookie: name=value; expires='.date('D, d-M-Y H:i:s', $tsn).' GMT; Max-Age=-6',
+ 'Set-Cookie: name=value; expires='.date('D, d-M-Y H:i:s', $tsc).' GMT; Max-Age=0',
+ 'Set-Cookie: name=value; path=/path/',
+ 'Set-Cookie: name=value; domain=domain.tld',
+ 'Set-Cookie: name=value; secure',
+ 'Set-Cookie: name=value; httponly'
+);
+
+$headers = headers_list();
+if (($i = count($expected)) > count($headers))
+{
+ echo "Less headers are being sent than expected - aborting";
+ return;
+}
+
+do
+{
+ if (strncmp(current($headers), 'Set-Cookie:', 11) !== 0)
+ {
+ continue;
+ }
+
+ if (current($headers) === current($expected))
+ {
+ $i--;
+ }
+ else
+ {
+ echo "Header mismatch:\n\tExpected: "
+ .current($expected)
+ ."\n\tReceived: ".current($headers)."\n";
+ }
+
+ next($expected);
+}
+while (next($headers) !== FALSE);
+
+echo ($i === 0)
+ ? 'OK'
+ : 'A total of '.$i.' errors found.';
+--EXPECTHEADERS--
+
+--EXPECT--
+OK \ No newline at end of file
diff --git a/ext/standard/tests/password/password_bcrypt_errors.phpt b/ext/standard/tests/password/password_bcrypt_errors.phpt
new file mode 100644
index 0000000000..2548c9accb
--- /dev/null
+++ b/ext/standard/tests/password/password_bcrypt_errors.phpt
@@ -0,0 +1,39 @@
+--TEST--
+Test error operation of password_hash() with bcrypt hashing
+--FILE--
+<?php
+//-=-=-=-
+
+var_dump(password_hash("foo", PASSWORD_BCRYPT, array("cost" => 3)));
+
+var_dump(password_hash("foo", PASSWORD_BCRYPT, array("cost" => 32)));
+
+var_dump(password_hash("foo", PASSWORD_BCRYPT, array("salt" => "foo")));
+
+var_dump(password_hash("foo", PASSWORD_BCRYPT, array("salt" => "123456789012345678901")));
+
+var_dump(password_hash("foo", PASSWORD_BCRYPT, array("salt" => 123)));
+
+var_dump(password_hash("foo", PASSWORD_BCRYPT, array("cost" => "foo")));
+
+?>
+--EXPECTF--
+Warning: password_hash(): Invalid bcrypt cost parameter specified: 3 in %s on line %d
+NULL
+
+Warning: password_hash(): Invalid bcrypt cost parameter specified: 32 in %s on line %d
+NULL
+
+Warning: password_hash(): Provided salt is too short: 3 expecting 22 in %s on line %d
+NULL
+
+Warning: password_hash(): Provided salt is too short: 21 expecting 22 in %s on line %d
+NULL
+
+Warning: password_hash(): Provided salt is too short: 3 expecting 22 in %s on line %d
+NULL
+
+Warning: password_hash(): Invalid bcrypt cost parameter specified: 0 in %s on line %d
+NULL
+
+
diff --git a/ext/standard/tests/password/password_get_info.phpt b/ext/standard/tests/password/password_get_info.phpt
new file mode 100644
index 0000000000..4c8dc04ff8
--- /dev/null
+++ b/ext/standard/tests/password/password_get_info.phpt
@@ -0,0 +1,58 @@
+--TEST--
+Test normal operation of password_get_info()
+--FILE--
+<?php
+//-=-=-=-
+// Test Bcrypt
+var_dump(password_get_info('$2y$10$MTIzNDU2Nzg5MDEyMzQ1Nej0NmcAWSLR.oP7XOR9HD/vjUuOj100y'));
+// Test Bcrypt Cost
+var_dump(password_get_info('$2y$11$MTIzNDU2Nzg5MDEyMzQ1Nej0NmcAWSLR.oP7XOR9HD/vjUuOj100y'));
+// Test Bcrypt Invalid Length
+var_dump(password_get_info('$2y$11$MTIzNDU2Nzg5MDEyMzQ1Nej0NmcAWSLR.oP7XOR9HD/vjUuOj100'));
+// Test Non-Bcrypt
+var_dump(password_get_info('$1$rasmusle$rISCgZzpwk3UhDidwXvin0'));
+
+echo "OK!";
+?>
+--EXPECT--
+array(3) {
+ ["algo"]=>
+ int(1)
+ ["algoName"]=>
+ string(6) "bcrypt"
+ ["options"]=>
+ array(1) {
+ ["cost"]=>
+ int(10)
+ }
+}
+array(3) {
+ ["algo"]=>
+ int(1)
+ ["algoName"]=>
+ string(6) "bcrypt"
+ ["options"]=>
+ array(1) {
+ ["cost"]=>
+ int(11)
+ }
+}
+array(3) {
+ ["algo"]=>
+ int(0)
+ ["algoName"]=>
+ string(7) "unknown"
+ ["options"]=>
+ array(0) {
+ }
+}
+array(3) {
+ ["algo"]=>
+ int(0)
+ ["algoName"]=>
+ string(7) "unknown"
+ ["options"]=>
+ array(0) {
+ }
+}
+OK!
diff --git a/ext/standard/tests/password/password_get_info_error.phpt b/ext/standard/tests/password/password_get_info_error.phpt
new file mode 100644
index 0000000000..af676744c8
--- /dev/null
+++ b/ext/standard/tests/password/password_get_info_error.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Test error operation of password_get_info()
+--FILE--
+<?php
+//-=-=-=-
+var_dump(password_get_info());
+var_dump(password_get_info(array()));
+
+echo "OK!";
+?>
+--EXPECTF--
+Warning: password_get_info() expects exactly 1 parameter, 0 given in %s on line %d
+NULL
+
+Warning: password_get_info() expects parameter 1 to be string, array given in %s on line %d
+NULL
+OK!
diff --git a/ext/standard/tests/password/password_hash.phpt b/ext/standard/tests/password/password_hash.phpt
new file mode 100644
index 0000000000..f59d3d5e48
--- /dev/null
+++ b/ext/standard/tests/password/password_hash.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Test normal operation of password_hash()
+--FILE--
+<?php
+//-=-=-=-
+
+var_dump(strlen(password_hash("foo", PASSWORD_BCRYPT)));
+
+$hash = password_hash("foo", PASSWORD_BCRYPT);
+
+var_dump($hash === crypt("foo", $hash));
+
+var_dump(password_hash("rasmuslerdorf", PASSWORD_BCRYPT, array("cost" => 7, "salt" => "usesomesillystringforsalt")));
+
+var_dump(password_hash("test", PASSWORD_BCRYPT, array("salt" => "123456789012345678901" . chr(0))));
+
+echo "OK!";
+?>
+--EXPECT--
+int(60)
+bool(true)
+string(60) "$2y$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi"
+string(60) "$2y$10$MTIzNDU2Nzg5MDEyMzQ1Nej0NmcAWSLR.oP7XOR9HD/vjUuOj100y"
+OK!
+
diff --git a/ext/standard/tests/password/password_hash_error.phpt b/ext/standard/tests/password/password_hash_error.phpt
new file mode 100644
index 0000000000..952250cb30
--- /dev/null
+++ b/ext/standard/tests/password/password_hash_error.phpt
@@ -0,0 +1,48 @@
+--TEST--
+Test error operation of password_hash()
+--FILE--
+<?php
+//-=-=-=-
+
+var_dump(password_hash());
+
+var_dump(password_hash("foo"));
+
+var_dump(password_hash("foo", array()));
+
+var_dump(password_hash("foo", 19, new StdClass));
+
+var_dump(password_hash("foo", PASSWORD_BCRYPT, "baz"));
+
+var_dump(password_hash(array(), PASSWORD_BCRYPT));
+
+var_dump(password_hash("123", PASSWORD_BCRYPT, array("salt" => array())));
+
+/* Non-string salt, checking for memory leaks */
+var_dump(password_hash('123', PASSWORD_BCRYPT, array('salt' => 1234)));
+
+?>
+--EXPECTF--
+Warning: password_hash() expects at least 2 parameters, 0 given in %s on line %d
+NULL
+
+Warning: password_hash() expects at least 2 parameters, 1 given in %s on line %d
+NULL
+
+Warning: password_hash() expects parameter 2 to be long, array given in %s on line %d
+NULL
+
+Warning: password_hash(): Unknown password hashing algorithm: 19 in %s on line %d
+NULL
+
+Warning: password_hash() expects parameter 3 to be array, string given in %s on line %d
+NULL
+
+Warning: password_hash() expects parameter 1 to be string, array given in %s on line %d
+NULL
+
+Warning: password_hash(): Non-string salt parameter supplied in %s on line %d
+NULL
+
+Warning: password_hash(): Provided salt is too short: 4 expecting 22 in %s on line %d
+NULL
diff --git a/ext/standard/tests/password/password_needs_rehash.phpt b/ext/standard/tests/password/password_needs_rehash.phpt
new file mode 100644
index 0000000000..734729e63d
--- /dev/null
+++ b/ext/standard/tests/password/password_needs_rehash.phpt
@@ -0,0 +1,45 @@
+--TEST--
+Test normal operation of password_needs_rehash()
+--FILE--
+<?php
+//-=-=-=-
+
+// Invalid Hash, always rehash
+var_dump(password_needs_rehash('', PASSWORD_BCRYPT));
+
+// Valid, as it's an unknown algorithm
+var_dump(password_needs_rehash('', 0));
+
+// Valid with cost the same
+var_dump(password_needs_rehash('$2y$10$MTIzNDU2Nzg5MDEyMzQ1Nej0NmcAWSLR.oP7XOR9HD/vjUuOj100y', PASSWORD_BCRYPT, array('cost' => 10)));
+
+// Valid with cost the same, additional params
+var_dump(password_needs_rehash('$2y$10$MTIzNDU2Nzg5MDEyMzQ1Nej0NmcAWSLR.oP7XOR9HD/vjUuOj100y', PASSWORD_BCRYPT, array('cost' => 10, 'foo' => 3)));
+
+// Invalid, different (lower) cost
+var_dump(password_needs_rehash('$2y$10$MTIzNDU2Nzg5MDEyMzQ1Nej0NmcAWSLR.oP7XOR9HD/vjUuOj100y', PASSWORD_BCRYPT, array('cost' => 09)));
+
+// Invalid, different (higher) cost
+var_dump(password_needs_rehash('$2y$10$MTIzNDU2Nzg5MDEyMzQ1Nej0NmcAWSLR.oP7XOR9HD/vjUuOj100y', PASSWORD_BCRYPT, array('cost' => 11)));
+
+// Valid with cost the default
+$cost = str_pad(PASSWORD_BCRYPT_DEFAULT_COST, 2, '0', STR_PAD_LEFT);
+var_dump(password_needs_rehash('$2y$'.$cost.'$MTIzNDU2Nzg5MDEyMzQ1Nej0NmcAWSLR.oP7XOR9HD/vjUuOj100y', PASSWORD_BCRYPT));
+
+// Should Issue Needs Rehash, Since Foo is cast to 0...
+var_dump(password_needs_rehash('$2y$10$MTIzNDU2Nzg5MDEyMzQ1Nej0NmcAWSLR.oP7XOR9HD/vjUuOj100y', PASSWORD_BCRYPT, array('cost' => 'foo')));
+
+
+
+echo "OK!";
+?>
+--EXPECT--
+bool(true)
+bool(false)
+bool(false)
+bool(false)
+bool(true)
+bool(true)
+bool(false)
+bool(true)
+OK!
diff --git a/ext/standard/tests/password/password_needs_rehash_error.phpt b/ext/standard/tests/password/password_needs_rehash_error.phpt
new file mode 100644
index 0000000000..e25ef8db3f
--- /dev/null
+++ b/ext/standard/tests/password/password_needs_rehash_error.phpt
@@ -0,0 +1,33 @@
+--TEST--
+Test error operation of password_needs_rehash()
+--FILE--
+<?php
+//-=-=-=-
+var_dump(password_needs_rehash());
+
+var_dump(password_needs_rehash(''));
+
+var_dump(password_needs_rehash('', "foo"));
+
+var_dump(password_needs_rehash(array(), 1));
+
+var_dump(password_needs_rehash("", 1, "foo"));
+
+echo "OK!";
+?>
+--EXPECTF--
+Warning: password_needs_rehash() expects at least 2 parameters, 0 given in %s on line %d
+NULL
+
+Warning: password_needs_rehash() expects at least 2 parameters, 1 given in %s on line %d
+NULL
+
+Warning: password_needs_rehash() expects parameter 2 to be long, string given in %s on line %d
+NULL
+
+Warning: password_needs_rehash() expects parameter 1 to be string, array given in %s on line %d
+NULL
+
+Warning: password_needs_rehash() expects parameter 3 to be array, string given in %s on line %d
+NULL
+OK!
diff --git a/ext/standard/tests/password/password_verify.phpt b/ext/standard/tests/password/password_verify.phpt
new file mode 100644
index 0000000000..e7ecc7edd3
--- /dev/null
+++ b/ext/standard/tests/password/password_verify.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Test normal operation of password_verify)
+--FILE--
+<?php
+//-=-=-=-
+
+var_dump(password_verify(123, 123));
+
+var_dump(password_verify("foo", '$2a$07$usesomesillystringforsalt$'));
+
+var_dump(password_verify('rasmusler', '$2a$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi'));
+
+var_dump(password_verify('rasmuslerdorf', '$2a$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi'));
+echo "OK!";
+?>
+--EXPECT--
+bool(false)
+bool(false)
+bool(false)
+bool(true)
+OK!
diff --git a/ext/standard/tests/password/password_verify_error.phpt b/ext/standard/tests/password/password_verify_error.phpt
new file mode 100644
index 0000000000..3e653fa04e
--- /dev/null
+++ b/ext/standard/tests/password/password_verify_error.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Test error operation of password_verify()
+--FILE--
+<?php
+//-=-=-=-
+
+var_dump(password_verify());
+
+var_dump(password_verify("foo"));
+
+?>
+--EXPECTF--
+Warning: password_verify() expects exactly 2 parameters, 0 given in %s on line %d
+bool(false)
+
+Warning: password_verify() expects exactly 2 parameters, 1 given in %s on line %d
+bool(false)
+
diff --git a/ext/standard/tests/php_ini_loaded_file.phpt b/ext/standard/tests/php_ini_loaded_file.phpt
index 747e0196f1..7d441582ee 100644
--- a/ext/standard/tests/php_ini_loaded_file.phpt
+++ b/ext/standard/tests/php_ini_loaded_file.phpt
@@ -10,5 +10,5 @@ precision=12
<?php
var_dump(php_ini_loaded_file());
?>
---EXPECTF--
-string(%d) "%sphp.ini"
+--EXPECTREGEX--
+string\(\d+\) ".*php\.ini"|bool\(false\)
diff --git a/ext/standard/tests/php_logo_guid.phpt b/ext/standard/tests/php_logo_guid.phpt
deleted file mode 100644
index c644b2893b..0000000000
--- a/ext/standard/tests/php_logo_guid.phpt
+++ /dev/null
@@ -1,13 +0,0 @@
---TEST--
-Check the output of the php_logo_guid() function
---CREDITS--
-Sebastian Schürmann
-sschuermann@chip.de
-Testfest 2009 Munich
---FILE--
-<?php
-echo php_logo_guid();
-?>
---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
deleted file mode 100644
index a9fa7d35d5..0000000000
--- a/ext/standard/tests/php_real_logo_guid.phpt
+++ /dev/null
@@ -1,12 +0,0 @@
---TEST--
-Testing the undocumented function php_real_logo_guid()
---CREDITS--
-Sebastian Schürmann
-sschuermann@chip.de
-Testfest 2009 Munich
---FILE--
-<?php
-echo php_real_logo_guid();
-?>
---EXPECT--
-PHPE9568F34-D428-11d2-A769-00AA001ACF42
diff --git a/ext/standard/tests/strings/bug61038.phpt b/ext/standard/tests/strings/bug61038.phpt
new file mode 100644
index 0000000000..7130804fa4
--- /dev/null
+++ b/ext/standard/tests/strings/bug61038.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Bug #61038: unpack("a5", "str\0\0") does not work as expected
+--FILE--
+<?php
+var_dump(unpack("a4", "str\0\0"));
+var_dump(unpack("a5", "str\0\0"));
+var_dump(unpack("a6", "str\0\0"));
+var_dump(unpack("a*", "str\0\0"));
+?>
+--EXPECTF--
+array(1) {
+ [1]=>
+ string(4) "str%c"
+}
+array(1) {
+ [1]=>
+ string(5) "str%c%c"
+}
+
+Warning: unpack(): Type a: not enough input, need 6, have 5 in %s on line %d
+bool(false)
+array(1) {
+ [1]=>
+ string(5) "str%c%c"
+}
+
diff --git a/ext/standard/tests/strings/bug63874.phpt b/ext/standard/tests/strings/bug63874.phpt
new file mode 100644
index 0000000000..066cc155df
--- /dev/null
+++ b/ext/standard/tests/strings/bug63874.phpt
@@ -0,0 +1,16 @@
+--TEST--
+Bug #63874 (Segfault if php_strip_whitespace has heredoc)
+--FILE--
+<?php
+echo php_strip_whitespace(__FILE__);
+
+return <<<A
+a
+A;
+?>
+--EXPECT--
+<?php
+echo php_strip_whitespace(__FILE__); return <<<A
+a
+A;
+?>
diff --git a/ext/standard/tests/strings/implode1.phpt b/ext/standard/tests/strings/implode1.phpt
index 3997c54b59..3720c06927 100644
--- a/ext/standard/tests/strings/implode1.phpt
+++ b/ext/standard/tests/strings/implode1.phpt
Binary files differ
diff --git a/ext/standard/tests/strings/pack_A.phpt b/ext/standard/tests/strings/pack_A.phpt
new file mode 100644
index 0000000000..59fc22e122
--- /dev/null
+++ b/ext/standard/tests/strings/pack_A.phpt
@@ -0,0 +1,25 @@
+--TEST--
+pack()/unpack(): "A" modifier
+--FILE--
+<?php
+var_dump(
+ pack("A5", "foo "),
+ pack("A4", "fooo"),
+ pack("A4", "foo"),
+ unpack("A*", "foo\0\rbar\0 \t\r\n"),
+ unpack("A4", "foo\0\rbar\0 \t\r\n")
+);
+?>
+--EXPECTF--
+string(5) "foo "
+string(4) "fooo"
+string(4) "foo "
+array(1) {
+ [1]=>
+ string(8) "foo%c%cbar"
+}
+array(1) {
+ [1]=>
+ string(3) "foo"
+}
+
diff --git a/ext/standard/tests/strings/pack_Z.phpt b/ext/standard/tests/strings/pack_Z.phpt
new file mode 100644
index 0000000000..4fd007ae0f
--- /dev/null
+++ b/ext/standard/tests/strings/pack_Z.phpt
@@ -0,0 +1,50 @@
+--TEST--
+pack()/unpack(): "Z" format
+--FILE--
+<?php
+var_dump(
+ pack("Z0", "f"),
+ pack("Z5", "foo\0"),
+ pack("Z4", "fooo"),
+ pack("Z4", "foo"),
+ pack("Z*", "foo"),
+ unpack("Z*", "foo\0\rbar\0 \t\r\n"),
+ unpack("Z9", "foo\0\rbar\0 \t\r\n"),
+ unpack("Z2", "\0"),
+ unpack("Z2", "\0\0"),
+ unpack("Z2", "A\0"),
+ unpack("Z2", "AB\0"),
+ unpack("Z2", "ABC")
+);
+--EXPECTF--
+Warning: unpack(): Type Z: not enough input, need 2, have 1 in %s on line %d
+string(0) ""
+string(5) "foo%c%c"
+string(4) "foo%c"
+string(4) "foo%c"
+string(4) "foo%c"
+array(1) {
+ [1]=>
+ string(3) "foo"
+}
+array(1) {
+ [1]=>
+ string(3) "foo"
+}
+bool(false)
+array(1) {
+ [1]=>
+ string(0) ""
+}
+array(1) {
+ [1]=>
+ string(1) "A"
+}
+array(1) {
+ [1]=>
+ string(2) "AB"
+}
+array(1) {
+ [1]=>
+ string(2) "AB"
+}
diff --git a/ext/standard/tests/strings/parse_str_basic3.phpt b/ext/standard/tests/strings/parse_str_basic3.phpt
index 619b1476ab..84f6a53bb1 100644
--- a/ext/standard/tests/strings/parse_str_basic3.phpt
+++ b/ext/standard/tests/strings/parse_str_basic3.phpt
Binary files differ
diff --git a/ext/standard/tests/strings/unpack_error.phpt b/ext/standard/tests/strings/unpack_error.phpt
index 43b2df1c0a..1ef97ccbaf 100644
--- a/ext/standard/tests/strings/unpack_error.phpt
+++ b/ext/standard/tests/strings/unpack_error.phpt
@@ -19,7 +19,7 @@ var_dump(unpack("I", pack("I", 65534), $extra_arg));
echo "\n-- Testing unpack() function with invalid format character --\n";
$extra_arg = 10;
-var_dump(unpack("Z", pack("I", 65534)));
+var_dump(unpack("G", pack("I", 65534)));
?>
===DONE===
--EXPECTF--
@@ -37,6 +37,6 @@ NULL
-- Testing unpack() function with invalid format character --
-Warning: unpack(): Invalid format type Z in %s on line %d
+Warning: unpack(): Invalid format type G in %s on line %d
bool(false)
===DONE===
diff --git a/ext/standard/tests/strings/vprintf_variation15_64bit.phpt b/ext/standard/tests/strings/vprintf_variation15_64bit.phpt
index 226f17572b..0475d12e69 100644
--- a/ext/standard/tests/strings/vprintf_variation15_64bit.phpt
+++ b/ext/standard/tests/strings/vprintf_variation15_64bit.phpt
@@ -62,8 +62,8 @@ int(16)
int(24)
-- Iteration 3 --
- 1234000 0 120
-int(25)
+ 1234000 3875820019684212736 120
+int(34)
-- Iteration 4 --
#1 0 $0 10
diff --git a/ext/standard/tests/strings/vsprintf_variation15_64bit.phpt b/ext/standard/tests/strings/vsprintf_variation15_64bit.phpt
index 3af1738e56..af55ce966f 100644
--- a/ext/standard/tests/strings/vsprintf_variation15_64bit.phpt
+++ b/ext/standard/tests/strings/vsprintf_variation15_64bit.phpt
@@ -58,7 +58,7 @@ string(16) "1234567 342391 0"
string(24) "12345678900 u 1234 12345"
-- Iteration 3 --
-string(25) " 1234000 0 120"
+string(34) " 1234000 3875820019684212736 120"
-- Iteration 4 --
string(10) "#1 0 $0 10"
diff --git a/ext/standard/tests/time/strptime_basic.phpt b/ext/standard/tests/time/strptime_basic.phpt
index 194a78f82b..30e3e82cc7 100644
--- a/ext/standard/tests/time/strptime_basic.phpt
+++ b/ext/standard/tests/time/strptime_basic.phpt
@@ -24,7 +24,7 @@ $input = "10:00:00 AM July 2 1963";
$tstamp = strtotime($input);
$str = strftime("%r %B%e %Y %Z", $tstamp);
-var_dump(strptime($str, '%H:%M:%S %p %B %d %Y %Z'));
+var_dump(strptime($str, '%H:%M:%S %p %B %d %Y'));
$str = strftime("%T %D", $tstamp);
var_dump(strptime($str, '%H:%M:%S %m/%d/%y'));
@@ -55,7 +55,7 @@ array(9) {
["tm_yday"]=>
int(182)
["unparsed"]=>
- string(3) "GMT"
+ string(4) " GMT"
}
array(9) {
["tm_sec"]=>
diff --git a/ext/standard/tests/zend_logo_guid.phpt b/ext/standard/tests/zend_logo_guid.phpt
deleted file mode 100644
index 44e213b25d..0000000000
--- a/ext/standard/tests/zend_logo_guid.phpt
+++ /dev/null
@@ -1,12 +0,0 @@
---TEST--
-Checking the zend_logo_guid() function
---CREDITS--
-Sebastian Schürmann
-sschuermann@chip.de
-Testfest 2009 Munich
---FILE--
-<?php
-echo zend_logo_guid();
-?>
---EXPECT--
-PHPE9568F35-D428-11d2-A769-00AA001ACF42
diff --git a/ext/standard/type.c b/ext/standard/type.c
index 45eb82fe3b..dcc8083e41 100644
--- a/ext/standard/type.c
+++ b/ext/standard/type.c
@@ -176,6 +176,20 @@ PHP_FUNCTION(floatval)
}
/* }}} */
+/* {{{ proto bool boolval(mixed var)
+ Get the boolean value of a variable */
+PHP_FUNCTION(boolval)
+{
+ zval **val;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &val) == FAILURE) {
+ return;
+ }
+
+ RETURN_BOOL(zend_is_true(*val));
+}
+/* }}} */
+
/* {{{ proto string strval(mixed var)
Get the string value of a variable */
PHP_FUNCTION(strval)
diff --git a/ext/standard/url_scanner_ex.c b/ext/standard/url_scanner_ex.c
index 671a22f5ba..8a5409341b 100644
--- a/ext/standard/url_scanner_ex.c
+++ b/ext/standard/url_scanner_ex.c
@@ -544,56 +544,69 @@ state_next_arg:
};
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
- if (yych <= ' ') {
+ if (yych <= '.') {
if (yych <= '\f') {
- if (yych <= 0x08) goto yy34;
- if (yych <= '\v') goto yy30;
- goto yy34;
+ if (yych <= 0x08) goto yy36;
+ if (yych <= '\v') goto yy32;
+ goto yy36;
} else {
- if (yych <= '\r') goto yy30;
- if (yych <= 0x1F) goto yy34;
- goto yy30;
+ if (yych <= '\r') goto yy32;
+ if (yych == ' ') goto yy32;
+ goto yy36;
}
} else {
if (yych <= '@') {
- if (yych != '>') goto yy34;
+ if (yych <= '/') goto yy28;
+ if (yych == '>') goto yy30;
+ goto yy36;
} else {
- if (yych <= 'Z') goto yy32;
- if (yych <= '`') goto yy34;
- if (yych <= 'z') goto yy32;
- goto yy34;
+ if (yych <= 'Z') goto yy34;
+ if (yych <= '`') goto yy36;
+ if (yych <= 'z') goto yy34;
+ goto yy36;
}
}
+yy28:
+ ++YYCURSOR;
+ if ((yych = *YYCURSOR) == '>') goto yy39;
+yy29:
+#line 323 "ext/standard/url_scanner_ex.re"
+ { passthru(STD_ARGS); goto state_plain_begin; }
+#line 576 "ext/standard/url_scanner_ex.c"
+yy30:
++YYCURSOR;
+yy31:
#line 320 "ext/standard/url_scanner_ex.re"
{ passthru(STD_ARGS); handle_form(STD_ARGS); goto state_plain_begin; }
-#line 571 "ext/standard/url_scanner_ex.c"
-yy30:
+#line 582 "ext/standard/url_scanner_ex.c"
+yy32:
++YYCURSOR;
yych = *YYCURSOR;
- goto yy37;
-yy31:
+ goto yy38;
+yy33:
#line 321 "ext/standard/url_scanner_ex.re"
{ passthru(STD_ARGS); goto state_next_arg; }
-#line 579 "ext/standard/url_scanner_ex.c"
-yy32:
+#line 590 "ext/standard/url_scanner_ex.c"
+yy34:
++YYCURSOR;
#line 322 "ext/standard/url_scanner_ex.re"
{ --YYCURSOR; STATE = STATE_ARG; goto state_arg; }
-#line 584 "ext/standard/url_scanner_ex.c"
-yy34:
- ++YYCURSOR;
-#line 323 "ext/standard/url_scanner_ex.re"
- { passthru(STD_ARGS); goto state_plain_begin; }
-#line 589 "ext/standard/url_scanner_ex.c"
+#line 595 "ext/standard/url_scanner_ex.c"
yy36:
+ yych = *++YYCURSOR;
+ goto yy29;
+yy37:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
-yy37:
+yy38:
if (yybm[0+yych] & 128) {
- goto yy36;
+ goto yy37;
}
+ goto yy33;
+yy39:
+ ++YYCURSOR;
+ yych = *YYCURSOR;
goto yy31;
}
#line 324 "ext/standard/url_scanner_ex.re"
@@ -602,7 +615,7 @@ yy37:
state_arg:
start = YYCURSOR;
-#line 606 "ext/standard/url_scanner_ex.c"
+#line 619 "ext/standard/url_scanner_ex.c"
{
YYCTYPE yych;
static const unsigned char yybm[] = {
@@ -641,32 +654,32 @@ state_arg:
};
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
- if (yych <= '@') goto yy42;
- if (yych <= 'Z') goto yy40;
- if (yych <= '`') goto yy42;
- if (yych >= '{') goto yy42;
-yy40:
+ if (yych <= '@') goto yy44;
+ if (yych <= 'Z') goto yy42;
+ if (yych <= '`') goto yy44;
+ if (yych >= '{') goto yy44;
+yy42:
++YYCURSOR;
yych = *YYCURSOR;
- goto yy45;
-yy41:
+ goto yy47;
+yy43:
#line 329 "ext/standard/url_scanner_ex.re"
{ passthru(STD_ARGS); handle_arg(STD_ARGS); STATE = STATE_BEFORE_VAL; goto state_before_val; }
-#line 656 "ext/standard/url_scanner_ex.c"
-yy42:
+#line 669 "ext/standard/url_scanner_ex.c"
+yy44:
++YYCURSOR;
#line 330 "ext/standard/url_scanner_ex.re"
{ passthru(STD_ARGS); STATE = STATE_NEXT_ARG; goto state_next_arg; }
-#line 661 "ext/standard/url_scanner_ex.c"
-yy44:
+#line 674 "ext/standard/url_scanner_ex.c"
+yy46:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
-yy45:
+yy47:
if (yybm[0+yych] & 128) {
- goto yy44;
+ goto yy46;
}
- goto yy41;
+ goto yy43;
}
#line 331 "ext/standard/url_scanner_ex.re"
@@ -674,7 +687,7 @@ yy45:
state_before_val:
start = YYCURSOR;
-#line 678 "ext/standard/url_scanner_ex.c"
+#line 691 "ext/standard/url_scanner_ex.c"
{
YYCTYPE yych;
static const unsigned char yybm[] = {
@@ -713,45 +726,45 @@ state_before_val:
};
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
- if (yych == ' ') goto yy48;
- if (yych == '=') goto yy50;
- goto yy52;
-yy48:
+ if (yych == ' ') goto yy50;
+ if (yych == '=') goto yy52;
+ goto yy54;
+yy50:
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == ' ') goto yy55;
- if (yych == '=') goto yy53;
-yy49:
+ if (yych == ' ') goto yy57;
+ if (yych == '=') goto yy55;
+yy51:
#line 337 "ext/standard/url_scanner_ex.re"
{ --YYCURSOR; goto state_next_arg_begin; }
-#line 727 "ext/standard/url_scanner_ex.c"
-yy50:
+#line 740 "ext/standard/url_scanner_ex.c"
+yy52:
++YYCURSOR;
yych = *YYCURSOR;
- goto yy54;
-yy51:
+ goto yy56;
+yy53:
#line 336 "ext/standard/url_scanner_ex.re"
{ passthru(STD_ARGS); STATE = STATE_VAL; goto state_val; }
-#line 735 "ext/standard/url_scanner_ex.c"
-yy52:
+#line 748 "ext/standard/url_scanner_ex.c"
+yy54:
yych = *++YYCURSOR;
- goto yy49;
-yy53:
+ goto yy51;
+yy55:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
-yy54:
+yy56:
if (yybm[0+yych] & 128) {
- goto yy53;
+ goto yy55;
}
- goto yy51;
-yy55:
+ goto yy53;
+yy57:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
- if (yych == ' ') goto yy55;
- if (yych == '=') goto yy53;
+ if (yych == ' ') goto yy57;
+ if (yych == '=') goto yy55;
YYCURSOR = YYMARKER;
- goto yy49;
+ goto yy51;
}
#line 338 "ext/standard/url_scanner_ex.re"
@@ -760,7 +773,7 @@ yy55:
state_val:
start = YYCURSOR;
-#line 764 "ext/standard/url_scanner_ex.c"
+#line 777 "ext/standard/url_scanner_ex.c"
{
YYCTYPE yych;
static const unsigned char yybm[] = {
@@ -801,83 +814,83 @@ state_val:
yych = *YYCURSOR;
if (yych <= ' ') {
if (yych <= '\f') {
- if (yych <= 0x08) goto yy63;
- if (yych <= '\n') goto yy65;
- goto yy63;
- } else {
- if (yych <= '\r') goto yy65;
- if (yych <= 0x1F) goto yy63;
+ if (yych <= 0x08) goto yy65;
+ if (yych <= '\n') goto yy67;
goto yy65;
+ } else {
+ if (yych <= '\r') goto yy67;
+ if (yych <= 0x1F) goto yy65;
+ goto yy67;
}
} else {
if (yych <= '&') {
- if (yych != '"') goto yy63;
+ if (yych != '"') goto yy65;
} else {
- if (yych <= '\'') goto yy62;
- if (yych == '>') goto yy65;
- goto yy63;
+ if (yych <= '\'') goto yy64;
+ if (yych == '>') goto yy67;
+ goto yy65;
}
}
yych = *(YYMARKER = ++YYCURSOR);
- if (yych != '>') goto yy74;
-yy61:
+ if (yych != '>') goto yy76;
+yy63:
#line 347 "ext/standard/url_scanner_ex.re"
{ passthru(STD_ARGS); goto state_next_arg_begin; }
-#line 827 "ext/standard/url_scanner_ex.c"
-yy62:
+#line 840 "ext/standard/url_scanner_ex.c"
+yy64:
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == '>') goto yy61;
- goto yy69;
-yy63:
+ if (yych == '>') goto yy63;
+ goto yy71;
+yy65:
++YYCURSOR;
yych = *YYCURSOR;
- goto yy67;
-yy64:
+ goto yy69;
+yy66:
#line 346 "ext/standard/url_scanner_ex.re"
{ handle_val(STD_ARGS, 0, ' '); goto state_next_arg_begin; }
-#line 839 "ext/standard/url_scanner_ex.c"
-yy65:
+#line 852 "ext/standard/url_scanner_ex.c"
+yy67:
yych = *++YYCURSOR;
- goto yy61;
-yy66:
+ goto yy63;
+yy68:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
-yy67:
+yy69:
if (yybm[0+yych] & 32) {
- goto yy66;
+ goto yy68;
}
- goto yy64;
-yy68:
+ goto yy66;
+yy70:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
-yy69:
+yy71:
if (yybm[0+yych] & 64) {
- goto yy68;
+ goto yy70;
}
- if (yych <= '=') goto yy71;
-yy70:
+ if (yych <= '=') goto yy73;
+yy72:
YYCURSOR = YYMARKER;
- goto yy61;
-yy71:
+ goto yy63;
+yy73:
++YYCURSOR;
#line 345 "ext/standard/url_scanner_ex.re"
{ handle_val(STD_ARGS, 1, '\''); goto state_next_arg_begin; }
-#line 868 "ext/standard/url_scanner_ex.c"
-yy73:
+#line 881 "ext/standard/url_scanner_ex.c"
+yy75:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
-yy74:
+yy76:
if (yybm[0+yych] & 128) {
- goto yy73;
+ goto yy75;
}
- if (yych >= '>') goto yy70;
+ if (yych >= '>') goto yy72;
++YYCURSOR;
#line 344 "ext/standard/url_scanner_ex.re"
{ handle_val(STD_ARGS, 1, '"'); goto state_next_arg_begin; }
-#line 881 "ext/standard/url_scanner_ex.c"
+#line 894 "ext/standard/url_scanner_ex.c"
}
#line 348 "ext/standard/url_scanner_ex.re"
@@ -998,7 +1011,7 @@ static void php_url_scanner_output_handler(char *output, uint output_len, char *
PHPAPI int php_url_scanner_add_var(char *name, int name_len, char *value, int value_len, int urlencode TSRMLS_DC)
{
- char *encoded;
+ char *encoded = NULL;
int encoded_len;
smart_str val;
diff --git a/ext/standard/user_filters.c b/ext/standard/user_filters.c
index 29a4c70d34..ef80f2b290 100644
--- a/ext/standard/user_filters.c
+++ b/ext/standard/user_filters.c
@@ -559,7 +559,7 @@ PHP_FUNCTION(stream_get_filters)
if (filters_hash) {
for(zend_hash_internal_pointer_reset(filters_hash);
- (key_flags = zend_hash_get_current_key_ex(filters_hash, &filter_name, &filter_name_len, &num_key, 0, NULL)) != HASH_KEY_NON_EXISTANT;
+ (key_flags = zend_hash_get_current_key_ex(filters_hash, &filter_name, &filter_name_len, &num_key, 0, NULL)) != HASH_KEY_NON_EXISTENT;
zend_hash_move_forward(filters_hash))
if (key_flags == HASH_KEY_IS_STRING) {
add_next_index_stringl(return_value, filter_name, filter_name_len - 1, 1);
diff --git a/ext/standard/var.c b/ext/standard/var.c
index 7603ff2ee0..d05f05527c 100644
--- a/ext/standard/var.c
+++ b/ext/standard/var.c
@@ -647,7 +647,7 @@ static void php_var_serialize_class(smart_str *buf, zval *struc, zval *retval_pt
for (;; zend_hash_move_forward_ex(HASH_OF(retval_ptr), &pos)) {
i = zend_hash_get_current_key_ex(HASH_OF(retval_ptr), &key, NULL, &index, 0, &pos);
- if (i == HASH_KEY_NON_EXISTANT) {
+ if (i == HASH_KEY_NON_EXISTENT) {
break;
}
@@ -858,7 +858,7 @@ static void php_var_serialize_intern(smart_str *buf, zval *struc, HashTable *var
zend_hash_internal_pointer_reset_ex(myht, &pos);
for (;; zend_hash_move_forward_ex(myht, &pos)) {
i = zend_hash_get_current_key_ex(myht, &key, &key_len, &index, 0, &pos);
- if (i == HASH_KEY_NON_EXISTANT) {
+ if (i == HASH_KEY_NON_EXISTENT) {
break;
}
if (incomplete_class && strcmp(key, MAGIC_MEMBER) == 0) {
diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c
index e39a3505cd..004274d406 100644
--- a/ext/standard/var_unserializer.c
+++ b/ext/standard/var_unserializer.c
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.13.5 on Mon Jul 29 17:57:26 2013 */
+/* Generated by re2c 0.13.5 */
#line 1 "ext/standard/var_unserializer.re"
/*
+----------------------------------------------------------------------+
diff --git a/ext/sybase_ct/config.m4 b/ext/sybase_ct/config.m4
index 81df1f3126..276fe12675 100644
--- a/ext/sybase_ct/config.m4
+++ b/ext/sybase_ct/config.m4
@@ -3,7 +3,7 @@ dnl $Id$
dnl
PHP_ARG_WITH(sybase-ct, for Sybase-CT support,
-[ --with-sybase-ct[=DIR] Include Sybase-CT support. DIR is the Sybase home
+[ --with-sybase-ct[=DIR] Include Sybase-CT support. DIR is the Sybase home
directory [/home/sybase]])
if test "$PHP_SYBASE_CT" != "no"; then
diff --git a/ext/sybase_ct/config.w32 b/ext/sybase_ct/config.w32
index bf56bd1402..c773b623af 100644
--- a/ext/sybase_ct/config.w32
+++ b/ext/sybase_ct/config.w32
@@ -7,8 +7,11 @@ ARG_WITH("sybase-ct", "SYBASE_CT support", "no");
if (PHP_SYBASE_CT != "no") {
if (CHECK_HEADER_ADD_INCLUDE("ctpublic.h", "CFLAGS_SYBASE_CT", PHP_PHP_BUILD + "\\sybase\\include;" + PHP_SYBASE_CT) &&
- CHECK_LIB("libcs.lib", "sybase_ct", PHP_PHP_BUILD + "\\sybase\\lib;" + PHP_SYBASE_CT) &&
- CHECK_LIB("libct.lib", "sybase_ct", PHP_PHP_BUILD + "\\sybase\\lib;" + PHP_SYBASE_CT)) {
+ (!X64 && CHECK_LIB("libsybcs.lib", "sybase_ct", PHP_PHP_BUILD + "\\sybase\\lib;" + PHP_SYBASE_CT) &&
+ CHECK_LIB("libsybct.lib", "sybase_ct", PHP_PHP_BUILD + "\\sybase\\lib;" + PHP_SYBASE_CT) ||
+ X64 && CHECK_LIB("libsybcs64.lib", "sybase_ct", PHP_PHP_BUILD + "\\sybase\\lib;" + PHP_SYBASE_CT) &&
+ CHECK_LIB("libsybct64.lib", "sybase_ct", PHP_PHP_BUILD + "\\sybase\\lib;" + PHP_SYBASE_CT))
+ ) {
EXTENSION('sybase_ct', 'php_sybase_ct.c');
AC_DEFINE('HAVE_SYBASE_CT', 1);
} else {
diff --git a/ext/tidy/config.m4 b/ext/tidy/config.m4
index 675498c8ce..102f6a827e 100644
--- a/ext/tidy/config.m4
+++ b/ext/tidy/config.m4
@@ -3,7 +3,7 @@ dnl $Id$
dnl
PHP_ARG_WITH(tidy,for TIDY support,
-[ --with-tidy[=DIR] Include TIDY support])
+[ --with-tidy[=DIR] Include TIDY support])
if test "$PHP_TIDY" != "no"; then
diff --git a/ext/tokenizer/tests/bug60097.phpt b/ext/tokenizer/tests/bug60097.phpt
new file mode 100644
index 0000000000..2116866c93
--- /dev/null
+++ b/ext/tokenizer/tests/bug60097.phpt
@@ -0,0 +1,121 @@
+--TEST--
+Bug 60097: token_get_all fails to lex nested heredoc
+--FILE--
+<?php
+
+var_dump(token_get_all('<?php
+<<<DOC1
+{$s(<<<DOC2
+DOC2
+)}
+DOC1;
+'));
+
+?>
+--EXPECT--
+array(14) {
+ [0]=>
+ array(3) {
+ [0]=>
+ int(374)
+ [1]=>
+ string(6) "<?php
+"
+ [2]=>
+ int(1)
+ }
+ [1]=>
+ array(3) {
+ [0]=>
+ int(378)
+ [1]=>
+ string(8) "<<<DOC1
+"
+ [2]=>
+ int(2)
+ }
+ [2]=>
+ array(3) {
+ [0]=>
+ int(381)
+ [1]=>
+ string(1) "{"
+ [2]=>
+ int(3)
+ }
+ [3]=>
+ array(3) {
+ [0]=>
+ int(310)
+ [1]=>
+ string(2) "$s"
+ [2]=>
+ int(3)
+ }
+ [4]=>
+ string(1) "("
+ [5]=>
+ array(3) {
+ [0]=>
+ int(378)
+ [1]=>
+ string(8) "<<<DOC2
+"
+ [2]=>
+ int(3)
+ }
+ [6]=>
+ array(3) {
+ [0]=>
+ int(379)
+ [1]=>
+ string(4) "DOC2"
+ [2]=>
+ int(4)
+ }
+ [7]=>
+ array(3) {
+ [0]=>
+ int(377)
+ [1]=>
+ string(1) "
+"
+ [2]=>
+ int(4)
+ }
+ [8]=>
+ string(1) ")"
+ [9]=>
+ string(1) "}"
+ [10]=>
+ array(3) {
+ [0]=>
+ int(315)
+ [1]=>
+ string(1) "
+"
+ [2]=>
+ int(5)
+ }
+ [11]=>
+ array(3) {
+ [0]=>
+ int(379)
+ [1]=>
+ string(4) "DOC1"
+ [2]=>
+ int(6)
+ }
+ [12]=>
+ string(1) ";"
+ [13]=>
+ array(3) {
+ [0]=>
+ int(377)
+ [1]=>
+ string(1) "
+"
+ [2]=>
+ int(6)
+ }
+}
diff --git a/ext/tokenizer/tests/token_get_all_variation11.phpt b/ext/tokenizer/tests/token_get_all_variation11.phpt
index ecc86177a4..98d89961b7 100644
--- a/ext/tokenizer/tests/token_get_all_variation11.phpt
+++ b/ext/tokenizer/tests/token_get_all_variation11.phpt
@@ -130,7 +130,7 @@ array(49) {
[6]=>
array(3) {
[0]=>
- int(283)
+ int(%d)
[1]=>
string(2) "=="
[2]=>
@@ -273,7 +273,7 @@ array(49) {
[27]=>
array(3) {
[0]=>
- int(283)
+ int(%d)
[1]=>
string(2) "=="
[2]=>
diff --git a/ext/tokenizer/tests/token_get_all_variation13.phpt b/ext/tokenizer/tests/token_get_all_variation13.phpt
index 9b2f3bc94f..6f85492a99 100644
--- a/ext/tokenizer/tests/token_get_all_variation13.phpt
+++ b/ext/tokenizer/tests/token_get_all_variation13.phpt
@@ -1005,7 +1005,7 @@ array(145) {
[122]=>
array(3) {
[0]=>
- int(288)
+ int(%d)
[1]=>
string(10) "instanceof"
[2]=>
diff --git a/ext/tokenizer/tests/token_get_all_variation17.phpt b/ext/tokenizer/tests/token_get_all_variation17.phpt
index dccc4c9c23..f71444bc1e 100644
--- a/ext/tokenizer/tests/token_get_all_variation17.phpt
+++ b/ext/tokenizer/tests/token_get_all_variation17.phpt
@@ -145,7 +145,7 @@ array(81) {
[14]=>
array(3) {
[0]=>
- int(283)
+ int(%d)
[1]=>
string(2) "=="
[2]=>
diff --git a/ext/tokenizer/tests/token_get_all_variation4.phpt b/ext/tokenizer/tests/token_get_all_variation4.phpt
index 45e6f8afbd..6bc111efba 100644
--- a/ext/tokenizer/tests/token_get_all_variation4.phpt
+++ b/ext/tokenizer/tests/token_get_all_variation4.phpt
@@ -339,7 +339,7 @@ array(89) {
[38]=>
array(3) {
[0]=>
- int(279)
+ int(%d)
[1]=>
string(2) "&&"
[2]=>
@@ -518,7 +518,7 @@ array(89) {
[60]=>
array(3) {
[0]=>
- int(278)
+ int(%d)
[1]=>
string(2) "||"
[2]=>
diff --git a/ext/tokenizer/tests/token_get_all_variation5.phpt b/ext/tokenizer/tests/token_get_all_variation5.phpt
index 0068f2866f..681fb48e57 100644
--- a/ext/tokenizer/tests/token_get_all_variation5.phpt
+++ b/ext/tokenizer/tests/token_get_all_variation5.phpt
@@ -181,7 +181,7 @@ array(94) {
[18]=>
array(3) {
[0]=>
- int(277)
+ int(%d)
[1]=>
string(2) "+="
[2]=>
@@ -238,7 +238,7 @@ array(94) {
[25]=>
array(3) {
[0]=>
- int(276)
+ int(%d)
[1]=>
string(2) "-="
[2]=>
@@ -295,7 +295,7 @@ array(94) {
[32]=>
array(3) {
[0]=>
- int(275)
+ int(%d)
[1]=>
string(2) "*="
[2]=>
@@ -352,7 +352,7 @@ array(94) {
[39]=>
array(3) {
[0]=>
- int(274)
+ int(%d)
[1]=>
string(2) "/="
[2]=>
@@ -409,7 +409,7 @@ array(94) {
[46]=>
array(3) {
[0]=>
- int(272)
+ int(%d)
[1]=>
string(2) "%="
[2]=>
@@ -466,7 +466,7 @@ array(94) {
[53]=>
array(3) {
[0]=>
- int(271)
+ int(%d)
[1]=>
string(2) "&="
[2]=>
@@ -523,7 +523,7 @@ array(94) {
[60]=>
array(3) {
[0]=>
- int(270)
+ int(%d)
[1]=>
string(2) "|="
[2]=>
@@ -580,7 +580,7 @@ array(94) {
[67]=>
array(3) {
[0]=>
- int(269)
+ int(%d)
[1]=>
string(2) "^="
[2]=>
@@ -637,7 +637,7 @@ array(94) {
[74]=>
array(3) {
[0]=>
- int(267)
+ int(%d)
[1]=>
string(3) ">>="
[2]=>
@@ -694,7 +694,7 @@ array(94) {
[81]=>
array(3) {
[0]=>
- int(268)
+ int(%d)
[1]=>
string(3) "<<="
[2]=>
@@ -751,7 +751,7 @@ array(94) {
[88]=>
array(3) {
[0]=>
- int(273)
+ int(%d)
[1]=>
string(2) ".="
[2]=>
diff --git a/ext/tokenizer/tests/token_get_all_variation6.phpt b/ext/tokenizer/tests/token_get_all_variation6.phpt
index 54936d0c89..6213dab9d0 100644
--- a/ext/tokenizer/tests/token_get_all_variation6.phpt
+++ b/ext/tokenizer/tests/token_get_all_variation6.phpt
@@ -191,7 +191,7 @@ array(50) {
[21]=>
array(3) {
[0]=>
- int(287)
+ int(%d)
[1]=>
string(2) "<<"
[2]=>
@@ -277,7 +277,7 @@ array(50) {
[32]=>
array(3) {
[0]=>
- int(286)
+ int(%d)
[1]=>
string(2) ">>"
[2]=>
diff --git a/ext/tokenizer/tests/token_get_all_variation8.phpt b/ext/tokenizer/tests/token_get_all_variation8.phpt
index 0cf1d63471..c80a5d0f04 100644
--- a/ext/tokenizer/tests/token_get_all_variation8.phpt
+++ b/ext/tokenizer/tests/token_get_all_variation8.phpt
@@ -794,7 +794,7 @@ array(108) {
[103]=>
array(3) {
[0]=>
- int(289)
+ int(%d)
[1]=>
string(7) "(unset)"
[2]=>
diff --git a/ext/tokenizer/tokenizer.c b/ext/tokenizer/tokenizer.c
index 2a30a9819c..8e2aaab923 100644
--- a/ext/tokenizer/tokenizer.c
+++ b/ext/tokenizer/tokenizer.c
@@ -138,11 +138,8 @@ static void tokenize(zval *return_value TSRMLS_DC)
token_line = ++CG(zend_lineno);
CG(increment_lineno) = 0;
}
- add_next_index_stringl(keyword, Z_STRVAL(token), Z_STRLEN(token), 1);
- efree(Z_STRVAL(token));
- } else {
- add_next_index_stringl(keyword, (char *)zendtext, zendleng, 1);
}
+ add_next_index_stringl(keyword, (char *)zendtext, zendleng, 1);
add_next_index_long(keyword, token_line);
add_next_index_zval(return_value, keyword);
} else {
diff --git a/ext/tokenizer/tokenizer_data.c b/ext/tokenizer/tokenizer_data.c
index d4ef1fdf54..681c0dd9af 100644
--- a/ext/tokenizer/tokenizer_data.c
+++ b/ext/tokenizer/tokenizer_data.c
@@ -21,7 +21,7 @@
/*
DO NOT EDIT THIS FILE!
This file is generated using tokenizer_data_gen.sh
-*/
+*/
#include "php.h"
#include "zend.h"
@@ -108,8 +108,10 @@ void tokenizer_register_constants(INIT_FUNC_ARGS) {
REGISTER_LONG_CONSTANT("T_FUNCTION", T_FUNCTION, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("T_CONST", T_CONST, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("T_RETURN", T_RETURN, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("T_YIELD", T_YIELD, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("T_TRY", T_TRY, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("T_CATCH", T_CATCH, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("T_FINALLY", T_FINALLY, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("T_THROW", T_THROW, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("T_USE", T_USE, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("T_INSTEADOF", T_INSTEADOF, CONST_CS | CONST_PERSISTENT);
@@ -242,8 +244,10 @@ char *get_token_type_name(int token_type)
case T_FUNCTION: return "T_FUNCTION";
case T_CONST: return "T_CONST";
case T_RETURN: return "T_RETURN";
+ case T_YIELD: return "T_YIELD";
case T_TRY: return "T_TRY";
case T_CATCH: return "T_CATCH";
+ case T_FINALLY: return "T_FINALLY";
case T_THROW: return "T_THROW";
case T_USE: return "T_USE";
case T_INSTEADOF: return "T_INSTEADOF";
diff --git a/ext/wddx/config.m4 b/ext/wddx/config.m4
index 2b02a92aa9..8f933d490a 100644
--- a/ext/wddx/config.m4
+++ b/ext/wddx/config.m4
@@ -7,11 +7,11 @@ PHP_ARG_ENABLE(wddx,whether to enable WDDX support,
if test -z "$PHP_LIBXML_DIR"; then
PHP_ARG_WITH(libxml-dir, libxml2 install dir,
- [ --with-libxml-dir=DIR WDDX: libxml2 install prefix], no, no)
+ [ --with-libxml-dir=DIR WDDX: libxml2 install prefix], no, no)
fi
PHP_ARG_WITH(libexpat-dir, libexpat dir for WDDX,
-[ --with-libexpat-dir=DIR WDDX: libexpat dir for XMLRPC-EPI (deprecated)],no,no)
+[ --with-libexpat-dir=DIR WDDX: libexpat dir for XMLRPC-EPI (deprecated)],no,no)
if test "$PHP_WDDX" != "no"; then
diff --git a/ext/wddx/wddx.c b/ext/wddx/wddx.c
index b0a6b82dfe..bc0244e358 100644
--- a/ext/wddx/wddx.c
+++ b/ext/wddx/wddx.c
@@ -405,7 +405,7 @@ static void php_wddx_serialize_string(wddx_packet *packet, zval *var TSRMLS_DC)
if (Z_STRLEN_P(var) > 0) {
char *buf;
- int buf_len;
+ size_t buf_len;
buf = php_escape_html_entities(Z_STRVAL_P(var), Z_STRLEN_P(var), &buf_len, 0, ENT_QUOTES, NULL TSRMLS_CC);
@@ -626,12 +626,12 @@ static void php_wddx_serialize_array(wddx_packet *packet, zval *arr)
*/
void php_wddx_serialize_var(wddx_packet *packet, zval *var, char *name, int name_len TSRMLS_DC)
{
- char *tmp_buf;
- char *name_esc;
- int name_esc_len;
HashTable *ht;
if (name) {
+ size_t name_esc_len;
+ char *tmp_buf, *name_esc;
+
name_esc = php_escape_html_entities(name, name_len, &name_esc_len, 0, ENT_QUOTES, NULL TSRMLS_CC);
tmp_buf = emalloc(name_esc_len + sizeof(WDDX_VAR_S));
snprintf(tmp_buf, name_esc_len + sizeof(WDDX_VAR_S), WDDX_VAR_S, name_esc);
diff --git a/ext/xml/compat.c b/ext/xml/compat.c
index 2a3d097ead..41f5d42012 100644
--- a/ext/xml/compat.c
+++ b/ext/xml/compat.c
@@ -39,7 +39,7 @@ _qualify_namespace(XML_Parser parser, const xmlChar *name, const xmlChar *URI, x
if (URI) {
/* Use libxml functions otherwise its memory deallocation is screwed up */
*qualified = xmlStrdup(URI);
- *qualified = xmlStrncat(*qualified, parser->_ns_seperator, 1);
+ *qualified = xmlStrncat(*qualified, parser->_ns_separator, 1);
*qualified = xmlStrncat(*qualified, name, xmlStrlen(name));
} else {
*qualified = xmlStrdup(name);
@@ -469,7 +469,7 @@ XML_ParserCreate_MM(const XML_Char *encoding, const XML_Memory_Handling_Suite *m
parser = (XML_Parser) emalloc(sizeof(struct _XML_Parser));
memset(parser, 0, sizeof(struct _XML_Parser));
parser->use_namespace = 0;
- parser->_ns_seperator = NULL;
+ parser->_ns_separator = NULL;
parser->parser = xmlCreatePushParserCtxt((xmlSAXHandlerPtr) &php_xml_compat_handlers, (void *) parser, NULL, 0, NULL);
if (parser->parser == NULL) {
@@ -491,7 +491,7 @@ XML_ParserCreate_MM(const XML_Char *encoding, const XML_Memory_Handling_Suite *m
if (sep != NULL) {
parser->use_namespace = 1;
parser->parser->sax2 = 1;
- parser->_ns_seperator = xmlStrdup(sep);
+ parser->_ns_separator = xmlStrdup(sep);
} else {
/* Reset flag as XML_SAX2_MAGIC is needed for xmlCreatePushParserCtxt
so must be set in the handlers */
@@ -707,21 +707,21 @@ static const XML_Char *const error_mapping[] = {
(const XML_Char *)"Entity value required",
(const XML_Char *)"chunk is not well balanced",
(const XML_Char *)"extra content at the end of well balanced chunk",
- (const XML_Char *)"XML_ERR_ENTITY_CHAR_ERROR",
- (const XML_Char *)"PEReferences forbidden in internal subset",
- (const XML_Char *)"Detected an entity reference loop",
- (const XML_Char *)"XML_ERR_ENTITY_BOUNDARY",
- (const XML_Char *)"Invalid URI",
- (const XML_Char *)"Fragment not allowed",
- (const XML_Char *)"XML_WAR_CATALOG_PI",
- (const XML_Char *)"XML_ERR_NO_DTD",
- (const XML_Char *)"conditional section INCLUDE or IGNORE keyword expected", /* 95 */
- (const XML_Char *)"Version in XML Declaration missing", /* 96 */
- (const XML_Char *)"XML_WAR_UNKNOWN_VERSION", /* 97 */
- (const XML_Char *)"XML_WAR_LANG_VALUE", /* 98 */
- (const XML_Char *)"XML_WAR_NS_URI", /* 99 */
- (const XML_Char *)"XML_WAR_NS_URI_RELATIVE", /* 100 */
- (const XML_Char *)"Missing encoding in text declaration" /* 101 */
+ (const XML_Char *)"XML_ERR_ENTITY_CHAR_ERROR",
+ (const XML_Char *)"PEReferences forbidden in internal subset",
+ (const XML_Char *)"Detected an entity reference loop",
+ (const XML_Char *)"XML_ERR_ENTITY_BOUNDARY",
+ (const XML_Char *)"Invalid URI",
+ (const XML_Char *)"Fragment not allowed",
+ (const XML_Char *)"XML_WAR_CATALOG_PI",
+ (const XML_Char *)"XML_ERR_NO_DTD",
+ (const XML_Char *)"conditional section INCLUDE or IGNORE keyword expected", /* 95 */
+ (const XML_Char *)"Version in XML Declaration missing", /* 96 */
+ (const XML_Char *)"XML_WAR_UNKNOWN_VERSION", /* 97 */
+ (const XML_Char *)"XML_WAR_LANG_VALUE", /* 98 */
+ (const XML_Char *)"XML_WAR_NS_URI", /* 99 */
+ (const XML_Char *)"XML_WAR_NS_URI_RELATIVE", /* 100 */
+ (const XML_Char *)"Missing encoding in text declaration" /* 101 */
};
PHPAPI const XML_Char *
@@ -770,8 +770,8 @@ PHPAPI void
XML_ParserFree(XML_Parser parser)
{
if (parser->use_namespace) {
- if (parser->_ns_seperator) {
- xmlFree(parser->_ns_seperator);
+ if (parser->_ns_separator) {
+ xmlFree(parser->_ns_separator);
}
}
if (parser->parser->myDoc) {
diff --git a/ext/xml/config.m4 b/ext/xml/config.m4
index 65f22915b9..ebfc0471e0 100644
--- a/ext/xml/config.m4
+++ b/ext/xml/config.m4
@@ -7,11 +7,11 @@ PHP_ARG_ENABLE(xml,whether to enable XML support,
if test -z "$PHP_LIBXML_DIR"; then
PHP_ARG_WITH(libxml-dir, libxml2 install dir,
- [ --with-libxml-dir=DIR XML: libxml2 install prefix], no, no)
+ [ --with-libxml-dir=DIR XML: libxml2 install prefix], no, no)
fi
PHP_ARG_WITH(libexpat-dir, libexpat install dir,
-[ --with-libexpat-dir=DIR XML: libexpat install prefix (deprecated)], no, no)
+[ --with-libexpat-dir=DIR XML: libexpat install prefix (deprecated)], no, no)
if test "$PHP_XML" != "no"; then
diff --git a/ext/xml/expat_compat.h b/ext/xml/expat_compat.h
index e693715813..dab9812122 100644
--- a/ext/xml/expat_compat.h
+++ b/ext/xml/expat_compat.h
@@ -38,6 +38,9 @@
#include <libxml/tree.h>
#include <libxml/hash.h>
+/* For compatibility with the misspelled version. */
+#define _ns_seperator _ns_separator
+
typedef xmlChar XML_Char;
typedef void (*XML_StartElementHandler)(void *, const XML_Char *, const XML_Char **);
@@ -61,7 +64,7 @@ typedef struct _XML_Memory_Handling_Suite {
typedef struct _XML_Parser {
int use_namespace;
- xmlChar *_ns_seperator;
+ xmlChar *_ns_separator;
void *user;
xmlParserCtxtPtr parser;
diff --git a/ext/xmlreader/config.m4 b/ext/xmlreader/config.m4
index 3614996fb4..d346b58eea 100644
--- a/ext/xmlreader/config.m4
+++ b/ext/xmlreader/config.m4
@@ -7,7 +7,7 @@ PHP_ARG_ENABLE(xmlreader, whether to enable XMLReader support,
if test -z "$PHP_LIBXML_DIR"; then
PHP_ARG_WITH(libxml-dir, libxml2 install dir,
- [ --with-libxml-dir=DIR XMLReader: libxml2 install prefix], no, no)
+ [ --with-libxml-dir=DIR XMLReader: libxml2 install prefix], no, no)
fi
if test "$PHP_XMLREADER" != "no"; then
diff --git a/ext/xmlreader/php_xmlreader.c b/ext/xmlreader/php_xmlreader.c
index b677b42995..ea7b5d6778 100644
--- a/ext/xmlreader/php_xmlreader.c
+++ b/ext/xmlreader/php_xmlreader.c
@@ -60,7 +60,7 @@ typedef struct _xmlreader_prop_handler {
static void xmlreader_register_prop_handler(HashTable *prop_handler, char *name, xmlreader_read_int_t read_int_func, xmlreader_read_const_char_t read_char_func, int rettype TSRMLS_DC)
{
xmlreader_prop_handler hnd;
-
+
hnd.read_char_func = read_char_func;
hnd.read_int_func = read_int_func;
hnd.type = rettype;
@@ -113,7 +113,7 @@ static int xmlreader_property_reader(xmlreader_object *obj, xmlreader_prop_handl
/* }}} */
/* {{{ xmlreader_get_property_ptr_ptr */
-zval **xmlreader_get_property_ptr_ptr(zval *object, zval *member, const zend_literal *key TSRMLS_DC)
+zval **xmlreader_get_property_ptr_ptr(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC)
{
xmlreader_object *obj;
zval tmp_member;
@@ -136,7 +136,7 @@ zval **xmlreader_get_property_ptr_ptr(zval *object, zval *member, const zend_lit
}
if (ret == FAILURE) {
std_hnd = zend_get_std_object_handlers();
- retval = std_hnd->get_property_ptr_ptr(object, member, key TSRMLS_CC);
+ retval = std_hnd->get_property_ptr_ptr(object, member, type, key TSRMLS_CC);
}
if (member == &tmp_member) {
@@ -225,7 +225,7 @@ void xmlreader_write_property(zval *object, zval *member, zval *value, const zen
/* }}} */
/* {{{ _xmlreader_get_valid_file_path */
-/* _xmlreader_get_valid_file_path and _xmlreader_get_relaxNG should be made a
+/* _xmlreader_get_valid_file_path and _xmlreader_get_relaxNG should be made a
common function in libxml extension as code is common to a few xml extensions */
char *_xmlreader_get_valid_file_path(char *source, char *resolved_path, int resolved_path_len TSRMLS_DC) {
xmlURI *uri;
@@ -275,8 +275,8 @@ char *_xmlreader_get_valid_file_path(char *source, char *resolved_path, int reso
#ifdef LIBXML_SCHEMAS_ENABLED
/* {{{ _xmlreader_get_relaxNG */
-static xmlRelaxNGPtr _xmlreader_get_relaxNG(char *source, int source_len, int type,
- xmlRelaxNGValidityErrorFunc error_func,
+static xmlRelaxNGPtr _xmlreader_get_relaxNG(char *source, int source_len, int type,
+ xmlRelaxNGValidityErrorFunc error_func,
xmlRelaxNGValidityWarningFunc warn_func TSRMLS_DC)
{
char *valid_file = NULL;
@@ -294,7 +294,7 @@ static xmlRelaxNGPtr _xmlreader_get_relaxNG(char *source, int source_len, int ty
break;
case XMLREADER_LOAD_STRING:
parser = xmlRelaxNGNewMemParserCtxt(source, source_len);
- /* If loading from memory, we need to set the base directory for the document
+ /* If loading from memory, we need to set the base directory for the document
but it is not apparent how to do that for schema's */
break;
default:
@@ -380,7 +380,7 @@ void xmlreader_objects_free_storage(void *object TSRMLS_DC)
xmlreader_object *intern = (xmlreader_object *)object;
zend_object_std_dtor(&intern->std TSRMLS_CC);
-
+
xmlreader_free_resources(intern);
efree(object);
@@ -528,7 +528,7 @@ static void php_xmlreader_set_relaxng_schema(INTERNAL_FUNCTION_PARAMETERS, int t
RETURN_TRUE;
}
}
-
+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to set schema. This must be set prior to reading or schema contains errors.");
RETURN_FALSE;
@@ -549,11 +549,11 @@ PHP_METHOD(xmlreader, close)
id = getThis();
intern = (xmlreader_object *)zend_object_store_get_object(id TSRMLS_CC);
- /* libxml is segfaulting in versions up to 2.6.8 using xmlTextReaderClose so for
- now we will free the whole reader when close is called as it would get rebuilt on
+ /* libxml is segfaulting in versions up to 2.6.8 using xmlTextReaderClose so for
+ now we will free the whole reader when close is called as it would get rebuilt on
a new load anyways */
xmlreader_free_resources(intern);
-
+
RETURN_TRUE;
}
/* }}} */
@@ -659,7 +659,7 @@ PHP_METHOD(xmlreader, getParserProperty)
/* {{{ proto boolean XMLReader::isValid()
Returns boolean indicating if parsed document is valid or not.
-Must set XMLREADER_LOADDTD or XMLREADER_VALIDATE parser option prior to the first call to read
+Must set XMLREADER_LOADDTD or XMLREADER_VALIDATE parser option prior to the first call to read
or this method will always return FALSE */
PHP_METHOD(xmlreader, isValid)
{
@@ -810,7 +810,7 @@ PHP_METHOD(xmlreader, read)
RETURN_BOOL(retval);
}
}
-
+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Load Data before trying to read");
RETURN_FALSE;
}
@@ -843,7 +843,7 @@ PHP_METHOD(xmlreader, next)
if (xmlStrEqual(xmlTextReaderConstLocalName(intern->ptr), (xmlChar *)name)) {
RETURN_TRUE;
}
- retval = xmlTextReaderNext(intern->ptr);
+ retval = xmlTextReaderNext(intern->ptr);
}
if (retval == -1) {
RETURN_FALSE;
@@ -851,7 +851,7 @@ PHP_METHOD(xmlreader, next)
RETURN_BOOL(retval);
}
}
-
+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Load Data before trying to read");
RETURN_FALSE;
}
@@ -975,7 +975,7 @@ PHP_METHOD(xmlreader, setSchema)
RETURN_TRUE;
}
}
-
+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to set schema. This must be set prior to reading or schema contains errors.");
RETURN_FALSE;
@@ -1035,7 +1035,7 @@ PHP_METHOD(xmlreader, setRelaxNGSchemaSource)
/* }}} */
/* TODO
-XMLPUBFUN int XMLCALL
+XMLPUBFUN int XMLCALL
xmlTextReaderSetSchema (xmlTextReaderPtr reader,
xmlSchemaPtr schema);
*/
@@ -1141,7 +1141,7 @@ PHP_METHOD(xmlreader, expand)
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|O!", &id, xmlreader_class_entry, &basenode, dom_node_class_entry) == FAILURE) {
return;
}
-
+
if (basenode != NULL) {
NODE_GET_OBJ(node, basenode, xmlNodePtr, domobj);
docp = node->doc;
@@ -1151,7 +1151,7 @@ PHP_METHOD(xmlreader, expand)
if (intern && intern->ptr) {
node = xmlTextReaderExpand(intern->ptr);
-
+
if (node == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "An Error Occurred while expanding ");
RETURN_FALSE;
@@ -1311,9 +1311,9 @@ static const zend_function_entry xmlreader_functions[] = {
*/
PHP_MINIT_FUNCTION(xmlreader)
{
-
+
zend_class_entry ce;
-
+
memcpy(&xmlreader_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
xmlreader_object_handlers.read_property = xmlreader_read_property;
xmlreader_object_handlers.write_property = xmlreader_write_property;
diff --git a/ext/xmlrpc/config.m4 b/ext/xmlrpc/config.m4
index 389d4adaf0..f82016edcb 100644
--- a/ext/xmlrpc/config.m4
+++ b/ext/xmlrpc/config.m4
@@ -8,18 +8,18 @@ sinclude(libxmlrpc/acinclude.m4)
sinclude(libxmlrpc/xmlrpc.m4)
PHP_ARG_WITH(xmlrpc, for XMLRPC-EPI support,
-[ --with-xmlrpc[=DIR] Include XMLRPC-EPI support])
+[ --with-xmlrpc[=DIR] Include XMLRPC-EPI support])
if test -z "$PHP_LIBXML_DIR"; then
PHP_ARG_WITH(libxml-dir, libxml2 install dir,
- [ --with-libxml-dir=DIR XMLRPC-EPI: libxml2 install prefix], no, no)
+ [ --with-libxml-dir=DIR XMLRPC-EPI: libxml2 install prefix], no, no)
fi
PHP_ARG_WITH(libexpat-dir, libexpat dir for XMLRPC-EPI,
-[ --with-libexpat-dir=DIR XMLRPC-EPI: libexpat dir for XMLRPC-EPI (deprecated)],no,no)
+[ --with-libexpat-dir=DIR XMLRPC-EPI: libexpat dir for XMLRPC-EPI (deprecated)],no,no)
PHP_ARG_WITH(iconv-dir, iconv dir for XMLRPC-EPI,
-[ --with-iconv-dir=DIR XMLRPC-EPI: iconv dir for XMLRPC-EPI],no,no)
+[ --with-iconv-dir=DIR XMLRPC-EPI: iconv dir for XMLRPC-EPI],no,no)
if test "$PHP_XMLRPC" != "no"; then
diff --git a/ext/xmlrpc/xmlrpc-epi-php.c b/ext/xmlrpc/xmlrpc-epi-php.c
index dc832966fc..799b47b3ef 100644
--- a/ext/xmlrpc/xmlrpc-epi-php.c
+++ b/ext/xmlrpc/xmlrpc-epi-php.c
@@ -502,7 +502,7 @@ static XMLRPC_VECTOR_TYPE determine_vector_type (HashTable *ht)
}
bArray = 1;
last_num = num_index;
- } else if (res == HASH_KEY_NON_EXISTANT) {
+ } else if (res == HASH_KEY_NON_EXISTENT) {
break;
} else if (res == HASH_KEY_IS_STRING) {
if (bArray) {
@@ -582,7 +582,7 @@ static XMLRPC_VALUE PHP_to_XMLRPC_worker (const char* key, zval* in_val, int dep
int res = my_zend_hash_get_current_key(Z_ARRVAL_P(val_arr), &my_key, &num_index);
switch (res) {
- case HASH_KEY_NON_EXISTANT:
+ case HASH_KEY_NON_EXISTENT:
break;
case HASH_KEY_IS_STRING:
case HASH_KEY_IS_LONG:
diff --git a/ext/xmlwriter/config.m4 b/ext/xmlwriter/config.m4
index 0a5d079430..b3b98012f8 100644
--- a/ext/xmlwriter/config.m4
+++ b/ext/xmlwriter/config.m4
@@ -7,7 +7,7 @@ PHP_ARG_ENABLE(xmlwriter, whether to enable XMLWriter support,
if test -z "$PHP_LIBXML_DIR"; then
PHP_ARG_WITH(libxml-dir, libxml2 install dir,
- [ --with-libxml-dir=DIR XMLWriter: libxml2 install prefix], no, no)
+ [ --with-libxml-dir=DIR XMLWriter: libxml2 install prefix], no, no)
fi
if test "$PHP_XMLWRITER" != "no"; then
diff --git a/ext/xsl/config.m4 b/ext/xsl/config.m4
index a2b16d24f0..9b6f8aaa49 100644
--- a/ext/xsl/config.m4
+++ b/ext/xsl/config.m4
@@ -3,7 +3,7 @@ dnl $Id$
dnl
PHP_ARG_WITH(xsl, for XSL support,
-[ --with-xsl[=DIR] Include XSL support. DIR is the libxslt base
+[ --with-xsl[=DIR] Include XSL support. DIR is the libxslt base
install directory (libxslt >= 1.1.0 required)])
if test "$PHP_XSL" != "no"; then
diff --git a/ext/xsl/php_xsl.c b/ext/xsl/php_xsl.c
index d8366d14ff..3d63dd0642 100644
--- a/ext/xsl/php_xsl.c
+++ b/ext/xsl/php_xsl.c
@@ -182,7 +182,7 @@ PHP_MINIT_FUNCTION(xsl)
REGISTER_LONG_CONSTANT("XSL_SECPREF_READ_NETWORK", XSL_SECPREF_READ_NETWORK, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("XSL_SECPREF_WRITE_NETWORK", XSL_SECPREF_WRITE_NETWORK, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("XSL_SECPREF_DEFAULT", XSL_SECPREF_DEFAULT, CONST_CS | CONST_PERSISTENT);
-
+
REGISTER_LONG_CONSTANT("LIBXSLT_VERSION", LIBXSLT_VERSION, CONST_CS | CONST_PERSISTENT);
REGISTER_STRING_CONSTANT("LIBXSLT_DOTTED_VERSION", LIBXSLT_DOTTED_VERSION, CONST_CS | CONST_PERSISTENT);
diff --git a/ext/zip/config.m4 b/ext/zip/config.m4
index 85f9119f5a..805d92442e 100644
--- a/ext/zip/config.m4
+++ b/ext/zip/config.m4
@@ -11,7 +11,7 @@ if test -z "$PHP_ZLIB_DIR"; then
fi
PHP_ARG_WITH(pcre-dir, pcre install prefix,
-[ --with-pcre-dir ZIP: pcre install prefix], no, no)
+[ --with-pcre-dir ZIP: pcre install prefix], no, no)
if test "$PHP_ZIP" != "no"; then
diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c
index abc21c7f15..05dd1ecc21 100644
--- a/ext/zip/php_zip.c
+++ b/ext/zip/php_zip.c
@@ -133,7 +133,7 @@ static char * php_zip_make_relative_path(char *path, int path_len) /* {{{ */
}
/* }}} */
-#ifdef PHP_ZIP_USE_OO
+#ifdef PHP_ZIP_USE_OO
/* {{{ php_zip_extract_file */
static int php_zip_extract_file(struct zip * za, char *dest, char *file, int file_len TSRMLS_DC)
{
@@ -295,7 +295,7 @@ done:
}
/* }}} */
-static int php_zip_add_file(struct zip *za, const char *filename, size_t filename_len,
+static int php_zip_add_file(struct zip *za, const char *filename, size_t filename_len,
char *entry_name, size_t entry_name_len, long offset_start, long offset_len TSRMLS_DC) /* {{{ */
{
struct zip_source *zs;
@@ -345,7 +345,7 @@ static int php_zip_add_file(struct zip *za, const char *filename, size_t filenam
}
/* }}} */
-static int php_zip_parse_options(zval *options, long *remove_all_path,
+static int php_zip_parse_options(zval *options, long *remove_all_path,
char **remove_path, int *remove_path_len, char **add_path, int *add_path_len TSRMLS_DC) /* {{{ */
{
zval **option;
@@ -375,11 +375,11 @@ static int php_zip_parse_options(zval *options, long *remove_all_path,
}
if (Z_STRLEN_PP(option) >= MAXPATHLEN) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "remove_path string is too long (max: %i, %i given)",
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "remove_path string is too long (max: %i, %i given)",
MAXPATHLEN - 1, Z_STRLEN_PP(option));
return -1;
}
- *remove_path_len = Z_STRLEN_PP(option);
+ *remove_path_len = Z_STRLEN_PP(option);
*remove_path = Z_STRVAL_PP(option);
}
@@ -395,11 +395,11 @@ static int php_zip_parse_options(zval *options, long *remove_all_path,
}
if (Z_STRLEN_PP(option) >= MAXPATHLEN) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "add_path string too long (max: %i, %i given)",
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "add_path string too long (max: %i, %i given)",
MAXPATHLEN - 1, Z_STRLEN_PP(option));
return -1;
}
- *add_path_len = Z_STRLEN_PP(option);
+ *add_path_len = Z_STRLEN_PP(option);
*add_path = Z_STRVAL_PP(option);
}
return 1;
@@ -528,7 +528,7 @@ int php_zip_glob(char *pattern, int pattern_len, long flags, zval *return_value
glob_t globbuf;
int n;
int ret;
-
+
if (pattern_len >= MAXPATHLEN) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Pattern exceeds the maximum allowed length of %d characters", MAXPATHLEN);
return -1;
@@ -539,9 +539,9 @@ int php_zip_glob(char *pattern, int pattern_len, long flags, zval *return_value
return -1;
}
-#ifdef ZTS
+#ifdef ZTS
if (!IS_ABSOLUTE_PATH(pattern, pattern_len)) {
- result = VCWD_GETCWD(cwd, MAXPATHLEN);
+ result = VCWD_GETCWD(cwd, MAXPATHLEN);
if (!result) {
cwd[0] = '\0';
}
@@ -554,7 +554,7 @@ int php_zip_glob(char *pattern, int pattern_len, long flags, zval *return_value
snprintf(work_pattern, MAXPATHLEN, "%s%c%s", cwd, DEFAULT_SLASH, pattern);
pattern = work_pattern;
- }
+ }
#endif
globbuf.gl_offs = 0;
@@ -564,7 +564,7 @@ int php_zip_glob(char *pattern, int pattern_len, long flags, zval *return_value
/* Some glob implementation simply return no data if no matches
were found, others return the GLOB_NOMATCH error code.
We don't want to treat GLOB_NOMATCH as an error condition
- so that PHP glob() behaves the same on both types of
+ so that PHP glob() behaves the same on both types of
implementations and so that 'foreach (glob() as ...'
can be used for simple glob() calls without further error
checking.
@@ -593,11 +593,11 @@ int php_zip_glob(char *pattern, int pattern_len, long flags, zval *return_value
for (n = 0; n < globbuf.gl_pathc; n++) {
/* we need to do this everytime since GLOB_ONLYDIR does not guarantee that
* all directories will be filtered. GNU libc documentation states the
- * following:
- * If the information about the type of the file is easily available
- * non-directories will be rejected but no extra work will be done to
- * determine the information for each file. I.e., the caller must still be
- * able to filter directories out.
+ * following:
+ * If the information about the type of the file is easily available
+ * non-directories will be rejected but no extra work will be done to
+ * determine the information for each file. I.e., the caller must still be
+ * able to filter directories out.
*/
if (flags & GLOB_ONLYDIR) {
struct stat s;
@@ -633,9 +633,9 @@ int php_zip_pcre(char *regexp, int regexp_len, char *path, int path_len, zval *r
int files_cnt;
char **namelist;
-#ifdef ZTS
+#ifdef ZTS
if (!IS_ABSOLUTE_PATH(path, path_len)) {
- result = VCWD_GETCWD(cwd, MAXPATHLEN);
+ result = VCWD_GETCWD(cwd, MAXPATHLEN);
if (!result) {
cwd[0] = '\0';
}
@@ -648,7 +648,7 @@ int php_zip_pcre(char *regexp, int regexp_len, char *path, int path_len, zval *r
snprintf(work_path, MAXPATHLEN, "%s%c%s", cwd, DEFAULT_SLASH, path);
path = work_path;
- }
+ }
#endif
if (ZIP_OPENBASEDIR_CHECKPATH(path)) {
@@ -665,7 +665,7 @@ int php_zip_pcre(char *regexp, int regexp_len, char *path, int path_len, zval *r
re = pcre_get_compiled_regex(regexp, &pcre_extra, &preg_options TSRMLS_CC);
if (!re) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid expression");
- return -1;
+ return -1;
}
array_init(return_value);
@@ -678,7 +678,7 @@ int php_zip_pcre(char *regexp, int regexp_len, char *path, int path_len, zval *r
int matches;
int namelist_len = strlen(namelist[i]);
-
+
if ((namelist_len == 1 && namelist[i][0] == '.') ||
(namelist_len == 2 && namelist[i][0] == '.' && namelist[i][1] == '.')) {
efree(namelist[i]);
@@ -686,7 +686,7 @@ int php_zip_pcre(char *regexp, int regexp_len, char *path, int path_len, zval *r
}
if ((path_len + namelist_len + 1) >= MAXPATHLEN) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "add_path string too long (max: %i, %i given)",
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "add_path string too long (max: %i, %i given)",
MAXPATHLEN - 1, (path_len + namelist_len + 1));
efree(namelist[i]);
break;
@@ -709,7 +709,7 @@ int php_zip_pcre(char *regexp, int regexp_len, char *path, int path_len, zval *r
/* 0 means that the vector is too small to hold all the captured substring offsets */
if (matches < 0) {
efree(namelist[i]);
- continue;
+ continue;
}
add_next_index_string(return_value, fullpath, 1);
@@ -785,7 +785,7 @@ static const zend_function_entry zip_functions[] = {
/* }}} */
/* {{{ ZE2 OO definitions */
-#ifdef PHP_ZIP_USE_OO
+#ifdef PHP_ZIP_USE_OO
static zend_class_entry *zip_class_entry;
static zend_object_handlers zip_object_handlers;
@@ -805,7 +805,7 @@ typedef struct _zip_prop_handler {
#endif
/* }}} */
-#ifdef PHP_ZIP_USE_OO
+#ifdef PHP_ZIP_USE_OO
static void php_zip_register_prop_handler(HashTable *prop_handler, char *name, zip_read_int_t read_int_func, zip_read_const_char_t read_char_func, zip_read_const_char_from_ze_t read_char_from_obj_func, int rettype TSRMLS_DC) /* {{{ */
{
zip_prop_handler hnd;
@@ -869,7 +869,7 @@ static int php_zip_property_reader(ze_zip_object *obj, zip_prop_handler *hnd, zv
}
/* }}} */
-static zval **php_zip_get_property_ptr_ptr(zval *object, zval *member, const zend_literal *key TSRMLS_DC) /* {{{ */
+static zval **php_zip_get_property_ptr_ptr(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */
{
ze_zip_object *obj;
zval tmp_member;
@@ -893,7 +893,7 @@ static zval **php_zip_get_property_ptr_ptr(zval *object, zval *member, const zen
if (obj->prop_handler != NULL) {
if (key) {
ret = zend_hash_quick_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, key->hash_value, (void **) &hnd);
- } else {
+ } else {
ret = zend_hash_find(obj->prop_handler, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, (void **) &hnd);
}
}
@@ -901,7 +901,7 @@ static zval **php_zip_get_property_ptr_ptr(zval *object, zval *member, const zen
if (ret == FAILURE) {
std_hnd = zend_get_std_object_handlers();
- retval = std_hnd->get_property_ptr_ptr(object, member, key TSRMLS_CC);
+ retval = std_hnd->get_property_ptr_ptr(object, member, type, key TSRMLS_CC);
}
if (member == &tmp_member) {
@@ -1483,7 +1483,7 @@ static PHP_NAMED_FUNCTION(zif_zip_entry_compressionmethod)
}
/* }}} */
-#ifdef PHP_ZIP_USE_OO
+#ifdef PHP_ZIP_USE_OO
/* {{{ proto mixed ZipArchive::open(string source [, int flags])
Create new zip using source uri for output, return TRUE on success or the error code */
static ZIPARCHIVE_METHOD(open)
@@ -1590,7 +1590,7 @@ static ZIPARCHIVE_METHOD(getStatusString)
zip_error_get(intern, &zep, &syp);
len = zip_error_to_str(error_string, 128, zep, syp);
- RETVAL_STRINGL(error_string, len, 1);
+ RETVAL_STRINGL(error_string, len, 1);
}
/* }}} */
@@ -1667,12 +1667,12 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /*
ZIP_FROM_OBJECT(intern, this);
/* 1 == glob, 2==pcre */
if (type == 1) {
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|la",
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|la",
&pattern, &pattern_len, &flags, &options) == FAILURE) {
return;
}
} else {
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|sa",
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|sa",
&pattern, &pattern_len, &path, &path_len, &options) == FAILURE) {
return;
}
@@ -1724,14 +1724,14 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /*
if (add_path) {
if ((add_path_len + file_stripped_len) > MAXPATHLEN) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Entry name too long (max: %d, %ld given)",
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Entry name too long (max: %d, %ld given)",
MAXPATHLEN - 1, (add_path_len + file_stripped_len));
zval_dtor(return_value);
RETURN_FALSE;
}
snprintf(entry_name_buf, MAXPATHLEN, "%s%s", add_path, file_stripped);
- entry_name = entry_name_buf;
+ entry_name = entry_name_buf;
entry_name_len = strlen(entry_name);
} else {
entry_name = Z_STRVAL_PP(zval_file);
@@ -1741,7 +1741,7 @@ static void php_zip_add_from_pattern(INTERNAL_FUNCTION_PARAMETERS, int type) /*
efree(basename);
basename = NULL;
}
- if (php_zip_add_file(intern, Z_STRVAL_PP(zval_file), Z_STRLEN_PP(zval_file),
+ if (php_zip_add_file(intern, Z_STRVAL_PP(zval_file), Z_STRLEN_PP(zval_file),
entry_name, entry_name_len, 0, 0 TSRMLS_CC) < 0) {
zval_dtor(return_value);
RETURN_FALSE;
@@ -1801,7 +1801,7 @@ static ZIPARCHIVE_METHOD(addFile)
entry_name_len = filename_len;
}
- if (php_zip_add_file(intern, filename, filename_len,
+ if (php_zip_add_file(intern, filename, filename_len,
entry_name, entry_name_len, 0, 0 TSRMLS_CC) < 0) {
RETURN_FALSE;
} else {
@@ -2770,7 +2770,7 @@ static const zend_function_entry zip_class_functions[] = {
/* {{{ PHP_MINIT_FUNCTION */
static PHP_MINIT_FUNCTION(zip)
{
-#ifdef PHP_ZIP_USE_OO
+#ifdef PHP_ZIP_USE_OO
zend_class_entry ce;
memcpy(&zip_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
@@ -2859,7 +2859,7 @@ static PHP_MINIT_FUNCTION(zip)
*/
static PHP_MSHUTDOWN_FUNCTION(zip)
{
-#ifdef PHP_ZIP_USE_OO
+#ifdef PHP_ZIP_USE_OO
zend_hash_destroy(&zip_prop_handlers);
php_unregister_url_stream_wrapper("zip" TSRMLS_CC);
#endif
diff --git a/ext/zlib/config0.m4 b/ext/zlib/config0.m4
index 25c7f4f420..ebf67cc001 100644
--- a/ext/zlib/config0.m4
+++ b/ext/zlib/config0.m4
@@ -3,7 +3,7 @@ dnl $Id$
dnl
PHP_ARG_WITH(zlib,for ZLIB support,
-[ --with-zlib[=DIR] Include ZLIB support (requires zlib >= 1.0.9)])
+[ --with-zlib[=DIR] Include ZLIB support (requires zlib >= 1.0.9)])
PHP_ARG_WITH(zlib-dir,if the location of ZLIB install directory is defined,
[ --with-zlib-dir=<DIR> Define the location of zlib install directory], no, no)
diff --git a/ext/zlib/tests/001.phpt b/ext/zlib/tests/001.phpt
index 0c2ca28c78..4850a65a5a 100644
--- a/ext/zlib/tests/001.phpt
+++ b/ext/zlib/tests/001.phpt
@@ -29,4 +29,4 @@ Strings are equal
100 36864
Strings are equal
5 15
-Strings are equal
+Strings are equal \ No newline at end of file
diff --git a/ext/zlib/tests/bug_52944-win.phpt b/ext/zlib/tests/bug_52944-win.phpt
deleted file mode 100644
index fa369f8fb4..0000000000
--- a/ext/zlib/tests/bug_52944-win.phpt
+++ /dev/null
@@ -1,24 +0,0 @@
---TEST--
-Bug #52944 (segfault with zlib filter and corrupted data)
---SKIPIF--
-<?php if (!extension_loaded("zlib")) print "skip"; ?>
-<?php
-if (substr(PHP_OS, 0, 3) != 'WIN') {
- die("skip windows only");
-}
---INI--
-allow_url_fopen=1
---FILE--
-<?php
-require dirname(__FILE__) . "/bug_52944_corrupted_data.inc";
-
-$fp = fopen('data://text/plain;base64,' . $data, 'r');
-stream_filter_append($fp, 'zlib.inflate', STREAM_FILTER_READ);
-var_dump(fread($fp,1));
-var_dump(fread($fp,1));
-fclose($fp);
-echo "Done.\n";
---EXPECT--
-string(1) "%"
-string(1) "C"
-Done.
diff --git a/ext/zlib/tests/bug_52944.phpt b/ext/zlib/tests/bug_52944.phpt
index ed4af3e157..ff82d29cc7 100644
--- a/ext/zlib/tests/bug_52944.phpt
+++ b/ext/zlib/tests/bug_52944.phpt
@@ -3,9 +3,6 @@ Bug #52944 (segfault with zlib filter and corrupted data)
--SKIPIF--
<?php if (!extension_loaded("zlib")) print "skip"; ?>
<?php
-if (substr(PHP_OS, 0, 3) == 'WIN') {
- die("skip not for windows");
-}
if (PHP_OS == 'Darwin') {
die("skip not for Darwin");
}
@@ -13,6 +10,10 @@ if (PHP_OS == 'Darwin') {
allow_url_fopen=1
--FILE--
<?php
+/* NOTE this test can fail on asm builds of zlib 1.2.5 or
+ 1.2.7 on at least Windows and Darwin. Using unoptimized
+ zlib build fixes the issue. */
+
require dirname(__FILE__) . "/bug_52944_corrupted_data.inc";
$fp = fopen('data://text/plain;base64,' . $data, 'r');
diff --git a/ext/zlib/tests/data.inc b/ext/zlib/tests/data.inc
index fb20f0bcdf..441199ff08 100644
--- a/ext/zlib/tests/data.inc
+++ b/ext/zlib/tests/data.inc
@@ -85,4 +85,4 @@ That summons thee to heaven or to hell.
QUOTE;
-?>
+?> \ No newline at end of file
diff --git a/ext/zlib/zlib_filter.c b/ext/zlib/zlib_filter.c
index 2054ec2ca2..9a59c3a855 100644
--- a/ext/zlib/zlib_filter.c
+++ b/ext/zlib/zlib_filter.c
@@ -62,10 +62,9 @@ static php_stream_filter_status_t php_zlib_inflate_filter(
{
php_zlib_filter_data *data;
php_stream_bucket *bucket;
- size_t consumed = 0, original_out, original_in;
+ size_t consumed = 0;
int status;
php_stream_filter_status_t exit_status = PSFS_FEED_ME;
- z_stream *streamp;
if (!thisfilter || !thisfilter->abstract) {
/* Should never happen */
@@ -73,9 +72,6 @@ static php_stream_filter_status_t php_zlib_inflate_filter(
}
data = (php_zlib_filter_data *)(thisfilter->abstract);
- streamp = &(data->strm);
- original_in = data->strm.total_in;
- original_out = data->strm.total_out;
while (buckets_in->head) {
size_t bin = 0, desired;
@@ -191,10 +187,9 @@ static php_stream_filter_status_t php_zlib_deflate_filter(
{
php_zlib_filter_data *data;
php_stream_bucket *bucket;
- size_t consumed = 0, original_out, original_in;
+ size_t consumed = 0;
int status;
php_stream_filter_status_t exit_status = PSFS_FEED_ME;
- z_stream *streamp;
if (!thisfilter || !thisfilter->abstract) {
/* Should never happen */
@@ -202,9 +197,6 @@ static php_stream_filter_status_t php_zlib_deflate_filter(
}
data = (php_zlib_filter_data *)(thisfilter->abstract);
- streamp = &(data->strm);
- original_in = data->strm.total_in;
- original_out = data->strm.total_out;
while (buckets_in->head) {
size_t bin = 0, desired;
diff --git a/main/fopen_wrappers.h b/main/fopen_wrappers.h
index 2dcc542016..4dde0e35eb 100644
--- a/main/fopen_wrappers.h
+++ b/main/fopen_wrappers.h
@@ -28,7 +28,7 @@ BEGIN_EXTERN_C()
PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle TSRMLS_DC);
PHPAPI char *expand_filepath(const char *filepath, char *real_path TSRMLS_DC);
PHPAPI char *expand_filepath_ex(const char *filepath, char *real_path, const char *relative_to, size_t relative_to_len TSRMLS_DC);
-PHPAPI char *expand_filepath_with_mode(const char *filepath, char *real_path, const char *relative_to, size_t relative_to_len, int realpath_mode TSRMLS_DC);
+PHPAPI char *expand_filepath_with_mode(const char *filepath, char *real_path, const char *relative_to, size_t relative_to_len, int use_realpath TSRMLS_DC);
PHPAPI int php_check_open_basedir(const char *path TSRMLS_DC);
PHPAPI int php_check_open_basedir_ex(const char *path, int warn TSRMLS_DC);
diff --git a/main/logos.h b/main/logos.h
deleted file mode 100644
index 23026adc73..0000000000
--- a/main/logos.h
+++ /dev/null
@@ -1,1080 +0,0 @@
-/*
- +----------------------------------------------------------------------+
- | PHP Version 5 |
- +----------------------------------------------------------------------+
- | Copyright (c) 1997-2014 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$ */
-
-#define CONTEXT_TYPE_IMAGE_GIF "Content-Type: image/gif"
-
-static const unsigned char zend_logo[] = {
- 71, 73, 70, 56, 57, 97, 113, 0, 72, 0,
- 213, 0, 0, 13, 13, 14, 1, 3, 6, 2,
- 5, 9, 46, 68, 94, 21, 29, 39, 5, 15,
- 26, 4, 10, 17, 29, 43, 58, 0, 1, 2,
- 9, 25, 42, 38, 105, 171, 24, 67, 109, 13,
- 36, 59, 10, 27, 45, 9, 25, 41, 35, 96,
- 157, 32, 87, 142, 29, 79, 130, 26, 70, 114,
- 20, 54, 87, 29, 77, 124, 10, 26, 42, 34,
- 88, 141, 10, 24, 38, 11, 26, 41, 1, 2,
- 3, 55, 80, 105, 45, 63, 81, 49, 53, 57,
- 5, 15, 24, 9, 26, 42, 30, 85, 138, 33,
- 92, 149, 26, 73, 117, 10, 28, 45, 32, 89,
- 142, 30, 84, 134, 26, 72, 115, 15, 42, 67,
- 23, 62, 99, 12, 32, 51, 7, 21, 33, 9,
- 26, 41, 8, 23, 35, 7, 25, 37, 51, 58,
- 63, 2, 4, 5, 25, 26, 26, 49, 50, 50,
- 255, 102, 0, 255, 255, 255, 204, 204, 204, 199,
- 199, 199, 191, 191, 191, 171, 171, 171, 146, 146,
- 146, 115, 115, 115, 85, 85, 85, 60, 60, 60,
- 55, 55, 55, 38, 38, 38, 7, 7, 7, 3,
- 3, 3, 0, 0, 0, 44, 0, 0, 0, 0,
- 113, 0, 72, 0, 0, 6, 255, 192, 153, 112,
- 72, 44, 26, 143, 200, 164, 114, 121, 252, 49,
- 159, 208, 168, 148, 248, 171, 58, 167, 210, 171,
- 208, 170, 197, 122, 191, 70, 109, 23, 140, 236,
- 138, 201, 232, 239, 121, 102, 221, 186, 217, 219,
- 171, 83, 46, 110, 15, 207, 235, 180, 190, 124,
- 135, 187, 229, 127, 127, 128, 112, 121, 108, 118,
- 132, 123, 137, 77, 118, 120, 136, 115, 109, 117,
- 85, 126, 147, 147, 128, 99, 138, 137, 99, 107,
- 146, 146, 148, 133, 159, 125, 136, 152, 163, 151,
- 135, 121, 144, 84, 157, 92, 169, 157, 111, 163,
- 175, 176, 83, 151, 177, 180, 181, 161, 182, 184,
- 185, 186, 187, 188, 189, 67, 54, 56, 58, 56,
- 53, 190, 197, 88, 55, 57, 60, 63, 2, 43,
- 2, 56, 198, 208, 74, 192, 58, 0, 63, 5,
- 12, 11, 35, 35, 12, 47, 209, 222, 67, 53,
- 201, 203, 34, 19, 20, 218, 231, 37, 63, 54,
- 223, 222, 60, 2, 216, 231, 241, 231, 206, 76,
- 193, 55, 236, 176, 63, 39, 242, 252, 35, 40,
- 58, 75, 114, 8, 40, 240, 227, 25, 62, 76,
- 60, 24, 244, 147, 55, 161, 202, 11, 24, 57,
- 134, 17, 201, 241, 99, 130, 191, 130, 7, 21,
- 225, 48, 176, 48, 30, 137, 5, 11, 38, 48,
- 88, 81, 5, 198, 51, 138, 22, 181, 53, 52,
- 152, 49, 141, 141, 31, 230, 58, 46, 60, 129,
- 194, 74, 202, 115, 43, 91, 234, 1, 112, 83,
- 102, 63, 255, 18, 38, 122, 226, 252, 145, 67,
- 39, 153, 26, 47, 68, 248, 92, 186, 176, 97,
- 81, 163, 88, 108, 188, 48, 80, 130, 169, 85,
- 134, 68, 161, 74, 177, 1, 160, 0, 137, 171,
- 96, 135, 62, 213, 186, 132, 171, 215, 176, 104,
- 71, 52, 188, 71, 54, 9, 210, 179, 105, 195,
- 166, 99, 219, 214, 198, 58, 34, 48, 12, 124,
- 213, 38, 163, 175, 223, 191, 50, 22, 132, 216,
- 139, 182, 132, 0, 30, 196, 250, 218, 37, 70,
- 198, 198, 141, 199, 144, 31, 223, 253, 114, 163,
- 10, 0, 97, 192, 126, 100, 59, 7, 24, 176,
- 10, 20, 229, 210, 146, 48, 128, 88, 72, 223,
- 28, 57, 38, 111, 197, 17, 163, 181, 235, 215,
- 58, 116, 68, 100, 60, 5, 134, 136, 18, 19,
- 80, 24, 168, 162, 48, 94, 95, 21, 6, 82,
- 168, 80, 209, 215, 128, 1, 20, 39, 8, 95,
- 37, 81, 160, 180, 105, 25, 177, 233, 62, 1,
- 246, 186, 186, 245, 24, 209, 177, 84, 140, 71,
- 97, 130, 114, 109, 33, 76, 48, 152, 176, 192,
- 111, 135, 20, 222, 211, 54, 167, 61, 163, 111,
- 246, 39, 55, 174, 203, 175, 254, 30, 74, 229,
- 152, 62, 73, 132, 24, 60, 162, 47, 131, 14,
- 12, 132, 224, 155, 95, 130, 145, 208, 89, 129,
- 40, 116, 211, 25, 12, 58, 72, 135, 68, 124,
- 214, 197, 38, 161, 14, 243, 73, 200, 222, 18,
- 27, 161, 213, 215, 4, 159, 37, 199, 255, 25,
- 96, 12, 116, 230, 223, 9, 11, 252, 32, 226,
- 11, 13, 74, 35, 223, 132, 19, 174, 24, 27,
- 75, 76, 192, 128, 66, 88, 126, 161, 160, 66,
- 122, 124, 201, 112, 2, 3, 195, 125, 54, 65,
- 95, 29, 4, 87, 227, 9, 126, 233, 192, 3,
- 12, 125, 161, 232, 160, 93, 207, 184, 200, 98,
- 139, 17, 74, 24, 197, 118, 96, 249, 7, 160,
- 128, 31, 242, 72, 30, 72, 33, 244, 149, 2,
- 122, 229, 201, 0, 224, 105, 60, 52, 216, 23,
- 131, 14, 226, 96, 194, 1, 78, 74, 152, 195,
- 13, 196, 208, 192, 90, 148, 177, 217, 7, 83,
- 149, 50, 112, 136, 220, 94, 34, 22, 216, 159,
- 12, 195, 101, 227, 37, 113, 50, 192, 0, 3,
- 156, 238, 165, 72, 196, 11, 21, 178, 184, 228,
- 117, 19, 66, 145, 225, 85, 53, 222, 72, 152,
- 136, 42, 152, 32, 224, 111, 42, 8, 10, 40,
- 161, 101, 222, 96, 67, 95, 61, 40, 58, 3,
- 13, 55, 24, 112, 221, 101, 19, 226, 64, 131,
- 17, 54, 64, 42, 229, 19, 50, 226, 249, 95,
- 128, 127, 238, 23, 166, 113, 194, 105, 250, 103,
- 160, 191, 18, 90, 232, 13, 59, 0, 249, 130,
- 168, 56, 160, 198, 195, 10, 214, 161, 144, 1,
- 131, 245, 21, 1, 33, 125, 177, 141, 181, 4,
- 149, 76, 137, 232, 23, 3, 38, 132, 9, 216,
- 9, 93, 126, 234, 105, 160, 34, 94, 208, 129,
- 14, 7, 152, 112, 255, 2, 4, 40, 84, 80,
- 157, 8, 30, 176, 154, 195, 133, 68, 200, 250,
- 34, 124, 119, 102, 171, 109, 113, 157, 142, 16,
- 238, 111, 160, 113, 58, 110, 167, 38, 252, 213,
- 192, 193, 12, 72, 32, 193, 3, 15, 128, 192,
- 128, 7, 175, 121, 32, 66, 7, 101, 230, 240,
- 42, 18, 53, 216, 171, 131, 106, 73, 224, 32,
- 0, 88, 221, 217, 216, 227, 200, 190, 234, 39,
- 210, 112, 12, 36, 23, 158, 175, 254, 154, 160,
- 105, 9, 5, 236, 88, 129, 7, 41, 83, 240,
- 65, 195, 32, 56, 236, 128, 107, 14, 36, 208,
- 64, 10, 24, 41, 161, 177, 181, 74, 84, 182,
- 194, 4, 85, 45, 181, 239, 134, 11, 236, 165,
- 31, 151, 95, 233, 199, 223, 8, 82, 27, 40,
- 3, 9, 39, 144, 56, 24, 4, 92, 119, 61,
- 129, 3, 96, 135, 221, 128, 8, 12, 0, 64,
- 239, 47, 26, 59, 88, 52, 53, 227, 132, 182,
- 208, 210, 128, 178, 76, 163, 12, 46, 135, 208,
- 245, 221, 92, 3, 21, 54, 216, 9, 152, 208,
- 48, 64, 72, 12, 237, 197, 52, 0, 152, 208,
- 209, 111, 193, 141, 204, 239, 102, 104, 45, 96,
- 128, 9, 20, 224, 45, 249, 215, 97, 51, 240,
- 1, 8, 10, 152, 80, 20, 14, 56, 208, 213,
- 38, 199, 181, 245, 214, 207, 111, 96, 130, 4,
- 146, 72, 114, 135, 69, 194, 10, 38, 64, 0,
- 130, 228, 120, 71, 240, 181, 8, 145, 67, 240,
- 255, 128, 2, 44, 164, 0, 26, 2, 66, 180,
- 9, 163, 23, 56, 20, 112, 184, 184, 242, 232,
- 119, 224, 212, 127, 18, 56, 152, 95, 14, 252,
- 8, 88, 129, 120, 255, 37, 216, 205, 17, 68,
- 160, 192, 3, 24, 212, 64, 131, 198, 58, 92,
- 12, 70, 101, 223, 125, 8, 172, 60, 218, 166,
- 252, 149, 136, 41, 251, 21, 64, 249, 201, 117,
- 221, 89, 202, 151, 131, 112, 251, 9, 211, 194,
- 54, 161, 218, 88, 212, 128, 237, 128, 207, 35,
- 15, 164, 144, 125, 65, 78, 141, 206, 3, 164,
- 0, 245, 69, 0, 34, 248, 95, 10, 134, 68,
- 2, 8, 244, 101, 71, 97, 3, 77, 237, 70,
- 240, 0, 18, 248, 110, 15, 58, 80, 10, 63,
- 48, 37, 55, 47, 129, 169, 128, 86, 10, 152,
- 12, 132, 19, 166, 2, 36, 112, 132, 31, 20,
- 83, 128, 28, 40, 3, 6, 52, 207, 116, 91,
- 227, 218, 3, 218, 68, 52, 50, 224, 32, 95,
- 228, 147, 1, 175, 134, 211, 65, 226, 13, 138,
- 116, 222, 249, 77, 1, 10, 38, 3, 7, 52,
- 160, 47, 96, 91, 0, 11, 83, 224, 128, 62,
- 197, 176, 107, 32, 224, 222, 217, 192, 240, 130,
- 25, 109, 16, 133, 91, 242, 159, 15, 63, 37,
- 176, 63, 25, 64, 0, 68, 108, 128, 7, 144,
- 232, 0, 37, 146, 81, 68, 14, 208, 20, 20,
- 163, 72, 167, 216, 128, 14, 85, 201, 66, 205,
- 155, 110, 224, 61, 37, 220, 255, 16, 63, 226,
- 235, 215, 135, 194, 5, 44, 78, 249, 5, 61,
- 86, 251, 65, 5, 36, 208, 23, 15, 52, 177,
- 136, 101, 100, 97, 18, 195, 197, 171, 52, 218,
- 205, 117, 51, 108, 163, 169, 132, 16, 171, 54,
- 118, 174, 142, 69, 48, 75, 248, 224, 22, 162,
- 45, 146, 171, 51, 8, 160, 221, 25, 17, 105,
- 70, 82, 90, 237, 91, 131, 137, 164, 37, 137,
- 80, 73, 238, 221, 11, 86, 93, 9, 95, 242,
- 180, 101, 128, 46, 10, 236, 148, 126, 177, 6,
- 5, 70, 153, 68, 69, 38, 18, 2, 255, 42,
- 34, 104, 34, 160, 74, 106, 9, 99, 8, 245,
- 51, 230, 147, 126, 55, 131, 26, 196, 178, 35,
- 225, 25, 153, 52, 131, 82, 55, 240, 84, 19,
- 107, 60, 234, 11, 0, 12, 16, 1, 16, 148,
- 160, 110, 43, 123, 100, 56, 243, 22, 2, 145,
- 128, 45, 101, 16, 152, 15, 118, 44, 54, 131,
- 100, 218, 239, 73, 111, 58, 66, 13, 120, 0,
- 151, 133, 60, 205, 116, 248, 20, 12, 5, 246,
- 227, 52, 126, 106, 195, 120, 50, 56, 146, 1,
- 46, 247, 1, 126, 86, 141, 156, 79, 132, 192,
- 61, 67, 240, 1, 117, 182, 6, 85, 141, 90,
- 38, 232, 134, 176, 17, 89, 198, 165, 35, 134,
- 17, 70, 14, 92, 32, 63, 134, 141, 224, 117,
- 176, 11, 105, 215, 44, 232, 208, 136, 178, 72,
- 34, 118, 212, 203, 69, 173, 226, 148, 26, 216,
- 133, 7, 255, 39, 80, 192, 4, 102, 42, 191,
- 17, 136, 52, 164, 37, 109, 211, 253, 48, 137,
- 49, 122, 90, 116, 165, 255, 100, 64, 86, 40,
- 74, 128, 22, 0, 224, 6, 48, 152, 128, 2,
- 64, 122, 211, 187, 229, 84, 153, 142, 226, 169,
- 18, 230, 41, 128, 164, 1, 149, 31, 37, 98,
- 166, 93, 134, 192, 129, 133, 49, 181, 169, 36,
- 125, 234, 147, 36, 68, 71, 47, 80, 213, 170,
- 252, 32, 79, 92, 232, 177, 4, 14, 80, 32,
- 103, 77, 229, 218, 83, 177, 51, 214, 6, 73,
- 53, 10, 103, 237, 71, 67, 126, 96, 0, 164,
- 133, 69, 4, 128, 147, 134, 15, 72, 240, 85,
- 174, 229, 236, 176, 175, 203, 105, 93, 223, 116,
- 215, 41, 228, 53, 30, 43, 177, 65, 14, 94,
- 80, 133, 21, 160, 64, 93, 75, 153, 0, 0,
- 158, 224, 130, 19, 60, 224, 110, 57, 99, 216,
- 237, 74, 0, 130, 8, 120, 192, 3, 99, 243,
- 192, 97, 234, 58, 161, 120, 42, 226, 177, 106,
- 9, 26, 37, 57, 167, 131, 23, 8, 207, 39,
- 20, 248, 1, 254, 136, 80, 3, 20, 44, 21,
- 180, 32, 32, 79, 4, 80, 16, 128, 11, 64,
- 64, 4, 34, 80, 65, 7, 94, 80, 38, 214,
- 202, 102, 183, 105, 168, 1, 12, 170, 26, 219,
- 26, 34, 19, 135, 29, 41, 128, 117, 137, 128,
- 3, 9, 252, 214, 176, 15, 24, 64, 15, 56,
- 247, 12, 24, 168, 75, 4, 6, 0, 135, 192,
- 14, 156, 139, 82, 90, 8, 164, 38, 219, 29,
- 2, 79, 150, 194, 0, 24, 44, 97, 7, 22,
- 184, 29, 195, 58, 106, 223, 58, 230, 160, 156,
- 68, 89, 108, 89, 115, 145, 3, 147, 48, 33,
- 131, 50, 89, 0, 3, 4, 16, 95, 33, 220,
- 224, 5, 26, 64, 193, 91, 111, 167, 57, 35,
- 132, 35, 53, 148, 116, 12, 100, 166, 248, 13,
- 143, 241, 163, 59, 34, 16, 192, 15, 120, 208,
- 222, 36, 208, 192, 49, 63, 216, 192, 9, 36,
- 192, 128, 137, 114, 152, 44, 47, 217, 140, 130,
- 9, 114, 25, 28, 76, 148, 9, 162, 2, 128,
- 141, 219, 50, 5, 122, 134, 120, 196, 174, 141,
- 46, 143, 167, 96, 131, 23, 221, 120, 200, 72,
- 214, 74, 16, 0, 0, 59 };
-
-static const unsigned char php_logo[] = {
- 71, 73, 70, 56, 57, 97, 120, 0, 67, 0,
- 230, 106, 0, 127, 130, 184, 57, 55, 71, 40,
- 37, 42, 204, 205, 226, 161, 164, 203, 211, 213,
- 231, 178, 180, 212, 67, 66, 88, 131, 134, 185,
- 130, 131, 179, 82, 82, 114, 144, 146, 194, 194,
- 196, 222, 170, 172, 208, 76, 75, 99, 91, 92,
- 131, 221, 222, 236, 59, 56, 60, 110, 113, 165,
- 106, 109, 157, 97, 99, 141, 117, 121, 177, 123,
- 126, 181, 229, 230, 240, 153, 156, 198, 140, 141,
- 193, 185, 186, 217, 107, 107, 146, 78, 78, 107,
- 113, 116, 169, 122, 122, 163, 136, 139, 189, 114,
- 116, 163, 116, 115, 152, 142, 144, 193, 90, 91,
- 126, 226, 227, 239, 123, 125, 173, 164, 165, 208,
- 109, 112, 162, 114, 118, 172, 149, 150, 200, 187,
- 189, 217, 116, 120, 174, 133, 136, 187, 146, 149,
- 195, 216, 217, 234, 146, 146, 196, 100, 102, 146,
- 107, 110, 159, 165, 168, 206, 148, 150, 197, 46,
- 43, 47, 83, 81, 104, 179, 180, 215, 108, 106,
- 140, 92, 91, 118, 138, 141, 191, 102, 104, 150,
- 104, 106, 154, 156, 159, 200, 49, 46, 57, 174,
- 176, 211, 156, 156, 205, 85, 86, 120, 158, 161,
- 202, 150, 153, 197, 129, 130, 175, 103, 105, 151,
- 63, 61, 80, 188, 190, 218, 94, 96, 137, 152,
- 153, 200, 140, 142, 191, 137, 138, 186, 87, 88,
- 124, 182, 183, 215, 213, 215, 232, 34, 30, 32,
- 108, 111, 158, 206, 208, 228, 191, 192, 220, 119,
- 123, 180, 118, 120, 167, 95, 94, 125, 153, 153,
- 204, 110, 111, 152, 115, 119, 174, 34, 30, 31,
- 255, 255, 255, 144, 142, 143, 89, 86, 87, 199,
- 198, 199, 238, 238, 245, 213, 212, 213, 246, 246,
- 250, 130, 128, 129, 172, 170, 171, 116, 114, 115,
- 241, 240, 241, 158, 156, 157, 227, 226, 227, 75,
- 72, 73, 185, 184, 185, 103, 100, 101, 137, 137,
- 182, 0, 255, 0, 71, 70, 95, 223, 224, 237,
- 155, 156, 204, 105, 107, 156, 111, 115, 167, 140,
- 140, 186, 184, 185, 217, 184, 186, 215, 154, 155,
- 204, 167, 170, 207, 219, 220, 235, 154, 156, 201,
- 102, 100, 132, 104, 103, 137, 167, 168, 210, 110,
- 112, 160, 139, 139, 185, 198, 199, 224, 199, 201,
- 225, 105, 108, 156, 151, 152, 203, 33, 249, 4,
- 1, 0, 0, 106, 0, 44, 0, 0, 0, 0,
- 120, 0, 67, 0, 0, 7, 255, 128, 106, 130,
- 131, 132, 133, 134, 135, 136, 137, 138, 139, 140,
- 141, 142, 143, 144, 145, 146, 147, 148, 149, 150,
- 151, 150, 109, 63, 109, 115, 152, 158, 159, 160,
- 63, 121, 121, 54, 62, 26, 113, 76, 26, 26,
- 76, 6, 62, 62, 13, 50, 4, 65, 60, 24,
- 66, 45, 11, 73, 34, 57, 31, 25, 57, 34,
- 47, 41, 160, 194, 161, 13, 26, 12, 125, 77,
- 5, 80, 80, 3, 125, 124, 12, 81, 81, 42,
- 114, 172, 175, 116, 177, 179, 66, 51, 45, 186,
- 31, 8, 0, 22, 22, 21, 87, 40, 37, 22,
- 9, 25, 193, 195, 235, 140, 38, 113, 124, 46,
- 108, 108, 16, 16, 117, 46, 201, 3, 212, 50,
- 179, 34, 31, 254, 44, 0, 17, 8, 4, 64,
- 176, 224, 55, 130, 225, 164, 172, 64, 241, 70,
- 194, 9, 63, 59, 158, 76, 25, 146, 132, 157,
- 69, 53, 65, 108, 12, 96, 67, 226, 130, 71,
- 18, 36, 242, 53, 16, 178, 64, 138, 201, 147,
- 40, 83, 170, 92, 121, 114, 92, 7, 9, 19,
- 118, 232, 128, 65, 225, 8, 5, 43, 67, 68,
- 92, 196, 20, 132, 9, 20, 142, 30, 47, 184,
- 48, 66, 167, 5, 203, 163, 72, 147, 162, 188,
- 242, 38, 6, 140, 35, 71, 30, 140, 88, 114,
- 196, 131, 206, 157, 144, 126, 104, 116, 1, 129,
- 35, 4, 35, 4, 88, 40, 29, 75, 54, 233,
- 149, 19, 58, 30, 44, 1, 162, 64, 193, 136,
- 41, 51, 255, 176, 46, 50, 161, 161, 64, 19,
- 23, 117, 10, 24, 72, 82, 182, 175, 95, 164,
- 29, 96, 44, 81, 192, 129, 131, 3, 60, 9,
- 228, 26, 202, 19, 101, 0, 148, 2, 3, 124,
- 228, 248, 187, 114, 1, 134, 203, 152, 49, 124,
- 160, 156, 244, 13, 5, 5, 14, 214, 172, 81,
- 224, 65, 177, 154, 60, 70, 248, 244, 25, 192,
- 100, 6, 231, 149, 31, 178, 112, 153, 77, 155,
- 75, 151, 215, 74, 221, 44, 89, 115, 224, 128,
- 131, 16, 59, 221, 69, 97, 192, 160, 1, 2,
- 220, 43, 49, 112, 193, 194, 188, 185, 153, 219,
- 200, 147, 118, 216, 93, 164, 200, 154, 210, 195,
- 126, 248, 144, 99, 68, 5, 15, 11, 209, 87,
- 170, 32, 211, 188, 185, 152, 2, 225, 149, 94,
- 121, 112, 32, 64, 0, 14, 112, 64, 153, 48,
- 192, 68, 14, 1, 0, 233, 87, 22, 16, 83,
- 158, 57, 25, 21, 249, 41, 245, 134, 2, 238,
- 245, 112, 7, 38, 115, 208, 225, 131, 1, 50,
- 28, 23, 160, 74, 93, 152, 209, 31, 22, 92,
- 16, 240, 160, 82, 49, 172, 209, 67, 15, 7,
- 236, 81, 201, 15, 50, 52, 208, 64, 73, 23,
- 166, 4, 64, 22, 19, 98, 145, 197, 102, 37,
- 38, 245, 64, 0, 27, 2, 39, 73, 27, 4,
- 236, 227, 96, 139, 39, 41, 55, 161, 25, 95,
- 224, 168, 148, 31, 69, 208, 64, 3, 21, 145,
- 216, 17, 4, 1, 51, 128, 135, 212, 255, 7,
- 153, 53, 217, 36, 139, 71, 169, 16, 198, 132,
- 98, 92, 208, 36, 137, 44, 49, 233, 228, 150,
- 248, 141, 133, 130, 3, 52, 8, 80, 195, 35,
- 72, 96, 16, 4, 148, 71, 125, 240, 69, 22,
- 108, 182, 233, 230, 155, 89, 116, 81, 64, 3,
- 93, 162, 84, 0, 24, 19, 146, 1, 103, 155,
- 23, 12, 96, 225, 73, 11, 236, 41, 40, 155,
- 93, 12, 208, 128, 82, 64, 8, 32, 128, 3,
- 141, 204, 32, 4, 6, 98, 41, 69, 192, 114,
- 41, 86, 106, 6, 24, 92, 124, 1, 32, 74,
- 93, 108, 81, 105, 138, 52, 108, 161, 69, 25,
- 93, 144, 104, 192, 148, 159, 78, 184, 5, 24,
- 94, 116, 113, 40, 82, 35, 8, 224, 4, 163,
- 138, 108, 35, 196, 141, 73, 141, 151, 234, 167,
- 91, 120, 1, 65, 151, 39, 238, 250, 41, 24,
- 99, 96, 32, 197, 0, 120, 10, 171, 106, 25,
- 3, 36, 53, 130, 19, 78, 224, 144, 72, 10,
- 34, 180, 128, 102, 82, 16, 240, 167, 108, 138,
- 97, 64, 96, 18, 6, 94, 108, 155, 34, 26,
- 183, 93, 224, 169, 184, 229, 209, 224, 69, 179,
- 72, 173, 1, 45, 118, 133, 252, 225, 203, 100,
- 101, 125, 33, 33, 186, 253, 121, 1, 160, 148,
- 248, 230, 219, 0, 138, 253, 54, 71, 67, 25,
- 127, 30, 21, 128, 19, 2, 44, 96, 72, 63,
- 244, 146, 21, 91, 192, 229, 109, 209, 227, 157,
- 16, 51, 167, 197, 255, 5, 225, 86, 140, 133,
- 24, 208, 29, 213, 129, 172, 99, 18, 146, 2,
- 2, 31, 212, 57, 214, 164, 59, 194, 57, 198,
- 25, 218, 78, 232, 5, 1, 157, 78, 200, 197,
- 155, 99, 112, 129, 70, 138, 90, 100, 129, 106,
- 196, 112, 150, 113, 198, 185, 19, 150, 129, 37,
- 75, 10, 64, 155, 6, 33, 222, 224, 58, 150,
- 174, 253, 137, 225, 45, 74, 11, 52, 208, 5,
- 121, 19, 106, 193, 0, 192, 253, 173, 136, 18,
- 6, 13, 124, 17, 65, 213, 89, 104, 81, 53,
- 187, 128, 26, 240, 69, 178, 253, 133, 97, 128,
- 82, 52, 204, 58, 200, 31, 0, 32, 160, 100,
- 89, 217, 230, 185, 169, 137, 89, 124, 221, 116,
- 22, 25, 151, 199, 227, 74, 16, 0, 221, 92,
- 206, 130, 51, 119, 198, 218, 42, 125, 48, 6,
- 206, 119, 31, 181, 4, 180, 10, 171, 33, 130,
- 5, 38, 147, 101, 175, 204, 5, 167, 20, 184,
- 170, 58, 83, 249, 116, 74, 49, 247, 119, 70,
- 22, 52, 4, 109, 236, 74, 161, 151, 167, 69,
- 227, 44, 117, 0, 237, 13, 130, 176, 144, 80,
- 95, 15, 79, 56, 198, 181, 39, 109, 222, 31,
- 26, 89, 160, 221, 220, 127, 42, 5, 27, 116,
- 25, 19, 210, 144, 197, 81, 169, 15, 206, 58,
- 75, 69, 184, 173, 70, 56, 115, 147, 133, 114,
- 127, 17, 244, 200, 210, 229, 253, 17, 142, 185,
- 74, 224, 22, 159, 197, 25, 170, 94, 112, 20,
- 255, 214, 229, 1, 175, 20, 7, 78, 244, 32,
- 72, 5, 148, 49, 93, 30, 26, 159, 167, 84,
- 123, 218, 228, 55, 119, 187, 74, 252, 246, 183,
- 69, 216, 99, 179, 132, 1, 241, 219, 83, 10,
- 5, 160, 37, 136, 21, 80, 166, 110, 217, 91,
- 158, 73, 12, 0, 190, 160, 245, 173, 57, 213,
- 211, 143, 239, 152, 3, 134, 44, 20, 14, 11,
- 135, 99, 9, 3, 168, 214, 159, 251, 9, 144,
- 128, 41, 184, 2, 251, 252, 130, 189, 242, 84,
- 136, 37, 201, 99, 78, 4, 58, 183, 187, 248,
- 157, 36, 133, 88, 8, 3, 233, 76, 183, 18,
- 0, 120, 109, 66, 228, 34, 203, 0, 157, 32,
- 8, 20, 24, 176, 47, 194, 235, 32, 238, 142,
- 69, 169, 236, 245, 174, 106, 203, 11, 98, 121,
- 188, 0, 192, 116, 29, 79, 63, 28, 44, 79,
- 24, 20, 184, 146, 29, 10, 162, 3, 40, 24,
- 33, 89, 116, 68, 189, 39, 162, 228, 3, 5,
- 240, 66, 233, 250, 67, 131, 49, 124, 225, 130,
- 39, 76, 73, 247, 38, 244, 189, 240, 113, 15,
- 2, 98, 156, 80, 245, 42, 119, 20, 43, 170,
- 97, 33, 90, 92, 90, 20, 153, 67, 46, 21,
- 248, 81, 5, 16, 232, 194, 24, 180, 48, 70,
- 209, 13, 160, 126, 204, 241, 32, 74, 242, 199,
- 51, 177, 101, 175, 11, 127, 4, 100, 23, 202,
- 224, 72, 153, 81, 113, 37, 232, 83, 223, 243,
- 58, 112, 133, 190, 236, 71, 255, 85, 90, 8,
- 101, 40, 197, 112, 175, 20, 137, 225, 11, 4,
- 120, 160, 10, 189, 104, 167, 9, 98, 161, 130,
- 23, 20, 149, 40, 181, 64, 202, 97, 137, 175,
- 44, 205, 163, 213, 7, 222, 208, 129, 190, 68,
- 72, 99, 104, 248, 194, 2, 78, 133, 67, 23,
- 154, 196, 92, 19, 146, 97, 33, 3, 118, 202,
- 161, 73, 231, 117, 130, 72, 129, 4, 222, 240,
- 67, 165, 40, 177, 95, 205, 60, 150, 43, 173,
- 182, 18, 68, 98, 129, 137, 26, 3, 131, 48,
- 251, 242, 56, 39, 68, 238, 121, 18, 232, 229,
- 88, 214, 216, 47, 26, 156, 97, 156, 82, 64,
- 102, 127, 184, 240, 170, 173, 169, 146, 57, 109,
- 12, 88, 4, 206, 112, 1, 103, 178, 205, 121,
- 130, 120, 193, 9, 36, 208, 73, 165, 48, 82,
- 92, 102, 32, 195, 24, 6, 80, 167, 25, 118,
- 208, 159, 196, 212, 31, 255, 240, 101, 6, 25,
- 50, 128, 142, 73, 41, 154, 19, 142, 70, 136,
- 33, 156, 224, 13, 99, 161, 152, 254, 102, 57,
- 75, 50, 112, 97, 12, 133, 66, 83, 160, 72,
- 26, 74, 86, 158, 68, 5, 92, 96, 233, 232,
- 46, 40, 6, 150, 134, 210, 164, 40, 101, 192,
- 16, 165, 3, 50, 67, 164, 224, 4, 39, 80,
- 39, 82, 96, 200, 133, 11, 208, 131, 30, 5,
- 248, 35, 1, 252, 105, 18, 64, 30, 245, 168,
- 153, 3, 212, 0, 158, 74, 143, 67, 46, 147,
- 57, 94, 255, 48, 234, 81, 147, 234, 71, 2,
- 236, 116, 44, 7, 75, 216, 33, 146, 16, 131,
- 19, 160, 0, 41, 215, 76, 36, 83, 125, 36,
- 133, 5, 52, 177, 60, 89, 192, 40, 114, 220,
- 229, 4, 120, 25, 34, 1, 101, 45, 104, 114,
- 238, 185, 66, 182, 178, 164, 1, 13, 140, 88,
- 199, 242, 83, 78, 105, 41, 162, 4, 121, 101,
- 201, 65, 249, 104, 76, 191, 74, 129, 1, 149,
- 108, 14, 24, 208, 19, 160, 114, 210, 106, 17,
- 136, 53, 171, 4, 171, 198, 0, 199, 170, 68,
- 119, 82, 188, 36, 101, 52, 122, 89, 70, 148,
- 96, 2, 49, 232, 64, 30, 165, 64, 212, 122,
- 122, 214, 36, 121, 115, 217, 233, 162, 211, 129,
- 3, 64, 171, 180, 141, 72, 0, 106, 37, 160,
- 197, 180, 98, 97, 12, 107, 245, 209, 2, 22,
- 199, 70, 185, 250, 133, 8, 61, 128, 150, 97,
- 35, 161, 132, 39, 76, 64, 179, 82, 248, 223,
- 22, 166, 75, 93, 222, 189, 214, 158, 212, 165,
- 46, 24, 6, 251, 26, 5, 200, 74, 0, 50,
- 154, 196, 11, 64, 224, 135, 24, 240, 22, 0,
- 5, 160, 42, 61, 16, 119, 93, 41, 160, 87,
- 189, 16, 112, 45, 101, 136, 112, 48, 39, 68,
- 128, 163, 150, 72, 128, 27, 80, 251, 134, 213,
- 182, 215, 175, 39, 176, 173, 114, 65, 241, 130,
- 41, 248, 1, 181, 170, 253, 175, 95, 81, 192,
- 1, 89, 57, 161, 8, 248, 5, 133, 255, 18,
- 244, 224, 134, 3, 247, 87, 193, 37, 58, 193,
- 26, 28, 220, 131, 240, 178, 131, 5, 20, 62,
- 176, 4, 206, 138, 225, 240, 28, 225, 0, 138,
- 18, 64, 15, 96, 167, 24, 22, 128, 96, 7,
- 110, 112, 67, 12, 168, 89, 98, 202, 248, 129,
- 3, 1, 8, 147, 0, 2, 192, 98, 211, 8,
- 34, 9, 37, 32, 194, 14, 96, 60, 1, 26,
- 215, 56, 41, 19, 32, 80, 15, 132, 36, 38,
- 187, 250, 120, 16, 41, 72, 128, 30, 116, 64,
- 4, 33, 187, 33, 168, 254, 197, 240, 27, 142,
- 128, 227, 13, 45, 185, 8, 120, 120, 193, 147,
- 23, 241, 2, 41, 235, 224, 204, 103, 222, 193,
- 71, 73, 124, 221, 29, 28, 65, 1, 237, 129,
- 209, 134, 14, 112, 3, 15, 141, 249, 17, 47,
- 64, 192, 20, 136, 0, 131, 62, 251, 153, 8,
- 126, 248, 168, 80, 243, 51, 1, 34, 60, 0,
- 52, 213, 113, 143, 162, 113, 16, 2, 59, 223,
- 153, 18, 34, 24, 194, 158, 41, 64, 233, 74,
- 83, 250, 8, 125, 174, 112, 160, 223, 192, 105,
- 78, 75, 224, 211, 159, 6, 42, 80, 137, 112,
- 105, 182, 136, 166, 55, 7, 168, 78, 17, 2,
- 112, 0, 28, 108, 32, 49, 143, 22, 70, 10,
- 62, 80, 2, 16, 88, 1, 42, 80, 121, 128,
- 174, 119, 61, 149, 37, 172, 5, 8, 108, 105,
- 11, 97, 10, 99, 152, 208, 156, 186, 55, 69,
- 80, 0, 21, 110, 56, 48, 4, 49, 199, 90,
- 49, 41, 80, 2, 2, 60, 224, 129, 13, 108,
- 32, 45, 190, 6, 118, 176, 219, 66, 108, 195,
- 112, 128, 10, 35, 24, 129, 21, 172, 80, 130,
- 102, 63, 251, 220, 139, 16, 65, 26, 16, 112,
- 21, 116, 187, 251, 221, 240, 142, 119, 188, 3,
- 1, 0, 59, 0 };
-
-static const unsigned char php_egg_logo[] = {
- 71, 73, 70, 56, 57, 97, 120, 0, 67, 0,
- 231, 255, 0, 18, 25, 33, 32, 30, 34, 28,
- 33, 44, 15, 35, 71, 6, 37, 85, 37, 40,
- 47, 34, 41, 53, 41, 40, 43, 9, 47, 109,
- 30, 45, 68, 21, 48, 84, 51, 46, 55, 43,
- 49, 59, 31, 59, 98, 15, 61, 128, 58, 55,
- 69, 50, 57, 74, 0, 66, 144, 56, 58, 60,
- 54, 59, 71, 32, 66, 113, 60, 65, 67, 63,
- 65, 84, 63, 68, 79, 28, 79, 145, 15, 82,
- 162, 75, 72, 98, 68, 78, 86, 74, 77, 88,
- 50, 82, 122, 41, 85, 134, 76, 78, 108, 70,
- 83, 101, 5, 94, 190, 0, 95, 197, 86, 80,
- 101, 28, 92, 159, 80, 84, 96, 83, 83, 115,
- 81, 87, 89, 22, 97, 183, 86, 88, 85, 0,
- 102, 210, 8, 101, 204, 24, 100, 177, 85, 90,
- 127, 35, 101, 169, 42, 100, 159, 88, 92, 103,
- 0, 107, 216, 69, 95, 132, 0, 108, 210, 84,
- 93, 112, 94, 90, 117, 18, 105, 201, 96, 92,
- 105, 89, 96, 98, 94, 93, 135, 94, 94, 126,
- 30, 106, 210, 7, 112, 222, 33, 108, 198, 16,
- 114, 217, 27, 113, 198, 24, 113, 209, 59, 108,
- 159, 96, 100, 138, 0, 120, 229, 44, 112, 180,
- 49, 112, 171, 71, 108, 148, 99, 104, 115, 90,
- 106, 125, 27, 115, 232, 100, 102, 147, 42, 115,
- 192, 86, 110, 137, 9, 123, 239, 106, 108, 105,
- 105, 105, 138, 33, 118, 228, 12, 125, 227, 48,
- 117, 208, 16, 126, 222, 37, 120, 224, 20, 125,
- 235, 35, 123, 213, 50, 121, 190, 43, 123, 206,
- 40, 123, 220, 105, 110, 160, 59, 122, 182, 78,
- 119, 158, 44, 122, 233, 3, 134, 250, 112, 112,
- 151, 73, 123, 175, 113, 118, 114, 51, 128, 205,
- 34, 129, 246, 11, 136, 245, 34, 130, 240, 113,
- 117, 149, 111, 116, 166, 111, 119, 141, 48, 130,
- 221, 38, 132, 235, 53, 130, 215, 97, 124, 146,
- 116, 122, 124, 117, 121, 131, 54, 130, 229, 41,
- 135, 232, 68, 130, 223, 46, 135, 246, 65, 134,
- 202, 42, 137, 241, 75, 131, 205, 124, 121, 161,
- 101, 125, 191, 86, 128, 210, 121, 122, 169, 105,
- 128, 157, 121, 122, 180, 114, 124, 181, 94, 128,
- 201, 81, 134, 185, 46, 138, 252, 76, 135, 195,
- 34, 142, 252, 62, 137, 229, 63, 138, 217, 33,
- 144, 247, 58, 139, 223, 56, 141, 246, 54, 143,
- 234, 57, 143, 241, 102, 135, 193, 129, 130, 176,
- 122, 136, 144, 46, 148, 252, 45, 149, 246, 118,
- 133, 191, 65, 146, 231, 73, 146, 216, 129, 133,
- 185, 135, 135, 156, 69, 148, 226, 44, 153, 255,
- 94, 143, 216, 132, 136, 175, 88, 146, 207, 137,
- 139, 136, 93, 146, 197, 95, 147, 188, 137, 139,
- 150, 104, 146, 178, 122, 143, 172, 135, 139, 191,
- 57, 156, 254, 67, 154, 245, 70, 154, 239, 134,
- 141, 180, 117, 145, 201, 120, 146, 190, 79, 154,
- 233, 140, 141, 188, 129, 144, 194, 142, 142, 176,
- 137, 147, 156, 88, 155, 222, 82, 157, 230, 93,
- 157, 218, 66, 162, 253, 100, 157, 210, 77, 161,
- 247, 55, 168, 255, 81, 162, 241, 148, 148, 195,
- 145, 149, 202, 127, 156, 204, 77, 166, 255, 142,
- 155, 177, 141, 153, 200, 123, 160, 193, 73, 171,
- 255, 93, 167, 240, 96, 167, 234, 152, 158, 160,
- 101, 167, 228, 119, 164, 206, 155, 158, 171, 110,
- 167, 219, 156, 155, 203, 89, 172, 252, 128, 164,
- 219, 151, 163, 174, 81, 178, 255, 158, 162, 202,
- 102, 175, 249, 93, 178, 251, 108, 175, 237, 103,
- 177, 244, 166, 168, 165, 97, 182, 255, 87, 185,
- 255, 149, 174, 216, 125, 181, 235, 110, 185, 252,
- 117, 183, 254, 171, 172, 209, 166, 175, 197, 103,
- 190, 255, 174, 176, 189, 140, 183, 221, 128, 184,
- 248, 120, 187, 249, 179, 180, 184, 115, 193, 253,
- 170, 183, 193, 174, 181, 215, 107, 197, 255, 135,
- 191, 246, 151, 192, 219, 187, 183, 213, 128, 197,
- 253, 121, 202, 255, 147, 198, 239, 188, 191, 219,
- 148, 200, 252, 192, 193, 197, 134, 205, 254, 171,
- 199, 236, 183, 199, 218, 163, 207, 251, 142, 213,
- 255, 158, 211, 253, 195, 205, 217, 166, 211, 245,
- 205, 204, 228, 153, 218, 255, 190, 210, 236, 186,
- 212, 231, 177, 213, 248, 162, 224, 255, 188, 221,
- 250, 214, 219, 221, 214, 219, 233, 174, 229, 254,
- 198, 225, 247, 209, 226, 248, 186, 233, 251, 227,
- 230, 239, 225, 241, 252, 253, 255, 252, 255, 255,
- 255, 33, 249, 4, 1, 10, 0, 255, 0, 44,
- 0, 0, 0, 0, 120, 0, 67, 0, 0, 8,
- 254, 0, 255, 9, 28, 72, 176, 160, 193, 131,
- 8, 19, 42, 92, 200, 176, 161, 195, 135, 16,
- 35, 74, 156, 72, 177, 162, 197, 139, 22, 131,
- 105, 12, 134, 177, 163, 199, 143, 193, 164, 73,
- 227, 38, 141, 28, 56, 112, 228, 76, 146, 20,
- 41, 205, 152, 75, 99, 183, 100, 201, 50, 101,
- 202, 147, 77, 79, 166, 102, 205, 250, 200, 19,
- 100, 73, 114, 239, 238, 221, 123, 71, 148, 104,
- 202, 163, 224, 86, 138, 124, 25, 115, 166, 205,
- 72, 145, 246, 72, 221, 195, 39, 207, 30, 69,
- 158, 118, 246, 220, 202, 208, 24, 184, 160, 252,
- 248, 9, 29, 59, 212, 100, 75, 99, 53, 159,
- 66, 93, 203, 182, 109, 84, 169, 124, 248, 156,
- 57, 163, 165, 174, 150, 60, 138, 76, 113, 221,
- 251, 207, 24, 183, 119, 97, 3, 135, 125, 71,
- 78, 90, 76, 62, 142, 70, 141, 18, 53, 109,
- 170, 227, 199, 144, 35, 75, 157, 91, 87, 137,
- 229, 28, 74, 190, 228, 229, 139, 209, 43, 96,
- 193, 247, 10, 203, 114, 212, 167, 82, 47, 93,
- 197, 138, 81, 163, 166, 173, 19, 47, 201, 176,
- 99, 59, 166, 171, 36, 135, 237, 22, 45, 114,
- 216, 209, 203, 25, 98, 176, 191, 66, 195, 134,
- 54, 230, 233, 150, 179, 100, 197, 106, 181, 90,
- 158, 171, 57, 179, 110, 231, 124, 185, 145, 77,
- 157, 186, 150, 218, 45, 76, 104, 111, 145, 71,
- 86, 239, 133, 198, 200, 254, 145, 189, 199, 205,
- 212, 212, 115, 244, 232, 157, 107, 86, 172, 185,
- 234, 92, 197, 154, 137, 11, 231, 11, 77, 245,
- 251, 178, 207, 40, 201, 254, 225, 131, 134, 39,
- 138, 124, 103, 80, 73, 68, 13, 37, 141, 39,
- 144, 213, 115, 14, 60, 235, 116, 211, 12, 123,
- 197, 136, 67, 141, 106, 226, 156, 51, 78, 16,
- 92, 208, 194, 7, 126, 28, 70, 166, 159, 9,
- 26, 132, 104, 130, 29, 2, 254, 67, 32, 81,
- 224, 200, 18, 91, 56, 240, 208, 35, 78, 51,
- 238, 49, 40, 223, 58, 240, 88, 99, 132, 31,
- 207, 168, 131, 14, 55, 206, 56, 115, 203, 41,
- 167, 172, 229, 73, 36, 158, 196, 133, 216, 83,
- 29, 58, 166, 69, 11, 26, 88, 96, 129, 6,
- 95, 112, 230, 213, 81, 210, 188, 21, 27, 59,
- 208, 208, 179, 14, 123, 205, 81, 227, 96, 55,
- 235, 208, 227, 14, 23, 126, 244, 162, 204, 49,
- 200, 64, 3, 13, 51, 194, 232, 162, 139, 50,
- 105, 106, 131, 13, 54, 225, 132, 227, 205, 157,
- 207, 96, 243, 204, 48, 195, 244, 72, 28, 126,
- 103, 48, 233, 164, 6, 36, 246, 20, 210, 81,
- 198, 224, 87, 143, 48, 12, 78, 8, 75, 43,
- 242, 21, 3, 38, 60, 227, 116, 224, 2, 22,
- 135, 32, 162, 41, 33, 112, 208, 129, 72, 35,
- 135, 8, 242, 72, 40, 163, 150, 82, 202, 42,
- 186, 172, 178, 203, 46, 169, 170, 154, 76, 50,
- 254, 123, 158, 194, 97, 14, 22, 60, 240, 192,
- 7, 188, 117, 228, 23, 74, 198, 88, 41, 219,
- 56, 189, 36, 19, 203, 57, 235, 80, 147, 11,
- 44, 176, 20, 211, 96, 51, 240, 192, 195, 14,
- 5, 36, 88, 129, 8, 33, 116, 200, 81, 198,
- 181, 101, 208, 1, 199, 27, 220, 110, 59, 69,
- 22, 130, 20, 82, 200, 35, 165, 76, 34, 110,
- 33, 147, 64, 162, 174, 42, 192, 200, 122, 223,
- 25, 38, 216, 186, 192, 19, 24, 133, 52, 82,
- 149, 247, 161, 179, 203, 35, 136, 8, 243, 72,
- 57, 244, 80, 179, 220, 39, 185, 192, 163, 77,
- 55, 244, 236, 227, 14, 5, 17, 0, 65, 7,
- 25, 101, 120, 81, 197, 196, 216, 82, 97, 49,
- 21, 81, 68, 145, 69, 22, 105, 116, 236, 113,
- 26, 161, 148, 59, 136, 24, 98, 64, 210, 203,
- 40, 28, 106, 161, 193, 2, 11, 88, 144, 171,
- 68, 246, 74, 163, 226, 125, 207, 156, 105, 8,
- 25, 212, 54, 218, 202, 39, 4, 227, 115, 142,
- 54, 233, 177, 211, 65, 4, 51, 84, 113, 109,
- 21, 77, 52, 1, 69, 23, 19, 15, 1, 197,
- 16, 84, 12, 17, 197, 182, 112, 8, 146, 198,
- 20, 86, 147, 139, 204, 49, 169, 78, 50, 200,
- 32, 144, 56, 210, 97, 14, 15, 176, 28, 37,
- 204, 198, 180, 228, 107, 108, 158, 60, 19, 202,
- 43, 159, 200, 225, 133, 28, 175, 224, 3, 15,
- 50, 176, 80, 2, 75, 254, 51, 94, 34, 140,
- 143, 208, 68, 119, 129, 45, 210, 93, 48, 13,
- 197, 210, 60, 240, 0, 133, 15, 111, 104, 138,
- 8, 28, 27, 79, 1, 199, 35, 163, 234, 18,
- 139, 155, 233, 206, 177, 97, 202, 22, 28, 112,
- 128, 14, 17, 5, 227, 210, 204, 213, 69, 178,
- 11, 40, 160, 16, 194, 8, 33, 134, 52, 17,
- 142, 122, 197, 236, 156, 11, 51, 185, 52, 3,
- 244, 62, 128, 207, 16, 49, 182, 93, 36, 125,
- 120, 23, 135, 67, 193, 131, 15, 112, 148, 147,
- 143, 58, 216, 8, 3, 249, 198, 89, 192, 1,
- 199, 33, 143, 196, 18, 203, 42, 144, 104, 222,
- 33, 31, 26, 120, 62, 194, 67, 162, 255, 121,
- 159, 35, 149, 104, 58, 135, 21, 100, 64, 92,
- 69, 139, 198, 238, 156, 236, 222, 226, 208, 131,
- 207, 56, 13, 56, 80, 116, 19, 215, 54, 81,
- 197, 24, 73, 23, 126, 248, 16, 62, 248, 144,
- 133, 62, 110, 112, 194, 50, 202, 113, 8, 231,
- 101, 193, 7, 64, 152, 220, 184, 30, 129, 42,
- 93, 168, 66, 108, 29, 50, 129, 231, 52, 208,
- 16, 89, 220, 162, 87, 248, 137, 68, 29, 178,
- 160, 6, 53, 188, 225, 5, 85, 176, 86, 21,
- 232, 1, 15, 113, 228, 98, 57, 173, 104, 143,
- 151, 224, 241, 190, 248, 249, 160, 126, 114, 136,
- 161, 181, 202, 16, 53, 167, 13, 97, 120, 105,
- 184, 7, 7, 12, 224, 4, 111, 192, 65, 114,
- 254, 144, 3, 66, 26, 14, 145, 6, 43, 88,
- 1, 11, 107, 128, 196, 42, 86, 1, 65, 14,
- 181, 224, 0, 1, 160, 160, 66, 100, 114, 139,
- 181, 197, 230, 22, 117, 152, 194, 20, 162, 160,
- 134, 42, 144, 64, 10, 248, 163, 67, 122, 214,
- 17, 187, 79, 232, 45, 23, 226, 16, 7, 62,
- 240, 97, 13, 5, 16, 109, 12, 215, 98, 4,
- 207, 64, 193, 51, 77, 53, 66, 83, 84, 240,
- 65, 26, 218, 113, 1, 3, 180, 1, 27, 144,
- 19, 196, 183, 128, 128, 196, 66, 132, 98, 13,
- 63, 72, 228, 15, 176, 32, 134, 68, 52, 241,
- 62, 45, 8, 64, 0, 106, 144, 144, 89, 152,
- 66, 22, 8, 186, 207, 40, 214, 32, 8, 107,
- 216, 194, 5, 67, 144, 218, 15, 134, 208, 5,
- 68, 184, 15, 30, 205, 120, 148, 25, 97, 1,
- 157, 125, 208, 227, 25, 3, 136, 64, 12, 232,
- 215, 136, 121, 200, 35, 31, 249, 168, 71, 61,
- 242, 33, 143, 118, 108, 67, 30, 208, 128, 195,
- 32, 218, 49, 1, 1, 180, 1, 121, 199, 120,
- 197, 35, 136, 184, 134, 102, 146, 11, 137, 88,
- 80, 228, 37, 104, 145, 36, 13, 72, 178, 80,
- 5, 153, 5, 78, 50, 73, 157, 72, 92, 98,
- 13, 135, 208, 135, 63, 252, 129, 132, 40, 116,
- 193, 105, 192, 11, 5, 62, 92, 217, 140, 157,
- 49, 162, 21, 104, 60, 199, 62, 224, 225, 10,
- 2, 68, 128, 10, 114, 254, 32, 196, 49, 178,
- 113, 129, 11, 112, 224, 159, 37, 224, 192, 6,
- 46, 176, 129, 108, 148, 99, 21, 213, 40, 230,
- 1, 78, 128, 3, 55, 240, 34, 29, 216, 8,
- 197, 36, 122, 81, 10, 114, 61, 2, 93, 107,
- 136, 230, 28, 230, 96, 13, 43, 202, 230, 1,
- 1, 56, 128, 119, 10, 146, 150, 251, 240, 65,
- 21, 88, 200, 194, 60, 198, 233, 143, 84, 164,
- 193, 104, 72, 43, 195, 49, 214, 8, 143, 216,
- 49, 226, 157, 197, 208, 70, 251, 216, 193, 5,
- 2, 100, 160, 10, 129, 64, 4, 54, 54, 81,
- 2, 24, 148, 128, 6, 48, 160, 193, 81, 3,
- 202, 0, 115, 120, 99, 19, 19, 40, 128, 1,
- 74, 208, 79, 6, 20, 32, 12, 222, 8, 133,
- 45, 136, 241, 141, 103, 232, 194, 84, 143, 72,
- 195, 15, 196, 112, 9, 87, 248, 226, 22, 28,
- 58, 3, 20, 183, 71, 144, 89, 16, 201, 163,
- 145, 185, 68, 74, 7, 145, 130, 106, 140, 83,
- 15, 136, 40, 131, 181, 154, 48, 6, 111, 140,
- 145, 61, 173, 72, 214, 131, 210, 83, 41, 2,
- 160, 128, 12, 140, 104, 68, 57, 220, 80, 212,
- 106, 224, 50, 151, 250, 248, 69, 9, 24, 208,
- 6, 126, 28, 225, 2, 1, 32, 70, 53, 126,
- 193, 88, 1, 0, 96, 17, 165, 96, 2, 65,
- 113, 16, 6, 76, 96, 98, 27, 202, 16, 43,
- 89, 51, 193, 10, 82, 108, 174, 58, 38, 144,
- 254, 228, 203, 134, 4, 87, 200, 220, 1, 11,
- 64, 160, 66, 16, 12, 80, 128, 118, 216, 195,
- 5, 141, 40, 31, 182, 216, 145, 30, 23, 181,
- 135, 149, 212, 8, 19, 60, 188, 145, 0, 4,
- 100, 225, 19, 59, 155, 7, 13, 78, 80, 130,
- 109, 60, 67, 24, 141, 128, 67, 33, 204, 81,
- 130, 2, 84, 224, 30, 37, 152, 128, 4, 242,
- 113, 167, 121, 216, 162, 152, 39, 120, 6, 8,
- 4, 192, 128, 13, 112, 160, 159, 6, 192, 68,
- 41, 122, 240, 131, 65, 0, 2, 16, 115, 48,
- 171, 51, 238, 3, 69, 41, 254, 195, 173, 181,
- 125, 12, 31, 122, 0, 132, 25, 248, 192, 3,
- 211, 56, 0, 13, 54, 145, 5, 50, 236, 149,
- 126, 236, 104, 17, 60, 186, 113, 44, 73, 73,
- 120, 29, 174, 136, 37, 28, 102, 215, 10, 121,
- 208, 192, 13, 71, 72, 135, 50, 38, 22, 133,
- 66, 164, 163, 187, 12, 216, 6, 7, 24, 112,
- 132, 114, 192, 33, 13, 144, 248, 69, 1, 0,
- 112, 2, 98, 126, 54, 30, 211, 32, 6, 26,
- 120, 11, 12, 32, 244, 64, 12, 115, 240, 195,
- 18, 174, 0, 8, 87, 144, 226, 20, 164, 147,
- 76, 36, 3, 48, 82, 243, 4, 120, 42, 3,
- 182, 193, 10, 86, 48, 3, 18, 20, 32, 0,
- 2, 32, 129, 26, 200, 80, 133, 194, 53, 129,
- 12, 236, 160, 17, 60, 210, 7, 11, 113, 172,
- 227, 204, 225, 144, 129, 254, 97, 65, 33, 12,
- 129, 165, 131, 3, 55, 112, 131, 45, 142, 81,
- 5, 42, 188, 225, 17, 237, 88, 241, 2, 36,
- 107, 128, 69, 196, 66, 13, 130, 120, 6, 26,
- 60, 187, 136, 106, 120, 22, 23, 186, 224, 90,
- 60, 12, 0, 0, 78, 76, 161, 7, 88, 152,
- 67, 16, 92, 176, 4, 34, 92, 97, 11, 91,
- 200, 132, 53, 204, 35, 153, 51, 72, 146, 94,
- 255, 120, 242, 84, 60, 177, 4, 41, 171, 64,
- 5, 59, 0, 2, 5, 18, 128, 1, 56, 220,
- 236, 90, 189, 83, 3, 59, 206, 97, 230, 102,
- 64, 55, 23, 201, 61, 179, 55, 26, 128, 128,
- 52, 188, 162, 24, 204, 128, 196, 52, 56, 0,
- 131, 77, 88, 67, 24, 132, 64, 196, 33, 212,
- 241, 139, 11, 20, 224, 8, 104, 184, 128, 0,
- 170, 129, 8, 53, 100, 193, 25, 16, 0, 0,
- 0, 182, 49, 104, 6, 36, 67, 153, 143, 184,
- 68, 2, 0, 192, 133, 52, 160, 0, 11, 87,
- 120, 129, 11, 88, 192, 110, 18, 144, 128, 8,
- 153, 118, 70, 162, 34, 99, 129, 40, 10, 196,
- 164, 128, 232, 193, 10, 98, 16, 131, 29, 248,
- 27, 8, 133, 224, 32, 33, 132, 123, 173, 70,
- 172, 35, 141, 235, 64, 6, 116, 97, 65, 172,
- 51, 103, 98, 0, 25, 120, 133, 48, 218, 163,
- 138, 84, 252, 51, 27, 232, 160, 6, 51, 160,
- 193, 142, 108, 28, 97, 2, 12, 176, 7, 18,
- 254, 250, 136, 142, 14, 102, 161, 19, 140, 102,
- 64, 59, 178, 189, 1, 109, 188, 34, 20, 133,
- 240, 131, 103, 57, 113, 136, 31, 44, 97, 14,
- 91, 32, 1, 187, 89, 224, 110, 23, 144, 160,
- 8, 96, 240, 3, 46, 146, 44, 149, 15, 4,
- 96, 1, 247, 174, 206, 41, 176, 96, 131, 29,
- 240, 32, 6, 42, 224, 247, 14, 124, 16, 5,
- 58, 88, 221, 193, 85, 240, 2, 51, 194, 113,
- 142, 110, 72, 40, 23, 202, 233, 70, 179, 202,
- 209, 1, 2, 212, 129, 25, 108, 202, 133, 55,
- 208, 192, 129, 18, 152, 227, 30, 230, 216, 6,
- 49, 156, 64, 108, 8, 164, 226, 30, 48, 152,
- 192, 6, 158, 65, 7, 53, 88, 1, 9, 158,
- 61, 194, 52, 102, 76, 12, 109, 8, 35, 22,
- 144, 232, 196, 161, 225, 32, 134, 43, 92, 161,
- 8, 47, 120, 1, 17, 212, 237, 110, 12, 252,
- 28, 211, 156, 128, 140, 18, 36, 41, 144, 215,
- 194, 198, 19, 115, 0, 194, 10, 84, 192, 131,
- 33, 240, 187, 223, 62, 160, 66, 178, 7, 14,
- 49, 50, 208, 233, 96, 231, 152, 16, 123, 230,
- 83, 142, 12, 59, 32, 22, 26, 103, 70, 43,
- 230, 1, 130, 182, 95, 128, 6, 19, 184, 64,
- 240, 139, 234, 134, 120, 84, 99, 197, 109, 240,
- 134, 26, 232, 80, 7, 11, 104, 123, 27, 72,
- 0, 192, 6, 228, 49, 14, 61, 165, 131, 6,
- 0, 144, 0, 43, 4, 254, 49, 136, 43, 16,
- 33, 8, 30, 136, 60, 188, 225, 237, 238, 23,
- 20, 97, 11, 153, 127, 204, 230, 3, 240, 223,
- 234, 140, 2, 11, 83, 142, 58, 15, 202, 80,
- 133, 167, 199, 96, 8, 141, 128, 155, 33, 62,
- 65, 6, 67, 112, 29, 26, 21, 114, 14, 204,
- 144, 83, 212, 112, 14, 222, 80, 118, 98, 128,
- 12, 180, 35, 12, 185, 32, 15, 16, 0, 103,
- 71, 0, 98, 71, 0, 3, 48, 224, 6, 219,
- 48, 15, 143, 32, 9, 28, 48, 1, 188, 80,
- 14, 84, 160, 6, 137, 192, 104, 23, 144, 14,
- 217, 38, 1, 188, 112, 130, 188, 0, 3, 152,
- 149, 10, 230, 50, 8, 150, 22, 4, 50, 0,
- 6, 91, 64, 4, 46, 224, 2, 145, 7, 126,
- 65, 16, 4, 91, 128, 11, 234, 199, 121, 255,
- 16, 23, 178, 81, 7, 82, 32, 2, 168, 22,
- 3, 62, 48, 4, 100, 160, 6, 79, 23, 5,
- 135, 240, 10, 173, 48, 45, 251, 7, 13, 231,
- 160, 38, 102, 118, 14, 117, 82, 39, 126, 0,
- 113, 186, 128, 12, 12, 88, 11, 185, 176, 13,
- 19, 112, 3, 37, 192, 15, 185, 84, 15, 243,
- 16, 15, 234, 112, 12, 136, 80, 10, 237, 64,
- 12, 196, 112, 15, 215, 64, 5, 112, 128, 11,
- 22, 208, 103, 182, 32, 1, 0, 192, 0, 239,
- 5, 80, 23, 208, 6, 207, 80, 8, 96, 3,
- 111, 70, 128, 6, 118, 192, 4, 96, 0, 121,
- 254, 36, 240, 2, 96, 176, 33, 150, 192, 5,
- 92, 224, 43, 235, 39, 16, 103, 224, 121, 144,
- 49, 10, 63, 48, 3, 163, 23, 3, 195, 243,
- 129, 101, 160, 6, 169, 247, 10, 200, 0, 10,
- 204, 209, 10, 194, 16, 14, 201, 195, 34, 7,
- 151, 12, 225, 0, 12, 10, 224, 0, 147, 160,
- 13, 180, 227, 133, 208, 240, 11, 196, 230, 6,
- 253, 112, 12, 159, 208, 119, 86, 103, 8, 214,
- 246, 10, 209, 80, 14, 209, 0, 10, 67, 0,
- 7, 227, 16, 15, 247, 192, 15, 72, 192, 91,
- 246, 176, 13, 169, 176, 8, 110, 144, 10, 214,
- 5, 61, 35, 227, 2, 91, 32, 3, 86, 33,
- 21, 92, 0, 6, 47, 224, 1, 50, 32, 10,
- 176, 17, 137, 63, 72, 137, 142, 113, 10, 98,
- 208, 116, 81, 199, 111, 60, 64, 5, 143, 83,
- 6, 67, 160, 6, 177, 16, 14, 208, 160, 13,
- 106, 194, 12, 200, 160, 12, 218, 112, 12, 82,
- 152, 12, 187, 160, 10, 151, 64, 1, 8, 240,
- 3, 10, 184, 51, 148, 208, 10, 139, 85, 2,
- 37, 176, 9, 253, 32, 12, 134, 80, 6, 251,
- 83, 62, 84, 144, 45, 141, 64, 8, 84, 192,
- 3, 158, 8, 4, 86, 64, 10, 28, 32, 0,
- 56, 224, 13, 194, 176, 11, 222, 80, 14, 202,
- 16, 10, 135, 32, 46, 141, 7, 111, 45, 224,
- 24, 145, 144, 9, 91, 0, 6, 70, 0, 6,
- 112, 101, 116, 72, 247, 254, 15, 123, 112, 6,
- 176, 65, 11, 63, 176, 111, 59, 208, 111, 154,
- 216, 142, 135, 0, 10, 136, 16, 10, 194, 160,
- 13, 201, 160, 13, 117, 34, 14, 208, 128, 12,
- 186, 208, 11, 187, 112, 9, 128, 224, 1, 20,
- 64, 0, 8, 96, 3, 203, 1, 11, 159, 112,
- 83, 175, 80, 15, 52, 208, 118, 196, 144, 15,
- 185, 32, 66, 67, 80, 5, 100, 64, 7, 81,
- 83, 56, 85, 48, 3, 20, 233, 3, 54, 208,
- 3, 157, 192, 0, 0, 64, 12, 208, 0, 10,
- 63, 4, 7, 202, 54, 146, 133, 48, 7, 151,
- 64, 4, 96, 112, 146, 144, 225, 7, 96, 192,
- 5, 226, 40, 21, 245, 38, 69, 158, 48, 23,
- 145, 97, 10, 115, 96, 3, 34, 48, 122, 231,
- 88, 122, 112, 160, 6, 165, 16, 11, 161, 112,
- 12, 202, 112, 9, 151, 16, 14, 226, 32, 143,
- 244, 40, 6, 24, 224, 0, 8, 128, 0, 17,
- 128, 2, 135, 128, 66, 173, 64, 9, 140, 64,
- 9, 185, 208, 15, 196, 144, 10, 191, 192, 15,
- 236, 0, 10, 114, 96, 56, 93, 32, 7, 73,
- 120, 67, 80, 64, 5, 59, 128, 132, 84, 0,
- 4, 107, 48, 104, 5, 240, 13, 194, 0, 10,
- 111, 0, 4, 64, 32, 57, 105, 128, 46, 171,
- 48, 7, 223, 39, 4, 145, 1, 132, 157, 246,
- 105, 2, 49, 11, 115, 33, 142, 167, 240, 3,
- 54, 224, 3, 153, 152, 56, 80, 243, 6, 112,
- 254, 0, 138, 177, 32, 12, 208, 160, 10, 106,
- 130, 13, 0, 24, 14, 197, 128, 148, 107, 208,
- 3, 86, 32, 138, 202, 193, 51, 85, 121, 83,
- 173, 112, 14, 229, 192, 14, 234, 80, 14, 173,
- 160, 87, 101, 0, 60, 33, 148, 132, 112, 32,
- 60, 60, 48, 3, 184, 233, 3, 170, 224, 75,
- 237, 128, 13, 79, 72, 5, 84, 246, 45, 83,
- 0, 136, 221, 71, 4, 50, 64, 147, 29, 178,
- 100, 35, 37, 147, 132, 249, 24, 137, 128, 152,
- 43, 224, 111, 57, 121, 132, 92, 4, 7, 161,
- 160, 12, 111, 162, 11, 115, 32, 153, 199, 176,
- 117, 63, 83, 158, 244, 8, 10, 148, 48, 144,
- 237, 25, 8, 44, 26, 8, 114, 16, 8, 169,
- 193, 8, 11, 41, 56, 133, 195, 3, 244, 99,
- 117, 84, 80, 5, 80, 192, 111, 244, 195, 63,
- 64, 16, 10, 186, 32, 12, 5, 234, 3, 49,
- 48, 3, 195, 153, 6, 88, 48, 50, 240, 246,
- 1, 73, 178, 7, 253, 213, 86, 90, 224, 160,
- 142, 33, 6, 33, 48, 101, 254, 118, 67, 169,
- 39, 8, 175, 208, 132, 210, 179, 11, 189, 176,
- 5, 202, 160, 12, 107, 194, 117, 83, 216, 10,
- 180, 83, 149, 44, 234, 5, 99, 224, 5, 127,
- 224, 5, 110, 58, 6, 178, 89, 6, 74, 51,
- 49, 80, 192, 144, 246, 83, 6, 159, 210, 119,
- 166, 55, 75, 12, 57, 3, 213, 201, 132, 160,
- 160, 6, 81, 48, 4, 254, 51, 48, 3, 89,
- 96, 68, 73, 234, 125, 65, 96, 2, 73, 18,
- 91, 1, 240, 50, 255, 160, 8, 81, 234, 24,
- 142, 176, 4, 33, 32, 2, 137, 57, 3, 84,
- 0, 5, 29, 84, 53, 64, 154, 42, 170, 144,
- 9, 92, 112, 9, 165, 16, 143, 196, 98, 133,
- 12, 184, 51, 104, 170, 166, 99, 176, 166, 115,
- 227, 162, 173, 154, 52, 247, 217, 101, 89, 87,
- 6, 132, 208, 8, 62, 89, 5, 67, 144, 147,
- 19, 195, 3, 43, 96, 3, 81, 240, 10, 141,
- 160, 6, 95, 217, 159, 126, 106, 3, 71, 36,
- 6, 68, 80, 4, 50, 144, 36, 106, 21, 0,
- 108, 5, 165, 147, 42, 21, 166, 96, 169, 83,
- 214, 111, 137, 83, 5, 206, 3, 10, 161, 48,
- 61, 170, 224, 7, 32, 0, 1, 50, 0, 9,
- 186, 64, 39, 86, 104, 120, 202, 161, 170, 140,
- 224, 166, 106, 250, 7, 109, 234, 166, 49, 228,
- 5, 134, 224, 5, 73, 67, 63, 114, 80, 5,
- 183, 154, 58, 55, 164, 2, 177, 73, 6, 80,
- 96, 164, 108, 214, 10, 92, 198, 63, 51, 16,
- 2, 6, 75, 95, 138, 42, 165, 248, 1, 82,
- 34, 117, 16, 166, 80, 23, 155, 115, 11, 87,
- 96, 161, 51, 192, 111, 156, 170, 108, 160, 32,
- 61, 171, 192, 10, 32, 16, 124, 48, 208, 9,
- 189, 128, 148, 208, 16, 14, 176, 72, 59, 55,
- 69, 154, 129, 192, 166, 127, 176, 166, 114, 163,
- 254, 166, 94, 0, 49, 77, 192, 3, 73, 208,
- 4, 115, 67, 6, 160, 128, 171, 132, 160, 6,
- 60, 10, 49, 60, 96, 3, 112, 112, 179, 100,
- 16, 8, 236, 8, 4, 54, 96, 176, 33, 128,
- 2, 40, 192, 2, 68, 160, 4, 213, 116, 77,
- 9, 33, 169, 90, 48, 21, 115, 160, 111, 153,
- 184, 3, 114, 136, 58, 135, 208, 173, 171, 224,
- 10, 253, 132, 6, 81, 113, 10, 172, 240, 38,
- 216, 160, 13, 242, 40, 164, 104, 250, 7, 129,
- 224, 174, 129, 192, 8, 114, 208, 166, 134, 128,
- 63, 17, 147, 56, 77, 32, 155, 132, 32, 138,
- 136, 80, 5, 58, 11, 5, 47, 219, 5, 253,
- 9, 7, 46, 74, 8, 236, 232, 3, 244, 133,
- 2, 71, 139, 180, 44, 16, 4, 73, 178, 100,
- 148, 164, 16, 121, 80, 23, 82, 225, 10, 55,
- 153, 137, 70, 168, 6, 136, 32, 8, 47, 86,
- 8, 165, 160, 9, 19, 96, 6, 142, 193, 7,
- 163, 176, 11, 202, 192, 117, 242, 232, 78, 108,
- 235, 174, 238, 58, 6, 104, 203, 170, 73, 227,
- 5, 73, 48, 179, 65, 139, 171, 175, 80, 109,
- 84, 80, 52, 178, 217, 4, 187, 58, 4, 217,
- 82, 5, 83, 99, 5, 61, 128, 180, 190, 203,
- 2, 46, 192, 180, 78, 36, 73, 254, 197, 184,
- 117, 145, 7, 180, 192, 116, 138, 201, 111, 133,
- 74, 117, 89, 112, 8, 186, 160, 9, 23, 16,
- 25, 159, 171, 83, 240, 254, 120, 66, 104, 58,
- 6, 129, 176, 166, 174, 10, 167, 100, 80, 175,
- 245, 138, 51, 160, 144, 11, 112, 153, 71, 47,
- 84, 62, 49, 91, 122, 116, 0, 60, 81, 0,
- 4, 152, 122, 180, 75, 144, 1, 25, 112, 184,
- 17, 68, 188, 15, 209, 184, 90, 80, 173, 54,
- 80, 168, 167, 39, 60, 22, 243, 6, 208, 43,
- 189, 146, 49, 10, 218, 112, 174, 19, 119, 44,
- 60, 67, 186, 45, 234, 162, 114, 80, 175, 93,
- 86, 6, 159, 0, 10, 177, 11, 7, 81, 112,
- 132, 47, 75, 175, 78, 99, 52, 60, 160, 2,
- 86, 90, 168, 54, 176, 4, 46, 144, 1, 87,
- 112, 141, 213, 113, 6, 245, 102, 111, 16, 33,
- 169, 138, 48, 177, 152, 184, 147, 19, 153, 122,
- 28, 154, 12, 156, 48, 189, 146, 241, 12, 87,
- 8, 13, 26, 215, 30, 237, 89, 11, 200, 128,
- 12, 178, 3, 93, 235, 234, 5, 101, 144, 132,
- 208, 149, 41, 21, 252, 144, 220, 27, 60, 117,
- 250, 116, 161, 228, 163, 132, 116, 5, 46, 144,
- 8, 248, 161, 4, 11, 32, 73, 139, 27, 17,
- 166, 240, 5, 144, 208, 3, 251, 187, 111, 165,
- 39, 135, 136, 240, 10, 146, 41, 192, 146, 113,
- 10, 231, 96, 133, 212, 32, 12, 112, 195, 162,
- 104, 27, 8, 173, 0, 55, 183, 214, 10, 55,
- 85, 149, 79, 200, 173, 144, 99, 96, 170, 35,
- 92, 192, 51, 4, 116, 64, 127, 161, 244, 129,
- 254, 83, 80, 156, 147, 16, 100, 222, 8, 91,
- 80, 116, 0, 103, 51, 17, 193, 192, 10, 145,
- 123, 161, 6, 118, 181, 175, 240, 38, 153, 64,
- 195, 53, 76, 178, 218, 128, 12, 185, 80, 149,
- 109, 251, 7, 132, 32, 7, 134, 240, 7, 49,
- 180, 182, 107, 11, 187, 91, 122, 8, 82, 96,
- 3, 89, 128, 8, 173, 208, 8, 154, 92, 6,
- 141, 208, 8, 129, 96, 8, 3, 103, 117, 207,
- 35, 81, 27, 203, 131, 212, 161, 4, 32, 21,
- 0, 18, 0, 169, 18, 49, 14, 107, 128, 137,
- 251, 150, 122, 87, 43, 12, 245, 8, 12, 27,
- 240, 151, 82, 241, 12, 218, 64, 13, 56, 44,
- 12, 181, 192, 8, 105, 123, 83, 210, 44, 55,
- 160, 204, 162, 148, 64, 48, 185, 16, 10, 161,
- 80, 68, 105, 48, 190, 114, 76, 205, 55, 149,
- 79, 172, 71, 45, 112, 208, 8, 163, 178, 10,
- 201, 128, 203, 176, 161, 5, 39, 60, 73, 30,
- 49, 8, 82, 230, 197, 95, 169, 202, 109, 162,
- 12, 192, 64, 3, 150, 0, 27, 201, 35, 12,
- 108, 34, 12, 210, 220, 162, 55, 229, 162, 110,
- 26, 203, 238, 249, 198, 177, 160, 12, 144, 48,
- 8, 177, 112, 12, 194, 0, 148, 205, 1, 55,
- 210, 44, 205, 229, 67, 7, 201, 6, 42, 12,
- 148, 12, 190, 0, 27, 124, 240, 1, 80, 20,
- 0, 46, 243, 17, 170, 96, 5, 133, 122, 155,
- 31, 168, 202, 14, 141, 254, 12, 189, 128, 4,
- 146, 32, 25, 124, 160, 13, 171, 44, 144, 45,
- 106, 8, 134, 240, 162, 11, 188, 182, 208, 149,
- 66, 229, 169, 13, 151, 160, 10, 247, 88, 10,
- 68, 89, 182, 85, 233, 96, 194, 101, 209, 81,
- 160, 108, 151, 211, 11, 192, 240, 24, 168, 192,
- 7, 42, 243, 209, 11, 144, 200, 30, 145, 12,
- 105, 80, 168, 205, 171, 6, 231, 252, 10, 151,
- 179, 11, 156, 112, 4, 252, 188, 198, 100, 112,
- 205, 46, 26, 208, 114, 243, 162, 238, 233, 133,
- 104, 87, 143, 47, 192, 10, 202, 80, 10, 200,
- 64, 148, 225, 160, 198, 104, 26, 8, 179, 137,
- 183, 114, 120, 8, 166, 162, 212, 190, 66, 43,
- 158, 115, 0, 243, 194, 21, 127, 232, 167, 51,
- 224, 111, 84, 87, 203, 165, 176, 11, 154, 0,
- 3, 220, 244, 24, 189, 16, 206, 14, 214, 182,
- 11, 108, 8, 105, 107, 211, 239, 36, 12, 150,
- 29, 39, 30, 176, 5, 172, 208, 11, 14, 205,
- 12, 218, 80, 11, 235, 73, 9, 44, 42, 155,
- 134, 128, 49, 181, 60, 9, 170, 48, 10, 230,
- 161, 5, 31, 240, 0, 125, 253, 0, 160, 182,
- 23, 147, 64, 180, 23, 58, 117, 84, 23, 5,
- 130, 112, 42, 174, 0, 3, 150, 240, 151, 171,
- 144, 58, 1, 205, 174, 114, 80, 205, 160, 108,
- 214, 3, 25, 209, 185, 160, 13, 202, 208, 0,
- 3, 224, 1, 151, 32, 166, 152, 57, 48, 134,
- 254, 112, 83, 16, 115, 45, 114, 184, 6, 125,
- 112, 7, 123, 160, 5, 241, 178, 0, 125, 61,
- 2, 216, 196, 23, 144, 80, 96, 21, 91, 177,
- 253, 19, 5, 83, 112, 216, 192, 80, 2, 95,
- 96, 23, 82, 234, 9, 165, 128, 8, 65, 27,
- 180, 110, 74, 8, 163, 221, 182, 54, 157, 205,
- 181, 192, 128, 185, 240, 10, 208, 160, 11, 13,
- 160, 0, 24, 0, 6, 208, 32, 158, 208, 208,
- 30, 234, 42, 223, 85, 144, 5, 216, 45, 23,
- 57, 208, 218, 44, 227, 221, 22, 240, 4, 90,
- 241, 29, 170, 64, 157, 215, 170, 147, 196, 147,
- 208, 201, 128, 4, 102, 96, 25, 32, 94, 23,
- 147, 120, 7, 125, 176, 6, 113, 160, 6, 214,
- 60, 55, 106, 122, 223, 114, 4, 79, 39, 148,
- 11, 255, 77, 1, 20, 112, 5, 170, 48, 182,
- 205, 12, 205, 159, 64, 57, 120, 144, 221, 219,
- 157, 3, 38, 80, 43, 101, 195, 50, 19, 238,
- 203, 189, 1, 185, 243, 188, 188, 62, 48, 5,
- 202, 128, 13, 201, 192, 6, 110, 224, 86, 121,
- 0, 226, 82, 174, 4, 34, 126, 6, 36, 222,
- 7, 120, 96, 226, 220, 226, 56, 17, 44, 154,
- 151, 227, 148, 118, 201, 10, 124, 50, 10, 142,
- 176, 33, 215, 225, 227, 77, 2, 228, 182, 242,
- 0, 53, 240, 5, 68, 94, 34, 229, 120, 169,
- 137, 169, 2, 6, 150, 5, 229, 186, 206, 48,
- 64, 16, 166, 160, 8, 192, 81, 62, 229, 32,
- 142, 25, 84, 238, 222, 115, 49, 232, 132, 110,
- 23, 215, 113, 25, 218, 17, 34, 78, 178, 232,
- 181, 98, 1, 109, 30, 32, 37, 162, 16, 151,
- 64, 184, 152, 26, 127, 73, 94, 10, 73, 9,
- 12, 56, 128, 16, 218, 148, 7, 121, 240, 5,
- 182, 17, 234, 162, 158, 3, 184, 129, 27, 218,
- 113, 234, 218, 209, 31, 253, 17, 34, 172, 206,
- 232, 38, 160, 3, 0, 82, 225, 145, 206, 16,
- 148, 142, 169, 116, 126, 164, 186, 144, 12, 187,
- 237, 16, 150, 20, 9, 118, 96, 7, 95, 240,
- 5, 216, 145, 29, 168, 158, 234, 170, 174, 1,
- 31, 160, 3, 184, 17, 236, 120, 33, 235, 179,
- 254, 16, 144, 75, 184, 136, 153, 106, 22, 185,
- 6, 147, 192, 10, 174, 176, 1, 60, 65, 19,
- 145, 240, 230, 207, 222, 17, 128, 64, 184, 33,
- 96, 164, 86, 144, 6, 225, 226, 165, 154, 32,
- 1, 223, 190, 238, 21, 225, 10, 75, 128, 2,
- 54, 240, 3, 66, 148, 6, 228, 178, 11, 192,
- 192, 4, 236, 158, 239, 2, 17, 16, 0, 59};
-
diff --git a/main/main.c b/main/main.c
index 8546500f32..66e4b6e93f 100644
--- a/main/main.c
+++ b/main/main.c
@@ -86,7 +86,6 @@
#include "php_content_types.h"
#include "php_ticks.h"
-#include "php_logos.h"
#include "php_streams.h"
#include "php_open_temporary_file.h"
@@ -527,6 +526,7 @@ PHP_INI_BEGIN()
STD_PHP_INI_ENTRY("default_mimetype", SAPI_DEFAULT_MIMETYPE, PHP_INI_ALL, OnUpdateString, default_mimetype, sapi_globals_struct,sapi_globals)
STD_PHP_INI_ENTRY("error_log", NULL, PHP_INI_ALL, OnUpdateErrorLog, error_log, php_core_globals, core_globals)
STD_PHP_INI_ENTRY("extension_dir", PHP_EXTENSION_DIR, PHP_INI_SYSTEM, OnUpdateStringUnempty, extension_dir, php_core_globals, core_globals)
+ STD_PHP_INI_ENTRY("sys_temp_dir", NULL, PHP_INI_SYSTEM, OnUpdateStringUnempty, sys_temp_dir, php_core_globals, core_globals)
STD_PHP_INI_ENTRY("include_path", PHP_INCLUDE_PATH, PHP_INI_ALL, OnUpdateStringUnempty, include_path, php_core_globals, core_globals)
PHP_INI_ENTRY("max_execution_time", "30", PHP_INI_ALL, OnUpdateTimeout)
STD_PHP_INI_ENTRY("open_basedir", NULL, PHP_INI_ALL, OnUpdateBaseDir, open_basedir, php_core_globals, core_globals)
@@ -557,7 +557,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|PHP_INI_PERDIR, NULL)
+ PHP_INI_ENTRY("max_file_uploads", "20", PHP_INI_SYSTEM|PHP_INI_PERDIR, 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)
@@ -1929,6 +1929,23 @@ int php_register_extensions(zend_module_entry **ptr, int count TSRMLS_DC)
}
return SUCCESS;
}
+
+/* A very long time ago php_module_startup() was refactored in a way
+ * which broke calling it with more than one additional module.
+ * This alternative to php_register_extensions() works around that
+ * by walking the shallower structure.
+ *
+ * See algo: https://bugs.php.net/bug.php?id=63159
+ */
+static int php_register_extensions_bc(zend_module_entry *ptr, int count TSRMLS_DC)
+{
+ while (count--) {
+ if (zend_register_internal_module(ptr++ TSRMLS_CC) == NULL) {
+ return FAILURE;
+ }
+ }
+ return SUCCESS;
+}
/* }}} */
#if defined(PHP_WIN32) && _MSC_VER >= 1400
@@ -2186,14 +2203,6 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod
return FAILURE;
}
- /* initialize registry for images to be used in phpinfo()
- (this uses configuration parameters from php.ini)
- */
- if (php_init_info_logos() == FAILURE) {
- php_printf("PHP: Unable to initialize info phpinfo logos.\n");
- return FAILURE;
- }
-
zuv.html_errors = 1;
zuv.import_use_extension = ".php";
php_startup_auto_globals(TSRMLS_C);
@@ -2207,7 +2216,7 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod
}
/* start additional PHP extensions */
- php_register_extensions(&additional_modules, num_additional_modules TSRMLS_CC);
+ php_register_extensions_bc(additional_modules, num_additional_modules TSRMLS_CC);
/* load and startup extensions compiled as shared objects (aka DLLs)
as requested by php.ini entries
@@ -2377,7 +2386,6 @@ void php_module_shutdown(TSRMLS_D)
/* Destroys filter & transport registries too */
php_shutdown_stream_wrappers(module_number TSRMLS_CC);
- php_shutdown_info_logos();
UNREGISTER_INI_ENTRIES();
/* close down the ini config */
@@ -2425,10 +2433,6 @@ PHPAPI int php_execute_script(zend_file_handle *primary_file TSRMLS_DC)
int retval = 0;
EG(exit_status) = 0;
- if (php_handle_special_queries(TSRMLS_C)) {
- zend_file_handle_dtor(primary_file TSRMLS_CC);
- return 0;
- }
#ifndef HAVE_BROKEN_GETCWD
# define OLD_CWD_SIZE 4096
old_cwd = do_alloca(OLD_CWD_SIZE, use_heap);
diff --git a/main/network.c b/main/network.c
index 59ce12ef20..fc2a94badd 100644
--- a/main/network.c
+++ b/main/network.c
@@ -25,7 +25,10 @@
#include <stddef.h>
+
+
#ifdef PHP_WIN32
+# include <Ws2tcpip.h>
# include "win32/inet.h"
# define O_RDONLY _O_RDONLY
# include "win32/param.h"
@@ -869,7 +872,7 @@ skip_bind:
efree(local_address);
}
}
- /* free error string recieved during previous iteration (if any) */
+ /* free error string received during previous iteration (if any) */
if (error_string && *error_string) {
efree(*error_string);
*error_string = NULL;
diff --git a/main/output.c b/main/output.c
index 0777b64e1d..72092e9561 100644
--- a/main/output.c
+++ b/main/output.c
@@ -1508,7 +1508,7 @@ PHP_FUNCTION(ob_get_status)
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &full_status) == FAILURE) {
return;
}
-
+
array_init(return_value);
if (!OG(active)) {
diff --git a/main/php.h b/main/php.h
index 63e33fd166..eff66d00b8 100644
--- a/main/php.h
+++ b/main/php.h
@@ -26,7 +26,7 @@
#include <dmalloc.h>
#endif
-#define PHP_API_VERSION 20100412
+#define PHP_API_VERSION 20121113
#define PHP_HAVE_STREAMS
#define YYDEBUG 0
@@ -60,7 +60,6 @@
# else
# define PHPAPI
# endif
-
# define THREAD_LS
# define PHP_DIR_SEPARATOR '/'
# define PHP_EOL "\n"
diff --git a/main/php_globals.h b/main/php_globals.h
index 6a4cf5a627..b65499f1b3 100644
--- a/main/php_globals.h
+++ b/main/php_globals.h
@@ -85,6 +85,7 @@ struct _php_core_globals {
char *open_basedir;
char *extension_dir;
char *php_binary;
+ char *sys_temp_dir;
char *upload_tmp_dir;
long upload_max_filesize;
diff --git a/main/php_ini.c b/main/php_ini.c
index 8c76a315c3..1faec6877d 100644
--- a/main/php_ini.c
+++ b/main/php_ini.c
@@ -357,7 +357,24 @@ static void php_load_php_extension_cb(void *arg TSRMLS_DC)
*/
static void php_load_zend_extension_cb(void *arg TSRMLS_DC)
{
- zend_load_extension(*((char **) arg));
+ char *filename = *((char **) arg);
+ int length = strlen(filename);
+
+ if (IS_ABSOLUTE_PATH(filename, length)) {
+ zend_load_extension(filename);
+ } else {
+ char *libpath;
+ char *extension_dir = INI_STR("extension_dir");
+ int extension_dir_len = strlen(extension_dir);
+
+ if (IS_SLASH(extension_dir[extension_dir_len-1])) {
+ spprintf(&libpath, 0, "%s%s", extension_dir, filename);
+ } else {
+ spprintf(&libpath, 0, "%s%c%s", extension_dir, DEFAULT_SLASH, filename);
+ }
+ zend_load_extension(libpath);
+ efree(libpath);
+ }
}
/* }}} */
diff --git a/main/php_logos.c b/main/php_logos.c
deleted file mode 100644
index 7ac3f6b598..0000000000
--- a/main/php_logos.c
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- +----------------------------------------------------------------------+
- | PHP Version 5 |
- +----------------------------------------------------------------------+
- | Copyright (c) 1997-2014 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 <hholzgra@php.net> |
- +----------------------------------------------------------------------+
-*/
-
-/* $Id$ */
-
-#include "php.h"
-#include "logos.h"
-#include "php_logos.h"
-#include "ext/standard/info.h"
-#include "SAPI.h"
-
-typedef struct _php_info_logo {
- const char *mimetype;
- int mimelen;
- const unsigned char *data;
- int size;
-} php_info_logo;
-
-static HashTable phpinfo_logo_hash;
-
-PHPAPI int php_register_info_logo(char *logo_string, const char *mimetype, const unsigned char *data, int size)
-{
- php_info_logo info_logo;
-
- info_logo.mimetype = mimetype;
- info_logo.mimelen = strlen(mimetype);
- info_logo.data = data;
- info_logo.size = size;
-
- return zend_hash_add(&phpinfo_logo_hash, logo_string, strlen(logo_string), &info_logo, sizeof(php_info_logo), NULL);
-}
-
-PHPAPI int php_unregister_info_logo(char *logo_string)
-{
- return zend_hash_del(&phpinfo_logo_hash, logo_string, strlen(logo_string));
-}
-
-int php_init_info_logos(void)
-{
- if(zend_hash_init(&phpinfo_logo_hash, 0, NULL, NULL, 1)==FAILURE)
- return FAILURE;
-
- php_register_info_logo(PHP_LOGO_GUID , "image/gif", php_logo , sizeof(php_logo));
- php_register_info_logo(PHP_EGG_LOGO_GUID, "image/gif", php_egg_logo, sizeof(php_egg_logo));
- php_register_info_logo(ZEND_LOGO_GUID , "image/gif", zend_logo , sizeof(zend_logo));
-
- return SUCCESS;
-}
-
-int php_shutdown_info_logos(void)
-{
- zend_hash_destroy(&phpinfo_logo_hash);
- return SUCCESS;
-}
-
-#define CONTENT_TYPE_HEADER "Content-Type: "
-int php_info_logos(const char *logo_string TSRMLS_DC)
-{
- php_info_logo *logo_image;
- char *content_header;
- int len;
-
- if(FAILURE==zend_hash_find(&phpinfo_logo_hash, (char *) logo_string, strlen(logo_string), (void **)&logo_image))
- return 0;
-
- len = sizeof(CONTENT_TYPE_HEADER) - 1 + logo_image->mimelen;
- content_header = emalloc(len + 1);
- memcpy(content_header, CONTENT_TYPE_HEADER, sizeof(CONTENT_TYPE_HEADER) - 1);
- memcpy(content_header + sizeof(CONTENT_TYPE_HEADER) - 1 , logo_image->mimetype, logo_image->mimelen);
- content_header[len] = '\0';
- sapi_add_header(content_header, len, 0);
-
- PHPWRITE((char*)logo_image->data, logo_image->size);
- return 1;
-}
-
-/*
- * 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/main/php_network.h b/main/php_network.h
index dd28f161aa..d69bba308a 100644
--- a/main/php_network.h
+++ b/main/php_network.h
@@ -21,6 +21,8 @@
#ifndef _PHP_NETWORK_H
#define _PHP_NETWORK_H
+#include <php.h>
+
#ifdef PHP_WIN32
# include "win32/inet.h"
#else
diff --git a/main/php_open_temporary_file.c b/main/php_open_temporary_file.c
index 58a9c63da1..16b61b8ba7 100644
--- a/main/php_open_temporary_file.c
+++ b/main/php_open_temporary_file.c
@@ -189,13 +189,28 @@ PHPAPI void php_shutdown_temporary_directory(void)
/*
* Determine where to place temporary files.
*/
-PHPAPI const char* php_get_temporary_directory(void)
+PHPAPI const char* php_get_temporary_directory(TSRMLS_D)
{
/* Did we determine the temporary directory already? */
if (temporary_directory) {
return temporary_directory;
}
+ /* Is there a temporary directory "sys_temp_dir" in .ini defined? */
+ {
+ char *sys_temp_dir = PG(sys_temp_dir);
+ if (sys_temp_dir) {
+ int len = strlen(sys_temp_dir);
+ if (len >= 2 && sys_temp_dir[len - 1] == DEFAULT_SLASH) {
+ temporary_directory = zend_strndup(sys_temp_dir, len - 1);
+ return temporary_directory;
+ } else if (len >= 1 && sys_temp_dir[len - 1] != DEFAULT_SLASH) {
+ temporary_directory = zend_strndup(sys_temp_dir, len);
+ return temporary_directory;
+ }
+ }
+ }
+
#ifdef PHP_WIN32
/* We can't count on the environment variables TEMP or TMP,
* and so must make the Win32 API call to get the default
@@ -263,7 +278,7 @@ PHPAPI int php_open_temporary_fd_ex(const char *dir, const char *pfx, char **ope
if (!dir || *dir == '\0') {
def_tmp:
- temp_dir = php_get_temporary_directory();
+ temp_dir = php_get_temporary_directory(TSRMLS_C);
if (temp_dir && *temp_dir != '\0' && (!open_basedir_check || !php_check_open_basedir(temp_dir TSRMLS_CC))) {
return php_do_open_temporary_file(temp_dir, pfx, opened_path_p TSRMLS_CC);
@@ -294,12 +309,12 @@ PHPAPI FILE *php_open_temporary_file(const char *dir, const char *pfx, char **op
if (fd == -1) {
return NULL;
}
-
+
fp = fdopen(fd, "r+b");
if (fp == NULL) {
close(fd);
}
-
+
return fp;
}
/* }}} */
diff --git a/main/php_open_temporary_file.h b/main/php_open_temporary_file.h
index c07b2b2dfe..873bffcb0a 100644
--- a/main/php_open_temporary_file.h
+++ b/main/php_open_temporary_file.h
@@ -25,7 +25,7 @@ BEGIN_EXTERN_C()
PHPAPI FILE *php_open_temporary_file(const char *dir, const char *pfx, char **opened_path_p TSRMLS_DC);
PHPAPI int php_open_temporary_fd_ex(const char *dir, const char *pfx, char **opened_path_p, zend_bool open_basedir_check TSRMLS_DC);
PHPAPI int php_open_temporary_fd(const char *dir, const char *pfx, char **opened_path_p TSRMLS_DC);
-PHPAPI const char *php_get_temporary_directory(void);
+PHPAPI const char *php_get_temporary_directory(TSRMLS_D);
PHPAPI void php_shutdown_temporary_directory(void);
END_EXTERN_C()
diff --git a/main/php_streams.h b/main/php_streams.h
index f3c9879144..b0ecff07ad 100644
--- a/main/php_streams.h
+++ b/main/php_streams.h
@@ -162,10 +162,6 @@ struct _php_stream_wrapper {
php_stream_wrapper_ops *wops; /* operations the wrapper can perform */
void *abstract; /* context for the wrapper */
int is_url; /* so that PG(allow_url_fopen) can be respected */
-
- /* support for wrappers to return (multiple) error messages to the stream opener */
- int err_count; /* unused */
- char **err_stack; /* unusued */
};
#define PHP_STREAM_FLAG_NO_SEEK 1
diff --git a/main/php_variables.c b/main/php_variables.c
index e9ec0789bc..ddd9408bb7 100644
--- a/main/php_variables.c
+++ b/main/php_variables.c
@@ -27,7 +27,6 @@
#include "php_globals.h"
#include "php_content_types.h"
#include "SAPI.h"
-#include "php_logos.h"
#include "zend_globals.h"
/* for systems that need to override reading of environment variables */
@@ -532,22 +531,6 @@ static void php_build_argv(char *s, zval *track_vars_array TSRMLS_DC)
}
/* }}} */
-/* {{{ php_handle_special_queries
- */
-PHPAPI int php_handle_special_queries(TSRMLS_D)
-{
- if (PG(expose_php) && SG(request_info).query_string && SG(request_info).query_string[0] == '=') {
- if (php_info_logos(SG(request_info).query_string + 1 TSRMLS_CC)) {
- return 1;
- } else if (!strcmp(SG(request_info).query_string + 1, PHP_CREDITS_GUID)) {
- php_print_credits(PHP_CREDITS_ALL TSRMLS_CC);
- return 1;
- }
- }
- return 0;
-}
-/* }}} */
-
/* {{{ php_register_server_variables
*/
static inline void php_register_server_variables(TSRMLS_D)
diff --git a/main/php_version.h b/main/php_version.h
index 213cd5386d..784ef62e41 100644
--- a/main/php_version.h
+++ b/main/php_version.h
@@ -1,8 +1,8 @@
/* automatically generated by configure */
/* edit configure.in to change version number */
#define PHP_MAJOR_VERSION 5
-#define PHP_MINOR_VERSION 4
-#define PHP_RELEASE_VERSION 25
+#define PHP_MINOR_VERSION 5
+#define PHP_RELEASE_VERSION 9
#define PHP_EXTRA_VERSION "-dev"
-#define PHP_VERSION "5.4.25-dev"
-#define PHP_VERSION_ID 50425
+#define PHP_VERSION "5.5.9-dev"
+#define PHP_VERSION_ID 50509
diff --git a/main/rfc1867.c b/main/rfc1867.c
index fab199b543..ab1eb75e7d 100644
--- a/main/rfc1867.c
+++ b/main/rfc1867.c
@@ -408,7 +408,7 @@ static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header T
/* get lines of text, or CRLF_CRLF */
- while( (line = get_line(self TSRMLS_CC)) && strlen(line) > 0 )
+ while( (line = get_line(self TSRMLS_CC)) && line[0] != '\0' )
{
/* add header to table */
char *key = line;
@@ -979,7 +979,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */
continue;
}
- if (strlen(filename) == 0) {
+ if (filename[0] == '\0') {
#if DEBUG_FILE_UPLOAD
sapi_module.sapi_error(E_NOTICE, "No file uploaded");
#endif
@@ -1063,12 +1063,12 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */
if (!cancel_upload && !end) {
#if DEBUG_FILE_UPLOAD
- sapi_module.sapi_error(E_NOTICE, "Missing mime boundary at the end of the data for file %s", strlen(filename) > 0 ? filename : "");
+ sapi_module.sapi_error(E_NOTICE, "Missing mime boundary at the end of the data for file %s", filename[0] != '\0' ? filename : "");
#endif
cancel_upload = UPLOAD_ERROR_C;
}
#if DEBUG_FILE_UPLOAD
- if (strlen(filename) > 0 && total_bytes == 0 && !cancel_upload) {
+ if (filename[0] != '\0' && total_bytes == 0 && !cancel_upload) {
sapi_module.sapi_error(E_WARNING, "Uploaded file size 0 - file [%s=%s] not saved", param, filename);
cancel_upload = 5;
}
diff --git a/main/streams/php_stream_context.h b/main/streams/php_stream_context.h
index ea40e5172e..58b298b689 100644
--- a/main/streams/php_stream_context.h
+++ b/main/streams/php_stream_context.h
@@ -53,7 +53,6 @@ struct _php_stream_notifier {
struct _php_stream_context {
php_stream_notifier *notifier;
zval *options; /* hash keyed by wrapper family or specific wrapper */
- zval *links; /* hash keyed by hostent for connection pooling */
int rsrc_id; /* used for auto-cleanup */
};
@@ -65,13 +64,6 @@ PHPAPI int php_stream_context_get_option(php_stream_context *context,
PHPAPI int php_stream_context_set_option(php_stream_context *context,
const char *wrappername, const char *optionname, zval *optionvalue);
-PHPAPI int php_stream_context_get_link(php_stream_context *context,
- const char *hostent, php_stream **stream);
-PHPAPI int php_stream_context_set_link(php_stream_context *context,
- const char *hostent, php_stream *stream);
-PHPAPI int php_stream_context_del_link(php_stream_context *context,
- php_stream *stream);
-
PHPAPI php_stream_notifier *php_stream_notification_alloc(void);
PHPAPI void php_stream_notification_free(php_stream_notifier *notifier);
END_EXTERN_C()
diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c
index e689eda9f6..a50662b78e 100644
--- a/main/streams/plain_wrapper.c
+++ b/main/streams/plain_wrapper.c
@@ -115,7 +115,7 @@ typedef struct {
unsigned is_pipe:1; /* don't try and seek */
unsigned cached_fstat:1; /* sb is valid */
unsigned _reserved:29;
-
+
int lock_flag; /* stores the lock state */
char *temp_file_name; /* if non-null, this is the path to a temporary file that
* is to be deleted when the stream is closed */
@@ -141,7 +141,7 @@ static int do_fstat(php_stdio_stream_data *d, int force)
if (!d->cached_fstat || force) {
int fd;
int r;
-
+
PHP_STDIOP_GET_FD(fd, d);
r = fstat(fd, &d->sb);
d->cached_fstat = r == 0;
@@ -154,7 +154,7 @@ static int do_fstat(php_stdio_stream_data *d, int force)
static php_stream *_php_stream_fopen_from_fd_int(int fd, const char *mode, const char *persistent_id STREAMS_DC TSRMLS_DC)
{
php_stdio_stream_data *self;
-
+
self = pemalloc_rel_orig(sizeof(*self), persistent_id);
memset(self, 0, sizeof(*self));
self->file = NULL;
@@ -163,14 +163,14 @@ static php_stream *_php_stream_fopen_from_fd_int(int fd, const char *mode, const
self->is_process_pipe = 0;
self->temp_file_name = NULL;
self->fd = fd;
-
+
return php_stream_alloc_rel(&php_stream_stdio_ops, self, persistent_id, mode);
}
static php_stream *_php_stream_fopen_from_file_int(FILE *file, const char *mode STREAMS_DC TSRMLS_DC)
{
php_stdio_stream_data *self;
-
+
self = emalloc_rel_orig(sizeof(*self));
memset(self, 0, sizeof(*self));
self->file = file;
@@ -215,7 +215,7 @@ PHPAPI php_stream *_php_stream_fopen_tmpfile(int dummy STREAMS_DC TSRMLS_DC)
self->temp_file_name = opened_path;
self->lock_flag = LOCK_UN;
-
+
return stream;
}
close(fd);
@@ -248,7 +248,7 @@ PHPAPI php_stream *_php_stream_fopen_from_fd(int fd, const char *mode, const cha
}
}
#endif
-
+
if (self->is_pipe) {
stream->flags |= PHP_STREAM_FLAG_NO_SEEK;
} else {
@@ -287,7 +287,7 @@ PHPAPI php_stream *_php_stream_fopen_from_file(FILE *file, const char *mode STRE
}
}
#endif
-
+
if (self->is_pipe) {
stream->flags |= PHP_STREAM_FLAG_NO_SEEK;
} else {
@@ -356,9 +356,9 @@ static size_t php_stdiop_read(php_stream *stream, char *buf, size_t count TSRMLS
so script can retry if desired */
ret = read(data->fd, buf, count);
}
-
+
stream->eof = (ret == 0 || (ret == (size_t)-1 && errno != EWOULDBLOCK && errno != EINTR && errno != EBADF));
-
+
} else {
#if HAVE_FLUSHIO
if (!data->is_pipe && data->last_op == 'w')
@@ -395,7 +395,7 @@ static int php_stdiop_close(php_stream *stream, int close_handle TSRMLS_DC)
data->file_mapping = NULL;
}
#endif
-
+
if (close_handle) {
if (data->file) {
if (data->is_process_pipe) {
@@ -465,14 +465,14 @@ static int php_stdiop_seek(php_stream *stream, off_t offset, int whence, off_t *
if (data->fd >= 0) {
off_t result;
-
+
result = lseek(data->fd, offset, whence);
if (result == (off_t)-1)
return -1;
*newoffset = result;
return 0;
-
+
} else {
ret = fseek(data->file, offset, whence);
*newoffset = ftell(data->file);
@@ -486,7 +486,7 @@ static int php_stdiop_cast(php_stream *stream, int castas, void **ret TSRMLS_DC)
php_stdio_stream_data *data = (php_stdio_stream_data*) stream->abstract;
assert(data != NULL);
-
+
/* as soon as someone touches the stdio layer, buffering may ensue,
* so we need to stop using the fd directly in that case */
@@ -504,7 +504,7 @@ static int php_stdiop_cast(php_stream *stream, int castas, void **ret TSRMLS_DC)
return FAILURE;
}
}
-
+
*(FILE**)ret = data->file;
data->fd = -1;
}
@@ -560,9 +560,9 @@ static int php_stdiop_set_option(php_stream *stream, int option, int value, void
int flags;
int oldval;
#endif
-
+
PHP_STDIOP_GET_FD(fd, data);
-
+
switch(option) {
case PHP_STREAM_OPTION_BLOCKING:
if (fd == -1)
@@ -574,20 +574,20 @@ static int php_stdiop_set_option(php_stream *stream, int option, int value, void
flags &= ~O_NONBLOCK;
else
flags |= O_NONBLOCK;
-
+
if (-1 == fcntl(fd, F_SETFL, flags))
return -1;
return oldval;
#else
return -1; /* not yet implemented */
#endif
-
+
case PHP_STREAM_OPTION_WRITE_BUFFER:
if (data->file == NULL) {
return -1;
}
-
+
if (ptrparam)
size = *(size_t *)ptrparam;
else
@@ -596,10 +596,10 @@ static int php_stdiop_set_option(php_stream *stream, int option, int value, void
switch(value) {
case PHP_STREAM_BUFFER_NONE:
return setvbuf(data->file, NULL, _IONBF, 0);
-
+
case PHP_STREAM_BUFFER_LINE:
return setvbuf(data->file, NULL, _IOLBF, size);
-
+
case PHP_STREAM_BUFFER_FULL:
return setvbuf(data->file, NULL, _IOFBF, size);
@@ -607,7 +607,7 @@ static int php_stdiop_set_option(php_stream *stream, int option, int value, void
return -1;
}
break;
-
+
case PHP_STREAM_OPTION_LOCKING:
if (fd == -1) {
return -1;
@@ -630,7 +630,7 @@ static int php_stdiop_set_option(php_stream *stream, int option, int value, void
{
php_stream_mmap_range *range = (php_stream_mmap_range*)ptrparam;
int prot, flags;
-
+
switch (value) {
case PHP_STREAM_MMAP_SUPPORTED:
return fd == -1 ? PHP_STREAM_OPTION_RETURN_ERR : PHP_STREAM_OPTION_RETURN_OK;
@@ -795,7 +795,7 @@ static int php_stdiop_set_option(php_stream *stream, int option, int value, void
return ftruncate(fd, new_size) == 0 ? PHP_STREAM_OPTION_RETURN_OK : PHP_STREAM_OPTION_RETURN_ERR;
}
}
-
+
default:
return PHP_STREAM_OPTION_RETURN_NOTIMPL;
}
@@ -868,7 +868,7 @@ static php_stream *php_plain_files_dir_opener(php_stream_wrapper *wrapper, char
if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && php_check_open_basedir(path TSRMLS_CC)) {
return NULL;
}
-
+
dir = VCWD_OPENDIR(path);
#ifdef PHP_WIN32
@@ -886,7 +886,7 @@ static php_stream *php_plain_files_dir_opener(php_stream_wrapper *wrapper, char
if (stream == NULL)
closedir(dir);
}
-
+
return stream;
}
/* }}} */
@@ -934,7 +934,7 @@ PHPAPI php_stream *_php_stream_fopen(const char *filename, const char *mode, cha
return ret;
}
}
-
+
fd = open(realpath, open_flags, 0666);
if (fd != -1) {
@@ -1003,9 +1003,12 @@ static php_stream *php_plain_files_stream_opener(php_stream_wrapper *wrapper, ch
static int php_plain_files_url_stater(php_stream_wrapper *wrapper, char *url, int flags, php_stream_statbuf *ssb, php_stream_context *context TSRMLS_DC)
{
+ char *p;
- if (strncmp(url, "file://", sizeof("file://") - 1) == 0) {
- url += sizeof("file://") - 1;
+ if ((p = strstr(url, "://")) != NULL) {
+ if (p < strchr(url, '/')) {
+ url = p + 3;
+ }
}
if (php_check_open_basedir_ex(url, (flags & PHP_STREAM_URL_STAT_QUIET) ? 0 : 1 TSRMLS_CC)) {
@@ -1034,7 +1037,9 @@ static int php_plain_files_unlink(php_stream_wrapper *wrapper, char *url, int op
int ret;
if ((p = strstr(url, "://")) != NULL) {
- url = p + 3;
+ if (p < strchr(url, '/')) {
+ url = p + 3;
+ }
}
if (php_check_open_basedir(url TSRMLS_CC)) {
@@ -1076,11 +1081,15 @@ static int php_plain_files_rename(php_stream_wrapper *wrapper, char *url_from, c
#endif
if ((p = strstr(url_from, "://")) != NULL) {
- url_from = p + 3;
+ if (p < strchr(url_from, '/')) {
+ url_from = p + 3;
+ }
}
if ((p = strstr(url_to, "://")) != NULL) {
- url_to = p + 3;
+ if (p < strchr(url_to, '/')) {
+ url_to = p + 3;
+ }
}
if (php_check_open_basedir(url_from TSRMLS_CC) || php_check_open_basedir(url_to TSRMLS_CC)) {
@@ -1146,7 +1155,9 @@ static int php_plain_files_mkdir(php_stream_wrapper *wrapper, char *dir, int mod
char *p;
if ((p = strstr(dir, "://")) != NULL) {
- dir = p + 3;
+ if (p < strchr(dir, '/')) {
+ dir = p + 3;
+ }
}
if (!recursive) {
@@ -1171,7 +1182,7 @@ static int php_plain_files_mkdir(php_stream_wrapper *wrapper, char *dir, int mod
}
if (p && dir_len == 1) {
- /* buf == "DEFAULT_SLASH" */
+ /* buf == "DEFAULT_SLASH" */
}
else {
/* find a top level directory we need to create */
@@ -1275,7 +1286,9 @@ static int php_plain_files_metadata(php_stream_wrapper *wrapper, char *url, int
#endif
if ((p = strstr(url, "://")) != NULL) {
- url = p + 3;
+ if (p < strchr(url, '/')) {
+ url = p + 3;
+ }
}
if (php_check_open_basedir(url TSRMLS_CC)) {
@@ -1411,7 +1424,7 @@ not_relative_path:
return php_stream_fopen_rel(filename, mode, opened_path, options);
}
-
+
#ifdef PHP_WIN32
if (IS_SLASH(filename[0])) {
size_t cwd_len;
@@ -1419,17 +1432,17 @@ not_relative_path:
cwd = virtual_getcwd_ex(&cwd_len TSRMLS_CC);
/* getcwd() will return always return [DRIVE_LETTER]:/) on windows. */
*(cwd+3) = '\0';
-
+
if (snprintf(trypath, MAXPATHLEN, "%s%s", cwd, filename) >= MAXPATHLEN) {
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "%s/%s path was truncated to %d", cwd, filename, MAXPATHLEN);
}
-
+
free(cwd);
-
+
if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && php_check_open_basedir(trypath TSRMLS_CC)) {
return NULL;
}
-
+
return php_stream_fopen_rel(trypath, mode, opened_path, options);
}
#endif
@@ -1481,7 +1494,7 @@ not_relative_path:
if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && php_check_open_basedir_ex(trypath, 0 TSRMLS_CC)) {
goto stream_skip;
}
-
+
stream = php_stream_fopen_rel(trypath, mode, opened_path, options);
if (stream) {
efree(pathbuf);
diff --git a/main/streams/streams.c b/main/streams/streams.c
index cac50ef03f..c17570bbeb 100644
--- a/main/streams/streams.c
+++ b/main/streams/streams.c
@@ -470,11 +470,6 @@ fprintf(stderr, "stream_free: %s:%p[%s] preserve_handle=%d release_cast=%d remov
while (zend_list_delete(stream->rsrc_id) == SUCCESS) {}
}
- /* Remove stream from any context link list */
- if (context && context->links) {
- php_stream_context_del_link(context, stream);
- }
-
if (close_options & PHP_STREAM_FREE_CALL_DTOR) {
if (release_cast && stream->fclose_stdiocast == PHP_STREAM_FCLOSE_FOPENCOOKIE) {
/* calling fclose on an fopencookied stream will ultimately
@@ -2187,10 +2182,6 @@ PHPAPI void php_stream_context_free(php_stream_context *context)
php_stream_notification_free(context->notifier);
context->notifier = NULL;
}
- if (context->links) {
- zval_ptr_dtor(&context->links);
- context->links = NULL;
- }
efree(context);
}
@@ -2253,66 +2244,6 @@ PHPAPI int php_stream_context_set_option(php_stream_context *context,
}
return zend_hash_update(Z_ARRVAL_PP(wrapperhash), (char*)optionname, strlen(optionname)+1, (void**)&copied_val, sizeof(zval *), NULL);
}
-
-PHPAPI int php_stream_context_get_link(php_stream_context *context,
- const char *hostent, php_stream **stream)
-{
- php_stream **pstream;
-
- if (!stream || !hostent || !context || !(context->links)) {
- return FAILURE;
- }
- if (SUCCESS == zend_hash_find(Z_ARRVAL_P(context->links), (char*)hostent, strlen(hostent)+1, (void**)&pstream)) {
- *stream = *pstream;
- return SUCCESS;
- }
- return FAILURE;
-}
-
-PHPAPI int php_stream_context_set_link(php_stream_context *context,
- const char *hostent, php_stream *stream)
-{
- if (!context) {
- return FAILURE;
- }
- if (!context->links) {
- ALLOC_INIT_ZVAL(context->links);
- array_init(context->links);
- }
- if (!stream) {
- /* Delete any entry for <hostent> */
- return zend_hash_del(Z_ARRVAL_P(context->links), (char*)hostent, strlen(hostent)+1);
- }
- return zend_hash_update(Z_ARRVAL_P(context->links), (char*)hostent, strlen(hostent)+1, (void**)&stream, sizeof(php_stream *), NULL);
-}
-
-PHPAPI int php_stream_context_del_link(php_stream_context *context,
- php_stream *stream)
-{
- php_stream **pstream;
- char *hostent;
- int ret = SUCCESS;
-
- if (!context || !context->links || !stream) {
- return FAILURE;
- }
-
- for(zend_hash_internal_pointer_reset(Z_ARRVAL_P(context->links));
- SUCCESS == zend_hash_get_current_data(Z_ARRVAL_P(context->links), (void**)&pstream);
- zend_hash_move_forward(Z_ARRVAL_P(context->links))) {
- if (*pstream == stream) {
- if (SUCCESS == zend_hash_get_current_key(Z_ARRVAL_P(context->links), &hostent, NULL, 0)) {
- if (FAILURE == zend_hash_del(Z_ARRVAL_P(context->links), (char*)hostent, strlen(hostent)+1)) {
- ret = FAILURE;
- }
- } else {
- ret = FAILURE;
- }
- }
- }
-
- return ret;
-}
/* }}} */
/* {{{ php_stream_dirent_alphasort
diff --git a/main/streams/xp_socket.c b/main/streams/xp_socket.c
index 2c7ca8d414..5bbbd78fac 100644
--- a/main/streams/xp_socket.c
+++ b/main/streams/xp_socket.c
@@ -426,7 +426,7 @@ static int php_sockop_cast(php_stream *stream, int castas, void **ret TSRMLS_DC)
case PHP_STREAM_AS_FD:
case PHP_STREAM_AS_SOCKETD:
if (ret)
- *(int*)ret = sock->socket;
+ *(php_socket_t *)ret = sock->socket;
return SUCCESS;
default:
return FAILURE;
diff --git a/main/win32_internal_function_disabled.h b/main/win32_internal_function_disabled.h
index fb96231109..7365262772 100644
--- a/main/win32_internal_function_disabled.h
+++ b/main/win32_internal_function_disabled.h
@@ -23,12 +23,14 @@
/*
Windows Server 2008 6.0
Windows Vista 6.0
+
+Verssions below are not supported anymore, php won't even load:
Windows Server 2003 R2 5.2
Windows Server 2003 5.2
Windows XP 5.1
Windows 2000 5.0
*/
-static const char *function_name_5[] = {"link", NULL};
-const int function_name_cnt_5 = 1;
+static const char *function_name_5[] = {NULL};
+const int function_name_cnt_5 = 0;
static const char *function_name_6[] = {"readlink", "symlink", NULL};
const int function_name_cnt_6 = 2;
diff --git a/makedist b/makedist
index bfc8fcc44a..f5823d3925 100755
--- a/makedist
+++ b/makedist
@@ -35,7 +35,10 @@ if test "${1}" = "1" -a "${2}" -lt "28"; then
fi
IFS="$old_IFS"
-PHPROOT=git@git.php.net:php-src.git
+if test "$PHPROOTx" == "x"; then
+ PHPROOT=git@git.php.net:php-src.git;
+fi
+
LT_TARGETS='ltconfig ltmain.sh config.guess config.sub'
if echo '\c' | grep -s c >/dev/null 2>&1
@@ -119,8 +122,14 @@ tar cf $ARCHIVE php-$VER || exit 10
bzip2 -9 $ARCHIVE || exit 11
echo ""
+$ECHO_N "makedist: making xz2zipped tar archive...$ECHO_C"
+rm -f $ARCHIVE.xz
+tar cf $ARCHIVE php-$VER || exit 10
+xz -9 $ARCHIVE || exit 12
+echo ""
+
$ECHO_N "makedist: cleaning up...$ECHO_C"
-rm -rf $DIRPATH || exit 12
+rm -rf $DIRPATH || exit 13
echo ""
exit 0
diff --git a/php.ini-development b/php.ini-development
index b935f22eb5..2ef47a40a2 100644
--- a/php.ini-development
+++ b/php.ini-development
@@ -730,6 +730,10 @@ user_dir =
; On windows:
; extension_dir = "ext"
+; Directory where the temporary files should be placed.
+; Defaults to the system default (see sys_get_temp_dir)
+; sys_temp_dir = "/tmp"
+
; Whether or not to enable the dl() function. The dl() function does NOT work
; properly in multithreaded servers, such as IIS or Zeus, and is automatically
; disabled on them.
@@ -1395,6 +1399,14 @@ session.save_handler = files
; http://php.net/session.save-path
;session.save_path = "/tmp"
+; Whether to use strict session mode.
+; Strict session mode does not accept uninitialized session ID and regenerate
+; session ID if browser sends uninitialized session ID. Strict mode protects
+; applications from session fixation via session adoption vulnerability. It is
+; disabled by default for maximum compatibility, but enabling it is encouraged.
+; https://wiki.php.net/rfc/strict_sessions
+session.use_strict_mode = 0
+
; Whether to use cookies.
; http://php.net/session.use-cookies
session.use_cookies = 1
@@ -1636,7 +1648,7 @@ mssql.min_error_severity = 10
mssql.min_message_severity = 10
; Compatibility mode with old versions of PHP 3.0.
-mssql.compatability_mode = Off
+mssql.compatibility_mode = Off
; Connect timeout
;mssql.connect_timeout = 5
@@ -1727,16 +1739,16 @@ mssql.secure_connection = Off
; Some encoding cannot work as internal encoding.
; (e.g. SJIS, BIG5, ISO-2022-*)
; http://php.net/mbstring.internal-encoding
-;mbstring.internal_encoding = EUC-JP
+;mbstring.internal_encoding = UTF-8
; http input encoding.
; http://php.net/mbstring.http-input
-;mbstring.http_input = auto
+;mbstring.http_input = UTF-8
; http output encoding. mb_output_handler must be
; registered as output buffer to function
; http://php.net/mbstring.http-output
-;mbstring.http_output = SJIS
+;mbstring.http_output = pass
; enable automatic encoding translation according to
; mbstring.internal_encoding setting. Input chars are
@@ -1754,7 +1766,7 @@ mssql.secure_connection = Off
; substitute_character used when character cannot be converted
; one from another
; http://php.net/mbstring.substitute-character
-;mbstring.substitute_character = none;
+;mbstring.substitute_character = none
; overload(replace) single byte functions by mbstring functions.
; mail(), ereg(), etc are overloaded by mb_send_mail(), mb_ereg(),
@@ -1768,7 +1780,7 @@ mssql.secure_connection = Off
;mbstring.func_overload = 0
; enable strict encoding detection.
-;mbstring.strict_detection = Off
+;mbstring.strict_detection = On
; This directive specifies the regex pattern of content types for which mb_output_handler()
; is activated.
@@ -1856,6 +1868,102 @@ ldap.max_links = -1
[dba]
;dba.default_handler=
+[opcache]
+; Determines if Zend OPCache is enabled
+;opcache.enable=0
+
+; Determines if Zend OPCache is enabled for the CLI version of PHP
+;opcache.enable_cli=0
+
+; The OPcache shared memory storage size.
+;opcache.memory_consumption=64
+
+; The amount of memory for interned strings in Mbytes.
+;opcache.interned_strings_buffer=4
+
+; The maximum number of keys (scripts) in the OPcache hash table.
+; Only numbers between 200 and 100000 are allowed.
+;opcache.max_accelerated_files=2000
+
+; The maximum percentage of "wasted" memory until a restart is scheduled.
+;opcache.max_wasted_percentage=5
+
+; When this directive is enabled, the OPcache appends the current working
+; directory to the script key, thus eliminating possible collisions between
+; files with the same name (basename). Disabling the directive improves
+; performance, but may break existing applications.
+;opcache.use_cwd=1
+
+; When disabled, you must reset the OPcache manually or restart the
+; webserver for changes to the filesystem to take effect.
+;opcache.validate_timestamps=1
+
+; How often (in seconds) to check file timestamps for changes to the shared
+; memory storage allocation. ("1" means validate once per second, but only
+; once per request. "0" means always validate)
+;opcache.revalidate_freq=2
+
+; Enables or disables file search in include_path optimization
+;opcache.revalidate_path=0
+
+; If disabled, all PHPDoc comments are dropped from the code to reduce the
+; size of the optimized code.
+;opcache.save_comments=1
+
+; If disabled, PHPDoc comments are not loaded from SHM, so "Doc Comments"
+; may be always stored (save_comments=1), but not loaded by applications
+; that don't need them anyway.
+;opcache.load_comments=1
+
+; If enabled, a fast shutdown sequence is used for the accelerated code
+;opcache.fast_shutdown=0
+
+; Allow file existence override (file_exists, etc.) performance feature.
+;opcache.enable_file_override=0
+
+; A bitmask, where each bit enables or disables the appropriate OPcache
+; passes
+;opcache.optimization_level=0xffffffff
+
+;opcache.inherited_hack=1
+;opcache.dups_fix=0
+
+; The location of the OPcache blacklist file (wildcards allowed).
+; Each OPcache blacklist file is a text file that holds the names of files
+; that should not be accelerated. The file format is to add each filename
+; to a new line. The filename may be a full path or just a file prefix
+; (i.e., /var/www/x blacklists all the files and directories in /var/www
+; that start with 'x'). Line starting with a ; are ignored (comments).
+;opcache.blacklist_filename=
+
+; Allows exclusion of large files from being cached. By default all files
+; are cached.
+;opcache.max_file_size=0
+
+; Check the cache checksum each N requests.
+; The default value of "0" means that the checks are disabled.
+;opcache.consistency_checks=0
+
+; How long to wait (in seconds) for a scheduled restart to begin if the cache
+; is not being accessed.
+;opcache.force_restart_timeout=180
+
+; OPcache error_log file name. Empty string assumes "stderr".
+;opcache.error_log=
+
+; All OPcache errors go to the Web server log.
+; By default, only fatal errors (level 0) or errors (level 1) are logged.
+; You can also enable warnings (level 2), info messages (level 3) or
+; debug messages (level 4).
+;opcache.log_verbosity_level=1
+
+; Preferred Shared Memory back-end. Leave empty and let the system decide.
+;opcache.preferred_memory_model=
+
+; Protect the shared memory from unexpected writing during script execution.
+; Useful for internal debugging only.
+;opcache.protect_memory=0
+
[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
diff --git a/php.ini-production b/php.ini-production
index 4ee7ac92ce..c39de742db 100644
--- a/php.ini-production
+++ b/php.ini-production
@@ -730,6 +730,10 @@ user_dir =
; On windows:
; extension_dir = "ext"
+; Directory where the temporary files should be placed.
+; Defaults to the system default (see sys_get_temp_dir)
+; sys_temp_dir = "/tmp"
+
; Whether or not to enable the dl() function. The dl() function does NOT work
; properly in multithreaded servers, such as IIS or Zeus, and is automatically
; disabled on them.
@@ -1395,6 +1399,14 @@ session.save_handler = files
; http://php.net/session.save-path
;session.save_path = "/tmp"
+; Whether to use strict session mode.
+; Strict session mode does not accept uninitialized session ID and regenerate
+; session ID if browser sends uninitialized session ID. Strict mode protects
+; applications from session fixation via session adoption vulnerability. It is
+; disabled by default for maximum compatibility, but enabling it is encouraged.
+; https://wiki.php.net/rfc/strict_sessions
+session.use_strict_mode = 0
+
; Whether to use cookies.
; http://php.net/session.use-cookies
session.use_cookies = 1
@@ -1636,7 +1648,7 @@ mssql.min_error_severity = 10
mssql.min_message_severity = 10
; Compatibility mode with old versions of PHP 3.0.
-mssql.compatability_mode = Off
+mssql.compatibility_mode = Off
; Connect timeout
;mssql.connect_timeout = 5
@@ -1727,16 +1739,16 @@ mssql.secure_connection = Off
; Some encoding cannot work as internal encoding.
; (e.g. SJIS, BIG5, ISO-2022-*)
; http://php.net/mbstring.internal-encoding
-;mbstring.internal_encoding = EUC-JP
+;mbstring.internal_encoding = UTF-8
; http input encoding.
; http://php.net/mbstring.http-input
-;mbstring.http_input = auto
+;mbstring.http_input = UTF-8
; http output encoding. mb_output_handler must be
; registered as output buffer to function
; http://php.net/mbstring.http-output
-;mbstring.http_output = SJIS
+;mbstring.http_output = pass
; enable automatic encoding translation according to
; mbstring.internal_encoding setting. Input chars are
@@ -1754,7 +1766,7 @@ mssql.secure_connection = Off
; substitute_character used when character cannot be converted
; one from another
; http://php.net/mbstring.substitute-character
-;mbstring.substitute_character = none;
+;mbstring.substitute_character = none
; overload(replace) single byte functions by mbstring functions.
; mail(), ereg(), etc are overloaded by mb_send_mail(), mb_ereg(),
@@ -1768,7 +1780,7 @@ mssql.secure_connection = Off
;mbstring.func_overload = 0
; enable strict encoding detection.
-;mbstring.strict_detection = Off
+;mbstring.strict_detection = On
; This directive specifies the regex pattern of content types for which mb_output_handler()
; is activated.
@@ -1856,6 +1868,102 @@ ldap.max_links = -1
[dba]
;dba.default_handler=
+[opcache]
+; Determines if Zend OPCache is enabled
+;opcache.enable=0
+
+; Determines if Zend OPCache is enabled for the CLI version of PHP
+;opcache.enable_cli=0
+
+; The OPcache shared memory storage size.
+;opcache.memory_consumption=64
+
+; The amount of memory for interned strings in Mbytes.
+;opcache.interned_strings_buffer=4
+
+; The maximum number of keys (scripts) in the OPcache hash table.
+; Only numbers between 200 and 100000 are allowed.
+;opcache.max_accelerated_files=2000
+
+; The maximum percentage of "wasted" memory until a restart is scheduled.
+;opcache.max_wasted_percentage=5
+
+; When this directive is enabled, the OPcache appends the current working
+; directory to the script key, thus eliminating possible collisions between
+; files with the same name (basename). Disabling the directive improves
+; performance, but may break existing applications.
+;opcache.use_cwd=1
+
+; When disabled, you must reset the OPcache manually or restart the
+; webserver for changes to the filesystem to take effect.
+;opcache.validate_timestamps=1
+
+; How often (in seconds) to check file timestamps for changes to the shared
+; memory storage allocation. ("1" means validate once per second, but only
+; once per request. "0" means always validate)
+;opcache.revalidate_freq=2
+
+; Enables or disables file search in include_path optimization
+;opcache.revalidate_path=0
+
+; If disabled, all PHPDoc comments are dropped from the code to reduce the
+; size of the optimized code.
+;opcache.save_comments=1
+
+; If disabled, PHPDoc comments are not loaded from SHM, so "Doc Comments"
+; may be always stored (save_comments=1), but not loaded by applications
+; that don't need them anyway.
+;opcache.load_comments=1
+
+; If enabled, a fast shutdown sequence is used for the accelerated code
+;opcache.fast_shutdown=0
+
+; Allow file existence override (file_exists, etc.) performance feature.
+;opcache.enable_file_override=0
+
+; A bitmask, where each bit enables or disables the appropriate OPcache
+; passes
+;opcache.optimization_level=0xffffffff
+
+;opcache.inherited_hack=1
+;opcache.dups_fix=0
+
+; The location of the OPcache blacklist file (wildcards allowed).
+; Each OPcache blacklist file is a text file that holds the names of files
+; that should not be accelerated. The file format is to add each filename
+; to a new line. The filename may be a full path or just a file prefix
+; (i.e., /var/www/x blacklists all the files and directories in /var/www
+; that start with 'x'). Line starting with a ; are ignored (comments).
+;opcache.blacklist_filename=
+
+; Allows exclusion of large files from being cached. By default all files
+; are cached.
+;opcache.max_file_size=0
+
+; Check the cache checksum each N requests.
+; The default value of "0" means that the checks are disabled.
+;opcache.consistency_checks=0
+
+; How long to wait (in seconds) for a scheduled restart to begin if the cache
+; is not being accessed.
+;opcache.force_restart_timeout=180
+
+; OPcache error_log file name. Empty string assumes "stderr".
+;opcache.error_log=
+
+; All OPcache errors go to the Web server log.
+; By default, only fatal errors (level 0) or errors (level 1) are logged.
+; You can also enable warnings (level 2), info messages (level 3) or
+; debug messages (level 4).
+;opcache.log_verbosity_level=1
+
+; Preferred Shared Memory back-end. Leave empty and let the system decide.
+;opcache.preferred_memory_model=
+
+; Protect the shared memory from unexpected writing during script execution.
+; Useful for internal debugging only.
+;opcache.protect_memory=0
+
[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
diff --git a/run-tests.php b/run-tests.php
index 25e480728f..d53c3b6c5e 100755
--- a/run-tests.php
+++ b/run-tests.php
@@ -240,6 +240,8 @@ $ini_overwrites = array(
'ignore_repeated_errors=0',
'precision=14',
'memory_limit=128M',
+ 'opcache.fast_shutdown=0',
+ 'opcache.file_update_protection=0',
);
function write_information($show_html)
@@ -311,6 +313,7 @@ VALGRIND : " . ($leak_check ? $valgrind_header : 'Not used') . "
define('PHP_QA_EMAIL', 'qa-reports@lists.php.net');
define('QA_SUBMISSION_PAGE', 'http://qa.php.net/buildtest-process.php');
define('QA_REPORTS_PAGE', 'http://qa.php.net/reports');
+define('TRAVIS_CI' , (bool) getenv('TRAVIS_PHP_VERSION'));
function save_or_mail_results()
{
@@ -318,7 +321,7 @@ function save_or_mail_results()
$PHP_FAILED_TESTS, $CUR_DIR, $php, $output_file, $compression;
/* We got failed Tests, offer the user to send an e-mail to QA team, unless NO_INTERACTION is set */
- if (!getenv('NO_INTERACTION')) {
+ if (!getenv('NO_INTERACTION') && !TRAVIS_CI) {
$fp = fopen("php://stdin", "r+");
if ($sum_results['FAILED'] || $sum_results['BORKED'] || $sum_results['WARNED'] || $sum_results['LEAKED'] || $sum_results['XFAILED']) {
echo "\nYou may have found a problem in PHP.";
@@ -335,8 +338,8 @@ function save_or_mail_results()
$just_save_results = (strtolower($user_input[0]) == 's');
}
- if ($just_save_results || !getenv('NO_INTERACTION')) {
- if ($just_save_results || strlen(trim($user_input)) == 0 || strtolower($user_input[0]) == 'y') {
+ if ($just_save_results || !getenv('NO_INTERACTION') || TRAVIS_CI) {
+ if ($just_save_results || TRAVIS_CI || strlen(trim($user_input)) == 0 || strtolower($user_input[0]) == 'y') {
/*
* Collect information about the host system for our report
* Fetch phpinfo() output so that we can see the PHP enviroment
@@ -348,7 +351,9 @@ function save_or_mail_results()
}
/* Ask the user to provide an email address, so that QA team can contact the user */
- if (!strncasecmp($user_input, 'y', 1) || strlen(trim($user_input)) == 0) {
+ if (TRAVIS_CI) {
+ $user_email = 'travis at php dot net';
+ } elseif (!strncasecmp($user_input, 'y', 1) || strlen(trim($user_input)) == 0) {
echo "\nPlease enter your email address.\n(Your address will be mangled so that it will not go out on any\nmailinglist in plain text): ";
flush();
$user_email = trim(fgets($fp, 1024));
@@ -424,7 +429,7 @@ function save_or_mail_results()
$failed_tests_data .= $sep . "PHPINFO" . $sep;
$failed_tests_data .= shell_exec($php . ' -ddisplay_errors=stderr -dhtml_errors=0 -i 2> /dev/null');
- if ($just_save_results || !mail_qa_team($failed_tests_data, $compression, $status)) {
+ if ($just_save_results || !mail_qa_team($failed_tests_data, $compression, $status) && !TRAVIS_CI) {
file_put_contents($output_file, $failed_tests_data);
if (!$just_save_results) {
@@ -432,7 +437,7 @@ function save_or_mail_results()
}
echo "Please send " . $output_file . " to " . PHP_QA_EMAIL . " manually, thank you.\n";
- } else {
+ } elseif (!getenv('NO_INTERACTION') && !TRAVIS_CI) {
fwrite($fp, "\nThank you for helping to make PHP better.\n");
fclose($fp);
}
@@ -810,14 +815,12 @@ HELP;
fclose($failed_tests_file);
}
- if (count($test_files) || count($test_results)) {
- compute_summary();
- if ($html_output) {
- fwrite($html_file, "<hr/>\n" . get_summary(false, true));
- }
- echo "=====================================================================";
- echo get_summary(false, false);
+ compute_summary();
+ if ($html_output) {
+ fwrite($html_file, "<hr/>\n" . get_summary(false, true));
}
+ echo "=====================================================================";
+ echo get_summary(false, false);
if ($html_output) {
fclose($html_file);
@@ -829,7 +832,7 @@ HELP;
junit_save_xml();
- if (getenv('REPORT_EXIT_STATUS') == 1 and preg_match('/FAILED(?: |$)/', implode(' ', $test_results))) {
+ if (getenv('REPORT_EXIT_STATUS') == 1 and $sum_results['FAILED']) {
exit(1);
}
diff --git a/sapi/apache/config.m4 b/sapi/apache/config.m4
index 1961289de0..7b0ee562eb 100644
--- a/sapi/apache/config.m4
+++ b/sapi/apache/config.m4
@@ -20,7 +20,7 @@ fi
dnl Apache 1.x shared module
PHP_ARG_WITH(apxs,,
-[ --with-apxs[=FILE] Build shared Apache 1.x module. FILE is the optional
+[ --with-apxs[=FILE] Build shared Apache 1.x module. FILE is the optional
pathname to the Apache apxs tool [apxs]], no, no)
AC_MSG_CHECKING([for Apache 1.x module support via DSO through APXS])
@@ -123,7 +123,7 @@ fi
dnl Apache 1.x static module
PHP_ARG_WITH(apache,,
-[ --with-apache[=DIR] Build Apache 1.x module. DIR is the top-level Apache
+[ --with-apache[=DIR] Build Apache 1.x module. DIR is the top-level Apache
build directory [/usr/local/apache]], no, no)
AC_MSG_CHECKING([for Apache 1.x module support])
@@ -237,7 +237,7 @@ if test -z "$enable_mod_charset" && test "$with_mod_charset"; then
fi
PHP_ARG_ENABLE(mod-charset, whether to enable Apache charset compatibility option,
-[ --enable-mod-charset APACHE: Enable transfer tables for mod_charset (Rus Apache)], no, no)
+[ --enable-mod-charset APACHE: Enable transfer tables for mod_charset (Rus Apache)], no, no)
if test "$PHP_MOD_CHARSET" = "yes"; then
AC_DEFINE(USE_TRANSFER_TABLES, 1, [ ])
diff --git a/sapi/apache2handler/config.m4 b/sapi/apache2handler/config.m4
index 753de10ba8..02f8a0b3ad 100644
--- a/sapi/apache2handler/config.m4
+++ b/sapi/apache2handler/config.m4
@@ -3,7 +3,7 @@ dnl $Id$
dnl
PHP_ARG_WITH(apxs2,,
-[ --with-apxs2[=FILE] Build shared Apache 2.0 Handler module. FILE is the optional
+[ --with-apxs2[=FILE] Build shared Apache 2.0 Handler module. FILE is the optional
pathname to the Apache apxs tool [apxs]], no, no)
AC_MSG_CHECKING([for Apache 2.0 handler-module support via DSO through APXS])
diff --git a/sapi/apache_hooks/config.m4 b/sapi/apache_hooks/config.m4
index 672f298084..e2c71b4274 100644
--- a/sapi/apache_hooks/config.m4
+++ b/sapi/apache_hooks/config.m4
@@ -239,7 +239,7 @@ if test -z "$enable_mod_charset" && test "$with_mod_charset"; then
fi
PHP_ARG_ENABLE(mod-charset, whether to enable Apache charset compatibility option,
-[ --enable-mod-charset APACHE (hooks): Enable transfer tables for mod_charset (Rus Apache)], no, no)
+[ --enable-mod-charset APACHE (hooks): Enable transfer tables for mod_charset (Rus Apache)], no, no)
if test "$PHP_MOD_CHARSET" = "yes"; then
AC_DEFINE(USE_TRANSFER_TABLES, 1, [ ])
diff --git a/sapi/caudium/config.m4 b/sapi/caudium/config.m4
index 8aba33e23d..5ce55f3f01 100644
--- a/sapi/caudium/config.m4
+++ b/sapi/caudium/config.m4
@@ -4,7 +4,7 @@ dnl
RESULT=no
PHP_ARG_WITH(caudium,,
-[ --with-caudium[=DIR] Build PHP as a Pike module for use with Caudium.
+[ --with-caudium[=DIR] Build PHP as a Pike module for use with Caudium.
DIR is the Caudium server dir [/usr/local/caudium/server]], no, no)
AC_MSG_CHECKING([for Caudium support])
diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c
index b8ff878fe4..b1e12f7324 100644
--- a/sapi/cgi/cgi_main.c
+++ b/sapi/cgi/cgi_main.c
@@ -884,7 +884,6 @@ static int sapi_cgi_activate(TSRMLS_D)
} else {
doc_root = getenv("DOCUMENT_ROOT");
}
-
/* DOCUMENT_ROOT should also be defined at this stage..but better check it anyway */
if (doc_root) {
doc_root_len = strlen(doc_root);
@@ -1689,8 +1688,8 @@ static void add_response_header(sapi_header_struct *h, zval *return_value TSRMLS
PHP_FUNCTION(apache_response_headers) /* {{{ */
{
- if (ZEND_NUM_ARGS() > 0) {
- WRONG_PARAM_COUNT;
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
}
if (!&SG(sapi_headers).headers) {
@@ -1956,7 +1955,11 @@ consult the installation file that came with this distribution, or visit \n\
}
if (bindpath) {
- fcgi_fd = fcgi_listen(bindpath, 128);
+ int backlog = 128;
+ if (getenv("PHP_FCGI_BACKLOG")) {
+ backlog = atoi(getenv("PHP_FCGI_BACKLOG"));
+ }
+ fcgi_fd = fcgi_listen(bindpath, backlog);
if (fcgi_fd < 0) {
fprintf(stderr, "Couldn't create FastCGI listen socket on port %s\n", bindpath);
#ifdef ZTS
diff --git a/sapi/cli/config.m4 b/sapi/cli/config.m4
index cdfa1f7daf..9a1b98da46 100644
--- a/sapi/cli/config.m4
+++ b/sapi/cli/config.m4
@@ -6,6 +6,23 @@ PHP_ARG_ENABLE(cli,,
[ --disable-cli Disable building CLI version of PHP
(this forces --without-pear)], yes, no)
+AC_CHECK_FUNCS(setproctitle)
+
+AC_CHECK_HEADERS([sys/pstat.h])
+
+AC_CACHE_CHECK([for PS_STRINGS], [cli_cv_var_PS_STRINGS],
+[AC_TRY_LINK(
+[#include <machine/vmparam.h>
+#include <sys/exec.h>
+],
+[PS_STRINGS->ps_nargvstr = 1;
+PS_STRINGS->ps_argvstr = "foo";],
+[cli_cv_var_PS_STRINGS=yes],
+[cli_cv_var_PS_STRINGS=no])])
+if test "$cli_cv_var_PS_STRINGS" = yes ; then
+ AC_DEFINE([HAVE_PS_STRINGS], [], [Define to 1 if the PS_STRINGS thing exists.])
+fi
+
AC_MSG_CHECKING(for CLI build)
if test "$PHP_CLI" != "no"; then
PHP_ADD_MAKEFILE_FRAGMENT($abs_srcdir/sapi/cli/Makefile.frag)
@@ -14,7 +31,7 @@ if test "$PHP_CLI" != "no"; then
SAPI_CLI_PATH=sapi/cli/php
dnl Select SAPI
- PHP_SELECT_SAPI(cli, program, php_cli.c php_http_parser.c php_cli_server.c,, '$(SAPI_CLI_PATH)')
+ PHP_SELECT_SAPI(cli, program, php_cli.c php_http_parser.c php_cli_server.c ps_title.c php_cli_process_title.c,, '$(SAPI_CLI_PATH)')
case $host_alias in
*aix*)
diff --git a/sapi/cli/config.w32 b/sapi/cli/config.w32
index 4d0dad58e8..adcbb2b496 100644
--- a/sapi/cli/config.w32
+++ b/sapi/cli/config.w32
@@ -6,7 +6,7 @@ ARG_ENABLE('crt-debug', 'Enable CRT memory dumps for debugging sent to STDERR',
ARG_ENABLE('cli-win32', 'Build console-less CLI version of PHP', 'no');
if (PHP_CLI == "yes") {
- SAPI('cli', 'php_cli.c php_http_parser.c php_cli_server.c', 'php.exe');
+ SAPI('cli', 'php_cli.c php_http_parser.c php_cli_server.c php_cli_process_title.c ps_title.c', 'php.exe');
ADD_FLAG("LIBS_CLI", "ws2_32.lib");
if (PHP_CRT_DEBUG == "yes") {
ADD_FLAG("CFLAGS_CLI", "/D PHP_WIN32_DEBUG_HEAP");
@@ -15,7 +15,7 @@ if (PHP_CLI == "yes") {
}
if (PHP_CLI_WIN32 == "yes") {
- SAPI('cli_win32', 'cli_win32.c', 'php-win.exe');
+ SAPI('cli_win32', 'cli_win32.c php_cli_process_title.c ps_title.c', 'php-win.exe');
ADD_FLAG("LDFLAGS_CLI_WIN32", "/stack:8388608");
}
diff --git a/sapi/cli/php_cli.c b/sapi/cli/php_cli.c
index 07371ee8e3..9daa382eec 100644
--- a/sapi/cli/php_cli.c
+++ b/sapi/cli/php_cli.c
@@ -86,6 +86,9 @@
#include "php_cli_server.h"
#endif
+#include "ps_title.h"
+#include "php_cli_process_title.h"
+
#ifndef PHP_WIN32
# define php_select(m, r, w, e, t) select(m, r, w, e, t)
#else
@@ -478,6 +481,8 @@ ZEND_END_ARG_INFO()
static const zend_function_entry additional_functions[] = {
ZEND_FE(dl, arginfo_dl)
+ PHP_FE(cli_set_process_title, arginfo_cli_set_process_title)
+ PHP_FE(cli_get_process_title, arginfo_cli_get_process_title)
{NULL, NULL, NULL}
};
@@ -1201,6 +1206,7 @@ int main(int argc, char *argv[])
int argc = __argc;
char **argv = __argv;
#endif
+
int c;
int exit_status = SUCCESS;
int module_started = 0, sapi_started = 0;
@@ -1212,6 +1218,12 @@ int main(int argc, char *argv[])
int ini_ignore = 0;
sapi_module_struct *sapi_module = &cli_sapi_module;
+ /*
+ * Do not move this initialization. It needs to happen before argv is used
+ * in any way.
+ */
+ argv = save_ps_args(argc, argv);
+
cli_sapi_module.additional_functions = additional_functions;
#if defined(PHP_WIN32) && defined(_DEBUG) && defined(PHP_WIN32_DEBUG_HEAP)
@@ -1300,6 +1312,7 @@ int main(int argc, char *argv[])
#ifndef PHP_CLI_WIN32_NO_CONSOLE
case 'S':
sapi_module = &cli_server_sapi_module;
+ cli_server_sapi_module.additional_functions = server_additional_functions;
break;
#endif
case 'h': /* help & quit */
@@ -1386,6 +1399,11 @@ out:
tsrm_shutdown();
#endif
+ /*
+ * Do not move this de-initialization. It needs to happen right before
+ * exiting.
+ */
+ cleanup_ps_args(argv);
exit(exit_status);
}
/* }}} */
diff --git a/sapi/cli/php_cli_process_title.c b/sapi/cli/php_cli_process_title.c
new file mode 100644
index 0000000000..dec5613670
--- /dev/null
+++ b/sapi/cli/php_cli_process_title.c
@@ -0,0 +1,80 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2014 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: Keyur Govande (kgovande@gmail.com) |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_cli_process_title.h"
+#include "ps_title.h"
+
+/* {{{ proto boolean cli_set_process_title(string arg)
+ Return a boolean to confirm if the process title was successfully changed or not */
+PHP_FUNCTION(cli_set_process_title)
+{
+ char *title = NULL;
+ int title_len;
+ int rc;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &title, &title_len) == FAILURE) {
+ return;
+ }
+
+ rc = set_ps_title(title);
+ if (rc == PS_TITLE_SUCCESS) {
+ RETURN_TRUE;
+ }
+
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "cli_set_process_title had an error: %s", ps_title_errno(rc));
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto string cli_get_process_title()
+ Return a string with the current process title. NULL if error. */
+PHP_FUNCTION(cli_get_process_title)
+{
+ int length = 0;
+ const char* title = NULL;
+ int rc;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ rc = get_ps_title(&length, &title);
+ if (rc != PS_TITLE_SUCCESS) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "cli_get_process_title had an error: %s", ps_title_errno(rc));
+ RETURN_NULL();
+ }
+
+ RETURN_STRINGL(title, length, 1);
+}
+/* }}} */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/main/php_logos.h b/sapi/cli/php_cli_process_title.h
index 94b1938f99..bd44d99111 100644
--- a/main/php_logos.h
+++ b/sapi/cli/php_cli_process_title.h
@@ -12,23 +12,32 @@
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
- | Author: |
+ | Author: Keyur Govande (kgovande@gmail.com) |
+----------------------------------------------------------------------+
*/
/* $Id$ */
+#ifndef PHP_PS_TITLE_HEADER
+#define PHP_PS_TITLE_HEADER
-#ifndef _PHP_LOGOS_H
-#define _PHP_LOGOS_H
+ZEND_BEGIN_ARG_INFO(arginfo_cli_set_process_title, 0)
+ ZEND_ARG_INFO(0, title)
+ZEND_END_ARG_INFO()
-BEGIN_EXTERN_C()
-PHPAPI int php_register_info_logo(char *logo_string, const char *mimetype, const unsigned char *data, int size);
-PHPAPI int php_unregister_info_logo(char *logo_string);
-END_EXTERN_C()
+ZEND_BEGIN_ARG_INFO(arginfo_cli_get_process_title, 0)
+ZEND_END_ARG_INFO()
-int php_init_info_logos(void);
-int php_shutdown_info_logos(void);
-int php_info_logos(const char *logo_string TSRMLS_DC);
+PHP_FUNCTION(cli_set_process_title);
+PHP_FUNCTION(cli_get_process_title);
-#endif /* _PHP_LOGOS_H */
+#endif
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */
diff --git a/sapi/cli/php_cli_server.c b/sapi/cli/php_cli_server.c
index e838d30558..a993d65bc6 100644
--- a/sapi/cli/php_cli_server.c
+++ b/sapi/cli/php_cli_server.c
@@ -105,6 +105,8 @@
#include "php_http_parser.h"
#include "php_cli_server.h"
+#include "php_cli_process_title.h"
+
#define OUTPUT_NOT_CHECKED -1
#define OUTPUT_IS_TTY 1
#define OUTPUT_NOT_TTY 0
@@ -131,6 +133,7 @@ typedef struct php_cli_server_request {
char *query_string;
size_t query_string_len;
HashTable headers;
+ HashTable headers_original_case;
char *content;
size_t content_len;
const char *ext;
@@ -252,7 +255,7 @@ static php_cli_server_http_response_status_code_pair status_map[] = {
static php_cli_server_http_response_status_code_pair template_map[] = {
{ 400, "<h1>%s</h1><p>Your browser sent a request that this server could not understand.</p>" },
- { 404, "<h1>%s</h1><p>The requested resource %s was not found on this server.</p>" },
+ { 404, "<h1>%s</h1><p>The requested resource <code class=\"url\">%s</code> was not found on this server.</p>" },
{ 500, "<h1>%s</h1><p>The server is temporarily unavailable.</p>" },
{ 501, "<h1>%s</h1><p>Request method not supported.</p>" }
};
@@ -266,12 +269,49 @@ static php_cli_server_ext_mime_type_pair mime_type_map[] = {
{ "jpg", "image/jpeg" },
{ "jpeg", "image/jpeg" },
{ "jpe", "image/jpeg" },
+ { "pdf", "application/pdf" },
{ "png", "image/png" },
{ "svg", "image/svg+xml" },
{ "txt", "text/plain" },
{ "webm", "video/webm" },
{ "ogv", "video/ogg" },
{ "ogg", "audio/ogg" },
+ { "3gp", "video/3gpp" }, /* This is standard video format used for MMS in phones */
+ { "apk", "application/vnd.android.package-archive" },
+ { "avi", "video/x-msvideo" },
+ { "bmp", "image/x-ms-bmp" },
+ { "csv", "text/comma-separated-values" },
+ { "doc", "application/msword" },
+ { "docx", "application/msword" },
+ { "flac", "audio/flac" },
+ { "gz", "application/x-gzip" },
+ { "gzip", "application/x-gzip" },
+ { "ics", "text/calendar" },
+ { "kml", "application/vnd.google-earth.kml+xml" },
+ { "kmz", "application/vnd.google-earth.kmz" },
+ { "m4a", "audio/mp4" },
+ { "mp3", "audio/mpeg" },
+ { "mp4", "video/mp4" },
+ { "mpg", "video/mpeg" },
+ { "mpeg", "video/mpeg" },
+ { "mov", "video/quicktime" },
+ { "odp", "application/vnd.oasis.opendocument.presentation" },
+ { "ods", "application/vnd.oasis.opendocument.spreadsheet" },
+ { "odt", "application/vnd.oasis.opendocument.text" },
+ { "oga", "audio/ogg" },
+ { "pdf", "application/pdf" },
+ { "pptx", "application/vnd.ms-powerpoint" },
+ { "pps", "application/vnd.ms-powerpoint" },
+ { "qt", "video/quicktime" },
+ { "swf", "application/x-shockwave-flash" },
+ { "tar", "application/x-tar" },
+ { "text", "text/plain" },
+ { "tif", "image/tiff" },
+ { "wav", "audio/wav" },
+ { "wmv", "video/x-ms-wmv" },
+ { "xls", "application/vnd.ms-excel" },
+ { "xlsx", "application/vnd.ms-excel" },
+ { "zip", "application/x-zip-compressed" },
{ NULL, NULL }
};
@@ -289,8 +329,10 @@ ZEND_DECLARE_MODULE_GLOBALS(cli_server);
* copied from ext/standard/info.c
*/
static const char php_cli_server_css[] = "<style>\n" \
- "body { background-color: #ffffff; color: #000000; }\n" \
- "h1 { font-family: sans-serif; font-size: 150%; background-color: #9999cc; font-weight: bold; color: #000000; margin-top: 0;}\n" \
+ "body { background-color: #fcfcfc; color: #333333; margin: 0; padding:0; }\n" \
+ "h1 { font-size: 1.5em; font-weight: normal; background-color: #9999cc; min-height:2em; line-height:2em; border-bottom: 1px inset black; margin: 0; }\n" \
+ "h1, p { padding-left: 10px; }\n" \
+ "code.url { background-color: #eeeeee; font-family:monospace; padding:0 2px;}\n" \
"</style>\n";
/* }}} */
@@ -430,6 +472,75 @@ static const char *get_mime_type(const char *ext, size_t ext_len) /* {{{ */
return NULL;
} /* }}} */
+PHP_FUNCTION(apache_request_headers) /* {{{ */
+{
+ php_cli_server_client *client;
+ HashTable *headers;
+ char *key;
+ uint key_len;
+ char **value_pointer;
+ HashPosition pos;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ client = SG(server_context);
+ headers = &client->request.headers_original_case;
+
+ array_init_size(return_value, zend_hash_num_elements(headers));
+
+ zend_hash_internal_pointer_reset_ex(headers, &pos);
+ while (zend_hash_get_current_data_ex(headers, (void **)&value_pointer, &pos) == SUCCESS) {
+ zend_hash_get_current_key_ex(headers, &key, &key_len, NULL, 0, &pos);
+ add_assoc_string_ex(return_value, key, key_len, *value_pointer, 1);
+ zend_hash_move_forward_ex(headers, &pos);
+ }
+}
+/* }}} */
+
+static void add_response_header(sapi_header_struct *h, zval *return_value TSRMLS_DC) /* {{{ */
+{
+ char *s, *p;
+ int len;
+ ALLOCA_FLAG(use_heap)
+
+ if (h->header_len > 0) {
+ p = strchr(h->header, ':');
+ len = p - h->header;
+ if (p && (len > 0)) {
+ while (len > 0 && (h->header[len-1] == ' ' || h->header[len-1] == '\t')) {
+ len--;
+ }
+ if (len) {
+ s = do_alloca(len + 1, use_heap);
+ memcpy(s, h->header, len);
+ s[len] = 0;
+ do {
+ p++;
+ } while (*p == ' ' || *p == '\t');
+ add_assoc_stringl_ex(return_value, s, len+1, p, h->header_len - (p - h->header), 1);
+ free_alloca(s, use_heap);
+ }
+ }
+ }
+}
+/* }}} */
+
+PHP_FUNCTION(apache_response_headers) /* {{{ */
+{
+ if (zend_parse_parameters_none() == FAILURE) {
+ return;
+ }
+
+ if (!&SG(sapi_headers).headers) {
+ RETURN_FALSE;
+ }
+ array_init(return_value);
+ zend_llist_apply_with_argument(&SG(sapi_headers).headers, (llist_apply_with_arg_func_t)add_response_header, return_value TSRMLS_CC);
+}
+/* }}} */
+
/* {{{ cli_server module
*/
@@ -474,6 +585,18 @@ zend_module_entry cli_server_module_entry = {
};
/* }}} */
+ZEND_BEGIN_ARG_INFO(arginfo_no_args, 0)
+ZEND_END_ARG_INFO()
+
+const zend_function_entry server_additional_functions[] = {
+ PHP_FE(cli_set_process_title, arginfo_cli_set_process_title)
+ PHP_FE(cli_get_process_title, arginfo_cli_get_process_title)
+ PHP_FE(apache_request_headers, arginfo_no_args)
+ PHP_FE(apache_response_headers, arginfo_no_args)
+ PHP_FALIAS(getallheaders, apache_request_headers, arginfo_no_args)
+ {NULL, NULL, NULL}
+};
+
static int sapi_cli_server_startup(sapi_module_struct *sapi_module) /* {{{ */
{
if (php_module_startup(sapi_module, &cli_server_module_entry, 1) == FAILURE) {
@@ -1289,6 +1412,7 @@ static int php_cli_server_request_ctor(php_cli_server_request *req) /* {{{ */
req->query_string = NULL;
req->query_string_len = 0;
zend_hash_init(&req->headers, 0, NULL, (void(*)(void*))char_ptr_dtor_p, 1);
+ zend_hash_init(&req->headers_original_case, 0, NULL, NULL, 1);
req->content = NULL;
req->content_len = 0;
req->ext = NULL;
@@ -1314,6 +1438,7 @@ static void php_cli_server_request_dtor(php_cli_server_request *req) /* {{{ */
pefree(req->query_string, 1);
}
zend_hash_destroy(&req->headers);
+ zend_hash_destroy(&req->headers_original_case);
if (req->content) {
pefree(req->content, 1);
}
@@ -1558,6 +1683,7 @@ static int php_cli_server_client_read_request_on_header_value(php_http_parser *p
{
char *header_name = zend_str_tolower_dup(client->current_header_name, client->current_header_name_len);
zend_hash_add(&client->request.headers, header_name, client->current_header_name_len + 1, &value, sizeof(char *), NULL);
+ zend_hash_add(&client->request.headers_original_case, client->current_header_name, client->current_header_name_len + 1, &value, sizeof(char *), NULL);
efree(header_name);
}
@@ -1983,40 +2109,38 @@ static int php_cli_server_request_shutdown(php_cli_server *server, php_cli_serve
static int php_cli_server_dispatch_router(php_cli_server *server, php_cli_server_client *client TSRMLS_DC) /* {{{ */
{
int decline = 0;
- if (!php_handle_special_queries(TSRMLS_C)) {
- zend_file_handle zfd;
- char *old_cwd;
-
- ALLOCA_FLAG(use_heap)
- old_cwd = do_alloca(MAXPATHLEN, use_heap);
- old_cwd[0] = '\0';
- php_ignore_value(VCWD_GETCWD(old_cwd, MAXPATHLEN - 1));
-
- zfd.type = ZEND_HANDLE_FILENAME;
- zfd.filename = server->router;
- zfd.handle.fp = NULL;
- zfd.free_filename = 0;
- zfd.opened_path = NULL;
-
- zend_try {
- zval *retval = NULL;
- if (SUCCESS == zend_execute_scripts(ZEND_REQUIRE TSRMLS_CC, &retval, 1, &zfd)) {
- if (retval) {
- decline = Z_TYPE_P(retval) == IS_BOOL && !Z_LVAL_P(retval);
- zval_ptr_dtor(&retval);
- }
- } else {
- decline = 1;
+ zend_file_handle zfd;
+ char *old_cwd;
+
+ ALLOCA_FLAG(use_heap)
+ old_cwd = do_alloca(MAXPATHLEN, use_heap);
+ old_cwd[0] = '\0';
+ php_ignore_value(VCWD_GETCWD(old_cwd, MAXPATHLEN - 1));
+
+ zfd.type = ZEND_HANDLE_FILENAME;
+ zfd.filename = server->router;
+ zfd.handle.fp = NULL;
+ zfd.free_filename = 0;
+ zfd.opened_path = NULL;
+
+ zend_try {
+ zval *retval = NULL;
+ if (SUCCESS == zend_execute_scripts(ZEND_REQUIRE TSRMLS_CC, &retval, 1, &zfd)) {
+ if (retval) {
+ decline = Z_TYPE_P(retval) == IS_BOOL && !Z_LVAL_P(retval);
+ zval_ptr_dtor(&retval);
}
- } zend_end_try();
-
- if (old_cwd[0] != '\0') {
- php_ignore_value(VCWD_CHDIR(old_cwd));
+ } else {
+ decline = 1;
}
+ } zend_end_try();
- free_alloca(old_cwd, use_heap);
+ if (old_cwd[0] != '\0') {
+ php_ignore_value(VCWD_CHDIR(old_cwd));
}
+ free_alloca(old_cwd, use_heap);
+
return decline;
}
/* }}} */
diff --git a/sapi/cli/php_cli_server.h b/sapi/cli/php_cli_server.h
index f8dff05d02..a8d7f46e7c 100644
--- a/sapi/cli/php_cli_server.h
+++ b/sapi/cli/php_cli_server.h
@@ -23,6 +23,7 @@
#include "SAPI.h"
+extern const zend_function_entry server_additional_functions[];
extern sapi_module_struct cli_server_sapi_module;
extern int do_cli_server(int argc, char **argv TSRMLS_DC);
diff --git a/sapi/cli/ps_title.c b/sapi/cli/ps_title.c
new file mode 100644
index 0000000000..53cd5fc9a0
--- /dev/null
+++ b/sapi/cli/ps_title.c
@@ -0,0 +1,437 @@
+/*
+ * PostgreSQL is released under the PostgreSQL License, a liberal Open Source
+ * license, similar to the BSD or MIT licenses.
+ * PostgreSQL Database Management System (formerly known as Postgres, then as
+ * Postgres95)
+ *
+ * Portions Copyright (c) 1996-2014, The PostgreSQL Global Development Group
+ *
+ * Portions Copyright (c) 1994, The Regents of the University of California
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without a written
+ * agreement is hereby granted, provided that the above copyright notice
+ * and this paragraph and the following two paragraphs appear in all copies.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
+ * LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
+ * EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
+ * "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * The following code is adopted from the PostgreSQL's ps_status(.h/.c).
+ */
+
+#include "ps_title.h"
+#include <stdio.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef PHP_WIN32
+#include "config.w32.h"
+#include <windows.h>
+#include <process.h>
+#else
+#include "php_config.h"
+extern char** environ;
+#endif
+
+#ifdef HAVE_SYS_PSTAT_H
+#include <sys/pstat.h> /* for HP-UX */
+#endif
+#ifdef HAVE_PS_STRINGS
+#include <machine/vmparam.h> /* for old BSD */
+#include <sys/exec.h>
+#endif
+#if defined(DARWIN)
+#include <crt_externs.h>
+#endif
+
+/*
+ * Ways of updating ps display:
+ *
+ * PS_USE_SETPROCTITLE
+ * use the function setproctitle(const char *, ...)
+ * (newer BSD systems)
+ * PS_USE_PSTAT
+ * use the pstat(PSTAT_SETCMD, )
+ * (HPUX)
+ * PS_USE_PS_STRINGS
+ * assign PS_STRINGS->ps_argvstr = "string"
+ * (some BSD systems)
+ * PS_USE_CHANGE_ARGV
+ * assign argv[0] = "string"
+ * (some other BSD systems)
+ * PS_USE_CLOBBER_ARGV
+ * write over the argv and environment area
+ * (Linux and most SysV-like systems)
+ * PS_USE_WIN32
+ * push the string out as the name of a Windows event
+ * PS_USE_NONE
+ * don't update ps display
+ * (This is the default, as it is safest.)
+ */
+#if defined(HAVE_SETPROCTITLE)
+#define PS_USE_SETPROCTITLE
+#elif defined(HAVE_SYS_PSTAT_H) && defined(PSTAT_SETCMD)
+#define PS_USE_PSTAT
+#elif defined(HAVE_PS_STRINGS)
+#define PS_USE_PS_STRINGS
+#elif defined(BSD) && !defined(DARWIN)
+#define PS_USE_CHANGE_ARGV
+#elif defined(__linux__) || defined(_AIX) || defined(__sgi) || (defined(sun) && !defined(BSD)) || defined(ultrix) || defined(__osf__) || defined(DARWIN)
+#define PS_USE_CLOBBER_ARGV
+#elif defined(PHP_WIN32)
+#define PS_USE_WIN32
+#else
+#define PS_USE_NONE
+#endif
+
+/* Different systems want the buffer padded differently */
+#if defined(_AIX) || defined(__linux__) || defined(DARWIN)
+#define PS_PADDING '\0'
+#else
+#define PS_PADDING ' '
+#endif
+
+#ifdef PS_USE_WIN32
+static char windows_error_details[64];
+static char ps_buffer[MAX_PATH];
+static const size_t ps_buffer_size = MAX_PATH;
+#elif defined(PS_USE_CLOBBER_ARGV)
+static char *ps_buffer; /* will point to argv area */
+static size_t ps_buffer_size; /* space determined at run time */
+static char *empty_environ[] = {0}; /* empty environment */
+#else
+#define PS_BUFFER_SIZE 256
+static char ps_buffer[PS_BUFFER_SIZE];
+static const size_t ps_buffer_size = PS_BUFFER_SIZE;
+#endif
+
+static size_t ps_buffer_cur_len; /* actual string length in ps_buffer */
+
+/* save the original argv[] location here */
+static int save_argc;
+static char** save_argv;
+
+/*
+ * This holds the 'locally' allocated environ from the save_ps_args method.
+ * This is subsequently free'd at exit.
+ */
+static char** frozen_environ, **new_environ;
+
+/*
+ * Call this method early, before any code has used the original argv passed in
+ * from main().
+ * If needed, this code will make deep copies of argv and environ and return
+ * these to the caller for further use. The original argv is then 'clobbered'
+ * to store the process title.
+ */
+char** save_ps_args(int argc, char** argv)
+{
+ save_argc = argc;
+ save_argv = argv;
+
+#if defined(PS_USE_CLOBBER_ARGV)
+ /*
+ * If we're going to overwrite the argv area, count the available space.
+ * Also move the environment to make additional room.
+ */
+ {
+ char* end_of_area = NULL;
+ int non_contiguous_area = 0;
+ int i;
+
+ /*
+ * check for contiguous argv strings
+ */
+ for (i = 0; (non_contiguous_area == 0) && (i < argc); i++)
+ {
+ if (i != 0 && end_of_area + 1 != argv[i])
+ non_contiguous_area = 1;
+ end_of_area = argv[i] + strlen(argv[i]);
+ }
+
+ /*
+ * check for contiguous environ strings following argv
+ */
+ for (i = 0; (non_contiguous_area == 0) && (environ[i] != NULL); i++)
+ {
+ if (end_of_area + 1 != environ[i])
+ non_contiguous_area = 1;
+ end_of_area = environ[i] + strlen(environ[i]);
+ }
+
+ if (non_contiguous_area != 0)
+ goto clobber_error;
+
+ ps_buffer = argv[0];
+ ps_buffer_size = end_of_area - argv[0];
+
+ /*
+ * move the environment out of the way
+ */
+ new_environ = (char **) malloc((i + 1) * sizeof(char *));
+ frozen_environ = (char **) malloc((i + 1) * sizeof(char *));
+ if (!new_environ || !frozen_environ)
+ goto clobber_error;
+ for (i = 0; environ[i] != NULL; i++)
+ {
+ new_environ[i] = strdup(environ[i]);
+ if (!new_environ[i])
+ goto clobber_error;
+ }
+ new_environ[i] = NULL;
+ environ = new_environ;
+ memcpy((char *)frozen_environ, (char *)new_environ, sizeof(char *) * (i + 1));
+
+ }
+#endif /* PS_USE_CLOBBER_ARGV */
+
+#if defined(PS_USE_CHANGE_ARGV) || defined(PS_USE_CLOBBER_ARGV)
+ /*
+ * If we're going to change the original argv[] then make a copy for
+ * argument parsing purposes.
+ *
+ * (NB: do NOT think to remove the copying of argv[]!
+ * On some platforms, getopt() keeps pointers into the argv array, and
+ * will get horribly confused when it is re-called to analyze a subprocess'
+ * argument string if the argv storage has been clobbered meanwhile.
+ * Other platforms have other dependencies on argv[].)
+ */
+ {
+ char** new_argv;
+ int i;
+
+ new_argv = (char **) malloc((argc + 1) * sizeof(char *));
+ if (!new_argv)
+ goto clobber_error;
+ for (i = 0; i < argc; i++)
+ {
+ new_argv[i] = strdup(argv[i]);
+ if (!new_argv[i])
+ goto clobber_error;
+ }
+ new_argv[argc] = NULL;
+
+#if defined(DARWIN)
+ /*
+ * Darwin (and perhaps other NeXT-derived platforms?) has a static
+ * copy of the argv pointer, which we may fix like so:
+ */
+ *_NSGetArgv() = new_argv;
+#endif
+
+ argv = new_argv;
+
+ }
+#endif /* PS_USE_CHANGE_ARGV or PS_USE_CLOBBER_ARGV */
+
+#if defined(PS_USE_CLOBBER_ARGV)
+ {
+ /* make extra argv slots point at end_of_area (a NUL) */
+ int i;
+ for (i = 1; i < save_argc; i++)
+ save_argv[i] = ps_buffer + ps_buffer_size;
+ }
+#endif /* PS_USE_CLOBBER_ARGV */
+
+#ifdef PS_USE_CHANGE_ARGV
+ save_argv[0] = ps_buffer; /* ps_buffer here is a static const array of size PS_BUFFER_SIZE */
+ save_argv[1] = NULL;
+#endif /* PS_USE_CHANGE_ARGV */
+
+ return argv;
+
+#if defined(PS_USE_CHANGE_ARGV) || defined(PS_USE_CLOBBER_ARGV)
+clobber_error:
+ /* probably can't happen?!
+ * if we ever get here, argv still points to originally passed
+ * in argument
+ */
+ save_argv = NULL;
+ save_argc = 0;
+ ps_buffer = NULL;
+ ps_buffer_size = 0;
+ return argv;
+#endif /* PS_USE_CHANGE_ARGV or PS_USE_CLOBBER_ARGV */
+}
+
+/*
+ * Returns PS_TITLE_SUCCESS if the OS supports this functionality
+ * and the init function was called.
+ * Otherwise returns NOT_AVAILABLE or NOT_INITIALIZED
+ */
+int is_ps_title_available()
+{
+#ifdef PS_USE_NONE
+ return PS_TITLE_NOT_AVAILABLE; /* disabled functionality */
+#endif
+
+ if (!save_argv)
+ return PS_TITLE_NOT_INITIALIZED;
+
+#ifdef PS_USE_CLOBBER_ARGV
+ if (!ps_buffer)
+ return PS_TITLE_BUFFER_NOT_AVAILABLE;
+#endif /* PS_USE_CLOBBER_ARGV */
+
+ return PS_TITLE_SUCCESS;
+}
+
+/*
+ * Convert error codes into error strings
+ */
+const char* ps_title_errno(int rc)
+{
+ switch(rc)
+ {
+ case PS_TITLE_SUCCESS:
+ return "Success";
+
+ case PS_TITLE_NOT_AVAILABLE:
+ return "Not available on this OS";
+
+ case PS_TITLE_NOT_INITIALIZED:
+ return "Not initialized correctly";
+
+ case PS_TITLE_BUFFER_NOT_AVAILABLE:
+ return "Buffer not contiguous";
+
+#ifdef PS_USE_WIN32
+ case PS_TITLE_WINDOWS_ERROR:
+ sprintf(windows_error_details, "Windows error code: %d", GetLastError());
+ return windows_error_details;
+#endif
+ }
+
+ return "Unknown error code";
+}
+
+/*
+ * Set a new process title.
+ * Returns the appropriate error code if if there's an error
+ * (like the functionality is compile time disabled, or the
+ * save_ps_args() was not called.
+ * Else returns 0 on success.
+ */
+int set_ps_title(const char* title)
+{
+ int rc = is_ps_title_available();
+ if (rc != PS_TITLE_SUCCESS)
+ return rc;
+
+ strncpy(ps_buffer, title, ps_buffer_size);
+ ps_buffer[ps_buffer_size - 1] = '\0';
+ ps_buffer_cur_len = strlen(ps_buffer);
+
+#ifdef PS_USE_SETPROCTITLE
+ setproctitle("%s", ps_buffer);
+#endif
+
+#ifdef PS_USE_PSTAT
+ {
+ union pstun pst;
+
+ pst.pst_command = ps_buffer;
+ pstat(PSTAT_SETCMD, pst, ps_buffer_cur_len, 0, 0);
+ }
+#endif /* PS_USE_PSTAT */
+
+#ifdef PS_USE_PS_STRINGS
+ PS_STRINGS->ps_nargvstr = 1;
+ PS_STRINGS->ps_argvstr = ps_buffer;
+#endif /* PS_USE_PS_STRINGS */
+
+#ifdef PS_USE_CLOBBER_ARGV
+ /* pad unused memory */
+ if (ps_buffer_cur_len < ps_buffer_size)
+ {
+ memset(ps_buffer + ps_buffer_cur_len, PS_PADDING,
+ ps_buffer_size - ps_buffer_cur_len);
+ }
+#endif /* PS_USE_CLOBBER_ARGV */
+
+#ifdef PS_USE_WIN32
+ {
+ if (!SetConsoleTitle(ps_buffer))
+ return PS_TITLE_WINDOWS_ERROR;
+ }
+#endif /* PS_USE_WIN32 */
+
+ return PS_TITLE_SUCCESS;
+}
+
+/*
+ * Returns the current ps_buffer value into string. On some platforms
+ * the string will not be null-terminated, so return the effective
+ * length into *displen.
+ * The return code indicates the error.
+ */
+int get_ps_title(int *displen, const char** string)
+{
+ int rc = is_ps_title_available();
+ if (rc != PS_TITLE_SUCCESS)
+ return rc;
+
+#ifdef PS_USE_WIN32
+ if (!(ps_buffer_cur_len = GetConsoleTitle(ps_buffer, ps_buffer_size)))
+ return PS_TITLE_WINDOWS_ERROR;
+#endif
+ *displen = (int)ps_buffer_cur_len;
+ *string = ps_buffer;
+ return PS_TITLE_SUCCESS;
+}
+
+/*
+ * Clean up the allocated argv and environ if applicable. Only call
+ * this right before exiting.
+ * This isn't needed per-se because the OS will clean-up anyway, but
+ * having and calling this will ensure Valgrind doesn't output 'false
+ * positives'.
+ */
+void cleanup_ps_args(char **argv)
+{
+#ifndef PS_USE_NONE
+ if (save_argv)
+ {
+ save_argv = NULL;
+ save_argc = 0;
+
+#ifdef PS_USE_CLOBBER_ARGV
+ {
+ int i;
+ for (i = 0; frozen_environ[i] != NULL; i++)
+ free(frozen_environ[i]);
+ free(frozen_environ);
+ free(new_environ);
+ /* leave a sane environment behind since some atexit() handlers
+ call getenv(). */
+ environ = empty_environ;
+ }
+#endif /* PS_USE_CLOBBER_ARGV */
+
+#if defined(PS_USE_CHANGE_ARGV) || defined(PS_USE_CLOBBER_ARGV)
+ {
+ int i;
+ for (i=0; argv[i] != NULL; i++)
+ free(argv[i]);
+ free(argv);
+ }
+#endif /* PS_USE_CHANGE_ARGV or PS_USE_CLOBBER_ARGV */
+ }
+#endif /* PS_USE_NONE */
+
+ return;
+}
diff --git a/sapi/cli/ps_title.h b/sapi/cli/ps_title.h
new file mode 100644
index 0000000000..09650fed08
--- /dev/null
+++ b/sapi/cli/ps_title.h
@@ -0,0 +1,42 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2014 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: Keyur Govande <kgovande@gmail.com> |
+ +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+#ifndef PS_TITLE_HEADER
+#define PS_TITLE_HEADER
+
+#define PS_TITLE_SUCCESS 0
+#define PS_TITLE_NOT_AVAILABLE 1
+#define PS_TITLE_NOT_INITIALIZED 2
+#define PS_TITLE_BUFFER_NOT_AVAILABLE 3
+#define PS_TITLE_WINDOWS_ERROR 4
+
+extern char** save_ps_args(int argc, char** argv);
+
+extern int set_ps_title(const char* new_str);
+
+extern int get_ps_title(int* displen, const char** string);
+
+extern const char* ps_title_errno(int rc);
+
+extern int is_ps_title_available();
+
+extern void cleanup_ps_args(char **argv);
+
+#endif // PS_TITLE_HEADER
diff --git a/sapi/cli/tests/bug64544.phpt b/sapi/cli/tests/bug64544.phpt
new file mode 100644
index 0000000000..cc49545c16
--- /dev/null
+++ b/sapi/cli/tests/bug64544.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Bug #64544 (Valgrind warnings after using putenv)
+--SKIPIF--
+<?php
+if (substr(PHP_OS, 0, 3) == "WIN") {
+ die("skip non windows test");
+}
+?>
+--FILE--
+<?php
+
+putenv("HOME=/tmp");
+var_dump(getenv("HOME"));
+
+putenv("FOO=BAR");
+var_dump(getenv("FOO"));
+?>
+--EXPECTF--
+string(4) "/tmp"
+string(3) "BAR"
diff --git a/sapi/cli/tests/cli_process_title_unix.phpt b/sapi/cli/tests/cli_process_title_unix.phpt
new file mode 100644
index 0000000000..c2632704c5
--- /dev/null
+++ b/sapi/cli/tests/cli_process_title_unix.phpt
@@ -0,0 +1,49 @@
+--TEST--
+Check cli_process_title support on Unix
+--SKIPIF--
+<?php
+if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN')
+ die("skip");
+?>
+--FILE--
+<?php
+echo "*** Testing setting the process title ***\n";
+
+$set_title = $original_title = uniqid("title", true);
+$pid = getmypid();
+
+if (cli_set_process_title($original_title) === true)
+ echo "Successfully set title\n";
+
+$ps_output = shell_exec("ps -p $pid -o command | tail -n 1");
+
+if ($ps_output === null)
+{
+ echo "ps failed\n";
+ die();
+}
+
+$loaded_title = trim($ps_output);
+if (strpos(strtoupper(substr(PHP_OS, 0, 13)), "BSD") !== false)
+{
+ // Fix up title for BSD
+ $set_title = "php: $original_title (php)";
+}
+
+if ($loaded_title == $set_title)
+ echo "Successfully verified title using ps\n";
+else
+ echo "Actually loaded from ps: $loaded_title\n";
+
+$read_title = cli_get_process_title();
+if ($read_title == $original_title)
+ echo "Successfully verified title using get\n";
+else
+ echo "Actually loaded from get: $read_title\n";
+
+?>
+--EXPECTF--
+*** Testing setting the process title ***
+Successfully set title
+Successfully verified title using ps
+Successfully verified title using get
diff --git a/sapi/cli/tests/cli_process_title_windows.phpt b/sapi/cli/tests/cli_process_title_windows.phpt
new file mode 100644
index 0000000000..472f9c10fe
--- /dev/null
+++ b/sapi/cli/tests/cli_process_title_windows.phpt
@@ -0,0 +1,83 @@
+--TEST--
+Check cli_process_title support in Windows
+--SKIPIF--
+<?php
+if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN')
+ die("skip");
+?>
+--FILE--
+<?php
+
+// On Windows 8 and Server 2012, this test does not work the same way. When the PowerShell
+// command "get-process" is executed using shell_exec, it overwrites the ConsoleTitle with
+// "Windows PowerShell" and this title ONLY clears away when the php.exe process exits
+// i.e. the test finishes.
+// On older versions like Windows 7 though, running the command appends
+// "Windows PowerShell" to the ConsoleTitle temporarily and the title reverts
+// back to the original once shell_exec is done.
+// Hence on Windows 8, we don't verify that the title is actually set by
+// cli_set_process_title(). We're only making the API calls to ensure there are
+// no warnings/errors.
+
+$is_windows8 = false;
+$ps_output = shell_exec("PowerShell -NoProfile \"(Get-Host).UI.RawUI.WindowTitle\"");
+if ($ps_output === null)
+{
+ echo "Get-Host failed\n";
+ die();
+}
+
+$ps_output = trim($ps_output);
+$end_title_windows8 = ": Windows PowerShell";
+if (($ps_output == "Windows PowerShell") || (strlen($ps_output) > strlen($end_title_windows8) && substr($ps_output,-strlen($end_title_windows8)) === $end_title_windows8))
+ $is_windows8 = true;
+
+echo "*** Testing setting the process title ***\n";
+
+$original_title = uniqid("title", true);
+$pid = getmypid();
+
+if (cli_set_process_title($original_title) === true)
+ echo "Successfully set title\n";
+
+if ($is_windows8)
+{
+ $loaded_title = $original_title;
+}
+else
+{
+ $loaded_title = shell_exec("PowerShell -NoProfile \"get-process cmd*,powershell* | Select-Object mainWindowTitle | ft -hide\"");
+
+ if ($loaded_title === null)
+ {
+ echo "Reading title using get-process failed\n";
+ die();
+ }
+
+ // Kind of convoluted. So when the test is run on Windows 7 or older, the console where
+ // the run-tests.php is executed forks a php.exe, which forks a cmd.exe, which then forks
+ // a final php.exe to run the actual test. But the console title is set for the original console.
+ // I couldn't figure out a good way to navigate this, so we're "grep'ing" all possible
+ // console windows for our very unique title. It should occur exactly once in the grep
+ // output.
+ if (substr_count($loaded_title, $original_title, 0) == 1)
+ $loaded_title = $original_title;
+}
+
+if ($loaded_title == $original_title)
+ echo "Successfully verified title using get-process\n";
+else
+ echo "Actually loaded from get-process: $loaded_title\n";
+
+$read_title = cli_get_process_title();
+if (substr_count($read_title, $original_title, 0) == 1)
+ echo "Successfully verified title using get\n";
+else
+ echo "Actually loaded from get: $read_title\n";
+
+?>
+--EXPECTF--
+*** Testing setting the process title ***
+Successfully set title
+Successfully verified title using get-process
+Successfully verified title using get \ No newline at end of file
diff --git a/sapi/cli/tests/php_cli_server_011.phpt b/sapi/cli/tests/php_cli_server_011.phpt
deleted file mode 100644
index a957a8ed4c..0000000000
--- a/sapi/cli/tests/php_cli_server_011.phpt
+++ /dev/null
@@ -1,41 +0,0 @@
---TEST--
-Bug #60180 ($_SERVER["PHP_SELF"] incorrect)
---SKIPIF--
-<?php
-include "skipif.inc";
-?>
---FILE--
-<?php
-include "php_cli_server.inc";
-php_cli_server_start('sytanx error;', TRUE);
-
-list($host, $port) = explode(':', PHP_CLI_SERVER_ADDRESS);
-$port = intval($port)?:80;
-
-$fp = fsockopen($host, $port, $errno, $errstr, 0.5);
-if (!$fp) {
- die("connect failed");
-}
-
-$logo_id = php_logo_guid();
-
-if(fwrite($fp, <<<HEADER
-GET /?={$logo_id} HTTP/1.1
-Host: {$host}
-
-
-HEADER
-)) {
- while (!feof($fp)) {
- if (("Content-Type: image/gif") == trim(fgets($fp))) {
- echo "okey";
- break;
- }
- }
-}
-
-fclose($fp);
-
-?>
---EXPECTF--
-okey
diff --git a/sapi/cli/tests/php_cli_server_013.phpt b/sapi/cli/tests/php_cli_server_013.phpt
index 570798a880..0e3f4ff74f 100644
--- a/sapi/cli/tests/php_cli_server_013.phpt
+++ b/sapi/cli/tests/php_cli_server_013.phpt
@@ -88,7 +88,7 @@ Content-Type: text/html; charset=UTF-8
Content-Length: %d
<!doctype html><html><head><title>404 Not Found</title><style>AAA</style>
-</head><body><h1>Not Found</h1><p>The requested resource / was not found on this server.</p></body></html>
+</head><body><h1>Not Found</h1><p>The requested resource <code class="url">/</code> was not found on this server.</p></body></html>
HTTP/1.1 404 Not Found
Host: %s
Connection: close
@@ -96,7 +96,7 @@ Content-Type: text/html; charset=UTF-8
Content-Length: %d
<!doctype html><html><head><title>404 Not Found</title><style>AAA</style>
-</head><body><h1>Not Found</h1><p>The requested resource /main/style.css was not found on this server.</p></body></html>
+</head><body><h1>Not Found</h1><p>The requested resource <code class="url">/main/style.css</code> was not found on this server.</p></body></html>
HTTP/1.1 404 Not Found
Host: %s
Connection: close
@@ -104,5 +104,5 @@ Content-Type: text/html; charset=UTF-8
Content-Length: %d
<!doctype html><html><head><title>404 Not Found</title><style>AAA</style>
-</head><body><h1>Not Found</h1><p>The requested resource /main/foo/bar was not found on this server.</p></body></html>
+</head><body><h1>Not Found</h1><p>The requested resource <code class="url">/main/foo/bar</code> was not found on this server.</p></body></html>
diff --git a/sapi/cli/tests/php_cli_server_014.phpt b/sapi/cli/tests/php_cli_server_014.phpt
index f8a9905613..e8bb5fa8a2 100644
--- a/sapi/cli/tests/php_cli_server_014.phpt
+++ b/sapi/cli/tests/php_cli_server_014.phpt
@@ -77,4 +77,4 @@ Content-Type: %s
Content-Length: %d
<!doctype html><html><head><title>404 Not Found</title><style>AAA</style>
-</head><body><h1>Not Found</h1><p>The requested resource /main/no-exists.php was not found on this server.</p></body></html>
+</head><body><h1>Not Found</h1><p>The requested resource <code class="url">/main/no-exists.php</code> was not found on this server.</p></body></html>
diff --git a/sapi/cli/tests/php_cli_server_019.phpt b/sapi/cli/tests/php_cli_server_019.phpt
new file mode 100644
index 0000000000..2b983e5c0a
--- /dev/null
+++ b/sapi/cli/tests/php_cli_server_019.phpt
@@ -0,0 +1,68 @@
+--TEST--
+Implement Req #65917 (getallheaders() is not supported by the built-in web server)
+--SKIPIF--
+<?php
+include "skipif.inc";
+?>
+--FILE--
+<?php
+include "php_cli_server.inc";
+php_cli_server_start(<<<'PHP'
+header('Bar-Foo: Foo');
+var_dump(getallheaders());
+var_dump(apache_request_headers());
+var_dump(apache_response_headers());
+PHP
+);
+
+list($host, $port) = explode(':', PHP_CLI_SERVER_ADDRESS);
+$port = intval($port)?:80;
+
+$fp = fsockopen($host, $port, $errno, $errstr, 0.5);
+if (!$fp) {
+ die("connect failed");
+}
+
+if(fwrite($fp, <<<HEADER
+GET / HTTP/1.1
+Host: {$host}
+Foo-Bar: Bar
+
+
+HEADER
+)) {
+ while (!feof($fp)) {
+ echo fgets($fp);
+ }
+}
+
+fclose($fp);
+?>
+--EXPECTF--
+HTTP/1.1 200 OK
+Host: %s
+Connection: close
+X-Powered-By: %s
+Bar-Foo: Foo
+Content-type: text/html
+
+array(2) {
+ ["Host"]=>
+ string(9) "localhost"
+ ["Foo-Bar"]=>
+ string(3) "Bar"
+}
+array(2) {
+ ["Host"]=>
+ string(9) "localhost"
+ ["Foo-Bar"]=>
+ string(3) "Bar"
+}
+array(3) {
+ ["X-Powered-By"]=>
+ string(%d) "P%s"
+ ["Bar-Foo"]=>
+ string(3) "Foo"
+ ["Content-type"]=>
+ string(9) "text/html"
+}
diff --git a/sapi/embed/config.m4 b/sapi/embed/config.m4
index 3a61b458f0..5ffb9b39bd 100644
--- a/sapi/embed/config.m4
+++ b/sapi/embed/config.m4
@@ -3,7 +3,7 @@ dnl $Id$
dnl
PHP_ARG_ENABLE(embed,,
-[ --enable-embed[=TYPE] EXPERIMENTAL: Enable building of embedded SAPI library
+[ --enable-embed[=TYPE] EXPERIMENTAL: Enable building of embedded SAPI library
TYPE is either 'shared' or 'static'. [TYPE=shared]], no, no)
AC_MSG_CHECKING([for embedded SAPI library support])
diff --git a/sapi/fpm/config.m4 b/sapi/fpm/config.m4
index 579f7c2846..bd6d64930b 100644
--- a/sapi/fpm/config.m4
+++ b/sapi/fpm/config.m4
@@ -3,7 +3,7 @@ dnl $Id$
dnl
PHP_ARG_ENABLE(fpm,,
-[ --enable-fpm Enable building of the fpm SAPI executable], no, no)
+[ --enable-fpm Enable building of the fpm SAPI executable], no, no)
dnl configure checks {{{
AC_DEFUN([AC_FPM_STDLIBS],
@@ -557,11 +557,11 @@ if test "$PHP_FPM" != "no"; then
AC_FPM_SELECT
PHP_ARG_WITH(fpm-user,,
- [ --with-fpm-user[=USER] Set the user for php-fpm to run as. (default: nobody)], nobody, no)
+ [ --with-fpm-user[=USER] Set the user for php-fpm to run as. (default: nobody)], nobody, no)
PHP_ARG_WITH(fpm-group,,
- [ --with-fpm-group[=GRP] Set the group for php-fpm to run as. For a system user, this
- should usually be set to match the fpm username (default: nobody)], nobody, no)
+ [ --with-fpm-group[=GRP] Set the group for php-fpm to run as. For a system user, this
+ should usually be set to match the fpm username (default: nobody)], nobody, no)
PHP_ARG_WITH(fpm-systemd,,
[ --with-fpm-systemd Activate systemd integration], no, no)
@@ -607,16 +607,12 @@ if test "$PHP_FPM" != "no"; then
AC_DEFINE_UNQUOTED(PHP_FPM_USER, "$php_fpm_user", [fpm user name])
AC_DEFINE_UNQUOTED(PHP_FPM_GROUP, "$php_fpm_group", [fpm group name])
- AC_DEFINE_UNQUOTED(PHP_FPM_USER, "$php_fpm_user", [fpm user name])
- AC_DEFINE_UNQUOTED(PHP_FPM_GROUP, "$php_fpm_group", [fpm group name])
-
PHP_ADD_BUILD_DIR(sapi/fpm/fpm)
PHP_ADD_BUILD_DIR(sapi/fpm/fpm/events)
PHP_OUTPUT(sapi/fpm/php-fpm.conf sapi/fpm/init.d.php-fpm sapi/fpm/php-fpm.service sapi/fpm/php-fpm.8 sapi/fpm/status.html)
PHP_ADD_MAKEFILE_FRAGMENT([$abs_srcdir/sapi/fpm/Makefile.frag])
SAPI_FPM_PATH=sapi/fpm/php-fpm
-
if test "$fpm_trace_type" && test -f "$abs_srcdir/sapi/fpm/fpm/fpm_trace_$fpm_trace_type.c"; then
PHP_FPM_TRACE_FILES="fpm/fpm_trace.c fpm/fpm_trace_$fpm_trace_type.c"
diff --git a/sapi/fpm/fpm/fastcgi.c b/sapi/fpm/fpm/fastcgi.c
index 80745a9c7e..d77b6f8ca7 100644
--- a/sapi/fpm/fpm/fastcgi.c
+++ b/sapi/fpm/fpm/fastcgi.c
@@ -611,7 +611,7 @@ static int fcgi_read_request(fcgi_request *req)
}
zend_hash_internal_pointer_reset_ex(req->env, &pos);
- while ((key_type = zend_hash_get_current_key_ex(req->env, &str_index, &str_length, &num_index, 0, &pos)) != HASH_KEY_NON_EXISTANT) {
+ while ((key_type = zend_hash_get_current_key_ex(req->env, &str_index, &str_length, &num_index, 0, &pos)) != HASH_KEY_NON_EXISTENT) {
int zlen;
zend_hash_move_forward_ex(req->env, &pos);
if (key_type != HASH_KEY_IS_STRING) {
diff --git a/sapi/fpm/fpm/fpm_sockets.h b/sapi/fpm/fpm/fpm_sockets.h
index cce5712b8c..121c016a7b 100644
--- a/sapi/fpm/fpm/fpm_sockets.h
+++ b/sapi/fpm/fpm/fpm_sockets.h
@@ -19,7 +19,7 @@
#if (__FreeBSD__) || (__OpenBSD__)
#define FPM_BACKLOG_DEFAULT -1
#else
-#define FPM_BACKLOG_DEFAULT 128
+#define FPM_BACKLOG_DEFAULT 65535
#endif
enum fpm_address_domain fpm_sockets_domain_from_address(char *addr);
diff --git a/sapi/fpm/php-fpm.conf.in b/sapi/fpm/php-fpm.conf.in
index af4f2fa325..9002a2933b 100644
--- a/sapi/fpm/php-fpm.conf.in
+++ b/sapi/fpm/php-fpm.conf.in
@@ -159,8 +159,8 @@ group = @php_fpm_group@
listen = 127.0.0.1:9000
; Set listen(2) backlog.
-; Default Value: 128 (-1 on FreeBSD and OpenBSD)
-;listen.backlog = 128
+; Default Value: 65535 (-1 on FreeBSD and OpenBSD)
+;listen.backlog = 65535
; Set permissions for unix socket, if one is used. In Linux, read/write
; permissions must be set in order to allow connections from a web server. Many
diff --git a/sapi/isapi/config.m4 b/sapi/isapi/config.m4
index 7c7dcf0c21..6014bab09f 100644
--- a/sapi/isapi/config.m4
+++ b/sapi/isapi/config.m4
@@ -3,7 +3,7 @@ dnl $Id$
dnl
PHP_ARG_WITH(isapi, for Zeus ISAPI support,
-[ --with-isapi[=DIR] Build PHP as an ISAPI module for use with Zeus], no, no)
+[ --with-isapi[=DIR] Build PHP as an ISAPI module for use with Zeus], no, no)
if test "$PHP_ISAPI" != "no"; then
if test "$PHP_ISAPI" = "yes"; then
diff --git a/sapi/litespeed/lsapi_main.c b/sapi/litespeed/lsapi_main.c
index 84e870d628..52c39f1b6c 100644
--- a/sapi/litespeed/lsapi_main.c
+++ b/sapi/litespeed/lsapi_main.c
@@ -75,8 +75,7 @@ static int lsapi_mode = 1;
static char *php_self = "";
static char *script_filename = "";
static int source_highlight = 0;
-static char * argv0 = NULL;
-static int engine = 1;
+
#ifdef ZTS
zend_compiler_globals *compiler_globals;
zend_executor_globals *executor_globals;
@@ -91,65 +90,40 @@ zend_module_entry litespeed_module_entry;
*/
static int php_lsapi_startup(sapi_module_struct *sapi_module)
{
- if (php_module_startup(sapi_module, NULL, 0)==FAILURE) {
- return FAILURE;
- }
- argv0 = sapi_module->executable_location;
- return SUCCESS;
+ if (php_module_startup(sapi_module, NULL, 0)==FAILURE) {
+ return FAILURE;
+ }
+ return SUCCESS;
}
/* }}} */
-/* {{{ sapi_lsapi_ini_defaults */
-
-/* overwriteable ini defaults must be set in sapi_cli_ini_defaults() */
-#define INI_DEFAULT(name,value)\
- ZVAL_STRING(tmp, value, 0);\
- zend_hash_update(configuration_hash, name, sizeof(name), tmp, sizeof(zval), (void**)&entry);\
- Z_STRVAL_P(entry) = zend_strndup(Z_STRVAL_P(entry), Z_STRLEN_P(entry))
-
-static void sapi_lsapi_ini_defaults(HashTable *configuration_hash)
-{
- zval *tmp, *entry;
-
-#if PHP_MAJOR_VERSION > 4
-/*
- MAKE_STD_ZVAL(tmp);
-
- INI_DEFAULT("register_long_arrays", "0");
-
- FREE_ZVAL(tmp);
-*/
-#endif
-
-}
-/* }}} */
/* {{{ sapi_lsapi_ub_write
*/
static int sapi_lsapi_ub_write(const char *str, uint str_length TSRMLS_DC)
{
- int ret;
- int remain;
- if ( lsapi_mode ) {
- ret = LSAPI_Write( str, str_length );
- if ( ret < str_length ) {
- php_handle_aborted_connection();
- return str_length - ret;
- }
- } else {
- remain = str_length;
- while( remain > 0 ) {
- ret = write( 1, str, remain );
- if ( ret <= 0 ) {
- php_handle_aborted_connection();
- return str_length - remain;
- }
- str += ret;
- remain -= ret;
- }
- }
- return str_length;
+ int ret;
+ int remain;
+ if ( lsapi_mode ) {
+ ret = LSAPI_Write( str, str_length );
+ if ( ret < str_length ) {
+ php_handle_aborted_connection();
+ return str_length - ret;
+ }
+ } else {
+ remain = str_length;
+ while( remain > 0 ) {
+ ret = write( 1, str, remain );
+ if ( ret <= 0 ) {
+ php_handle_aborted_connection();
+ return str_length - remain;
+ }
+ str += ret;
+ remain -= ret;
+ }
+ }
+ return str_length;
}
/* }}} */
@@ -158,11 +132,11 @@ static int sapi_lsapi_ub_write(const char *str, uint str_length TSRMLS_DC)
*/
static void sapi_lsapi_flush( void * server_context )
{
- if ( lsapi_mode ) {
- if ( LSAPI_Flush() == -1) {
- php_handle_aborted_connection();
- }
- }
+ if ( lsapi_mode ) {
+ if ( LSAPI_Flush() == -1) {
+ php_handle_aborted_connection();
+ }
+ }
}
/* }}} */
@@ -171,12 +145,8 @@ static void sapi_lsapi_flush( void * server_context )
*/
static int sapi_lsapi_deactivate(TSRMLS_D)
{
- if ( SG(request_info).path_translated )
- {
- efree( SG(request_info).path_translated );
- }
-
- return SUCCESS;
+ LSAPI_Finish();
+ return SUCCESS;
}
/* }}} */
@@ -187,99 +157,46 @@ static int sapi_lsapi_deactivate(TSRMLS_D)
*/
static char *sapi_lsapi_getenv( char * name, size_t name_len TSRMLS_DC )
{
- if ( lsapi_mode ) {
- return LSAPI_GetEnv( name );
- } else {
- return getenv( name );
- }
+ if ( lsapi_mode ) {
+ return LSAPI_GetEnv( name );
+ } else {
+ return getenv( name );
+ }
}
/* }}} */
-/*
-static int add_variable( const char * pKey, int keyLen, const char * pValue, int valLen,
- void * arg )
-{
- php_register_variable_safe((char *)pKey, (char *)pValue, valLen, (zval *)arg TSRMLS_CC);
- return 1;
-}
-*/
static int add_variable( const char * pKey, int keyLen, const char * pValue, int valLen,
- void * arg )
+ void * arg )
{
- zval * gpc_element, **gpc_element_p;
- HashTable * symtable1 = Z_ARRVAL_P((zval * )arg);
- register char * pKey1 = (char *)pKey;
-
- MAKE_STD_ZVAL(gpc_element);
- Z_STRLEN_P( gpc_element ) = valLen;
- Z_STRVAL_P( gpc_element ) = estrndup(pValue, valLen);
- Z_TYPE_P( gpc_element ) = IS_STRING;
-#if PHP_MAJOR_VERSION > 4
- zend_symtable_update( symtable1, pKey1, keyLen + 1, &gpc_element, sizeof( zval *), (void **) &gpc_element_p );
-#else
- zend_hash_update( symtable1, pKey1, keyLen + 1, &gpc_element, sizeof( zval *), (void **) &gpc_element_p );
-#endif
- return 1;
+ php_register_variable_safe((char *)pKey, (char *)pValue, valLen, (zval *)arg TSRMLS_CC);
+ return 1;
}
-#if ((PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 4) || PHP_MAJOR_VERSION < 5)
-static int add_variable_magic_quote( const char * pKey, int keyLen, const char * pValue, int valLen,
- void * arg )
-{
- zval * gpc_element, **gpc_element_p;
- HashTable * symtable1 = Z_ARRVAL_P((zval * )arg);
- register char * pKey1 = (char *)pKey;
-
- MAKE_STD_ZVAL(gpc_element);
- Z_STRLEN_P( gpc_element ) = valLen;
- Z_STRVAL_P( gpc_element ) = php_addslashes((char *)pValue, valLen, &Z_STRLEN_P( gpc_element ), 0 );
- Z_TYPE_P( gpc_element ) = IS_STRING;
-#if PHP_MAJOR_VERSION > 4
- zend_symtable_update( symtable1, pKey1, keyLen + 1, &gpc_element, sizeof( zval *), (void **) &gpc_element_p );
-#else
- zend_hash_update( symtable1, pKey1, keyLen + 1, &gpc_element, sizeof( zval *), (void **) &gpc_element_p );
-#endif
- return 1;
-}
-
-#endif
/* {{{ sapi_lsapi_register_variables
*/
static void sapi_lsapi_register_variables(zval *track_vars_array TSRMLS_DC)
{
- char * php_self = "";
- if ( lsapi_mode ) {
- if ( (SG(request_info).request_uri ) )
- php_self = (SG(request_info).request_uri );
-#if ((PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 4) || PHP_MAJOR_VERSION < 5)
- if (!PG(magic_quotes_gpc)) {
-#endif
- LSAPI_ForeachHeader( add_variable, track_vars_array );
- LSAPI_ForeachEnv( add_variable, track_vars_array );
- add_variable("PHP_SELF", 8, php_self, strlen( php_self ), track_vars_array );
-#if ((PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION < 4) || PHP_MAJOR_VERSION < 5)
- } else {
- LSAPI_ForeachHeader( add_variable_magic_quote, track_vars_array );
- LSAPI_ForeachEnv( add_variable_magic_quote, track_vars_array );
- add_variable_magic_quote("PHP_SELF", 8, php_self, strlen( php_self ), track_vars_array );
- }
-#endif
- php_import_environment_variables(track_vars_array TSRMLS_CC);
- } else {
- php_import_environment_variables(track_vars_array TSRMLS_CC);
+ if ( lsapi_mode ) {
+ LSAPI_ForeachHeader( add_variable, track_vars_array );
+ LSAPI_ForeachEnv( add_variable, track_vars_array );
+ php_import_environment_variables(track_vars_array TSRMLS_CC);
- php_register_variable("PHP_SELF", php_self, track_vars_array TSRMLS_CC);
- php_register_variable("SCRIPT_NAME", php_self, track_vars_array TSRMLS_CC);
- php_register_variable("SCRIPT_FILENAME", script_filename, track_vars_array TSRMLS_CC);
- php_register_variable("PATH_TRANSLATED", script_filename, track_vars_array TSRMLS_CC);
- php_register_variable("DOCUMENT_ROOT", "", track_vars_array TSRMLS_CC);
+ php_register_variable("PHP_SELF", (SG(request_info).request_uri ? SG(request_info).request_uri:""), track_vars_array TSRMLS_CC);
+ } else {
+ php_import_environment_variables(track_vars_array TSRMLS_CC);
- }
+ php_register_variable("PHP_SELF", php_self, track_vars_array TSRMLS_CC);
+ php_register_variable("SCRIPT_NAME", php_self, track_vars_array TSRMLS_CC);
+ php_register_variable("SCRIPT_FILENAME", script_filename, track_vars_array TSRMLS_CC);
+ php_register_variable("PATH_TRANSLATED", script_filename, track_vars_array TSRMLS_CC);
+ php_register_variable("DOCUMENT_ROOT", "", track_vars_array TSRMLS_CC);
+
+ }
}
/* }}} */
@@ -288,11 +205,11 @@ static void sapi_lsapi_register_variables(zval *track_vars_array TSRMLS_DC)
*/
static int sapi_lsapi_read_post(char *buffer, uint count_bytes TSRMLS_DC)
{
- if ( lsapi_mode ) {
- return LSAPI_ReadReqBody( buffer, count_bytes );
- } else {
- return 0;
- }
+ if ( lsapi_mode ) {
+ return LSAPI_ReadReqBody( buffer, count_bytes );
+ } else {
+ return 0;
+ }
}
/* }}} */
@@ -303,11 +220,11 @@ static int sapi_lsapi_read_post(char *buffer, uint count_bytes TSRMLS_DC)
*/
static char *sapi_lsapi_read_cookies(TSRMLS_D)
{
- if ( lsapi_mode ) {
- return LSAPI_GetHeader( H_COOKIE );
- } else {
- return NULL;
- }
+ if ( lsapi_mode ) {
+ return LSAPI_GetHeader( H_COOKIE );
+ } else {
+ return NULL;
+ }
}
/* }}} */
@@ -316,33 +233,33 @@ static char *sapi_lsapi_read_cookies(TSRMLS_D)
*/
static int sapi_lsapi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
{
- sapi_header_struct *h;
- zend_llist_position pos;
- if ( lsapi_mode ) {
- LSAPI_SetRespStatus( SG(sapi_headers).http_response_code );
-
- h = zend_llist_get_first_ex(&sapi_headers->headers, &pos);
- while (h) {
- if ( h->header_len > 0 ) {
- LSAPI_AppendRespHeader(h->header, h->header_len);
- }
- h = zend_llist_get_next_ex(&sapi_headers->headers, &pos);
- }
- if (SG(sapi_headers).send_default_content_type) {
- char *hd;
- int len;
- char headerBuf[SAPI_LSAPI_MAX_HEADER_LENGTH];
-
- hd = sapi_get_default_content_type(TSRMLS_C);
- len = snprintf( headerBuf, SAPI_LSAPI_MAX_HEADER_LENGTH - 1,
- "Content-type: %s", hd );
- efree(hd);
-
- LSAPI_AppendRespHeader( headerBuf, len );
- }
- }
- LSAPI_FinalizeRespHeaders();
- return SAPI_HEADER_SENT_SUCCESSFULLY;
+ sapi_header_struct *h;
+ zend_llist_position pos;
+ if ( lsapi_mode ) {
+ LSAPI_SetRespStatus( SG(sapi_headers).http_response_code );
+
+ h = zend_llist_get_first_ex(&sapi_headers->headers, &pos);
+ while (h) {
+ if ( h->header_len > 0 ) {
+ LSAPI_AppendRespHeader(h->header, h->header_len);
+ }
+ h = zend_llist_get_next_ex(&sapi_headers->headers, &pos);
+ }
+ if (SG(sapi_headers).send_default_content_type) {
+ char *hd;
+ int len;
+ char headerBuf[SAPI_LSAPI_MAX_HEADER_LENGTH];
+
+ hd = sapi_get_default_content_type(TSRMLS_C);
+ len = snprintf( headerBuf, SAPI_LSAPI_MAX_HEADER_LENGTH - 1,
+ "Content-type: %s", hd );
+ efree(hd);
+
+ LSAPI_AppendRespHeader( headerBuf, len );
+ }
+ }
+ LSAPI_FinalizeRespHeaders();
+ return SAPI_HEADER_SENT_SUCCESSFULLY;
}
@@ -353,8 +270,8 @@ static int sapi_lsapi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
*/
static void sapi_lsapi_log_message(char *message TSRMLS_DC)
{
- int len = strlen( message );
- LSAPI_Write_Stderr( message, len);
+ int len = strlen( message );
+ LSAPI_Write_Stderr( message, len);
}
/* }}} */
@@ -363,247 +280,158 @@ static void sapi_lsapi_log_message(char *message TSRMLS_DC)
*/
static sapi_module_struct lsapi_sapi_module =
{
- "litespeed",
- "LiteSpeed V5.5",
+ "litespeed",
+ "LiteSpeed",
- php_lsapi_startup, /* startup */
- php_module_shutdown_wrapper, /* shutdown */
+ php_lsapi_startup, /* startup */
+ php_module_shutdown_wrapper, /* shutdown */
- NULL, /* activate */
- sapi_lsapi_deactivate, /* deactivate */
+ NULL, /* activate */
+ sapi_lsapi_deactivate, /* deactivate */
- sapi_lsapi_ub_write, /* unbuffered write */
- sapi_lsapi_flush, /* flush */
- NULL, /* get uid */
- sapi_lsapi_getenv, /* getenv */
+ sapi_lsapi_ub_write, /* unbuffered write */
+ sapi_lsapi_flush, /* flush */
+ NULL, /* get uid */
+ sapi_lsapi_getenv, /* getenv */
- php_error, /* error handler */
+ php_error, /* error handler */
- NULL, /* header handler */
- sapi_lsapi_send_headers, /* send headers handler */
- NULL, /* send header handler */
+ NULL, /* header handler */
+ sapi_lsapi_send_headers, /* send headers handler */
+ NULL, /* send header handler */
- sapi_lsapi_read_post, /* read POST data */
- sapi_lsapi_read_cookies, /* read Cookies */
+ sapi_lsapi_read_post, /* read POST data */
+ sapi_lsapi_read_cookies, /* read Cookies */
- sapi_lsapi_register_variables, /* register server variables */
- sapi_lsapi_log_message, /* Log message */
+ sapi_lsapi_register_variables, /* register server variables */
+ sapi_lsapi_log_message, /* Log message */
- NULL, /* php.ini path override */
- NULL, /* block interruptions */
- NULL, /* unblock interruptions */
- NULL, /* default post reader */
- NULL, /* treat data */
- NULL, /* executable location */
+ NULL, /* php.ini path override */
+ NULL, /* block interruptions */
+ NULL, /* unblock interruptions */
+ NULL, /* default post reader */
+ NULL, /* treat data */
+ NULL, /* executable location */
- 0, /* php.ini ignore */
+ 0, /* php.ini ignore */
- STANDARD_SAPI_MODULE_PROPERTIES
+ STANDARD_SAPI_MODULE_PROPERTIES
};
/* }}} */
static int init_request_info( TSRMLS_D )
{
- char * pContentType = LSAPI_GetHeader( H_CONTENT_TYPE );
- char * pAuth;
-
- SG(request_info).content_type = pContentType ? pContentType : "";
- SG(request_info).request_method = LSAPI_GetRequestMethod();
- SG(request_info).query_string = LSAPI_GetQueryString();
- SG(request_info).request_uri = LSAPI_GetScriptName();
- SG(request_info).content_length = LSAPI_GetReqBodyLen();
- SG(request_info).path_translated = estrdup( LSAPI_GetScriptFileName());
-
- /* It is not reset by zend engine, set it to 0. */
- SG(sapi_headers).http_response_code = 0;
-
- pAuth = LSAPI_GetHeader( H_AUTHORIZATION );
- php_handle_auth_data(pAuth TSRMLS_CC);
-}
-
-static char s_cur_chdir[4096] = "";
+ char * pContentType = LSAPI_GetHeader( H_CONTENT_TYPE );
+ char * pAuth;
+
+ SG(request_info).content_type = pContentType ? pContentType : "";
+ SG(request_info).request_method = LSAPI_GetRequestMethod();
+ SG(request_info).query_string = LSAPI_GetQueryString();
+ SG(request_info).request_uri = LSAPI_GetScriptName();
+ SG(request_info).content_length = LSAPI_GetReqBodyLen();
+ SG(request_info).path_translated = LSAPI_GetScriptFileName();
-static int lsapi_chdir_primary_script( zend_file_handle * file_handle )
-{
-#if PHP_MAJOR_VERSION > 4
- char * p;
- char ch;
-
- SG(options) |= SAPI_OPTION_NO_CHDIR;
- getcwd( s_cur_chdir, sizeof( s_cur_chdir ) );
-
- p = strrchr( file_handle->filename, '/' );
- if ( *p )
- {
- *p = 0;
- if ( strcmp( file_handle->filename, s_cur_chdir ) != 0 ) {
- chdir( file_handle->filename );
- }
- *p++ = '/';
- ch = *p;
- *p = 0;
- if ( !CWDG(cwd).cwd ||
- ( strcmp( file_handle->filename, CWDG(cwd).cwd ) != 0 ) ) {
- CWDG(cwd).cwd_length = p - file_handle->filename;
- CWDG(cwd).cwd = (char *) realloc(CWDG(cwd).cwd, CWDG(cwd).cwd_length+1);
- memmove( CWDG(cwd).cwd, file_handle->filename, CWDG(cwd).cwd_length+1 );
- }
- *p = ch;
- }
- /* virtual_file_ex(&CWDG(cwd), file_handle->filename, NULL, CWD_REALPATH); */
-#else
- VCWD_CHDIR_FILE( file_handle->filename );
-#endif
- return 0;
-}
-
-static int lsapi_fopen_primary_script( zend_file_handle * file_handle )
-{
- FILE * fp;
- char * p;
- fp = fopen( SG(request_info).path_translated, "rb" );
- if ( !fp )
- {
- return -1;
- }
- file_handle->type = ZEND_HANDLE_FP;
- file_handle->handle.fp = fp;
- file_handle->filename = SG(request_info).path_translated;
- file_handle->free_filename = 0;
- file_handle->opened_path = NULL;
-
- lsapi_chdir_primary_script( file_handle );
-
- return 0;
+ /* It is not reset by zend engine, set it to 0. */
+ SG(sapi_headers).http_response_code = 0;
+
+ pAuth = LSAPI_GetHeader( H_AUTHORIZATION );
+ php_handle_auth_data(pAuth TSRMLS_CC);
}
-static int lsapi_execute_script( zend_file_handle * file_handle TSRMLS_DC)
+static int lsapi_module_main(int show_source TSRMLS_DC)
{
- char *p;
- int len;
- file_handle->type = ZEND_HANDLE_FILENAME;
- file_handle->handle.fd = 0;
- file_handle->filename = SG(request_info).path_translated;
- file_handle->free_filename = 0;
- file_handle->opened_path = NULL;
-
- p = argv0;
- *p++ = ':';
- len = strlen( SG(request_info).path_translated );
- if ( len > 45 )
- len = len - 45;
- else
- len = 0;
- memccpy( p, SG(request_info).path_translated + len, 0, 46 );
-
- php_execute_script(file_handle TSRMLS_CC);
- return 0;
+ zend_file_handle file_handle = {0};
-}
+ if (php_request_startup(TSRMLS_C) == FAILURE ) {
+ return -1;
+ }
+ if (show_source) {
+ zend_syntax_highlighter_ini syntax_highlighter_ini;
+ php_get_highlight_struct(&syntax_highlighter_ini);
+ highlight_file(SG(request_info).path_translated, &syntax_highlighter_ini TSRMLS_CC);
+ } else {
+ file_handle.type = ZEND_HANDLE_FILENAME;
+ file_handle.handle.fd = 0;
+ file_handle.filename = SG(request_info).path_translated;
+ file_handle.free_filename = 0;
+ file_handle.opened_path = NULL;
-static int lsapi_module_main(int show_source TSRMLS_DC)
-{
- zend_file_handle file_handle = {0};
-
- if (php_request_startup(TSRMLS_C) == FAILURE ) {
- return -1;
- }
- if (show_source) {
- zend_syntax_highlighter_ini syntax_highlighter_ini;
-
- php_get_highlight_struct(&syntax_highlighter_ini);
- highlight_file(SG(request_info).path_translated, &syntax_highlighter_ini TSRMLS_CC);
- } else {
- lsapi_execute_script( &file_handle TSRMLS_CC);
- }
- zend_try {
- php_request_shutdown(NULL);
- *argv0 = 0;
- } zend_end_try();
- return 0;
+ php_execute_script(&file_handle TSRMLS_CC);
+ }
+ zend_try {
+ php_request_shutdown(NULL);
+ } zend_end_try();
+ return 0;
}
static int alter_ini( const char * pKey, int keyLen, const char * pValue, int valLen,
- void * arg )
+ void * arg )
{
- int type = ZEND_INI_PERDIR;
- if ( '\001' == *pKey ) {
- ++pKey;
- if ( *pKey == 4 ) {
- type = ZEND_INI_SYSTEM;
- }
- ++pKey;
- --keyLen;
- if (( keyLen == 7 )&&( strncasecmp( pKey, "engine", 6 )== 0 ))
- {
- if ( *pValue == '0' )
- engine = 0;
- }
- else
- zend_alter_ini_entry((char *)pKey, keyLen,
- (char *)pValue, valLen,
- type, PHP_INI_STAGE_ACTIVATE);
- }
- return 1;
+ int type = ZEND_INI_PERDIR;
+ if ( '\001' == *pKey ) {
+ ++pKey;
+ if ( *pKey == 4 ) {
+ type = ZEND_INI_SYSTEM;
+ }
+ ++pKey;
+ --keyLen;
+ zend_alter_ini_entry((char *)pKey, keyLen,
+ (char *)pValue, valLen,
+ type, PHP_INI_STAGE_ACTIVATE);
+ }
+ return 1;
}
static void override_ini()
{
- LSAPI_ForeachSpecialEnv( alter_ini, NULL );
+ LSAPI_ForeachSpecialEnv( alter_ini, NULL );
}
static int processReq( TSRMLS_D )
{
- int ret = 0;
- zend_first_try {
- /* avoid server_context==NULL checks */
- SG(server_context) = (void *) 1;
-
- engine = 1;
- override_ini();
-
- if ( engine ) {
- init_request_info( TSRMLS_C );
-
- if ( lsapi_module_main( source_highlight TSRMLS_CC ) == -1 ) {
- ret = -1;
- }
- } else {
- LSAPI_AppendRespHeader( "status: 403", 11 );
- LSAPI_AppendRespHeader( "content-type: text/html", 23 );
- LSAPI_Write( "Forbidden: PHP engine is disable.\n", 34 );
- }
- } zend_end_try();
- return ret;
+ int ret = 0;
+ zend_first_try {
+ /* avoid server_context==NULL checks */
+ SG(server_context) = (void *) 1;
+
+ init_request_info( TSRMLS_C );
+
+ override_ini();
+
+ if ( lsapi_module_main( source_highlight TSRMLS_CC ) == -1 ) {
+ ret = -1;
+ }
+ } zend_end_try();
+ return ret;
}
static void cli_usage( TSRMLS_D )
{
- static const char * usage =
- "Usage: php\n"
- " php -[b|c|h|i|q|s|v|?] [<file>] [args...]\n"
- " Run in LSAPI mode, only '-b', '-s' and '-c' are effective\n"
- " Run in Command Line Interpreter mode when parameters are specified\n"
- "\n"
- " -b <address:port>|<port> Bind Path for external LSAPI Server mode\n"
- " -c <path>|<file> Look for php.ini file in this directory\n"
- " -h This help\n"
- " -i PHP information\n"
- " -q Quiet-mode. Suppress HTTP Header output.\n"
- " -s Display colour syntax highlighted source.\n"
- " -v Version number\n"
- " -? This help\n"
- "\n"
- " args... Arguments passed to script.\n";
- php_output_startup();
- php_output_activate(TSRMLS_C);
- php_printf( "%s", usage );
+ static const char * usage =
+ "Usage: php\n"
+ " php -[b|c|h|i|q|s|v|?] [<file>] [args...]\n"
+ " Run in LSAPI mode, only '-b', '-s' and '-c' are effective\n"
+ " Run in Command Line Interpreter mode when parameters are specified\n"
+ "\n"
+ " -b <address:port>|<port> Bind Path for external LSAPI Server mode\n"
+ " -c <path>|<file> Look for php.ini file in this directory\n"
+ " -h This help\n"
+ " -i PHP information\n"
+ " -q Quiet-mode. Suppress HTTP Header output.\n"
+ " -s Display colour syntax highlighted source.\n"
+ " -v Version number\n"
+ " -? This help\n"
+ "\n"
+ " args... Arguments passed to script.\n";
+ php_output_startup();
+ php_output_activate(TSRMLS_C);
+ php_printf( "%s", usage );
#ifdef PHP_OUTPUT_NEWAPI
php_output_end_all(TSRMLS_C);
#else
@@ -612,250 +440,250 @@ static void cli_usage( TSRMLS_D )
}
static int parse_opt( int argc, char * argv[], int *climode,
- char **php_ini_path, char ** php_bind )
-{
- char ** p = &argv[1];
- char ** argend= &argv[argc];
- int c;
- while (( p < argend )&&(**p == '-' )) {
- c = *((*p)+1);
- ++p;
- switch( c ) {
- case 'b':
- if ( p >= argend ) {
- fprintf( stderr, "TCP or socket address must be specified following '-b' option.\n");
- return -1;
- }
- *php_bind = *p++;
- break;
-
- case 'c':
- if ( p >= argend ) {
- fprintf( stderr, "<path> or <file> must be specified following '-c' option.\n");
-
- return -1;
- }
- *php_ini_path = *p++;
- break;
- case 's':
- source_highlight = 1;
- break;
- case 'h':
- case 'i':
- case 'q':
- case 'v':
- case '?':
- default:
- *climode = 1;
- break;
- }
- }
- if ( p - argv < argc ) {
- *climode = 1;
- }
- return 0;
+ char **php_ini_path, char ** php_bind )
+{
+ char ** p = &argv[1];
+ char ** argend= &argv[argc];
+ int c;
+ while (( p < argend )&&(**p == '-' )) {
+ c = *((*p)+1);
+ ++p;
+ switch( c ) {
+ case 'b':
+ if ( p >= argend ) {
+ fprintf( stderr, "TCP or socket address must be specified following '-b' option.\n");
+ return -1;
+ }
+ *php_bind = *p++;
+ break;
+
+ case 'c':
+ if ( p >= argend ) {
+ fprintf( stderr, "<path> or <file> must be specified following '-c' option.\n");
+
+ return -1;
+ }
+ *php_ini_path = *p++;
+ break;
+ case 's':
+ source_highlight = 1;
+ break;
+ case 'h':
+ case 'i':
+ case 'q':
+ case 'v':
+ case '?':
+ default:
+ *climode = 1;
+ break;
+ }
+ }
+ if ( p - argv < argc ) {
+ *climode = 1;
+ }
+ return 0;
}
static int cli_main( int argc, char * argv[] )
{
- static const char * ini_defaults[] = {
- "report_zend_debug", "0",
- "display_errors", "1",
- "register_argc_argv", "1",
- "html_errors", "0",
- "implicit_flush", "1",
- "output_buffering", "0",
- "max_execution_time", "0",
- "max_input_time", "-1",
- NULL
- };
-
- const char ** ini;
- char ** p = &argv[1];
- char ** argend= &argv[argc];
- int ret = 0;
- int c;
- lsapi_mode = 0; /* enter CLI mode */
+ static const char * ini_defaults[] = {
+ "report_zend_debug", "0",
+ "display_errors", "1",
+ "register_argc_argv", "1",
+ "html_errors", "0",
+ "implicit_flush", "1",
+ "output_buffering", "0",
+ "max_execution_time", "0",
+ "max_input_time", "-1",
+ NULL
+ };
+
+ const char ** ini;
+ char ** p = &argv[1];
+ char ** argend= &argv[argc];
+ int ret = 0;
+ int c;
+ lsapi_mode = 0; /* enter CLI mode */
#ifdef PHP_WIN32
- _fmode = _O_BINARY; /*sets default for file streams to binary */
- setmode(_fileno(stdin), O_BINARY); /* make the stdio mode be binary */
- setmode(_fileno(stdout), O_BINARY); /* make the stdio mode be binary */
- setmode(_fileno(stderr), O_BINARY); /* make the stdio mode be binary */
+ _fmode = _O_BINARY; /*sets default for file streams to binary */
+ setmode(_fileno(stdin), O_BINARY); /* make the stdio mode be binary */
+ setmode(_fileno(stdout), O_BINARY); /* make the stdio mode be binary */
+ setmode(_fileno(stderr), O_BINARY); /* make the stdio mode be binary */
#endif
- zend_first_try {
- SG(server_context) = (void *) 1;
-
- zend_uv.html_errors = 0; /* tell the engine we're in non-html mode */
- CG(in_compilation) = 0; /* not initialized but needed for several options */
- EG(uninitialized_zval_ptr) = NULL;
-
- for( ini = ini_defaults; *ini; ini+=2 ) {
- zend_alter_ini_entry( (char *)*ini, strlen( *ini )+1,
- (char *)*(ini+1), strlen( *(ini+1) ),
- PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
- }
-
- while (( p < argend )&&(**p == '-' )) {
- c = *((*p)+1);
- ++p;
- switch( c ) {
- case 'q':
- break;
- case 'i':
- if (php_request_startup(TSRMLS_C) != FAILURE) {
- php_print_info(0xFFFFFFFF TSRMLS_CC);
+ zend_first_try {
+ SG(server_context) = (void *) 1;
+
+ zend_uv.html_errors = 0; /* tell the engine we're in non-html mode */
+ CG(in_compilation) = 0; /* not initialized but needed for several options */
+ EG(uninitialized_zval_ptr) = NULL;
+
+ for( ini = ini_defaults; *ini; ini+=2 ) {
+ zend_alter_ini_entry( (char *)*ini, strlen( *ini )+1,
+ (char *)*(ini+1), strlen( *(ini+1) ),
+ PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
+ }
+
+ while (( p < argend )&&(**p == '-' )) {
+ c = *((*p)+1);
+ ++p;
+ switch( c ) {
+ case 'q':
+ break;
+ case 'i':
+ if (php_request_startup(TSRMLS_C) != FAILURE) {
+ php_print_info(0xFFFFFFFF TSRMLS_CC);
#ifdef PHP_OUTPUT_NEWAPI
php_output_end_all(TSRMLS_C);
#else
php_end_ob_buffers(1 TSRMLS_CC);
#endif
- php_request_shutdown( NULL );
- }
- ret = 1;
- break;
- case 'v':
- if (php_request_startup(TSRMLS_C) != FAILURE) {
+ php_request_shutdown( NULL );
+ }
+ ret = 1;
+ break;
+ case 'v':
+ if (php_request_startup(TSRMLS_C) != FAILURE) {
#if ZEND_DEBUG
- php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2014 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
+ php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2014 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
#else
- php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2014 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
+ php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2014 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
#endif
#ifdef PHP_OUTPUT_NEWAPI
php_output_end_all(TSRMLS_C);
#else
php_end_ob_buffers(1 TSRMLS_CC);
#endif
- php_request_shutdown( NULL );
- }
- ret = 1;
- break;
- case 'c':
- ++p;
- /* fall through */
- case 's':
- break;
-
- case 'h':
- case '?':
- default:
- cli_usage(TSRMLS_C);
- ret = 1;
- break;
-
- }
- }
- if ( !ret ) {
- if ( *p ) {
- zend_file_handle file_handle = {0};
-
- file_handle.type = ZEND_HANDLE_FP;
- file_handle.handle.fp = VCWD_FOPEN(*p, "rb");
-
- if ( file_handle.handle.fp ) {
- script_filename = *p;
- php_self = *p;
-
- SG(request_info).path_translated = estrdup(*p);
- SG(request_info).argc = argc - (p - argv);
- SG(request_info).argv = p;
-
- if (php_request_startup(TSRMLS_C) == FAILURE ) {
- fclose( file_handle.handle.fp );
- ret = 2;
- } else {
- if (source_highlight) {
- zend_syntax_highlighter_ini syntax_highlighter_ini;
-
- php_get_highlight_struct(&syntax_highlighter_ini);
- highlight_file(SG(request_info).path_translated, &syntax_highlighter_ini TSRMLS_CC);
- } else {
- file_handle.filename = *p;
- file_handle.free_filename = 0;
- file_handle.opened_path = NULL;
-
- php_execute_script(&file_handle TSRMLS_CC);
- }
-
- php_request_shutdown( NULL );
- }
- } else {
- php_printf("Could not open input file: %s.\n", *p);
- }
- } else {
- cli_usage(TSRMLS_C);
- }
- }
-
- }zend_end_try();
-
- php_module_shutdown(TSRMLS_C);
+ php_request_shutdown( NULL );
+ }
+ ret = 1;
+ break;
+ case 'c':
+ ++p;
+ /* fall through */
+ case 's':
+ break;
+
+ case 'h':
+ case '?':
+ default:
+ cli_usage(TSRMLS_C);
+ ret = 1;
+ break;
+
+ }
+ }
+ if ( !ret ) {
+ if ( *p ) {
+ zend_file_handle file_handle = {0};
+
+ file_handle.type = ZEND_HANDLE_FP;
+ file_handle.handle.fp = VCWD_FOPEN(*p, "rb");
+
+ if ( file_handle.handle.fp ) {
+ script_filename = *p;
+ php_self = *p;
+
+ SG(request_info).path_translated = *p;
+ SG(request_info).argc = argc - (p - argv);
+ SG(request_info).argv = p;
+
+ if (php_request_startup(TSRMLS_C) == FAILURE ) {
+ fclose( file_handle.handle.fp );
+ ret = 2;
+ } else {
+ if (source_highlight) {
+ zend_syntax_highlighter_ini syntax_highlighter_ini;
+
+ php_get_highlight_struct(&syntax_highlighter_ini);
+ highlight_file(SG(request_info).path_translated, &syntax_highlighter_ini TSRMLS_CC);
+ } else {
+ file_handle.filename = *p;
+ file_handle.free_filename = 0;
+ file_handle.opened_path = NULL;
+
+ php_execute_script(&file_handle TSRMLS_CC);
+ }
+
+ php_request_shutdown( NULL );
+ }
+ } else {
+ php_printf("Could not open input file: %s.\n", *p);
+ }
+ } else {
+ cli_usage(TSRMLS_C);
+ }
+ }
+
+ }zend_end_try();
+
+ php_module_shutdown(TSRMLS_C);
#ifdef ZTS
- tsrm_shutdown();
+ tsrm_shutdown();
#endif
- return ret;
+ return ret;
}
static int s_stop;
void litespeed_cleanup(int signal)
{
- s_stop = signal;
+ s_stop = signal;
}
void start_children( int children )
{
- struct sigaction act, old_term, old_quit, old_int, old_usr1;
- int running = 0;
- int status;
- pid_t pid;
-
- /* Create a process group */
- setsid();
-
- /* Set up handler to kill children upon exit */
- act.sa_flags = 0;
- act.sa_handler = litespeed_cleanup;
- if( sigaction( SIGTERM, &act, &old_term ) ||
- sigaction( SIGINT, &act, &old_int ) ||
- sigaction( SIGUSR1, &act, &old_usr1 ) ||
- sigaction( SIGQUIT, &act, &old_quit )) {
- perror( "Can't set signals" );
- exit( 1 );
- }
- s_stop = 0;
- while( 1 ) {
- while((!s_stop )&&( running < children )) {
- pid = fork();
- switch( pid ) {
- case 0: /* children process */
-
- /* don't catch our signals */
- sigaction( SIGTERM, &old_term, 0 );
- sigaction( SIGQUIT, &old_quit, 0 );
- sigaction( SIGINT, &old_int, 0 );
- sigaction( SIGUSR1, &old_usr1, 0 );
- return ;
- case -1:
- perror( "php (pre-forking)" );
- exit( 1 );
- break;
- default: /* parent process */
- running++;
- break;
- }
- }
- if ( s_stop ) {
- break;
- }
- pid = wait( &status );
- running--;
- }
- kill( -getpgrp(), SIGUSR1 );
- exit( 0 );
+ struct sigaction act, old_term, old_quit, old_int, old_usr1;
+ int running = 0;
+ int status;
+ pid_t pid;
+
+ /* Create a process group */
+ setsid();
+
+ /* Set up handler to kill children upon exit */
+ act.sa_flags = 0;
+ act.sa_handler = litespeed_cleanup;
+ if( sigaction( SIGTERM, &act, &old_term ) ||
+ sigaction( SIGINT, &act, &old_int ) ||
+ sigaction( SIGUSR1, &act, &old_usr1 ) ||
+ sigaction( SIGQUIT, &act, &old_quit )) {
+ perror( "Can't set signals" );
+ exit( 1 );
+ }
+ s_stop = 0;
+ while( 1 ) {
+ while((!s_stop )&&( running < children )) {
+ pid = fork();
+ switch( pid ) {
+ case 0: /* children process */
+
+ /* don't catch our signals */
+ sigaction( SIGTERM, &old_term, 0 );
+ sigaction( SIGQUIT, &old_quit, 0 );
+ sigaction( SIGINT, &old_int, 0 );
+ sigaction( SIGUSR1, &old_usr1, 0 );
+ return ;
+ case -1:
+ perror( "php (pre-forking)" );
+ exit( 1 );
+ break;
+ default: /* parent process */
+ running++;
+ break;
+ }
+ }
+ if ( s_stop ) {
+ break;
+ }
+ pid = wait( &status );
+ running--;
+ }
+ kill( -getpgrp(), SIGUSR1 );
+ exit( 0 );
}
@@ -863,185 +691,153 @@ void start_children( int children )
#include <fcntl.h>
int main( int argc, char * argv[] )
{
- int ret;
- int bindFd;
-
- char * php_ini_path = NULL;
- char * php_bind = NULL;
- char * p;
- int n;
- int climode = 0;
- struct timeval tv_req_begin;
- struct timeval tv_req_end;
- int slow_script_msec = 0;
- char time_buf[40];
-
+ int ret;
+ int bindFd;
+
+ char * php_ini_path = NULL;
+ char * php_bind = NULL;
+ char * p;
+ int n;
+ int climode = 0;
+
#ifdef HAVE_SIGNAL_H
#if defined(SIGPIPE) && defined(SIG_IGN)
- signal(SIGPIPE, SIG_IGN);
+ signal(SIGPIPE, SIG_IGN);
#endif
#endif
#ifdef ZTS
- tsrm_startup(1, 1, 0, NULL);
+ tsrm_startup(1, 1, 0, NULL);
#endif
- if (argc > 1 ) {
- if ( parse_opt( argc, argv, &climode,
- &php_ini_path, &php_bind ) == -1 ) {
- return 1;
- }
- }
- if ( climode ) {
- lsapi_sapi_module.phpinfo_as_text = 1;
- }
- argv0 = argv[0] + strlen( argv[0] );
- sapi_startup(&lsapi_sapi_module);
+ if (argc > 1 ) {
+ if ( parse_opt( argc, argv, &climode,
+ &php_ini_path, &php_bind ) == -1 ) {
+ return 1;
+ }
+ }
+ if ( climode ) {
+ lsapi_sapi_module.phpinfo_as_text = 1;
+ }
+ sapi_startup(&lsapi_sapi_module);
#ifdef ZTS
- compiler_globals = ts_resource(compiler_globals_id);
- executor_globals = ts_resource(executor_globals_id);
- core_globals = ts_resource(core_globals_id);
- sapi_globals = ts_resource(sapi_globals_id);
- tsrm_ls = ts_resource(0);
+ compiler_globals = ts_resource(compiler_globals_id);
+ executor_globals = ts_resource(executor_globals_id);
+ core_globals = ts_resource(core_globals_id);
+ sapi_globals = ts_resource(sapi_globals_id);
+ tsrm_ls = ts_resource(0);
- SG(request_info).path_translated = NULL;
+ SG(request_info).path_translated = NULL;
#endif
- lsapi_sapi_module.executable_location = argv[0];
-
- if ( php_ini_path ) {
- lsapi_sapi_module.php_ini_path_override = php_ini_path;
- }
+ lsapi_sapi_module.executable_location = argv[0];
+ if ( php_ini_path ) {
+ lsapi_sapi_module.php_ini_path_override = php_ini_path;
+ }
- lsapi_sapi_module.ini_defaults = sapi_lsapi_ini_defaults;
-
- if (php_module_startup(&lsapi_sapi_module, &litespeed_module_entry, 1) == FAILURE) {
+ if (php_module_startup(&lsapi_sapi_module, &litespeed_module_entry, 1) == FAILURE) {
#ifdef ZTS
- tsrm_shutdown();
+ tsrm_shutdown();
#endif
- return FAILURE;
- }
-
- if ( climode ) {
- return cli_main(argc, argv);
- }
-
- if ( php_bind ) {
- bindFd = LSAPI_CreateListenSock( php_bind, 10 );
- if ( bindFd == -1 ) {
- fprintf( stderr,
- "Failed to bind socket [%s]: %s\n", php_bind, strerror( errno ) );
- exit( 2 );
- }
- if ( bindFd != 0 ) {
- dup2( bindFd, 0 );
- close( bindFd );
- }
- }
-
- LSAPI_Init();
+ return FAILURE;
+ }
+
+ if ( climode ) {
+ return cli_main(argc, argv);
+ }
+
+
+ if ( php_bind ) {
+ bindFd = LSAPI_CreateListenSock( php_bind, 10 );
+ if ( bindFd == -1 ) {
+ fprintf( stderr,
+ "Failed to bind socket [%s]: %s\n", php_bind, strerror( errno ) );
+ exit( 2 );
+ }
+ if ( bindFd != 0 ) {
+ dup2( bindFd, 0 );
+ close( bindFd );
+ }
+ }
+
+ LSAPI_Init();
- LSAPI_Init_Env_Parameters( NULL );
-
- slow_script_msec = LSAPI_Get_Slow_Req_Msecs();
-
- if ( php_bind ) {
- LSAPI_No_Check_ppid();
- }
-
- while( LSAPI_Prefork_Accept_r( &g_req ) >= 0 ) {
- if ( slow_script_msec ) {
- gettimeofday( &tv_req_begin, NULL );
- }
- ret = processReq(TSRMLS_C);
- if ( slow_script_msec ) {
- gettimeofday( &tv_req_end, NULL );
- n = ((long) tv_req_end.tv_sec - tv_req_begin.tv_sec ) * 1000
- + (tv_req_end.tv_usec - tv_req_begin.tv_usec) / 1000;
- if ( n > slow_script_msec )
- {
- strftime( time_buf, 30, "%d/%b/%Y:%H:%M:%S", localtime( &tv_req_end.tv_sec ) );
- fprintf( stderr, "[%s] Slow PHP script: %d ms\n URL: %s %s\n Query String: %s\n Script: %s\n",
- time_buf, n, LSAPI_GetRequestMethod(),
- LSAPI_GetScriptName(), LSAPI_GetQueryString(),
- LSAPI_GetScriptFileName() );
-
- }
- }
- LSAPI_Finish();
- if ( ret ) {
- break;
- }
- }
- php_module_shutdown(TSRMLS_C);
+ LSAPI_Init_Env_Parameters( NULL );
+
+ if ( php_bind ) {
+ LSAPI_No_Check_ppid();
+ }
+
+ while( LSAPI_Prefork_Accept_r( &g_req ) >= 0 ) {
+ ret = processReq(TSRMLS_C);
+ LSAPI_Finish();
+ if ( ret ) {
+ break;
+ }
+ }
+ php_module_shutdown(TSRMLS_C);
#ifdef ZTS
- tsrm_shutdown();
+ tsrm_shutdown();
#endif
- return ret;
+ return ret;
}
/* LiteSpeed PHP module starts here */
-#if PHP_MAJOR_VERSION > 4
-
/* {{{ arginfo */
ZEND_BEGIN_ARG_INFO(arginfo_litespeed__void, 0)
ZEND_END_ARG_INFO()
/* }}} */
-#else
-#define arginfo_litespeed__void NULL
-#endif
-
PHP_FUNCTION(litespeed_request_headers);
PHP_FUNCTION(litespeed_response_headers);
PHP_MINFO_FUNCTION(litespeed);
zend_function_entry litespeed_functions[] = {
- PHP_FE(litespeed_request_headers, arginfo_litespeed__void)
- PHP_FE(litespeed_response_headers, arginfo_litespeed__void)
- PHP_FALIAS(getallheaders, litespeed_request_headers, arginfo_litespeed__void)
- PHP_FALIAS(apache_request_headers, litespeed_request_headers, arginfo_litespeed__void)
- PHP_FALIAS(apache_response_headers, litespeed_response_headers, arginfo_litespeed__void)
- {NULL, NULL, NULL}
+ PHP_FE(litespeed_request_headers, arginfo_litespeed__void)
+ PHP_FE(litespeed_response_headers, arginfo_litespeed__void)
+ PHP_FALIAS(getallheaders, litespeed_request_headers, arginfo_litespeed__void)
+ PHP_FALIAS(apache_request_headers, litespeed_request_headers, arginfo_litespeed__void)
+ PHP_FALIAS(apache_response_headers, litespeed_response_headers, arginfo_litespeed__void)
+ {NULL, NULL, NULL}
};
static PHP_MINIT_FUNCTION(litespeed)
{
- /* REGISTER_INI_ENTRIES(); */
- return SUCCESS;
+ /* REGISTER_INI_ENTRIES(); */
+ return SUCCESS;
}
static PHP_MSHUTDOWN_FUNCTION(litespeed)
{
- /* UNREGISTER_INI_ENTRIES(); */
- return SUCCESS;
+ /* UNREGISTER_INI_ENTRIES(); */
+ return SUCCESS;
}
zend_module_entry litespeed_module_entry = {
- STANDARD_MODULE_HEADER,
- "litespeed",
- litespeed_functions,
- PHP_MINIT(litespeed),
- PHP_MSHUTDOWN(litespeed),
- NULL,
- NULL,
- NULL,
- NO_VERSION_YET,
- STANDARD_MODULE_PROPERTIES
+ STANDARD_MODULE_HEADER,
+ "litespeed",
+ litespeed_functions,
+ PHP_MINIT(litespeed),
+ PHP_MSHUTDOWN(litespeed),
+ NULL,
+ NULL,
+ NULL,
+ NO_VERSION_YET,
+ STANDARD_MODULE_PROPERTIES
};
static int add_associate_array( const char * pKey, int keyLen, const char * pValue, int valLen,
- void * arg )
+ void * arg )
{
- add_assoc_string_ex( (zval *)arg, (char *)pKey, keyLen+1, (char *)pValue, 1 );
- return 1;
+ add_assoc_string_ex( (zval *)arg, (char *)pKey, keyLen+1, (char *)pValue, 1 );
+ return 1;
}
@@ -1049,14 +845,13 @@ static int add_associate_array( const char * pKey, int keyLen, const char * pVal
Fetch all HTTP request headers */
PHP_FUNCTION(litespeed_request_headers)
{
- /* TODO: */
- if (ZEND_NUM_ARGS() > 0) {
- WRONG_PARAM_COUNT;
- }
- array_init(return_value);
+ /* TODO: */
+ if (ZEND_NUM_ARGS() > 0) {
+ WRONG_PARAM_COUNT;
+ }
+ array_init(return_value);
- if ( lsapi_mode )
- LSAPI_ForeachOrgHeader( add_associate_array, return_value );
+ LSAPI_ForeachOrgHeader( add_associate_array, return_value );
}
/* }}} */
@@ -1067,40 +862,40 @@ PHP_FUNCTION(litespeed_request_headers)
Fetch all HTTP response headers */
PHP_FUNCTION(litespeed_response_headers)
{
- sapi_header_struct *h;
- zend_llist_position pos;
- char * p;
- int len;
- char headerBuf[SAPI_LSAPI_MAX_HEADER_LENGTH];
-
- if (ZEND_NUM_ARGS() > 0) {
- WRONG_PARAM_COUNT;
- }
-
- if (!&SG(sapi_headers).headers) {
- RETURN_FALSE;
- }
- array_init(return_value);
-
- h = zend_llist_get_first_ex(&SG(sapi_headers).headers, &pos);
- while (h) {
- if ( h->header_len > 0 ) {
- p = strchr( h->header, ':' );
- len = p - h->header;
- if (( p )&&( len > 0 )) {
- memmove( headerBuf, h->header, len );
- while( len > 0 && (isspace( headerBuf[len-1])) ) {
- --len;
- }
- headerBuf[len] = 0;
- if ( len ) {
- while( isspace(*++p));
- add_assoc_string_ex(return_value, headerBuf, len+1, p, 1 );
- }
- }
- }
- h = zend_llist_get_next_ex(&SG(sapi_headers).headers, &pos);
- }
+ sapi_header_struct *h;
+ zend_llist_position pos;
+ char * p;
+ int len;
+ char headerBuf[SAPI_LSAPI_MAX_HEADER_LENGTH];
+
+ if (ZEND_NUM_ARGS() > 0) {
+ WRONG_PARAM_COUNT;
+ }
+
+ if (!&SG(sapi_headers).headers) {
+ RETURN_FALSE;
+ }
+ array_init(return_value);
+
+ h = zend_llist_get_first_ex(&SG(sapi_headers).headers, &pos);
+ while (h) {
+ if ( h->header_len > 0 ) {
+ p = strchr( h->header, ':' );
+ len = p - h->header;
+ if (( p )&&( len > 0 )) {
+ memmove( headerBuf, h->header, len );
+ while( len > 0 && (isspace( headerBuf[len-1])) ) {
+ --len;
+ }
+ headerBuf[len] = 0;
+ if ( len ) {
+ while( isspace(*++p));
+ add_assoc_string_ex(return_value, headerBuf, len+1, p, 1 );
+ }
+ }
+ }
+ h = zend_llist_get_next_ex(&SG(sapi_headers).headers, &pos);
+ }
}
/* }}} */
diff --git a/sapi/litespeed/lsapilib.c b/sapi/litespeed/lsapilib.c
index 1bb16b3268..24b5a7e559 100644
--- a/sapi/litespeed/lsapilib.c
+++ b/sapi/litespeed/lsapilib.c
@@ -86,7 +86,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
static int g_inited = 0;
static int g_running = 1;
static int s_ppid;
-static int s_slow_req_msecs = 0;
LSAPI_Request g_req = { -1, -1 };
void Flush_RespBuf_r( LSAPI_Request * pReq );
@@ -508,13 +507,11 @@ static int parseRequest( LSAPI_Request * pReq, int totalLen )
return 0;
}
-static int s_accept_notify = 0;
-
static struct lsapi_packet_header ack = {'L', 'S',
LSAPI_REQ_RECEIVED, LSAPI_ENDIAN, {LSAPI_PACKET_HEADER_LEN} };
-static inline int notify_req_received( int fd )
+static inline int notify_req_received( LSAPI_Request * pReq )
{
- if ( write( fd, &ack, LSAPI_PACKET_HEADER_LEN )
+ if ( write( pReq->m_fd, &ack, LSAPI_PACKET_HEADER_LEN )
< LSAPI_PACKET_HEADER_LEN ) {
return -1;
}
@@ -570,10 +567,7 @@ static int readReq( LSAPI_Request * pReq )
pReq->m_bufProcessed = packetLen;
pReq->m_reqState = LSAPI_ST_REQ_BODY | LSAPI_ST_RESP_HEADER;
- if ( !s_accept_notify )
- return notify_req_received( pReq->m_fd );
- else
- return 0;
+ return notify_req_received( pReq );
}
@@ -683,10 +677,6 @@ int LSAPI_Accept_r( LSAPI_Request * pReq )
setsockopt(pReq->m_fd, IPPROTO_TCP, TCP_NODELAY,
(char *)&nodelay, sizeof(nodelay));
}
-
- if ( s_accept_notify )
- return notify_req_received( pReq->m_fd );
-
}
} else {
return -1;
@@ -1249,13 +1239,12 @@ int LSAPI_ForeachHeader_r( LSAPI_Request * pReq,
while( pCur < pEnd ) {
pKey = pReq->m_pHttpHeader + pCur->nameOff;
keyLen = pCur->nameLen;
- if ( keyLen > 250 ) {
- keyLen = 250;
- }
-
pKeyEnd = pKey + keyLen;
memcpy( achHeaderName, "HTTP_", 5 );
p = &achHeaderName[5];
+ if ( keyLen > 250 ) {
+ keyLen = 250;
+ }
while( pKey < pKeyEnd ) {
char ch = *pKey++;
@@ -1640,9 +1629,6 @@ static int lsapi_accept( int fdListen )
setsockopt( fd, IPPROTO_TCP, TCP_NODELAY,
(char *)&nodelay, sizeof(nodelay));
}
-
- if ( s_accept_notify )
- notify_req_received( fd );
}
return fd;
@@ -2087,15 +2073,6 @@ void LSAPI_Set_Server_Max_Idle_Secs( int serverMaxIdle )
}
}
-void LSAPI_Set_Slow_Req_Msecs( int msecs )
-{
- s_slow_req_msecs = msecs;
-}
-
-int LSAPI_Get_Slow_Req_Msecs()
-{
- return s_slow_req_msecs;
-}
void LSAPI_No_Check_ppid()
{
@@ -2149,18 +2126,6 @@ void LSAPI_Init_Env_Parameters( fn_select_t fp )
avoidFork = atoi( p );
}
- p = getenv( "LSAPI_ACCEPT_NOTIFY" );
- if ( p ) {
- s_accept_notify = atoi( p );
- }
-
- p = getenv( "LSAPI_SLOW_REQ_MSECS" );
- if ( p ) {
- n = atoi( p );
- LSAPI_Set_Slow_Req_Msecs( n );
- }
-
-
#if defined( RLIMIT_CORE )
p = getenv( "LSAPI_ALLOW_CORE_DUMP" );
if ( !p ) {
diff --git a/sapi/litespeed/lsapilib.h b/sapi/litespeed/lsapilib.h
index 45934ad464..9d6255b327 100644
--- a/sapi/litespeed/lsapilib.h
+++ b/sapi/litespeed/lsapilib.h
@@ -343,11 +343,6 @@ void LSAPI_Set_Max_Process_Time( int secs );
void LSAPI_Init_Env_Parameters( fn_select_t fp );
-void LSAPI_Set_Slow_Req_Msecs( int msecs );
-
-int LSAPI_Get_Slow_Req_Msecs( );
-
-
#if defined (c_plusplus) || defined (__cplusplus)
}
#endif
diff --git a/sapi/milter/config.m4 b/sapi/milter/config.m4
index 48c7a5d804..4bcad80bb4 100644
--- a/sapi/milter/config.m4
+++ b/sapi/milter/config.m4
@@ -3,7 +3,7 @@ dnl $Id$
dnl
PHP_ARG_WITH(milter, for Milter support,
-[ --with-milter[=DIR] Build PHP as Milter application], no, no)
+[ --with-milter[=DIR] Build PHP as Milter application], no, no)
if test "$PHP_MILTER" != "no"; then
if test "$PHP_MILTER" = "yes"; then
diff --git a/sapi/pi3web/config.m4 b/sapi/pi3web/config.m4
index 7859481508..347a74ca06 100644
--- a/sapi/pi3web/config.m4
+++ b/sapi/pi3web/config.m4
@@ -3,7 +3,7 @@ dnl $Id$
dnl
PHP_ARG_WITH(pi3web, for Pi3Web support,
-[ --with-pi3web[=DIR] Build PHP as Pi3Web module], no, no)
+[ --with-pi3web[=DIR] Build PHP as Pi3Web module], no, no)
if test "$PHP_PI3WEB" != "no"; then
if test "$PHP_PI3WEB" = "yes"; then
diff --git a/sapi/roxen/config.m4 b/sapi/roxen/config.m4
index 9b0bb90c35..7601b0c1ed 100644
--- a/sapi/roxen/config.m4
+++ b/sapi/roxen/config.m4
@@ -7,7 +7,7 @@ PHP_ARG_WITH(roxen,,
directory, normally /usr/local/roxen/server], no, no)
PHP_ARG_ENABLE(roxen-zts, whether Roxen module is build using ZTS,
-[ --enable-roxen-zts ROXEN: Build the Roxen module using Zend Thread Safety], no, no)
+[ --enable-roxen-zts ROXEN: Build the Roxen module using Zend Thread Safety], no, no)
RESULT=
AC_MSG_CHECKING([for Roxen/Pike support])
diff --git a/server-tests.php b/server-tests.php
index 684e111c91..688fee485a 100755
--- a/server-tests.php
+++ b/server-tests.php
@@ -138,7 +138,7 @@ function generate_diff($wanted,$output)
}
function mkpath($path,$mode = 0777) {
- $dirs = split('[\\/]',$path);
+ $dirs = preg_split('/[\\/]/',$path);
$path = $dirs[0];
for($i = 1;$i < count($dirs);$i++) {
$path .= '/'.$dirs[$i];
@@ -358,7 +358,7 @@ class HTTPRequest
return $this->outgoing_payload;
}
- function &_sendHTTP()
+ function _sendHTTP()
{
$this->_getRequest();
$host = $this->urlparts['host'];
@@ -555,7 +555,7 @@ class testHarness {
{
// get the list of installed extensions
$out = $this->runscript(PHP_EXTENSIONS_SCRIPT,true);
- $this->exts_to_test = split(":",$out);
+ $this->exts_to_test = explode(":",$out);
sort($this->exts_to_test);
$this->exts_tested = count($this->exts_to_test);
}
@@ -716,9 +716,9 @@ class testHarness {
if (@$this->conf['TEST_PATHS']) {
$this->test_dirs = array();
if ($this->iswin32) {
- $paths = split(';',$this->conf['TEST_PATHS']);
+ $paths = explode(';',$this->conf['TEST_PATHS']);
} else {
- $paths = split(':|;',$this->conf['TEST_PATHS']);
+ $paths = explode(':|;',$this->conf['TEST_PATHS']);
}
foreach($paths as $path) {
$this->test_dirs[] = realpath($path);
@@ -1152,7 +1152,7 @@ class testHarness {
while (!feof($fp)) {
$line = fgets($fp);
// Match the beginning of a section.
- if (ereg('^--([A-Z]+)--',$line,$r)) {
+ if (preg_match('/^--([A-Z]+)--/',$line,$r)) {
$section = $r[1];
$section_text[$section] = '';
continue;
@@ -1211,14 +1211,14 @@ class testHarness {
if (!$output) return NULL;
if ($this->conf['TEST_PHP_DETAILED'] > 2)
print "SKIPIF: [$output]\n";
- if (eregi("^skip", $output)){
+ if (preg_match("/^skip/i", $output)){
- $reason = (ereg("^skip[[:space:]]*(.+)\$", $output)) ? ereg_replace("^skip[[:space:]]*(.+)\$", "\\1", $output) : FALSE;
+ $reason = (preg_match("/^skip\s*(.+)\$/", $output)) ? preg_replace("/^skip\s*(.+)\$/", "\\1", $output) : FALSE;
$this->showstatus($section_text['TEST'], 'SKIPPED', $reason);
return 'SKIPPED';
}
- if (eregi("^info", $output)) {
- $reason = (ereg("^info[[:space:]]*(.+)\$", $output)) ? ereg_replace("^info[[:space:]]*(.+)\$", "\\1", $output) : FALSE;
+ if (preg_match("/^info/i", $output)) {
+ $reason = (preg_match("/^info\s*(.+)\$/", $output)) ? preg_replace("/^info\s*(.+)\$/", "\\1", $output) : FALSE;
if ($reason) {
$tested .= " (info: $reason)";
}
@@ -1244,19 +1244,19 @@ class testHarness {
$tested = $section_text['TEST']." [$shortname]";
if ($this->conf['TEST_WEB']) {
- $tmp_file = ereg_replace('\.phpt$','.'.$this->conf['TEST_WEB_EXT'],$file);
+ $tmp_file = preg_replace('/\.phpt$/','.'.$this->conf['TEST_WEB_EXT'],$file);
$uri = $this->conf['TEST_BASE_SCRIPT_NAME'].str_replace($this->conf['TEST_BASE_PATH'], '', $tmp_file);
$uri = str_replace('\\', '/', $uri);
} else {
- $tmp_file = ereg_replace('\.phpt$','.php',$file);
+ $tmp_file = preg_replace('/\.phpt$/','.php',$file);
}
@unlink($tmp_file);
// unlink old test results
- @unlink(ereg_replace('\.phpt$','.diff',$file));
- @unlink(ereg_replace('\.phpt$','.log',$file));
- @unlink(ereg_replace('\.phpt$','.exp',$file));
- @unlink(ereg_replace('\.phpt$','.out',$file));
+ @unlink(preg_replace('/\.phpt$/','.diff',$file));
+ @unlink(preg_replace('/\.phpt$/','.log',$file));
+ @unlink(preg_replace('/\.phpt$/','.exp',$file));
+ @unlink(preg_replace('/\.phpt$/','.out',$file));
if (!$this->conf['TEST_WEB']) {
// Reset environment from any previous test.
@@ -1425,15 +1425,68 @@ class testHarness {
}
$wanted_re = preg_replace('/\r\n/',"\n",$wanted);
if (isset($section_text['EXPECTF'])) {
- $wanted_re = preg_quote($wanted_re, '/');
+ // do preg_quote, but miss out any %r delimited sections
+ $temp = "";
+ $r = "%r";
+ $startOffset = 0;
+ $length = strlen($wanted_re);
+ while($startOffset < $length) {
+ $start = strpos($wanted_re, $r, $startOffset);
+ if ($start !== false) {
+ // we have found a start tag
+ $end = strpos($wanted_re, $r, $start+2);
+ if ($end === false) {
+ // unbalanced tag, ignore it.
+ $end = $start = $length;
+ }
+ } else {
+ // no more %r sections
+ $start = $end = $length;
+ }
+ // quote a non re portion of the string
+ $temp = $temp . preg_quote(substr($wanted_re, $startOffset, ($start - $startOffset)), '/');
+ // add the re unquoted.
+ if ($end > $start) {
+ $temp = $temp . '(' . substr($wanted_re, $start+2, ($end - $start-2)). ')';
+ }
+ $startOffset = $end + 2;
+ }
+ $wanted_re = $temp;
+
+ $wanted_re = str_replace(
+ array('%binary_string_optional%'),
+ 'string',
+ $wanted_re
+ );
+ $wanted_re = str_replace(
+ array('%unicode_string_optional%'),
+ 'string',
+ $wanted_re
+ );
+ $wanted_re = str_replace(
+ array('%unicode\|string%', '%string\|unicode%'),
+ 'string',
+ $wanted_re
+ );
+ $wanted_re = str_replace(
+ array('%u\|b%', '%b\|u%'),
+ '',
+ $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);
+ $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);
// %f allows two points "-.0.0" but that is the best *simple* expression
+
}
/* DEBUG YOUR REGEX HERE
var_dump($wanted_re);
@@ -1489,8 +1542,8 @@ class testHarness {
$this->failed_tests[] = array(
'name' => $file,
'test_name' => $tested,
- 'output' => ereg_replace('\.phpt$','.log', $file),
- 'diff' => ereg_replace('\.phpt$','.diff', $file)
+ 'output' => preg_replace('/\.phpt$/','.log', $file),
+ 'diff' => preg_replace('/\.phpt$/','.diff', $file)
);
if ($this->conf['TEST_PHP_DETAILED'])
@@ -1498,25 +1551,25 @@ class testHarness {
// write .exp
if (strpos($this->conf['TEST_PHP_LOG_FORMAT'],'E') !== FALSE) {
- $logname = ereg_replace('\.phpt$','.exp',$file);
+ $logname = preg_replace('/\.phpt$/','.exp',$file);
file_put_contents($logname,$wanted);
}
// write .out
if (strpos($this->conf['TEST_PHP_LOG_FORMAT'],'O') !== FALSE) {
- $logname = ereg_replace('\.phpt$','.out',$file);
+ $logname = preg_replace('/\.phpt$/','.out',$file);
file_put_contents($logname,$output);
}
// write .diff
if (strpos($this->conf['TEST_PHP_LOG_FORMAT'],'D') !== FALSE) {
- $logname = ereg_replace('\.phpt$','.diff',$file);
+ $logname = preg_replace('/\.phpt$/','.diff',$file);
file_put_contents($logname,generate_diff($wanted,$output));
}
// write .log
if (strpos($this->conf['TEST_PHP_LOG_FORMAT'],'L') !== FALSE) {
- $logname = ereg_replace('\.phpt$','.log',$file);
+ $logname = preg_replace('/\.phpt$/','.log',$file);
file_put_contents($logname,
"\n---- EXPECTED OUTPUT\n$wanted\n".
"---- ACTUAL OUTPUT\n$output\n".
diff --git a/tests/basic/php_egg_logo_guid.phpt b/tests/basic/php_egg_logo_guid.phpt
deleted file mode 100644
index b3c5d7bdfd..0000000000
--- a/tests/basic/php_egg_logo_guid.phpt
+++ /dev/null
@@ -1,13 +0,0 @@
---TEST--
-Testing php_egg_logo_guid() function
---FILE--
-<?php
-echo php_egg_logo_guid();
-?>
---EXPECT--
-PHPE9568F36-D428-11d2-A769-00AA001ACF42
-
---CREDITS--
-Jason Easter <easter@phpug-wuerzburg.de>
-PHPUG Würzburg <phpug-wuerzburg.de>
-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
deleted file mode 100644
index b5724a96ab..0000000000
--- a/tests/basic/php_logo_guid.phpt
+++ /dev/null
@@ -1,10 +0,0 @@
---TEST--
-Testing php_logo_guid() function
---FILE--
-<?php
-echo php_logo_guid();
-?>
---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
deleted file mode 100644
index 2b9003a350..0000000000
--- a/tests/basic/php_real_logo_guid.phpt
+++ /dev/null
@@ -1,12 +0,0 @@
---TEST--
-Testing php_real_logo_guid() function
---FILE--
-<?php
-echo php_real_logo_guid();
-?>
---EXPECT--
-PHPE9568F34-D428-11d2-A769-00AA001ACF42
---CREDITS--
-Jason Easter <easter@phpug-wuerzburg.de>
-PHPUG Würzburg <phpug-wuerzburg.de>
-Testfest 2009 2009-06-20 \ No newline at end of file
diff --git a/tests/basic/req60524-win.phpt b/tests/basic/req60524-win.phpt
new file mode 100644
index 0000000000..b2e7cfdab4
--- /dev/null
+++ b/tests/basic/req60524-win.phpt
@@ -0,0 +1,13 @@
+--TEST--
+Req #60524 (Specify temporary directory)
+--INI--
+sys_temp_dir=C:\Windows
+--SKIPIF--
+<?php
+if( substr(PHP_OS, 0, 3) != "WIN" )
+ die('skip Run only on Windows');
+?>
+--FILE--
+<?php echo sys_get_temp_dir(); ?>
+--EXPECT--
+C:\\Windows
diff --git a/tests/basic/req60524.phpt b/tests/basic/req60524.phpt
new file mode 100644
index 0000000000..7cc3edfabf
--- /dev/null
+++ b/tests/basic/req60524.phpt
@@ -0,0 +1,14 @@
+--TEST--
+Req #60524 (Specify temporary directory)
+--INI--
+sys_temp_dir=/path/to/temp/dir
+--SKIPIF--
+<?php
+if (substr(PHP_OS, 0, 3) == 'WIN') {
+ die('skip non-windows only test');
+}
+?>
+--FILE--
+<?php echo sys_get_temp_dir(); ?>
+--EXPECT--
+/path/to/temp/dir
diff --git a/tests/basic/zend_logo_guid.phpt b/tests/basic/zend_logo_guid.phpt
deleted file mode 100644
index 23ca0165ae..0000000000
--- a/tests/basic/zend_logo_guid.phpt
+++ /dev/null
@@ -1,13 +0,0 @@
---TEST--
-Testing zend_logo_guid() function
---FILE--
-<?php
-echo zend_logo_guid();
-?>
---EXPECT--
-PHPE9568F35-D428-11d2-A769-00AA001ACF42
-
---CREDITS--
-Jason Easter <easter@phpug-wuerzburg.de>
-PHPUG Würzburg <phpug-wuerzburg.de>
-Testfest 2009 2009-06-20 \ No newline at end of file
diff --git a/tests/classes/bug65768.phpt b/tests/classes/bug65768.phpt
new file mode 100644
index 0000000000..17ec93cf24
--- /dev/null
+++ b/tests/classes/bug65768.phpt
@@ -0,0 +1,36 @@
+--TEST--
+Bug #65768: date_diff accepts only DateTime instance even though docs say about DateTimeInterface
+--INI--
+date.timezone=Europe/London
+--FILE--
+<?php
+
+$dt1 = new DateTime("2010-10-20");
+$dti1 = new DateTimeImmutable("2010-10-25");
+$dti2 = new DateTimeImmutable("2010-10-28");
+
+$diff1 = $dt1->diff($dti1);
+echo $diff1->y, " ", $diff1->m, " ", $diff1->d, " ",
+ $diff1->h, " ", $diff1->i, " ", $diff1->s, "\n";
+
+$diff2 = $dti1->diff($dti2);
+echo $diff2->y, " ", $diff2->m, " ", $diff2->d, " ",
+ $diff2->h, " ", $diff2->i, " ", $diff2->s, "\n";
+
+$diff3 = date_diff($dt1, $dti2);
+echo $diff3->y, " ", $diff3->m, " ", $diff3->d, " ",
+ $diff3->h, " ", $diff3->i, " ", $diff3->s, "\n";
+
+class cdt1 extends DateTime implements DateTimeInterface {}
+
+class cdt2 extends DateTimeImmutable implements DateTimeInterface {}
+
+class cdt3 implements DateTimeInterface {}
+
+?>
+--EXPECTF--
+0 0 5 0 0 0
+0 0 3 0 0 0
+0 0 8 0 0 0
+
+Fatal error: DateTimeInterface can't be implemented by user classes in %sbug65768.php on line %d
diff --git a/tests/classes/implicit_instantiation_001.phpt b/tests/classes/implicit_instantiation_001.phpt
index 8d2f32da21..51427df1e8 100644
--- a/tests/classes/implicit_instantiation_001.phpt
+++ b/tests/classes/implicit_instantiation_001.phpt
@@ -20,7 +20,7 @@ foreach($c as $name => $value) {
echo "\n --> Attempting implicit conversion to object using increment...\n";
$c->$name->prop++;
$c->$name = $value; // reset value in case implicit conversion was successful
-
+
echo "\n --> Attempting implicit conversion to object using assignment...\n";
$c->$name->prop = "Implicit instantiation!";
$c->$name = $value; // reset value in case implicit conversion was successful
@@ -41,6 +41,8 @@ var_dump($c);
Warning: Creating default object from empty value in %s on line 18
+Notice: Undefined property: stdClass::$prop in %s on line 18
+
--> Attempting implicit conversion to object using assignment...
Warning: Creating default object from empty value in %s on line 22
@@ -49,12 +51,16 @@ Warning: Creating default object from empty value in %s on line 22
Warning: Creating default object from empty value in %s on line 26
+Notice: Undefined property: stdClass::$prop in %s on line 26
+
---( $c->emptyString )---
--> Attempting implicit conversion to object using increment...
Warning: Creating default object from empty value in %s on line 18
+Notice: Undefined property: stdClass::$prop in %s on line 18
+
--> Attempting implicit conversion to object using assignment...
Warning: Creating default object from empty value in %s on line 22
@@ -63,12 +69,16 @@ Warning: Creating default object from empty value in %s on line 22
Warning: Creating default object from empty value in %s on line 26
+Notice: Undefined property: stdClass::$prop in %s on line 26
+
---( $c->null )---
--> Attempting implicit conversion to object using increment...
Warning: Creating default object from empty value in %s on line 18
+Notice: Undefined property: stdClass::$prop in %s on line 18
+
--> Attempting implicit conversion to object using assignment...
Warning: Creating default object from empty value in %s on line 22
@@ -77,6 +87,8 @@ Warning: Creating default object from empty value in %s on line 22
Warning: Creating default object from empty value in %s on line 26
+Notice: Undefined property: stdClass::$prop in %s on line 26
+
---( $c->boolTrue )---
--> Attempting implicit conversion to object using increment...
@@ -143,4 +155,4 @@ Warning: Attempt to assign property of non-object in %s on line 26
%unicode|string%(5) "hello"
[%u|b%"intZero"]=>
int(0)
-} \ No newline at end of file
+}
diff --git a/tests/func/011.phpt b/tests/func/011.phpt
new file mode 100644
index 0000000000..ec93214a78
--- /dev/null
+++ b/tests/func/011.phpt
@@ -0,0 +1,10 @@
+--TEST--
+Test bitwise AND, OR, XOR, NOT and logical NOT in INI via error_reporting
+--INI--
+error_reporting = E_ALL & E_NOTICE | E_STRICT ^ E_DEPRECATED & ~E_WARNING | !E_ERROR
+--FILE--
+<?php
+echo ini_get('error_reporting');
+?>
+--EXPECT--
+10248
diff --git a/tests/func/bug64523.phpt b/tests/func/bug64523.phpt
new file mode 100644
index 0000000000..e0092ada64
--- /dev/null
+++ b/tests/func/bug64523.phpt
@@ -0,0 +1,10 @@
+--TEST--
+Bug #64523: XOR not parsed in INI
+--INI--
+error_reporting = E_ALL ^ E_NOTICE ^ E_STRICT ^ E_DEPRECATED
+--FILE--
+<?php
+echo ini_get('error_reporting');
+?>
+--EXPECTF--
+22519
diff --git a/tests/lang/bug24403.phpt b/tests/lang/bug24403.phpt
index fe99257d3d..8f4934e7b9 100644
--- a/tests/lang/bug24403.phpt
+++ b/tests/lang/bug24403.phpt
@@ -17,4 +17,5 @@ class a
}
new a();
?>
---EXPECT--
+--EXPECTF--
+Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in %s on line %d
diff --git a/tests/lang/foreachLoop.007.phpt b/tests/lang/foreachLoop.007.phpt
deleted file mode 100644
index f47fdc735f..0000000000
--- a/tests/lang/foreachLoop.007.phpt
+++ /dev/null
@@ -1,11 +0,0 @@
---TEST--
-Foreach loop tests - error case: reference to constant array.
---FILE--
-<?php
-echo "\nReference to constant array\n";
-foreach (array(1,2) as &$v) {
- var_dump($v);
-}
-?>
---EXPECTF--
-Parse error: %s on line 3
diff --git a/tests/lang/foreachLoop.008.phpt b/tests/lang/foreachLoop.008.phpt
deleted file mode 100644
index 787f43b883..0000000000
--- a/tests/lang/foreachLoop.008.phpt
+++ /dev/null
@@ -1,10 +0,0 @@
---TEST--
-Foreach loop tests - error case: reference to constant array, with key.
---FILE--
-<?php
-foreach (array(1,2) as $k=>&$v) {
- var_dump($v);
-}
-?>
---EXPECTF--
-Fatal error: Cannot create references to elements of a temporary array expression in %s on line 2
diff --git a/tests/output/ob_017.phpt b/tests/output/ob_017.phpt
index 517fafe991..1dc5fc59be 100644
--- a/tests/output/ob_017.phpt
+++ b/tests/output/ob_017.phpt
@@ -1,5 +1,7 @@
--TEST--
output buffering - stati
+--INI--
+opcache.optimization_level=0
--FILE--
<?php
$stati = array();
diff --git a/tests/output/ob_start_basic_004.phpt b/tests/output/ob_start_basic_004.phpt
index 16f09e8a9a..710df7a8a0 100644
--- a/tests/output/ob_start_basic_004.phpt
+++ b/tests/output/ob_start_basic_004.phpt
@@ -1,5 +1,7 @@
--TEST--
ob_start() chunk_size: confirm buffer is flushed after any output call that causes its length to equal or exceed chunk_size.
+--INI--
+opcache.optimization_level=0
--FILE--
<?php
/*
diff --git a/tests/strings/001.phpt b/tests/strings/001.phpt
index 3bfd3dbc30..98ceceb350 100644
--- a/tests/strings/001.phpt
+++ b/tests/strings/001.phpt
@@ -177,9 +177,23 @@ if ($ss == "\$'") {
}
-echo "Testing uniqid: ";
+echo "Testing uniqid(true): ";
+$str = "prefix";
+$ui1 = uniqid($str, true);
+$ui2 = uniqid($str, true);
+
+$len = 29;
+
+if (strlen($ui1) == strlen($ui2) && strlen($ui1) == $len && $ui1 != $ui2) {
+ echo("passed\n");
+} else {
+ echo("failed!\n");
+}
+
+echo "Testing uniqid(false): ";
$str = "prefix";
$ui1 = uniqid($str);
+usleep( 1 );
$ui2 = uniqid($str);
$len = strncasecmp(PHP_OS, 'CYGWIN', 6) ? 19 : 29;
@@ -207,4 +221,5 @@ Testing ufirst: passed
Testing strtr: passed
Testing addslashes: passed
Testing stripslashes: passed
-Testing uniqid: passed
+Testing uniqid(true): passed
+Testing uniqid(false): passed
diff --git a/travis/compile.sh b/travis/compile.sh
new file mode 100755
index 0000000000..2b53099651
--- /dev/null
+++ b/travis/compile.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+./buildconf
+./configure --quiet \
+--with-pdo-mysql=mysqlnd \
+--with-mysql=mysqlnd \
+--with-mysqli=mysqlnd \
+--with-pgsql \
+--with-pdo-pgsql \
+--with-pdo-sqlite \
+--enable-intl \
+--without-pear \
+--with-gd \
+--with-jpeg-dir=/usr \
+--with-png-dir=/usr \
+--enable-exif \
+--enable-zip \
+--with-zlib \
+--with-zlib-dir=/usr \
+--with-mcrypt=/usr \
+--enable-soap \
+--enable-xmlreader \
+--with-xsl \
+--with-curl=/usr \
+--with-tidy \
+--with-xmlrpc \
+--enable-sysvsem \
+--enable-sysvshm \
+--enable-shmop \
+--enable-pcntl \
+--with-readline \
+--enable-mbstring \
+--with-curl \
+--with-gettext \
+--enable-sockets \
+--with-bz2 \
+--with-openssl \
+--enable-bcmath
+make --quiet
diff --git a/travis/ext/curl/setup.sh b/travis/ext/curl/setup.sh
new file mode 100755
index 0000000000..74dad16eb3
--- /dev/null
+++ b/travis/ext/curl/setup.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+export PHP_CURL_HTTP_REMOTE_SERVER="http://localhost"
+cd ./ext/curl/tests/responder
+sudo php -S localhost:80 &
+cd - \ No newline at end of file
diff --git a/travis/ext/mysql/setup.sh b/travis/ext/mysql/setup.sh
new file mode 100755
index 0000000000..a3ba75cb2d
--- /dev/null
+++ b/travis/ext/mysql/setup.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+mysql -e "CREATE DATABASE IF NOT EXISTS test"
diff --git a/travis/ext/mysqli/setup.sh b/travis/ext/mysqli/setup.sh
new file mode 100755
index 0000000000..a3ba75cb2d
--- /dev/null
+++ b/travis/ext/mysqli/setup.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+mysql -e "CREATE DATABASE IF NOT EXISTS test"
diff --git a/travis/ext/pdo_mysql/setup.sh b/travis/ext/pdo_mysql/setup.sh
new file mode 100755
index 0000000000..a3ba75cb2d
--- /dev/null
+++ b/travis/ext/pdo_mysql/setup.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+mysql -e "CREATE DATABASE IF NOT EXISTS test"
diff --git a/travis/ext/pdo_pgsql/setup.sh b/travis/ext/pdo_pgsql/setup.sh
new file mode 100755
index 0000000000..6f16f72cc2
--- /dev/null
+++ b/travis/ext/pdo_pgsql/setup.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+export PDO_PGSQL_TEST_DSN='pgsql:host=localhost port=5432 dbname=test user=postgres password=' \ No newline at end of file
diff --git a/travis/ext/pgsql/setup.sh b/travis/ext/pgsql/setup.sh
new file mode 100755
index 0000000000..32b39a4044
--- /dev/null
+++ b/travis/ext/pgsql/setup.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+echo '
+<?php $conn_str .= " user=postgres"; ?>' >> "./ext/pgsql/tests/config.inc"
+psql -c 'create database test;' -U postgres \ No newline at end of file
diff --git a/win32/build/Makefile b/win32/build/Makefile
index e2d62545b8..057b584549 100644
--- a/win32/build/Makefile
+++ b/win32/build/Makefile
@@ -55,10 +55,10 @@ Zend\zend_language_parser.c Zend\zend_language_parser.h: Zend\zend_language_pars
!if $(RE2C) != ""
Zend\zend_ini_scanner.c: Zend\zend_ini_scanner.l
- $(RE2C) $(RE2C_FLAGS) --case-inverted -cbdFt Zend/zend_ini_scanner_defs.h -oZend/zend_ini_scanner.c Zend/zend_ini_scanner.l
+ $(RE2C) $(RE2C_FLAGS) --no-generation-date --case-inverted -cbdFt Zend/zend_ini_scanner_defs.h -oZend/zend_ini_scanner.c Zend/zend_ini_scanner.l
Zend\zend_language_scanner.c: Zend\zend_language_scanner.l
- $(RE2C) $(RE2C_FLAGS) --case-inverted -cbdFt Zend/zend_language_scanner_defs.h -oZend/zend_language_scanner.c Zend/zend_language_scanner.l
+ $(RE2C) $(RE2C_FLAGS) --no-generation-date --case-inverted -cbdFt Zend/zend_language_scanner_defs.h -oZend/zend_language_scanner.c Zend/zend_language_scanner.l
!endif
!if $(PGOMGR) != ""
diff --git a/win32/build/config.w32 b/win32/build/config.w32
index f025ae2f39..849a9372f7 100644
--- a/win32/build/config.w32
+++ b/win32/build/config.w32
@@ -155,7 +155,7 @@ if (VCVERS >= 1400) {
// disable annoying warnings. In addition, time_t defaults
// to 64-bit. Ask for 32-bit.
if (X64) {
- ADD_FLAG('CFLAGS', ' /wd4996 /Wp64 ');
+ ADD_FLAG('CFLAGS', ' /wd4996 ');
} else {
ADD_FLAG('CFLAGS', ' /wd4996 /D_USE_32BIT_TIME_T=1 ');
}
@@ -181,8 +181,13 @@ if (VCVERS >= 1500 && PHP_MP != 'disable') {
}
// General link flags
-DEFINE("LDFLAGS", "/nologo /version:" +
- PHP_VERSION + "." + PHP_MINOR_VERSION + "." + PHP_RELEASE_VERSION);
+
+if (VCVERS >= 1700) {
+ DEFINE("LDFLAGS", "/nologo ");
+} else {
+ DEFINE("LDFLAGS", "/nologo /version:" +
+ PHP_VERSION + "." + PHP_MINOR_VERSION + "." + PHP_RELEASE_VERSION);
+}
// General DLL link flags
DEFINE("DLL_LDFLAGS", "/dll ");
@@ -359,7 +364,7 @@ ADD_SOURCES("Zend", "zend_language_parser.c zend_language_scanner.c \
zend_stream.c zend_iterators.c zend_interfaces.c zend_objects.c \
zend_object_handlers.c zend_objects_API.c \
zend_default_classes.c zend_execute.c zend_strtod.c zend_gc.c zend_closures.c \
- zend_float.c zend_string.c");
+ zend_float.c zend_string.c zend_generators.c");
if (VCVERS == 1200) {
AC_DEFINE('ZEND_DVAL_TO_LVAL_CAST_OK', 1);
@@ -368,7 +373,7 @@ if (VCVERS == 1200) {
ADD_SOURCES("main", "main.c snprintf.c spprintf.c getopt.c fopen_wrappers.c \
php_scandir.c php_ini.c SAPI.c rfc1867.c php_content_types.c strlcpy.c \
strlcat.c mergesort.c reentrancy.c php_variables.c php_ticks.c network.c \
- php_open_temporary_file.c php_logos.c output.c internal_functions.c php_sprintf.c");
+ php_open_temporary_file.c output.c internal_functions.c php_sprintf.c");
ADD_SOURCES("win32", "inet.c fnmatch.c sockets.c");
// Newer versions have it
diff --git a/win32/build/config.w32.h.in b/win32/build/config.w32.h.in
index c6cf076bab..9efdfdea3e 100644
--- a/win32/build/config.w32.h.in
+++ b/win32/build/config.w32.h.in
@@ -6,8 +6,8 @@
/* Define the minimum supported version */
#undef _WIN32_WINNT
#undef NTDDI_VERSION
-#define _WIN32_WINNT 0x0501
-#define NTDDI_VERSION 0x05010200
+#define _WIN32_WINNT 0x0600
+#define NTDDI_VERSION 0x06000100
/* Default PHP / PEAR directories */
#define PHP_CONFIG_FILE_PATH (getenv("SystemRoot"))?getenv("SystemRoot"):""
diff --git a/win32/build/config.w32.phpize.in b/win32/build/config.w32.phpize.in
index b8bf45ea57..7b3b40633b 100644
--- a/win32/build/config.w32.phpize.in
+++ b/win32/build/config.w32.phpize.in
@@ -134,7 +134,7 @@ if (VCVERS >= 1400) {
// disable annoying warnings. In addition, time_t defaults
// to 64-bit. Ask for 32-bit.
if (X64) {
- ADD_FLAG('CFLAGS', ' /wd4996 /Wp64 ');
+ ADD_FLAG('CFLAGS', ' /wd4996 ');
} else {
ADD_FLAG('CFLAGS', ' /wd4996 /D_USE_32BIT_TIME_T=1 ');
}
diff --git a/win32/build/confutils.js b/win32/build/confutils.js
index c0a1ce895b..d9a0c1b5f1 100644
--- a/win32/build/confutils.js
+++ b/win32/build/confutils.js
@@ -46,6 +46,7 @@ VC_VERSIONS[1310] = 'MSVC7.1 (Visual C++ 2003)';
VC_VERSIONS[1400] = 'MSVC8 (Visual C++ 2005)';
VC_VERSIONS[1500] = 'MSVC9 (Visual C++ 2008)';
VC_VERSIONS[1600] = 'MSVC10 (Visual C++ 2010)';
+VC_VERSIONS[1700] = 'MSVC11 (Visual C++ 2012)';
var VC_VERSIONS_SHORT = new Array();
VC_VERSIONS_SHORT[1200] = 'VC6';
@@ -54,6 +55,7 @@ VC_VERSIONS_SHORT[1310] = 'VC7.1';
VC_VERSIONS_SHORT[1400] = 'VC8';
VC_VERSIONS_SHORT[1500] = 'VC9';
VC_VERSIONS_SHORT[1600] = 'VC10';
+VC_VERSIONS_SHORT[1700] = 'VC11';
if (PROGRAM_FILES == null) {
PROGRAM_FILES = "C:\\Program Files";
diff --git a/win32/build/libs_version.txt b/win32/build/libs_version.txt
index ddbd925934..44420ddec8 100644
--- a/win32/build/libs_version.txt
+++ b/win32/build/libs_version.txt
@@ -1,16 +1,16 @@
bz2-1.0.6
-cclient-2007e
+cclient-2007f
freetype-2.4.10
-icu-49.1.2
-jpeglib-8
+icu-51.2
+jpeglib-9
libcurl-7.30.0
libiconv-1.14
libmcrypt-2.5.8
-libmpir-2.5.1
-libpng-1.2.50
-libpq-8.3.6
+libmpir-2.6.0
+libpng-1.5.14
+libpq-9.2.2
libssh2-1.4.2
-libtidy-20090325
+libtidy-20090406
libxslt-1.1.27
-libxml-2.7.8
-openssl-0.9.8y
+libxml-2.9.1
+openssl-1.0.1e
diff --git a/win32/build/mkdist.php b/win32/build/mkdist.php
index 5ed9bdc81a..23d26c9c53 100644
--- a/win32/build/mkdist.php
+++ b/win32/build/mkdist.php
@@ -238,8 +238,6 @@ $text_files = array(
"php.ini-development" => "php.ini-development",
"php.ini-production" => "php.ini-production",
"win32/install.txt" => "install.txt",
- "win32/pws-php5cgi.reg" => "pws-php5cgi.reg",
- "win32/pws-php5isapi.reg" => "pws-php5isapi.reg",
);
foreach ($text_files as $src => $dest) {
@@ -443,7 +441,7 @@ function make_phar_dot_phar($dist_dir)
$phar->setStub(implode('', $stub));
echo "Creating phar.phar.bat\n";
- file_put_contents($dist_dir . '/phar.phar.bat', "%~dp0php.exe %~dp0pharcommand.phar %*\r\n");
+ file_put_contents($dist_dir . '/phar.phar.bat', "\"%~dp0php.exe\" \"%~dp0pharcommand.phar\" %*\r\n");
}
if (!is_dir($test_dir)) {
diff --git a/win32/inet.c b/win32/inet.c
index b794bcaeb4..686cf1265c 100644
--- a/win32/inet.c
+++ b/win32/inet.c
@@ -1,81 +1,5 @@
-#include "config.w32.h"
-#if (_WIN32_WINNT < 0x0600) /* Vista/2k8 have these functions */
-#include "php.h"
-#include <winsock2.h>
-#include <windows.h>
-#include <Ws2tcpip.h>
-
#include "inet.h"
-PHPAPI int inet_pton(int af, const char* src, void* dst)
-{
- int address_length;
- struct sockaddr_storage sa;
- struct sockaddr_in *sin = (struct sockaddr_in *)&sa;
- struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&sa;
-
- switch (af) {
- case AF_INET:
- address_length = sizeof (struct sockaddr_in);
- break;
-
- case AF_INET6:
- address_length = sizeof (struct sockaddr_in6);
- break;
-
- default:
- return -1;
- }
-
- if (WSAStringToAddress ((LPTSTR) src, af, NULL, (LPSOCKADDR) &sa, &address_length) == 0) {
- switch (af) {
- case AF_INET:
- memcpy (dst, &sin->sin_addr, sizeof (struct in_addr));
- break;
-
- case AF_INET6:
- memcpy (dst, &sin6->sin6_addr, sizeof (struct in6_addr));
- break;
- }
- return 1;
- }
-
- return 0;
-}
-
-PHPAPI const char* inet_ntop(int af, const void* src, char* dst, size_t size)
-{
- int address_length;
- DWORD string_length = size;
- struct sockaddr_storage sa;
- struct sockaddr_in *sin = (struct sockaddr_in *)&sa;
- struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&sa;
-
- memset (&sa, 0, sizeof (sa));
- switch (af) {
- case AF_INET:
- address_length = sizeof (struct sockaddr_in);
- sin->sin_family = af;
- memcpy (&sin->sin_addr, src, sizeof (struct in_addr));
- break;
-
- case AF_INET6:
- address_length = sizeof (struct sockaddr_in6);
- sin6->sin6_family = af;
- memcpy (&sin6->sin6_addr, src, sizeof (struct in6_addr));
- break;
-
- default:
- return NULL;
- }
-
- if (WSAAddressToString ((LPSOCKADDR) &sa, address_length, NULL, dst, &string_length) == 0) {
- return dst;
- }
-
- return NULL;
-}
-
int inet_aton(const char *cp, struct in_addr *inp) {
inp->s_addr = inet_addr(cp);
@@ -85,4 +9,3 @@ int inet_aton(const char *cp, struct in_addr *inp) {
return 1;
}
-#endif
diff --git a/win32/inet.h b/win32/inet.h
index e58083828f..d71723759f 100644
--- a/win32/inet.h
+++ b/win32/inet.h
@@ -1,10 +1,4 @@
-#if _MSC_VER >= 1500
-# include <In6addr.h>
-#endif
-#include <Ws2tcpip.h>
+#include <php.h>
+#include <Winsock2.h>
-#if (_WIN32_WINNT < 0x0600)
-PHPAPI int inet_pton(int af, const char* src, void* dst);
-PHPAPI const char* inet_ntop(int af, const void* src, char* dst, size_t size);
PHPAPI int inet_aton(const char *cp, struct in_addr *inp);
-#endif
diff --git a/win32/install.txt b/win32/install.txt
index 2883dd37f5..b240ad2723 100644
--- a/win32/install.txt
+++ b/win32/install.txt
@@ -9,7 +9,7 @@ Installing PHP
Windows Installer
Manual Installation Steps
ActiveScript
- Microsoft IIS / PWS
+ Microsoft IIS
Apache 1.3.x on Microsoft Windows
Apache 2.0.x on Microsoft Windows
Sun, iPlanet and Netscape servers on Microsoft Windows
@@ -211,7 +211,7 @@ Windows Installer (PHP 5.1.0 and earlier)
The Windows PHP installer is available from the downloads page at
http://www.php.net/downloads.php. This installs the CGI version of PHP
- and for IIS, PWS, and Xitami, it configures the web server as well. The
+ and for IIS and Xitami, it configures the web server as well. The
installer does not include any extra external PHP extensions
(php_*.dll) as you'll only find those in the Windows Zip Package and
PECL downloads.
@@ -433,7 +433,7 @@ c:\php
follow the next step. Set the doc_root to point to your web servers
document_root. For example:
-doc_root = c:\inetpub\wwwroot // for IIS/PWS
+doc_root = c:\inetpub\wwwroot // for IIS
doc_root = c:\apache\htdocs // for Apache
@@ -442,11 +442,6 @@ doc_root = c:\apache\htdocs // for Apache
what is already built in. Note that on a new installation it is
advisable to first get PHP working and tested without any
extensions before enabling them in php.ini.
- * On PWS and IIS, you can set the browscap configuration setting to
- point to: c:\windows\system\inetsrv\browscap.ini on Windows 9x/Me,
- c:\winnt\system32\inetsrv\browscap.ini on NT/2000, and
- c:\windows\system32\inetsrv\browscap.ini on XP. For an up-to-date
- browscap.ini, read the following FAQ.
PHP is now setup on your system. The next step is to choose a web
server, and enable it to run PHP. Choose a web server from the table of
@@ -499,7 +494,7 @@ ActiveScript
folder, if you wish to load extensions, etc.
__________________________________________________________________
-Microsoft IIS / PWS
+Microsoft IIS
This section contains notes and hints specific to IIS (Microsoft
Internet Information Server).
@@ -511,7 +506,7 @@ Microsoft IIS / PWS
yourself from those attacks.
__________________________________________________________________
-General considerations for all installations of PHP with IIS or PWS
+General considerations for all installations of PHP with IIS
* First, read the Manual Installation Instructions. Do not skip this
step as it provides crucial information for installing PHP on
@@ -543,7 +538,7 @@ General considerations for all installations of PHP with IIS or PWS
downloaded in the "Collection of PECL modules" package. Files such
as php_zip.dll and php_ssh2.dll. Download PHP files here.
* When defining the executable, the 'check that file exists' box may
- also be checked. For a small performance penalty, the IIS (or PWS)
+ also be checked. For a small performance penalty, the IIS
will check that the script file exists and sort out authentication
before firing up PHP. This means that the web server will provide
sensible 404 style error messages instead of CGI errors complaining
@@ -1579,7 +1574,7 @@ cgi error:
11. Windows: I've followed all the instructions, but still can't get
PHP and IIS to work together!
- 12. When running PHP as CGI with IIS, PWS, OmniHTTPD or Xitami, I get
+ 12. When running PHP as CGI with IIS, OmniHTTPD or Xitami, I get
the following error: Security Alert! PHP CGI cannot be accessed
directly..
@@ -1824,7 +1819,7 @@ cgi error:
tell it that PHP is a script engine. Also, you will want to read this
faq.
- 12. When running PHP as CGI with IIS, PWS, OmniHTTPD or Xitami, I get
+ 12. When running PHP as CGI with IIS, OmniHTTPD or Xitami, I get
the following error: Security Alert! PHP CGI cannot be accessed
directly..
diff --git a/win32/php5dll.dsp b/win32/php5dll.dsp
index 2216d7dfe6..cc56f538af 100644
--- a/win32/php5dll.dsp
+++ b/win32/php5dll.dsp
@@ -164,10 +164,6 @@ SOURCE=..\main\php_ini.c
# End Source File
# Begin Source File
-SOURCE=..\main\php_logos.c
-# End Source File
-# Begin Source File
-
SOURCE=..\main\php_open_temporary_file.c
# End Source File
# Begin Source File
@@ -288,10 +284,6 @@ SOURCE=..\main\php_ini.h
# End Source File
# Begin Source File
-SOURCE=..\main\php_logos.h
-# End Source File
-# Begin Source File
-
SOURCE=..\main\php_open_temporary_file.h
# End Source File
# Begin Source File
diff --git a/win32/php5dllts.dsp b/win32/php5dllts.dsp
index a8e93ec5e7..3755ea79f9 100644
--- a/win32/php5dllts.dsp
+++ b/win32/php5dllts.dsp
@@ -201,10 +201,6 @@ SOURCE=..\main\php_ini.c
# End Source File
# Begin Source File
-SOURCE=..\main\php_logos.c
-# End Source File
-# Begin Source File
-
SOURCE=..\main\php_open_temporary_file.c
# End Source File
# Begin Source File
@@ -317,10 +313,6 @@ SOURCE=..\main\php_ini.h
# End Source File
# Begin Source File
-SOURCE=..\main\php_logos.h
-# End Source File
-# Begin Source File
-
SOURCE=..\main\php_main.h
# End Source File
# Begin Source File
diff --git a/win32/pws-php5cgi.reg b/win32/pws-php5cgi.reg
deleted file mode 100644
index 46edc77386..0000000000
--- a/win32/pws-php5cgi.reg
+++ /dev/null
@@ -1,6 +0,0 @@
-REGEDIT4
-
-[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\w3svc\parameters\Script Map]
-".php"="[PUT PATH HERE]\\php.exe"
-
-
diff --git a/win32/pws-php5isapi.reg b/win32/pws-php5isapi.reg
deleted file mode 100644
index 393604d28d..0000000000
--- a/win32/pws-php5isapi.reg
+++ /dev/null
@@ -1,5 +0,0 @@
-REGEDIT4
-
-[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\w3svc\parameters\Script Map]
-".php"="[PUT PATH HERE]\\php5isapi.dll"
-
diff --git a/win32/select.c b/win32/select.c
index 94d4a6988c..8e44636945 100644
--- a/win32/select.c
+++ b/win32/select.c
@@ -36,7 +36,7 @@
* */
PHPAPI int php_select(int max_fd, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tv)
{
- DWORD ms_total, limit;
+ ULONGLONG ms_total, limit;
HANDLE handles[MAXIMUM_WAIT_OBJECTS];
int handle_slot_to_fd[MAXIMUM_WAIT_OBJECTS];
int n_handles = 0, i;
@@ -97,7 +97,7 @@ PHPAPI int php_select(int max_fd, fd_set *rfds, fd_set *wfds, fd_set *efds, stru
FD_ZERO(&awrite);
FD_ZERO(&aexcept);
- limit = GetTickCount() + ms_total;
+ limit = GetTickCount64() + ms_total;
do {
retcode = 0;
@@ -149,7 +149,7 @@ PHPAPI int php_select(int max_fd, fd_set *rfds, fd_set *wfds, fd_set *efds, stru
}
}
}
- } while (retcode == 0 && (ms_total == INFINITE || GetTickCount() < limit));
+ } while (retcode == 0 && (ms_total == INFINITE || GetTickCount64() < limit));
if (rfds) {
*rfds = aread;
diff --git a/win32/sendmail.c b/win32/sendmail.c
index f541016f58..93e68f4b1a 100644
--- a/win32/sendmail.c
+++ b/win32/sendmail.c
@@ -25,6 +25,7 @@
#ifndef NETWARE
#include <winsock2.h>
#include "time.h"
+# include <Ws2tcpip.h>
#else /* NETWARE */
#include <netware/sendmail_nw.h>
#endif /* NETWARE */
diff --git a/win32/syslog.reg b/win32/syslog.reg
index 4d3e273970..cb12d6e6b9 100644
--- a/win32/syslog.reg
+++ b/win32/syslog.reg
@@ -2,4 +2,4 @@ REGEDIT4
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application\PHP-5.3.99-dev]
"TypesSupported"=dword:00000007
-"EventMessageFile"="g:\\test\\srcinstall6\\php5ts_debug.dll"
+"EventMessageFile"="g:\\test\\srctrunkinstall\\php5ts.dll"