summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-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.c754
-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.c1070
-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.c356
-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/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.w3232
-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.c2090
-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/README216
-rw-r--r--ext/opcache/ZendAccelerator.c2818
-rw-r--r--ext/opcache/ZendAccelerator.h397
-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.inc3
-rw-r--r--ext/opcache/tests/blacklist.phpt32
-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/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/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/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.c759
-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.c343
-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.c4
-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.c98
-rw-r--r--ext/session/mod_files.h2
-rw-r--r--ext/session/mod_mm.c61
-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.c246
-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_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.c11
-rw-r--r--ext/soap/tests/bugs/bug34657.phpt7
-rw-r--r--ext/soap/tests/bugs/bug47273.phpt3
-rw-r--r--ext/sockets/config.m42
-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.h32
-rw-r--r--ext/sockets/sendrecvmsg.c454
-rw-r--r--ext/sockets/sendrecvmsg.h36
-rw-r--r--ext/sockets/sockaddr_conv.c136
-rw-r--r--ext/sockets/sockaddr_conv.h31
-rw-r--r--ext/sockets/sockets.c716
-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.h12
-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/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/bug22414.phpt2
-rw-r--r--ext/standard/tests/file/disk_free_space_basic.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/parse_ini_file.phpt36
-rw-r--r--ext/standard/tests/general_functions/boolval.phpt29
-rw-r--r--ext/standard/tests/general_functions/parse_ini_string_001.phpt36
-rw-r--r--ext/standard/tests/mail/mail_log.phpt48
-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/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/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
1183 files changed, 76930 insertions, 22102 deletions
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 868acec870..1e7837b098 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 010b8d4d13..d881494cb5 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 ce4bdd67c0..ecf395b161 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 ad92849743..5450370cd9 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 556f356b97..e153d35804 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 597b059951..355779e4ad 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..91dfd275b5
--- /dev/null
+++ b/ext/curl/curl_file.c
@@ -0,0 +1,177 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 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 d122051ade..9fdb57cc4e 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 38c1f1a53f..af78651ba1 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 911d87a6b4..c45ed80fc2 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..d1aed87940
--- /dev/null
+++ b/ext/curl/share.c
@@ -0,0 +1,136 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 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 2683ae0880..0000000000
--- a/ext/curl/streams.c
+++ /dev/null
@@ -1,542 +0,0 @@
-/*
- +----------------------------------------------------------------------+
- | PHP Version 5 |
- +----------------------------------------------------------------------+
- | Copyright (c) 1997-2013 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 f510a665e8..0e99e231d6 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 480ea38d91..e669c855a4 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 2f457a9882..84354e300f 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 2acb765e63..3f8e1254ef 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 e15a38150c..23fe202ba9 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 2bb555a68b..742a2f60c3 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);
}
/* }}} */
@@ -1941,7 +1991,10 @@ zend_object_iterator *date_object_period_get_iterator(zend_class_entry *ce, zval
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);
INIT_CLASS_ENTRY(ce_date, "DateTime", date_funcs_date);
ce_date.create_object = date_object_new_date;
@@ -1951,6 +2004,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 +2021,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 +2136,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 +2175,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 +2291,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 +2639,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 +2679,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 +2717,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 +2807,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 +2997,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 +3007,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 +3016,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 +3038,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,50 +3074,125 @@ 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;
+ int bias = 1;
+
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);
DATE_CHECK_INITIALIZED(intobj->initialized, DateInterval);
- new_time = timelib_add(dateobj->time, intobj->diff);
- timelib_time_dtor(dateobj->time);
- dateobj->time = new_time;
+ if (intobj->diff->have_weekday_relative || intobj->diff->have_special_relative) {
+ memcpy(&dateobj->time->relative, intobj->diff, sizeof(struct timelib_rel_time));
+ } else {
+ if (intobj->diff->invert) {
+ bias = -1;
+ }
+ memset(&dateobj->time->relative, 0, sizeof(struct timelib_rel_time));
+ dateobj->time->relative.y = intobj->diff->y * bias;
+ dateobj->time->relative.m = intobj->diff->m * bias;
+ dateobj->time->relative.d = intobj->diff->d * bias;
+ dateobj->time->relative.h = intobj->diff->h * bias;
+ dateobj->time->relative.i = intobj->diff->i * bias;
+ dateobj->time->relative.s = intobj->diff->s * bias;
+ }
+ dateobj->time->have_relative = 1;
+ dateobj->time->sse_uptodate = 0;
+
+ timelib_update_ts(dateobj->time, NULL);
+ timelib_update_from_sse(dateobj->time);
+ dateobj->time->have_relative = 0;
+}
+
+/* {{{ 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;
+ int bias = 1;
+
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);
@@ -2930,15 +3203,61 @@ PHP_FUNCTION(date_sub)
return;
}
- new_time = timelib_sub(dateobj->time, intobj->diff);
- timelib_time_dtor(dateobj->time);
- dateobj->time = new_time;
+ if (intobj->diff->invert) {
+ bias = -1;
+ }
+
+ memset(&dateobj->time->relative, 0, sizeof(struct timelib_rel_time));
+ dateobj->time->relative.y = 0 - (intobj->diff->y * bias);
+ dateobj->time->relative.m = 0 - (intobj->diff->m * bias);
+ dateobj->time->relative.d = 0 - (intobj->diff->d * bias);
+ dateobj->time->relative.h = 0 - (intobj->diff->h * bias);
+ dateobj->time->relative.i = 0 - (intobj->diff->i * bias);
+ dateobj->time->relative.s = 0 - (intobj->diff->s * bias);
+ dateobj->time->have_relative = 1;
+ dateobj->time->sse_uptodate = 0;
+
+ timelib_update_ts(dateobj->time, NULL);
+ timelib_update_from_sse(dateobj->time);
+
+ dateobj->time->have_relative = 0;
+}
+
+/* {{{ 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 +3266,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 +3295,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 +3309,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 +3356,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 +3382,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 +3492,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 +3586,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);
@@ -3257,6 +3701,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 +4395,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_date, &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 +4426,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 +4442,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 +4902,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 be0df38b69..536629a25f 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 082aa5cdb6..34aa635a54 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 7534568d39..47dd576496 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 e1359b65e9..05ee95c0ec 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 485b1997e6..eeece57011 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 3cd97702b3..cc09b3dd80 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 d17c7cbd55..efe6d9070f 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 f4183d2f9a..6c8cf84e9f 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 bd9c98756b..db8ec83a44 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 14bd256a42..4a34357ccf 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 6496ccdb6a..12aebcf366 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 9bc53a0e47..65e61dfea7 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 03b00bd9f6..39433d6ece 100644
--- a/ext/filter/logical_filters.c
+++ b/ext/filter/logical_filters.c
@@ -781,6 +781,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 cbe1c47200..e31f0f0817 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 b82017e21f..30b3ba6285 100644
--- a/ext/ftp/ftp.c
+++ b/ext/ftp/ftp.c
@@ -790,7 +790,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];
@@ -828,7 +827,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;
@@ -1187,12 +1185,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 0e35eceba3..c9e080faab 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
@@ -259,50 +251,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
@@ -310,36 +273,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"
@@ -363,8 +323,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
@@ -378,8 +337,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
@@ -392,44 +350,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
@@ -439,9 +381,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/"
@@ -454,7 +395,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 3279463b7e..fb258214a1 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);
@@ -1703,6 +1619,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 +1790,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 +1808,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 +2082,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 +2092,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 +2111,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 +2131,6 @@ PHP_FUNCTION(imagesetbrush)
RETURN_TRUE;
}
/* }}} */
-#endif
/* {{{ proto resource imagecreate(int x_size, int y_size)
Create a new image */
@@ -2230,19 +2163,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 +2183,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 +2225,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 +2257,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 +2310,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 +2334,6 @@ PHP_FUNCTION(imagecreatefromstring)
ZEND_REGISTER_RESOURCE(return_value, im, le_gd);
}
/* }}} */
-#endif
/* {{{ _php_image_create_from
*/
@@ -2434,9 +2345,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 +2361,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 +2398,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 +2413,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 +2422,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 +2434,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 +2449,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 +2456,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 +2478,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 +2494,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 +2505,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 +2512,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 +2521,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 +2536,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 +2580,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 +2589,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 +2604,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 +2632,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 +2641,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 +2658,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 +2691,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 +2704,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 +2718,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 +2737,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 +2744,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 +2753,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 +2760,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 +2804,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 +2821,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 +2872,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 +2889,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 */
@@ -3758,7 +3610,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 +3667,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 +3744,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 +3760,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 +3790,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 +3810,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 +3836,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 +3845,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 +4327,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 +4334,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 +4345,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 +4355,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 +4401,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 +4425,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 +4464,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 +4471,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 +4483,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 +4583,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 \
@@ -5045,7 +4861,7 @@ PHP_FUNCTION(imageconvolution)
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);
+ 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 +4869,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 +4880,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 +4936,428 @@ 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) {
+ 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) {
+ 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) {
+ 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) {
+ 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:
+ convert_to_double_ex(zval_affine_elem);
+ affine[i] = Z_DVAL_PP(zval_affine_elem);
+ 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) {
+ convert_to_long_ex(tmp);
+ 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) {
+ convert_to_long_ex(tmp);
+ 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) {
+ convert_to_long_ex(tmp);
+ 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) {
+ convert_to_long_ex(tmp);
+ 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) {
+ convert_to_double_ex(tmp);
+ 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) {
+ convert_to_double_ex(tmp);
+ 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:
+ convert_to_double_ex(tmp);
+ m1[i] = Z_DVAL_PP(tmp);
+ 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:
+ convert_to_double_ex(tmp);
+ m2[i] = Z_DVAL_PP(tmp);
+ 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 b0e8aa66ab..2a0b500e9e 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..f0b888a4f1
--- /dev/null
+++ b/ext/gd/libgd/gd_crop.c
@@ -0,0 +1,356 @@
+/**
+ * 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;
+
+ if (src->trueColor) {
+ dst = gdImageCreateTrueColor(crop->width, crop->height);
+ gdImageSaveAlpha(dst, 1);
+ } else {
+ dst = gdImageCreate(crop->width, crop->height);
+ gdImagePaletteCopy(dst, src);
+ }
+ dst->transparent = src->transparent;
+
+ if (src->sx < (crop->x + crop->width -1)) {
+ crop->width = src->sx - crop->x + 1;
+ }
+ if (src->sy < (crop->y + crop->height -1)) {
+ crop->height = src->sy - crop->y + 1;
+ }
+#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
+ if (dst == NULL) {
+ return NULL;
+ } else {
+ int 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 70bc85a08b..22fac40dd0 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/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 f5dca3fe54..117221484e 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 4acf4a4c2f..4bfddbacd9 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..bb1dca8124 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,6 +96,27 @@ 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");
AC_DEFINE("HAVE_INTL", 1, "Internationalization support enabled");
} else {
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 a786fef45c..c3664b9ee9 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 08c07c2edc..ec707ce346 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 71d57d6d9b..e95f898c15 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 b1cb45db76..354cb548a7 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 a42f2e8809..4e430b6ea2 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¥é¥¤¥»¥ó¥¹¤Ë½¾¤¦¡£
+
+
¥¤¥ó¥¹¥È¡¼¥ë
¥±¡¼¥¹£±: Unix¤ÈCygwin´Ä¶­
@@ -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 Perl¡¢Java¡¢ASISʸˡ¤Î¥Æ¥¹¥È
+ 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¤ÎÎΰè¤òÆâÉô¤Ç³ä¤êÅö¤Æ¤Ê¤¤¡£
+
+ Àµ¾ï½ªÎ»Ìá¤êÃÍ: 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.h¤ÎÃæ¤ÎNOT_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.h¤ÎÃæ¤ÎNOT_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_PERL¤ÈONIG_SYNTAX_JAVA¤Ç¤ÏÍ­¸ú
- * \p{property}, \P{property}
- ⤷ONIG_SYNTAX_PERL¤ÈONIG_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", "¤¢v¤º¤¢v¤º", 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("\\w‹SŽÔ", " ‹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*", "ŽqŽqŽq", 0, 6);
+ x2("”n*", "Ž­”n”n”n”n", 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(".*(ƒtƒH)ƒ“Eƒ}(ƒ“()ƒVƒ…ƒ^)ƒCƒ“", "ƒtƒHƒ“Eƒ}ƒ“ƒ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", "’NH’NH", 0, 8);
+ x2("...(’NH|[‚ -‚¤]{3})\\1", "‚ a‚ ’NH’NH", 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", "‚ v‚¸‚ v‚¸", 0, 10);
+ x2("(?<‹ð‚©>•Ï|\\(\\g<‹ð‚©>\\))", "((((((•Ï))))))", 0, 14);
+ x2("\\A(?:\\g<ˆ¢_1>|\\g<‰]_2>|\\zI—¹ (?<ˆ¢_1>ŠÏ|Ž©\\g<‰]_2>Ž©)(?<‰]_2>Ý|•ìŽF\\g<ˆ¢_1>•ìŽF))$", "•ìŽFŽ©•ìŽFŽ©ÝŽ©•ìŽFŽ©•ìŽF", 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 d5ae7529df..276220ac11 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 0fcddddbd0..07568e6c2a 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 fbeaa60ef0..d74f0829d9 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 b73c842046..2b7d3e19c3 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 078b402ff4..88bb9ab21e 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 2710b9de23..ad4e25c66f 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 6078a5e758..e67aba8da0 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 8bcb02fdc5..6f2e404087 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 d3e900003e..7e447c63e5 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 3a7b91b995..e10e3702ea 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 e1557efce1..c24b974de8 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 f85f029571..d823ea89eb 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 f50371bf0d..bd9cee28f1 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 34d0a661ff..0000000000
--- a/ext/mysqli/mysqli_report.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- +----------------------------------------------------------------------+
- | PHP Version 5 |
- +----------------------------------------------------------------------+
- | Copyright (c) 1997-2013 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 0f5ccdd63d..3ea7bafe49 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 1f7e761c40..8b329bb5d0 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..5a7d69d665 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 20e63e1405..6e17412edb 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 e707c415db..40933630ed 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 39c1711b02..80e8156016 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 33c007026a..e6b0f08815 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 918697a5f5..8611d99864 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 3aeb8f2bb1..9ed109b7dc 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 8766a4b25d..0ca419b5a8 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 fb8a360240..5e617f5b2b 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 f98c163e74..de0bbae073 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 e209a71b49..699346c999 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 e813df2ee5..4ace69adcf 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 21be3fd37b..7116943cd5 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 c967fb3a9f..516200e0d5 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 40de45b06f..a1c589a8b7 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 77e1196413..fabceb4c8d 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 f32fe4afdc..aa914061d6 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 190ed697b6..38ef6cc855 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 3a1f6a0521..1eca92776f 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 2beb290312..a3a973e811 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 56790b0bc1..4d9c655932 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 1d22e6cc05..989781d665 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 dd23555b94..ae07bb7b51 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 271cb29717..f52eb65b06 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 5c07a3c3c9..99981f7e75 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 4f456a3ce7..0d29973cde 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 253784c364..26dd4c65ae 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 002135566c..016840cf04 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 6632bc88ff..f1079526f6 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 d8d7d0f47a..155e57d2cd 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..8c4c58e493
--- /dev/null
+++ b/ext/opcache/Optimizer/block_pass.c
@@ -0,0 +1,2090 @@
+#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);
+ }
+ 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..c932530128
--- /dev/null
+++ b/ext/opcache/Optimizer/zend_optimizer.c
@@ -0,0 +1,351 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2013 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..98275a20aa
--- /dev/null
+++ b/ext/opcache/Optimizer/zend_optimizer.h
@@ -0,0 +1,49 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2013 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..616bdf74f6
--- /dev/null
+++ b/ext/opcache/Optimizer/zend_optimizer_internal.h
@@ -0,0 +1,86 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2013 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..cb6ac342c4
--- /dev/null
+++ b/ext/opcache/README
@@ -0,0 +1,216 @@
+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.
+
+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.
+
+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..c0edf7e477
--- /dev/null
+++ b/ext/opcache/ZendAccelerator.c
@@ -0,0 +1,2818 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2013 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;
+}
+
+static inline 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);
+ zend_accel_hash_update(&ZCSG(hash), new_key, key_length + 1, 1, bucket);
+ } 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).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 &&
+ /* 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_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)
+ 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
+
+# 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);
+ 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);
+# else
+ ZCSG(interned_strings_start) = ZCSG(interned_strings_end) = NULL;
+# endif
+
+ 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);
+ 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;
+ }
+
+ 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;
+ }
+
+#if ZEND_EXTENSION_API_NO > PHP_5_3_X_API_NO
+# 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
+
+}
+
+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-2013", /* 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..cbc50d2b71
--- /dev/null
+++ b/ext/opcache/ZendAccelerator.h
@@ -0,0 +1,397 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2013 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 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..12f00554a1
--- /dev/null
+++ b/ext/opcache/shared_alloc_mmap.c
@@ -0,0 +1,78 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2013 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..f3377dec60
--- /dev/null
+++ b/ext/opcache/shared_alloc_posix.c
@@ -0,0 +1,98 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2013 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..a88cc2e196
--- /dev/null
+++ b/ext/opcache/shared_alloc_shm.c
@@ -0,0 +1,145 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2013 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..fb84857368
--- /dev/null
+++ b/ext/opcache/shared_alloc_win32.c
@@ -0,0 +1,344 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2013 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.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..57e4c306dd
--- /dev/null
+++ b/ext/opcache/tests/blacklist.phpt
@@ -0,0 +1,32 @@
+--TEST--
+Blacklist (with glob, quote and comments)
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.blacklist_filename={PWD}/opcache-*.blacklist
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--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/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..a1e469ff2f
--- /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/issue0149.phpt b/ext/opcache/tests/issue0149.phpt
new file mode 100644
index 0000000000..7044d39388
--- /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/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..eb0bc2146c
--- /dev/null
+++ b/ext/opcache/zend_accelerator_blacklist.c
@@ -0,0 +1,381 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2013 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..626b8d2c47
--- /dev/null
+++ b/ext/opcache/zend_accelerator_blacklist.h
@@ -0,0 +1,49 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2013 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..93349e3d17
--- /dev/null
+++ b/ext/opcache/zend_accelerator_debug.c
@@ -0,0 +1,99 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2013 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..2ff88e21d3
--- /dev/null
+++ b/ext/opcache/zend_accelerator_debug.h
@@ -0,0 +1,33 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2013 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..afd227c5d5
--- /dev/null
+++ b/ext/opcache/zend_accelerator_hash.c
@@ -0,0 +1,224 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2013 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..fdfddb4064
--- /dev/null
+++ b/ext/opcache/zend_accelerator_hash.h
@@ -0,0 +1,98 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2013 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..c3df1a68f7
--- /dev/null
+++ b/ext/opcache/zend_accelerator_module.c
@@ -0,0 +1,759 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2013 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;
+ }
+ }
+
+ 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;
+ }
+
+ 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..539b4e85af
--- /dev/null
+++ b/ext/opcache/zend_accelerator_module.h
@@ -0,0 +1,28 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2013 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..85d5a05fa2
--- /dev/null
+++ b/ext/opcache/zend_accelerator_util_funcs.c
@@ -0,0 +1,1077 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2013 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..ddaae86b28
--- /dev/null
+++ b/ext/opcache/zend_accelerator_util_funcs.h
@@ -0,0 +1,50 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2013 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..9f1940e061
--- /dev/null
+++ b/ext/opcache/zend_persist.c
@@ -0,0 +1,684 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2013 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..cf3fb73cdd
--- /dev/null
+++ b/ext/opcache/zend_persist.h
@@ -0,0 +1,29 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2013 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..18af756f6e
--- /dev/null
+++ b/ext/opcache/zend_persist_calc.c
@@ -0,0 +1,343 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2013 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 { \
+ const char *tmp = accel_new_interned_string((str), (len), !IS_INTERNED((str)) 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..cf4e0ff0f7
--- /dev/null
+++ b/ext/opcache/zend_shared_alloc.c
@@ -0,0 +1,494 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2013 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..e94ecab9b3
--- /dev/null
+++ b/ext/opcache/zend_shared_alloc.h
@@ -0,0 +1,182 @@
+/*
+ +----------------------------------------------------------------------+
+ | Zend OPcache |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1998-2013 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 26792e2428..59a58b1c00 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);
@@ -707,7 +719,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)) {
@@ -835,7 +847,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");
@@ -857,7 +869,7 @@ static int php_openssl_parse_config(struct php_x509_request * req, zval * option
}
PHP_SSL_CONFIG_SYNTAX_CHECK(request_extensions_section);
-
+
return SUCCESS;
}
/* }}} */
@@ -1037,10 +1049,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);
@@ -1099,7 +1111,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
@@ -1145,7 +1157,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;
}
/* }}} */
@@ -1365,14 +1377,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));
@@ -1493,11 +1505,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));
@@ -1714,8 +1726,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);
@@ -1768,7 +1780,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;
@@ -1862,11 +1874,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);
@@ -1875,7 +1887,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;
}
@@ -1916,7 +1928,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");
@@ -1952,9 +1964,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;
@@ -1965,13 +1977,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);
}
}
@@ -1997,7 +2009,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");
@@ -2020,7 +2032,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());
@@ -2037,13 +2049,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);
}
}
@@ -2067,12 +2079,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;
@@ -2102,12 +2114,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;
@@ -2115,7 +2127,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);
@@ -2127,13 +2139,13 @@ PHP_FUNCTION(openssl_pkcs12_read)
} else {
zval_dtor(zextracerts);
}
-
+
RETVAL_TRUE;
-
+
PKCS12_free(p12);
}
}
-
+
cleanup:
if (bio_in) {
BIO_free(bio_in);
@@ -2141,7 +2153,7 @@ PHP_FUNCTION(openssl_pkcs12_read)
if (pkey) {
EVP_PKEY_free(pkey);
}
- if (cert) {
+ if (cert) {
X509_free(cert);
}
}
@@ -2160,7 +2172,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");
@@ -2180,15 +2192,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);
@@ -2198,7 +2210,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,
@@ -2219,10 +2231,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;
@@ -2237,7 +2249,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++) {
@@ -2318,7 +2330,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;
}
@@ -2459,13 +2471,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");
@@ -2487,7 +2499,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;
}
@@ -2507,9 +2519,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");
@@ -2520,7 +2532,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) {
@@ -2537,7 +2549,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)) {
@@ -2550,11 +2562,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) {
@@ -2571,7 +2583,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) {
@@ -2590,12 +2602,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) {
@@ -2627,10 +2639,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");
}
@@ -2755,14 +2767,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 {
@@ -2787,7 +2799,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) {
@@ -2821,8 +2833,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;
@@ -2896,7 +2908,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);
@@ -2905,7 +2917,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:
@@ -2955,13 +2967,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;
}
/* }}} */
@@ -2990,7 +3002,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;
@@ -3121,7 +3133,7 @@ PHP_FUNCTION(openssl_pkey_new)
}
RETURN_FALSE;
}
- }
+ }
PHP_SSL_REQ_INIT(&req);
@@ -3150,7 +3162,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;
}
@@ -3162,11 +3174,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) {
@@ -3209,7 +3221,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;
}
@@ -3221,7 +3233,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) {
@@ -3343,7 +3355,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)) {
@@ -3367,7 +3379,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:
@@ -3388,7 +3400,7 @@ PHP_FUNCTION(openssl_pkey_get_details)
}
break;
case EVP_PKEY_DH:
-
+
ktype = OPENSSL_KEYTYPE_DH;
if (pkey->pkey.dh != NULL) {
@@ -3404,7 +3416,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;
@@ -3421,6 +3433,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]]]])
@@ -3438,7 +3501,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,
@@ -3446,7 +3509,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) {
@@ -3498,11 +3561,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;
@@ -3551,14 +3614,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;
}
@@ -3569,7 +3632,7 @@ PHP_FUNCTION(openssl_pkcs7_encrypt)
}
outfile = BIO_new_file(outfilename, "w");
- if (outfile == NULL) {
+ if (outfile == NULL) {
goto clean_exit;
}
@@ -3696,12 +3759,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;
}
}
@@ -3812,7 +3875,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;
}
@@ -3831,7 +3894,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:
@@ -3864,7 +3927,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;
@@ -3882,10 +3945,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:
@@ -3902,7 +3965,7 @@ PHP_FUNCTION(openssl_private_encrypt)
if (cryptedbuf) {
efree(cryptedbuf);
}
- if (keyresource == -1) {
+ if (keyresource == -1) {
EVP_PKEY_free(pkey);
}
}
@@ -3940,10 +4003,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);
@@ -3968,7 +4031,7 @@ PHP_FUNCTION(openssl_private_decrypt)
if (keyresource == -1) {
EVP_PKEY_free(pkey);
}
- if (cryptedbuf) {
+ if (cryptedbuf) {
efree(cryptedbuf);
}
}
@@ -3992,7 +4055,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");
@@ -4005,10 +4068,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:
@@ -4051,7 +4114,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");
@@ -4064,10 +4127,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);
@@ -4075,10 +4138,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);
@@ -4196,7 +4259,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;
}
@@ -4255,7 +4318,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) {
@@ -4350,7 +4413,7 @@ clean_exit:
if (key_resources[i] == -1) {
EVP_PKEY_free(pkeys[i]);
}
- if (eks[i]) {
+ if (eks[i]) {
efree(eks[i]);
}
}
@@ -4396,13 +4459,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;
@@ -4636,7 +4699,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
@@ -4699,7 +4762,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);
}
/* }}} */
@@ -4715,7 +4778,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);
}
/* }}} */
@@ -5054,7 +5117,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 427a643bf9..e6b064a277 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 6e74d8024f..a1a7ffc3f4 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);
}
diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c
index 47d58f51e1..b66f4722e8 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 b3cccac44f..574276b7ce 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 0d5d505fb7..7d34d9feb1 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 29d69898f4..37d8752d62 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 9622cb3cc2..04e71823b9 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 57c683ab0f..91d0bf0412 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 32d13bafaf..cd86503dd7 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 0d4e525cd1..78c4ceefe9 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 65d7435a73..24f7aa2182 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 c8f7d3d432..32d407af70 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 a48cde2f97..98af1bffc2 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 c85687ef5c..13b3d6428e 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 daa85f1b70..fcfb647184 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 aeb11851c5..7d2922fbaa 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 8275c9c994..d3a3aab6b9 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 a6d7bff414..f8325d0c63 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 924138d8fa..f4197a5b11 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 227bd15dc7..31d12e3da7 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 6ba745e9cb..e3b64859b8 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 bd460696bd..d4032ca947 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 c4a7c554f0..b1f7484f24 100644
--- a/ext/reflection/php_reflection.c
+++ b/ext/reflection/php_reflection.c
@@ -3087,6 +3087,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)
@@ -4185,32 +4193,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;
@@ -4222,7 +4238,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;
@@ -4235,6 +4251,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) {
@@ -4243,9 +4260,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);
}
}
@@ -4275,9 +4290,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);
@@ -4286,19 +4302,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) {
@@ -4307,8 +4332,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;
@@ -4320,7 +4343,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;
@@ -4333,6 +4356,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) {
@@ -4341,9 +4365,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);
}
}
@@ -5697,6 +5719,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 1665ba53aa..004d9d4637 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,25 @@ 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_files_open(data, PS(id) TSRMLS_CC);
if (data->fd < 0) {
return FAILURE;
}
@@ -454,6 +456,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 c97d168b1e..94cbd6d025 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 e0d16d1924..3d37b981bc 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,25 @@ 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);
+ }
+
+ sd = ps_sd_lookup(data, PS(id), 0);
if (sd) {
*vallen = sd->datalen;
*val = emalloc(sd->datalen + 1);
@@ -444,6 +476,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 57d7bd0edc..1b606b9a33 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 fd149ccff4..6b2998c426 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 1ed1e7bbd5..ea53af9ebe 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 adc5e70402..e8e79f0fa6 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 e699cb9b5c..7bb6584621 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,38 @@ 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;
}
}
+ 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 rase 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));
+ */
+ }
+ 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;
}
}
/* }}} */
@@ -745,6 +788,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)
@@ -783,6 +827,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))
@@ -964,10 +1046,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)
};
@@ -1179,6 +1262,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"
@@ -1226,6 +1310,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));
}
}
@@ -1290,10 +1377,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;
@@ -1440,19 +1532,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) {
@@ -1598,7 +1685,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)
{
@@ -1610,11 +1697,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;
@@ -1628,11 +1711,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) {
@@ -1650,7 +1733,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;
}
@@ -1682,6 +1787,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;
}
@@ -1689,7 +1798,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);
@@ -1703,7 +1813,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]);
}
@@ -1745,9 +1855,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;
}
@@ -1792,11 +1902,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;
}
@@ -2013,13 +2125,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)
@@ -2062,6 +2175,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[]
@@ -2103,6 +2219,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[] = {
@@ -2112,6 +2236,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 }
};
/* }}} */
@@ -2171,7 +2296,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;
@@ -2196,7 +2321,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;
@@ -2220,15 +2345,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_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 2358f2be65..eba46b9091 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 93c2b21ddc..4e2510afc8 100644
--- a/ext/snmp/snmp.c
+++ b/ext/snmp/snmp.c
@@ -2482,20 +2482,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 897956d91b..5cec3e558e 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 7fc755d51b..86ab03d9c8 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 0e37db5d4c..7d0a3c16f1 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 9371df6fb4..00e80efbcb 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");
}
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/sockets/config.m4 b/ext/sockets/config.m4
index 4032621ce6..9c75249646 100644
--- a/ext/sockets/config.m4
+++ b/ext/sockets/config.m4
@@ -43,6 +43,6 @@ if test "$PHP_SOCKETS" != "no"; 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])
+ 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 43b6f7dddf..ecf3a65a32 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 f46a6a8f61..81a1bca799 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 fabc9c4c3e..17abf95a19 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,6 +94,17 @@ 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
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..64523c3191
--- /dev/null
+++ b/ext/sockets/sockaddr_conv.c
@@ -0,0 +1,136 @@
+#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
+
+#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;
+ hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG;
+ 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 d094b3cc1d..4a2a41b5fd 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>
@@ -85,10 +64,13 @@
# 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 +94,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 +249,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 +342,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 +359,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 +390,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 +553,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 +600,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 +610,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 +624,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 +637,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 +677,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 +692,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 +724,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 +755,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 +902,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 +971,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 +1008,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 +1362,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 +1395,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 +1416,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 +1435,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 +1472,7 @@ PHP_FUNCTION(socket_strerror)
return;
}
- RETURN_STRING(php_strerror(arg1 TSRMLS_CC), 1);
+ RETURN_STRING(sockets_strerror(arg1 TSRMLS_CC), 1);
}
/* }}} */
@@ -1663,7 +1481,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 +1499,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 +1519,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 +1534,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 +1869,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 +1921,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 +1938,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 +1956,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 +1966,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 +2062,7 @@ ipv6_loop_hops:
#endif
default:
+default_case:
convert_to_long_ex(arg4);
ov = Z_LVAL_PP(arg4);
@@ -2405,12 +2071,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 +2114,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 +2213,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 +2268,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 +2294,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 +2303,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 35f4e5056b..716990d80f 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 552f67b185..ca8076a957 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 7f0ce631b1..3dc7b7925c 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 f7be97d4ce..273bc7506a 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 fec7e2c4ac..86a5371ed3 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 d2de85b2a7..cb1f68dcf1 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 eb8247654e..30532756cb 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 39cc0d1337..73d9d2e614 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 131e70102c..b558f70340 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 1deacc7159..360a691d38 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 ba0051630f..96b3c30bbd 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 7ce0819491..530c8d0e63 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..2770d162fb 100644
--- a/ext/standard/credits_ext.h
+++ b/ext/standard/credits_ext.h
@@ -17,8 +17,8 @@ CREDIT_LINE("COM and .Net", "Wez Furlong");
CREDIT_LINE("ctype", "Hartmut Holzgraefe");
CREDIT_LINE("cURL", "Sterling Hughes");
CREDIT_LINE("Date/Time Support", "Derick Rethans");
-CREDIT_LINE("DB-LIB (MS SQL, Sybase)", "Wez Furlong, Frank M. Kromann");
CREDIT_LINE("DBA", "Sascha Schumann, Marcus Boerger");
+CREDIT_LINE("DB-LIB (MS SQL, Sybase)", "Wez Furlong, Frank M. Kromann");
CREDIT_LINE("DOM", "Christian Stocker, Rob Richards, Marcus Boerger");
CREDIT_LINE("enchant", "Pierre-Alain Joye, Ilia Alshanetsky");
CREDIT_LINE("ereg", "Rasmus Lerdorf, Jim Winstead, Jaakko Hyvätti");
@@ -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("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 Schlueter");
+CREDIT_LINE("MySQL", "Zeev Suraski, Zak Greant, Georg Richter, Andrey Hristov");
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");
@@ -68,8 +68,8 @@ CREDIT_LINE("SNMP", "Rasmus Lerdorf, Harrie Hazewinkel, Mike Jackson, Steven Law
CREDIT_LINE("SOAP", "Brad Lafountain, Shane Caraveo, Dmitry Stogov");
CREDIT_LINE("Sockets", "Chris Vandomelen, Sterling Hughes, Daniel Beulshausen, Jason Greene");
CREDIT_LINE("SPL", "Marcus Boerger, Etienne Kneuss");
-CREDIT_LINE("SQLite 3.x driver for PDO", "Wez Furlong");
CREDIT_LINE("SQLite3", "Scott MacVicar, Ilia Alshanetsky, Brad Dewar");
+CREDIT_LINE("SQLite 3.x driver for PDO", "Wez Furlong");
CREDIT_LINE("Sybase-CT", "Zeev Suraski, Tom May, Timm Friebe");
CREDIT_LINE("System V Message based IPC", "Wez Furlong");
CREDIT_LINE("System V Semaphores", "Tom May");
@@ -77,9 +77,9 @@ CREDIT_LINE("System V Shared Memory", "Christian Cartus");
CREDIT_LINE("tidy", "John Coggeshall, Ilia Alshanetsky");
CREDIT_LINE("tokenizer", "Andrei Zmievski, Johannes Schlueter");
CREDIT_LINE("WDDX", "Andrei Zmievski");
-CREDIT_LINE("XML", "Stig Bakken, Thies C. Arntzen, Sterling Hughes");
CREDIT_LINE("XMLReader", "Rob Richards");
CREDIT_LINE("xmlrpc", "Dan Libby");
+CREDIT_LINE("XML", "Stig Bakken, Thies C. Arntzen, Sterling Hughes");
CREDIT_LINE("XMLWriter", "Rob Richards, Pierre-Alain Joye");
CREDIT_LINE("XSL", "Christian Stocker, Rob Richards");
CREDIT_LINE("Zip", "Pierre-Alain Joye");
diff --git a/ext/standard/crypt.c b/ext/standard/crypt.c
index c6e0351af2..113a5bd0f5 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 4d6a94766a..ceb975e93b 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 f7af63bcf4..ad6bdad34f 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 0a4512ecd4..2bcdfd64bf 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 73be21d9a9..2713d23f1d 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 da08c36cf8..5310ff6c03 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 3e5073591e..f9b8021950 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 9af70f2856..f854fddf49 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 cb2e469845..48e0e85cc5 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 aca20796fc..46a0dfc240 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 b4f6a926c1..9499981f27 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 be2d655263..f6b3d5406e 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 eb80395f53..3f525a793a 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..ca852038a6
--- /dev/null
+++ b/ext/standard/password.c
@@ -0,0 +1,460 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 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 942c33f9e8..1cf2779071 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 47d78377c5..6025685539 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..abc343d66e
--- /dev/null
+++ b/ext/standard/php_password.h
@@ -0,0 +1,48 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 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 2ec851632e..3c7535da1f 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 292b66710f..e434ae05f4 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 6373751107..d78ca9976b 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 f487763b9e..0610ecfc49 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 c744cb46fc..b9d7427eb9 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;
}
@@ -2851,7 +2852,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,
@@ -2877,62 +2878,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)
{
@@ -3030,7 +2975,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++) {
@@ -5652,7 +5603,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/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/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/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/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/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/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/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/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 5c4085a28a..5d93f66f5b 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 236276a648..2c2dfda1b1 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 b44be124a1..1e5c38a373 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 2d0339a6a3..fb2a310f4c 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 8a35e0a5af..f7546428b1 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/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 132a7f299f..ee96e2eaa1 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 1f563da6b5..57b29e1dd7 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 967da6a490..afeca90489 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 c2d4497ba1..a4c66d259b 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 424785f566..1c94e45fd3 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 adf282120e..aae55c8b3e 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 925b554a56..b73cbcfe24 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 6cbd91a797..41e1b9fa23 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 1f435bbb00..d3ec27bafe 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 5f276ad788..8ccd9e161c 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;